Move to src dir.
authorRadek Czajka <rczajka@rczajka.pl>
Sun, 29 Sep 2024 21:04:11 +0000 (23:04 +0200)
committerRadek Czajka <rczajka@rczajka.pl>
Sun, 29 Sep 2024 21:04:11 +0000 (23:04 +0200)
1078 files changed:
.gitmodules
Dockerfile
api/__init__.py [deleted file]
api/admin.py [deleted file]
api/handlers.py [deleted file]
api/helpers.py [deleted file]
api/models.py [deleted file]
api/templates/oauth/challenge.html [deleted file]
api/templates/piston/authorize_token.html [deleted file]
api/tests.py [deleted file]
api/urls.py [deleted file]
api/views.py [deleted file]
catalogue/__init__.py [deleted file]
catalogue/admin.py [deleted file]
catalogue/forms.py [deleted file]
catalogue/management/__init__.py [deleted file]
catalogue/management/commands/__init__.py [deleted file]
catalogue/management/commands/extract_attachments.py [deleted file]
catalogue/management/commands/importlessons.py [deleted file]
catalogue/management/commands/repackage.py [deleted file]
catalogue/management/commands/republish.py [deleted file]
catalogue/migrations/0001_initial.py [deleted file]
catalogue/migrations/0002_auto__add_field_section_slug.py [deleted file]
catalogue/migrations/0003_auto__chg_field_lesson_xml_file__chg_field_lesson_student_package__chg.py [deleted file]
catalogue/migrations/0004_auto__add_part__add_attachment__add_field_lesson_pdf__add_field_lesson.py [deleted file]
catalogue/migrations/0005_auto__add_field_lesson_dc.py [deleted file]
catalogue/migrations/0006_auto__add_field_attachment_slug__add_field_attachment_ext__add_unique_.py [deleted file]
catalogue/migrations/0007_auto__add_field_lesson_type__chg_field_lesson_section.py [deleted file]
catalogue/migrations/0008_auto__del_field_lesson_depth.py [deleted file]
catalogue/migrations/0009_auto__add_field_section_xml_file.py [deleted file]
catalogue/migrations/0010_auto.py [deleted file]
catalogue/migrations/0011_auto__chg_field_lesson_xml_file__chg_field_lesson_student_pdf__chg_fie.py [deleted file]
catalogue/migrations/0012_auto__add_lessonstub.py [deleted file]
catalogue/migrations/0013_auto__add_field_section_image.py [deleted file]
catalogue/migrations/0014_auto__add_field_section_summary.py [deleted file]
catalogue/migrations/0015_auto__add_field_lesson_description.py [deleted file]
catalogue/migrations/0016_auto__add_field_section_pic__add_field_section_pic_attribution__add_fi.py [deleted file]
catalogue/migrations/0017_auto__chg_field_attachment_file.py [deleted file]
catalogue/migrations/0018_auto__add_field_lesson_weasy_pdf.py [deleted file]
catalogue/migrations/__init__.py [deleted file]
catalogue/models.py [deleted file]
catalogue/publish.py [deleted file]
catalogue/search_indexes.py [deleted file]
catalogue/static/catalogue/css/carousel.css [deleted file]
catalogue/static/catalogue/css/carousel.scss [deleted file]
catalogue/static/catalogue/css/exercise.css [deleted file]
catalogue/static/catalogue/css/exercise.scss [deleted file]
catalogue/static/catalogue/css/layout.css [deleted file]
catalogue/static/catalogue/css/layout.scss [deleted file]
catalogue/static/catalogue/css/lesson.css [deleted file]
catalogue/static/catalogue/css/lesson.scss [deleted file]
catalogue/static/catalogue/css/section_list.css [deleted file]
catalogue/static/catalogue/css/section_list.scss [deleted file]
catalogue/static/catalogue/img/carousel-left.png [deleted file]
catalogue/static/catalogue/img/carousel-right.png [deleted file]
catalogue/static/catalogue/img/carousel/katarzyna-wlodarczyk.jpg [deleted file]
catalogue/static/catalogue/js/carousel.js [deleted file]
catalogue/static/catalogue/js/edumed.js [deleted file]
catalogue/static/catalogue/js/jquery-ui-1.10.0.custom.js [deleted file]
catalogue/static/catalogue/js/jquery.cycle.all.js [deleted file]
catalogue/static/catalogue/js/lesson-list.js [deleted file]
catalogue/static/catalogue/js/lesson.js [deleted file]
catalogue/templates/catalogue/latest_blog_posts.html [deleted file]
catalogue/templates/catalogue/lesson/added-var/lesson_detail.html [deleted file]
catalogue/templates/catalogue/lesson/added/lesson_detail.html [deleted file]
catalogue/templates/catalogue/lesson/appendix/lesson_detail.html [deleted file]
catalogue/templates/catalogue/lesson/box-icons.html [deleted file]
catalogue/templates/catalogue/lesson/course/lesson_detail.html [deleted file]
catalogue/templates/catalogue/lesson/lesson_detail.html [deleted file]
catalogue/templates/catalogue/lesson/project/lesson_detail.html [deleted file]
catalogue/templates/catalogue/lesson/synthetic/lesson_detail.html [deleted file]
catalogue/templates/catalogue/lesson_list.html [deleted file]
catalogue/templates/catalogue/section_detail.html [deleted file]
catalogue/templates/catalogue/snippets/carousel.html [deleted file]
catalogue/templates/catalogue/snippets/lesson_link.html [deleted file]
catalogue/templates/catalogue/snippets/lesson_nav.html [deleted file]
catalogue/templates/catalogue/snippets/lesson_or_stub.html [deleted file]
catalogue/templates/catalogue/snippets/level_box.html [deleted file]
catalogue/templates/catalogue/snippets/levels_main.html [deleted file]
catalogue/templates/search/indexes/catalogue/lesson_text.txt [deleted file]
catalogue/templatetags/__init__.py [deleted file]
catalogue/templatetags/catalogue_tags.py [deleted file]
catalogue/tests.py [deleted file]
catalogue/urls.py [deleted file]
catalogue/views.py [deleted file]
chunks/__init__.py [deleted file]
chunks/admin.py [deleted file]
chunks/fixtures/chunks.json [deleted file]
chunks/locale/de/LC_MESSAGES/django.mo [deleted file]
chunks/locale/de/LC_MESSAGES/django.po [deleted file]
chunks/locale/en/LC_MESSAGES/django.mo [deleted file]
chunks/locale/en/LC_MESSAGES/django.po [deleted file]
chunks/locale/es/LC_MESSAGES/django.mo [deleted file]
chunks/locale/es/LC_MESSAGES/django.po [deleted file]
chunks/locale/fr/LC_MESSAGES/django.mo [deleted file]
chunks/locale/fr/LC_MESSAGES/django.po [deleted file]
chunks/locale/it/LC_MESSAGES/django.mo [deleted file]
chunks/locale/it/LC_MESSAGES/django.po [deleted file]
chunks/locale/jp/LC_MESSAGES/django.mo [deleted file]
chunks/locale/jp/LC_MESSAGES/django.po [deleted file]
chunks/locale/lt/LC_MESSAGES/django.mo [deleted file]
chunks/locale/lt/LC_MESSAGES/django.po [deleted file]
chunks/locale/pl/LC_MESSAGES/django.mo [deleted file]
chunks/locale/pl/LC_MESSAGES/django.po [deleted file]
chunks/locale/ru/LC_MESSAGES/django.mo [deleted file]
chunks/locale/ru/LC_MESSAGES/django.po [deleted file]
chunks/locale/uk/LC_MESSAGES/django.mo [deleted file]
chunks/locale/uk/LC_MESSAGES/django.po [deleted file]
chunks/models.py [deleted file]
chunks/templatetags/__init__.py [deleted file]
chunks/templatetags/chunks.py [deleted file]
comment/__init__.py [deleted file]
comment/admin.py [deleted file]
comment/locale/pl/LC_MESSAGES/django.mo [deleted file]
comment/locale/pl/LC_MESSAGES/django.po [deleted file]
comment/migrations/0001_initial.py [deleted file]
comment/migrations/0002_auto__add_field_commentdocument_language_code.py [deleted file]
comment/migrations/__init__.py [deleted file]
comment/models.py [deleted file]
comment/templates/comment/commentdocument_detail.html [deleted file]
comment/templates/comment/commentdocument_list.html [deleted file]
comment/urls.py [deleted file]
comment/views.py [deleted file]
contact/__init__.py [deleted file]
contact/admin.py [deleted file]
contact/fields.py [deleted file]
contact/forms.py [deleted file]
contact/locale/pl/LC_MESSAGES/django.mo [deleted file]
contact/locale/pl/LC_MESSAGES/django.po [deleted file]
contact/mailing.py [deleted file]
contact/management/__init__.py [deleted file]
contact/management/commands/__init__.py [deleted file]
contact/management/commands/export_newsletter.py [deleted file]
contact/migrations/0001_initial.py [deleted file]
contact/migrations/0002_auto__add_attachment.py [deleted file]
contact/migrations/0003_auto__add_field_contact_key.py [deleted file]
contact/migrations/__init__.py [deleted file]
contact/models.py [deleted file]
contact/templates/admin/contact/contact/change_list.html [deleted file]
contact/templates/contact/disabled_contact_form.html [deleted file]
contact/templates/contact/form.html [deleted file]
contact/templates/contact/mail_body.txt [deleted file]
contact/templates/contact/mail_managers_body.txt [deleted file]
contact/templates/contact/mail_managers_subject.txt [deleted file]
contact/templates/contact/mail_subject.txt [deleted file]
contact/templates/contact/thanks.html [deleted file]
contact/templatetags/__init__.py [deleted file]
contact/templatetags/contact_tags.py [deleted file]
contact/urls.py [deleted file]
contact/views.py [deleted file]
contact/widgets.py [deleted file]
curriculum/__init__.py [deleted file]
curriculum/admin.py [deleted file]
curriculum/fixtures/competences.json [deleted file]
curriculum/fixtures/curriculum.json [deleted file]
curriculum/locale/pl/LC_MESSAGES/django.mo [deleted file]
curriculum/locale/pl/LC_MESSAGES/django.po [deleted file]
curriculum/migrations/0001_initial.py [deleted file]
curriculum/migrations/0002_auto__add_field_level_group.py [deleted file]
curriculum/migrations/0003_auto__chg_field_level_slug.py [deleted file]
curriculum/migrations/0004_auto__add_curriculum__add_curriculumlevel__add_curriculumcourse.py [deleted file]
curriculum/migrations/0005_auto__add_field_curriculumcourse_accusative.py [deleted file]
curriculum/migrations/0006_auto__add_field_competencelevel_description_pl__add_field_competencele.py [deleted file]
curriculum/migrations/0007_translatable_fields_data_migration.py [deleted file]
curriculum/migrations/0008_auto__del_field_competencelevel_description__del_field_section_name__d.py [deleted file]
curriculum/migrations/0009_auto__chg_field_competencelevel_description_en__chg_field_competencele.py [deleted file]
curriculum/migrations/0010_auto__add_field_level_meta_name.py [deleted file]
curriculum/migrations/0011_meta_name.py [deleted file]
curriculum/migrations/0012_auto__add_unique_level_meta_name__add_unique_level_slug.py [deleted file]
curriculum/migrations/0013_auto__add_field_level_package__add_field_level_student_package.py [deleted file]
curriculum/migrations/0014_auto__add_unique_curriculum_identifier.py [deleted file]
curriculum/migrations/0015_auto__chg_field_curriculum_title.py [deleted file]
curriculum/migrations/0016_auto__add_field_curriculumlevel_verbose.py [deleted file]
curriculum/migrations/0017_verbose_level.py [deleted file]
curriculum/migrations/__init__.py [deleted file]
curriculum/models.py [deleted file]
curriculum/static/curriculum/curriculum.css [deleted file]
curriculum/static/curriculum/curriculum.js [deleted file]
curriculum/static/curriculum/curriculum.scss [deleted file]
curriculum/templates/curriculum/competence_detail.html [deleted file]
curriculum/templates/curriculum/competence_list.html [deleted file]
curriculum/templates/curriculum/snippets/competence.html [deleted file]
curriculum/templates/curriculum/snippets/course_box.html [deleted file]
curriculum/templates/curriculum/snippets/course_boxes.html [deleted file]
curriculum/templates/curriculum/snippets/course_boxes_toc.html [deleted file]
curriculum/templates/curriculum/snippets/curriculum.html [deleted file]
curriculum/templatetags/__init__.py [deleted file]
curriculum/templatetags/curriculum_tags.py [deleted file]
curriculum/tests.py [deleted file]
curriculum/urls.py [deleted file]
curriculum/views.py [deleted file]
docker-compose.yml
edumed/__init__.py [deleted file]
edumed/contact_forms.py [deleted file]
edumed/contact_forms_test.py [deleted file]
edumed/context_processors.py [deleted file]
edumed/forms.py [deleted file]
edumed/forum.py [deleted file]
edumed/locale-contrib/django.pot [deleted file]
edumed/locale-contrib/pl/LC_MESSAGES/django.mo [deleted file]
edumed/locale-contrib/pl/LC_MESSAGES/django.po [deleted file]
edumed/locale/pl/LC_MESSAGES/django.mo [deleted file]
edumed/locale/pl/LC_MESSAGES/django.po [deleted file]
edumed/milurls.py [deleted file]
edumed/settings/__init__.py [deleted file]
edumed/settings/apps.py [deleted file]
edumed/settings/auth.py [deleted file]
edumed/settings/basic.py [deleted file]
edumed/settings/cache.py [deleted file]
edumed/settings/context.py [deleted file]
edumed/settings/contrib.py [deleted file]
edumed/settings/custom.py [deleted file]
edumed/settings/locale.py [deleted file]
edumed/settings/logging.py [deleted file]
edumed/settings/middleware.py [deleted file]
edumed/settings/paths.py [deleted file]
edumed/settings/search.py [deleted file]
edumed/settings/static.py [deleted file]
edumed/static/css/_mixins.scss [deleted file]
edumed/static/css/_vars.scss [deleted file]
edumed/static/css/base.css [deleted file]
edumed/static/css/base.scss [deleted file]
edumed/static/css/form.css [deleted file]
edumed/static/css/form.scss [deleted file]
edumed/static/css/forum.css [deleted file]
edumed/static/css/forum.scss [deleted file]
edumed/static/css/main.css [deleted file]
edumed/static/css/main.scss [deleted file]
edumed/static/css/mil.css [deleted file]
edumed/static/css/mil.scss [deleted file]
edumed/static/css/promobox.css [deleted file]
edumed/static/css/promobox.scss [deleted file]
edumed/static/img/banners/440px_Forum.jpg [deleted file]
edumed/static/img/banners/440px_Salon-1.jpg [deleted file]
edumed/static/img/banners/960x150_edukacjaMedialna.jpg [deleted file]
edumed/static/img/banners/OC_collegium_web_970x250.jpg [deleted file]
edumed/static/img/banners/oc-banner.png [deleted file]
edumed/static/img/favicon.png [deleted file]
edumed/static/img/header-bar.png [deleted file]
edumed/static/img/icons/activity-kind.png [deleted file]
edumed/static/img/icons/activity-time.png [deleted file]
edumed/static/img/icons/activity-tools.png [deleted file]
edumed/static/img/icons/activity_dark.png [deleted file]
edumed/static/img/icons/activity_orange.png [deleted file]
edumed/static/img/icons/activity_white.png [deleted file]
edumed/static/img/icons/announce_dark.png [deleted file]
edumed/static/img/icons/announce_orange.png [deleted file]
edumed/static/img/icons/announce_white.png [deleted file]
edumed/static/img/icons/internet_black.png [deleted file]
edumed/static/img/icons/knowledge_dark.png [deleted file]
edumed/static/img/icons/knowledge_orange.png [deleted file]
edumed/static/img/icons/knowledge_white.png [deleted file]
edumed/static/img/icons/lesson-plan_dark.png [deleted file]
edumed/static/img/icons/lesson-plan_orange.png [deleted file]
edumed/static/img/icons/lesson-plan_white.png [deleted file]
edumed/static/img/icons/nointernet_black.png [deleted file]
edumed/static/img/icons/reference_dark.png [deleted file]
edumed/static/img/icons/reference_orange.png [deleted file]
edumed/static/img/icons/reference_white.png [deleted file]
edumed/static/img/icons/time_dark.png [deleted file]
edumed/static/img/icons/time_orange.png [deleted file]
edumed/static/img/icons/time_white.png [deleted file]
edumed/static/img/logo-mil.png [deleted file]
edumed/static/img/logo-oc.png [deleted file]
edumed/static/img/logo.png [deleted file]
edumed/static/img/logo_fnp.png [deleted file]
edumed/static/img/logo_fnp_white.png [deleted file]
edumed/static/img/menu/dla-trenera.png [deleted file]
edumed/static/img/menu/dla-trenera_active.png [deleted file]
edumed/static/img/menu/dla-ucznia.png [deleted file]
edumed/static/img/menu/dla-ucznia_active.png [deleted file]
edumed/static/img/menu/kompetencje.png [deleted file]
edumed/static/img/menu/kompetencje_active.png [deleted file]
edumed/static/img/menu/lekcje.png [deleted file]
edumed/static/img/menu/lekcje_active.png [deleted file]
edumed/static/img/menu/mil/catalog.png [deleted file]
edumed/static/img/menu/mil/consultations.png [deleted file]
edumed/static/img/menu/mil/contact.png [deleted file]
edumed/static/img/menu/mil/knowledgebase.png [deleted file]
edumed/static/img/menu/mil/lang_en.png [deleted file]
edumed/static/img/menu/mil/lang_pl.png [deleted file]
edumed/static/img/menu/mil/takepart.png [deleted file]
edumed/static/img/menu/o-nas.png [deleted file]
edumed/static/img/menu/o-nas_active.png [deleted file]
edumed/static/img/menu/old/katalog.png [deleted file]
edumed/static/img/menu/old/katalog_active.png [deleted file]
edumed/static/img/menu/old/kontakt.png [deleted file]
edumed/static/img/menu/old/kontakt_active.png [deleted file]
edumed/static/img/menu/old/lekcje.png [deleted file]
edumed/static/img/menu/old/lekcje_active.png [deleted file]
edumed/static/img/menu/old/o-nas.png [deleted file]
edumed/static/img/menu/old/o-nas_active.png [deleted file]
edumed/static/img/menu/old/szkolenia.png [deleted file]
edumed/static/img/menu/old/szkolenia_active.png [deleted file]
edumed/static/img/menu/old/wesprzyj.png [deleted file]
edumed/static/img/menu/old/wesprzyj_active.png [deleted file]
edumed/static/img/menu/old/wspolpraca.png [deleted file]
edumed/static/img/menu/old/wspolpraca_active.png [deleted file]
edumed/static/img/menu/olimpiada.png [deleted file]
edumed/static/img/menu/olimpiada/harmonogram.png [deleted file]
edumed/static/img/menu/olimpiada/harmonogram_active.png [deleted file]
edumed/static/img/menu/olimpiada/komitet.png [deleted file]
edumed/static/img/menu/olimpiada/komitet_active.png [deleted file]
edumed/static/img/menu/olimpiada/kontakt.png [deleted file]
edumed/static/img/menu/olimpiada/kontakt_active.png [deleted file]
edumed/static/img/menu/olimpiada/literatura.png [deleted file]
edumed/static/img/menu/olimpiada/literatura_active.png [deleted file]
edumed/static/img/menu/olimpiada/program.png [deleted file]
edumed/static/img/menu/olimpiada/program_active.png [deleted file]
edumed/static/img/menu/olimpiada/regulamin.png [deleted file]
edumed/static/img/menu/olimpiada/regulamin_active.png [deleted file]
edumed/static/img/menu/olimpiada/svg/harmonogram.svg [deleted file]
edumed/static/img/menu/olimpiada/svg/harmonogram_active.svg [deleted file]
edumed/static/img/menu/olimpiada/svg/komitet.svg [deleted file]
edumed/static/img/menu/olimpiada/svg/komitet_active.svg [deleted file]
edumed/static/img/menu/olimpiada/svg/kontakt.svg [deleted file]
edumed/static/img/menu/olimpiada/svg/kontakt_active.svg [deleted file]
edumed/static/img/menu/olimpiada/svg/literatura.svg [deleted file]
edumed/static/img/menu/olimpiada/svg/literatura_active.svg [deleted file]
edumed/static/img/menu/olimpiada/svg/program.svg [deleted file]
edumed/static/img/menu/olimpiada/svg/program_active.svg [deleted file]
edumed/static/img/menu/olimpiada/svg/regulamin.svg [deleted file]
edumed/static/img/menu/olimpiada/svg/regulamin_active.svg [deleted file]
edumed/static/img/menu/olimpiada_active.png [deleted file]
edumed/static/img/menu/svg/convert.txt [deleted file]
edumed/static/img/menu/svg/dla-trenera.svg [deleted file]
edumed/static/img/menu/svg/dla-trenera_active.svg [deleted file]
edumed/static/img/menu/svg/dla-ucznia.svg [deleted file]
edumed/static/img/menu/svg/dla-ucznia_active.svg [deleted file]
edumed/static/img/menu/svg/kompetencje.svg [deleted file]
edumed/static/img/menu/svg/kompetencje_active.svg [deleted file]
edumed/static/img/menu/svg/lekcje.svg [deleted file]
edumed/static/img/menu/svg/lekcje_active.svg [deleted file]
edumed/static/img/menu/svg/o-nas.svg [deleted file]
edumed/static/img/menu/svg/o-nas_active.svg [deleted file]
edumed/static/img/menu/svg/olimpiada.svg [deleted file]
edumed/static/img/menu/svg/olimpiada_active.svg [deleted file]
edumed/static/img/nina-white.png [deleted file]
edumed/static/img/nina.jpg [deleted file]
edumed/static/img/ornaments/draggable.png [deleted file]
edumed/static/img/sciezki-kopernika/cc.jpg [deleted file]
edumed/static/img/sciezki-kopernika/fe.jpg [deleted file]
edumed/static/img/sciezki-kopernika/fnp.png [deleted file]
edumed/static/img/sciezki-kopernika/ue.jpg [deleted file]
edumed/static/jquery/colorbox/colorbox.css [deleted file]
edumed/static/jquery/colorbox/images/border.png [deleted file]
edumed/static/jquery/colorbox/images/controls.png [deleted file]
edumed/static/jquery/colorbox/images/ie6/borderBottomCenter.png [deleted file]
edumed/static/jquery/colorbox/images/ie6/borderBottomLeft.png [deleted file]
edumed/static/jquery/colorbox/images/ie6/borderBottomRight.png [deleted file]
edumed/static/jquery/colorbox/images/ie6/borderMiddleLeft.png [deleted file]
edumed/static/jquery/colorbox/images/ie6/borderMiddleRight.png [deleted file]
edumed/static/jquery/colorbox/images/ie6/borderTopCenter.png [deleted file]
edumed/static/jquery/colorbox/images/ie6/borderTopLeft.png [deleted file]
edumed/static/jquery/colorbox/images/ie6/borderTopRight.png [deleted file]
edumed/static/jquery/colorbox/images/loading.gif [deleted file]
edumed/static/jquery/colorbox/images/loading_background.png [deleted file]
edumed/static/jquery/colorbox/images/overlay.png [deleted file]
edumed/static/jquery/colorbox/jquery.colorbox-min.js [deleted file]
edumed/static/jquery/colorbox/jquery.colorbox-pl.js [deleted file]
edumed/static/js/formset.js [deleted file]
edumed/templates/404.html [deleted file]
edumed/templates/404_mil.html [deleted file]
edumed/templates/500.html [deleted file]
edumed/templates/annoy.html [deleted file]
edumed/templates/base.html [deleted file]
edumed/templates/base_forum.html [deleted file]
edumed/templates/base_mil.html [deleted file]
edumed/templates/base_super.html [deleted file]
edumed/templates/contact/collegium-mlodych-test/form.html [deleted file]
edumed/templates/contact/collegium-mlodych-test/mail_subject.txt [deleted file]
edumed/templates/contact/collegium-mlodych-test/results.html [deleted file]
edumed/templates/contact/collegium-mlodych-test/results_email.txt [deleted file]
edumed/templates/contact/collegium-mlodych/form.html [deleted file]
edumed/templates/contact/collegium-mlodych/mail_body.txt [deleted file]
edumed/templates/contact/collegium-mlodych/mail_subject.txt [deleted file]
edumed/templates/contact/collegium-mlodych/on_hold.html [deleted file]
edumed/templates/contact/collegium-mlodych/thanks.html [deleted file]
edumed/templates/contact/konkurs/mail_body.txt [deleted file]
edumed/templates/contact/konkurs/mail_subject.txt [deleted file]
edumed/templates/contact/konkurs/thanks.html [deleted file]
edumed/templates/contact/misja-cybernautow/mail_body.txt [deleted file]
edumed/templates/contact/olimpiada/form.html [deleted file]
edumed/templates/contact/olimpiada/mail_body.txt [deleted file]
edumed/templates/contact/olimpiada/mail_subject.txt [deleted file]
edumed/templates/contact/olimpiada/student_mail_body.html [deleted file]
edumed/templates/contact/olimpiada/student_mail_subject.html [deleted file]
edumed/templates/contact/olimpiada/thanks.html [deleted file]
edumed/templates/contact/sciezki-kopernika-test/form.html [deleted file]
edumed/templates/contact/sciezki-kopernika-test/mail_subject.txt [deleted file]
edumed/templates/contact/sciezki-kopernika-test/results.html [deleted file]
edumed/templates/contact/sciezki-kopernika-test/results_email.txt [deleted file]
edumed/templates/contact/sciezki-kopernika/form.html [deleted file]
edumed/templates/contact/sciezki-kopernika/mail_body.txt [deleted file]
edumed/templates/contact/sciezki-kopernika/mail_subject.txt [deleted file]
edumed/templates/contact/sciezki-kopernika/thanks.html [deleted file]
edumed/templates/contact/sugestie/mail_body.txt [deleted file]
edumed/templates/contact/sugestie/mail_subject.txt [deleted file]
edumed/templates/contact/sugestie/thanks.html [deleted file]
edumed/templates/contact/tem/mail_body.txt [deleted file]
edumed/templates/contact/tem/mail_subject.txt [deleted file]
edumed/templates/contact/tem/thanks.html [deleted file]
edumed/templates/contact/trenerzy-cybernauci/mail_body.txt [deleted file]
edumed/templates/contact/trenerzy-cybernauci/mail_subject.txt [deleted file]
edumed/templates/contact/trenerzy-cybernauci2017 [deleted symlink]
edumed/templates/contact/wspolpraca/mail_body.txt [deleted file]
edumed/templates/contact/wspolpraca/mail_subject.txt [deleted file]
edumed/templates/contact/wspolpraca/thanks.html [deleted file]
edumed/templates/contact/wtem/form.html [deleted file]
edumed/templates/contact/wtem/mail_body.txt [deleted file]
edumed/templates/contact/wtem/mail_subject.txt [deleted file]
edumed/templates/contact/wtem/student_mail_body.html [deleted file]
edumed/templates/contact/wtem/student_mail_subject.html [deleted file]
edumed/templates/contact/wtem/thanks.html [deleted file]
edumed/templates/flatpages/default.html [deleted file]
edumed/templates/flatpages/mil.html [deleted file]
edumed/templates/flatpages/sciezki.html [deleted file]
edumed/templates/home.html [deleted file]
edumed/templates/home_mil.html [deleted file]
edumed/templates/olimpiada_teaser.html [deleted file]
edumed/templates/pybb/_need_to_login_message.html [deleted file]
edumed/templates/pybb/avatar.html [deleted file]
edumed/templates/pybb/breadcrumb.html [deleted file]
edumed/templates/pybb/breadcrumb_top_extra_crumb.html [deleted file]
edumed/templates/sciezki_logos.html [deleted file]
edumed/templates/search/search.html [deleted file]
edumed/templatetags/__init__.py [deleted file]
edumed/templatetags/inline_stylesheet.py [deleted file]
edumed/urls.py [deleted file]
edumed/utils.py [deleted file]
edumed/views.py [deleted file]
edumed/wsgi.py [deleted file]
fabfile.py [deleted file]
forum/__init__.py [deleted file]
forum/forms.py [deleted file]
forum/locale/pl/LC_MESSAGES/django.mo [deleted file]
forum/locale/pl/LC_MESSAGES/django.po [deleted file]
forum/middleware.py [deleted file]
forum/migrations/0001_initial.py [deleted file]
forum/migrations/__init__.py [deleted file]
forum/models.py [deleted file]
forum/search_indexes.py [deleted file]
forum/templates/forum/related_lesson_info.html [deleted file]
forum/templates/forum/search_results.html [deleted file]
forum/templates/pybb/category.html [deleted file]
forum/templates/pybb/forum_last_update_info.html [deleted file]
forum/templates/pybb/post_form.html [deleted file]
forum/templates/pybb/topic.html [deleted file]
forum/templates/pybb/topic_last_message_info.html [deleted file]
forum/templates/search/indexes/pybb/post_text.txt [deleted file]
forum/urls.py [deleted file]
forum/views.py [deleted file]
lib/librarian [deleted submodule]
manage.py [deleted file]
publishers/__init__.py [deleted file]
publishers/admin.py [deleted file]
publishers/migrations/0001_initial.py [deleted file]
publishers/migrations/__init__.py [deleted file]
publishers/models.py [deleted file]
src/api/__init__.py [new file with mode: 0644]
src/api/admin.py [new file with mode: 0644]
src/api/handlers.py [new file with mode: 0644]
src/api/helpers.py [new file with mode: 0644]
src/api/models.py [new file with mode: 0644]
src/api/templates/oauth/challenge.html [new file with mode: 0644]
src/api/templates/piston/authorize_token.html [new file with mode: 0644]
src/api/tests.py [new file with mode: 0644]
src/api/urls.py [new file with mode: 0644]
src/api/views.py [new file with mode: 0644]
src/catalogue/__init__.py [new file with mode: 0644]
src/catalogue/admin.py [new file with mode: 0755]
src/catalogue/forms.py [new file with mode: 0644]
src/catalogue/management/__init__.py [new file with mode: 0755]
src/catalogue/management/commands/__init__.py [new file with mode: 0755]
src/catalogue/management/commands/extract_attachments.py [new file with mode: 0644]
src/catalogue/management/commands/importlessons.py [new file with mode: 0755]
src/catalogue/management/commands/repackage.py [new file with mode: 0755]
src/catalogue/management/commands/republish.py [new file with mode: 0644]
src/catalogue/migrations/0001_initial.py [new file with mode: 0644]
src/catalogue/migrations/0002_auto__add_field_section_slug.py [new file with mode: 0644]
src/catalogue/migrations/0003_auto__chg_field_lesson_xml_file__chg_field_lesson_student_package__chg.py [new file with mode: 0644]
src/catalogue/migrations/0004_auto__add_part__add_attachment__add_field_lesson_pdf__add_field_lesson.py [new file with mode: 0644]
src/catalogue/migrations/0005_auto__add_field_lesson_dc.py [new file with mode: 0644]
src/catalogue/migrations/0006_auto__add_field_attachment_slug__add_field_attachment_ext__add_unique_.py [new file with mode: 0644]
src/catalogue/migrations/0007_auto__add_field_lesson_type__chg_field_lesson_section.py [new file with mode: 0644]
src/catalogue/migrations/0008_auto__del_field_lesson_depth.py [new file with mode: 0644]
src/catalogue/migrations/0009_auto__add_field_section_xml_file.py [new file with mode: 0644]
src/catalogue/migrations/0010_auto.py [new file with mode: 0644]
src/catalogue/migrations/0011_auto__chg_field_lesson_xml_file__chg_field_lesson_student_pdf__chg_fie.py [new file with mode: 0644]
src/catalogue/migrations/0012_auto__add_lessonstub.py [new file with mode: 0644]
src/catalogue/migrations/0013_auto__add_field_section_image.py [new file with mode: 0644]
src/catalogue/migrations/0014_auto__add_field_section_summary.py [new file with mode: 0644]
src/catalogue/migrations/0015_auto__add_field_lesson_description.py [new file with mode: 0644]
src/catalogue/migrations/0016_auto__add_field_section_pic__add_field_section_pic_attribution__add_fi.py [new file with mode: 0644]
src/catalogue/migrations/0017_auto__chg_field_attachment_file.py [new file with mode: 0644]
src/catalogue/migrations/0018_auto__add_field_lesson_weasy_pdf.py [new file with mode: 0644]
src/catalogue/migrations/__init__.py [new file with mode: 0644]
src/catalogue/models.py [new file with mode: 0644]
src/catalogue/publish.py [new file with mode: 0755]
src/catalogue/search_indexes.py [new file with mode: 0755]
src/catalogue/static/catalogue/css/carousel.css [new file with mode: 0644]
src/catalogue/static/catalogue/css/carousel.scss [new file with mode: 0755]
src/catalogue/static/catalogue/css/exercise.css [new file with mode: 0644]
src/catalogue/static/catalogue/css/exercise.scss [new file with mode: 0755]
src/catalogue/static/catalogue/css/layout.css [new file with mode: 0644]
src/catalogue/static/catalogue/css/layout.scss [new file with mode: 0755]
src/catalogue/static/catalogue/css/lesson.css [new file with mode: 0644]
src/catalogue/static/catalogue/css/lesson.scss [new file with mode: 0755]
src/catalogue/static/catalogue/css/section_list.css [new file with mode: 0644]
src/catalogue/static/catalogue/css/section_list.scss [new file with mode: 0755]
src/catalogue/static/catalogue/img/carousel-left.png [new file with mode: 0644]
src/catalogue/static/catalogue/img/carousel-right.png [new file with mode: 0644]
src/catalogue/static/catalogue/img/carousel/katarzyna-wlodarczyk.jpg [new file with mode: 0644]
src/catalogue/static/catalogue/js/carousel.js [new file with mode: 0755]
src/catalogue/static/catalogue/js/edumed.js [new file with mode: 0644]
src/catalogue/static/catalogue/js/jquery-ui-1.10.0.custom.js [new file with mode: 0644]
src/catalogue/static/catalogue/js/jquery.cycle.all.js [new file with mode: 0644]
src/catalogue/static/catalogue/js/lesson-list.js [new file with mode: 0644]
src/catalogue/static/catalogue/js/lesson.js [new file with mode: 0755]
src/catalogue/templates/catalogue/latest_blog_posts.html [new file with mode: 0755]
src/catalogue/templates/catalogue/lesson/added-var/lesson_detail.html [new file with mode: 0644]
src/catalogue/templates/catalogue/lesson/added/lesson_detail.html [new file with mode: 0644]
src/catalogue/templates/catalogue/lesson/appendix/lesson_detail.html [new file with mode: 0755]
src/catalogue/templates/catalogue/lesson/box-icons.html [new file with mode: 0644]
src/catalogue/templates/catalogue/lesson/course/lesson_detail.html [new file with mode: 0755]
src/catalogue/templates/catalogue/lesson/lesson_detail.html [new file with mode: 0755]
src/catalogue/templates/catalogue/lesson/project/lesson_detail.html [new file with mode: 0755]
src/catalogue/templates/catalogue/lesson/synthetic/lesson_detail.html [new file with mode: 0755]
src/catalogue/templates/catalogue/lesson_list.html [new file with mode: 0755]
src/catalogue/templates/catalogue/section_detail.html [new file with mode: 0755]
src/catalogue/templates/catalogue/snippets/carousel.html [new file with mode: 0755]
src/catalogue/templates/catalogue/snippets/lesson_link.html [new file with mode: 0755]
src/catalogue/templates/catalogue/snippets/lesson_nav.html [new file with mode: 0755]
src/catalogue/templates/catalogue/snippets/lesson_or_stub.html [new file with mode: 0644]
src/catalogue/templates/catalogue/snippets/level_box.html [new file with mode: 0755]
src/catalogue/templates/catalogue/snippets/levels_main.html [new file with mode: 0644]
src/catalogue/templates/search/indexes/catalogue/lesson_text.txt [new file with mode: 0755]
src/catalogue/templatetags/__init__.py [new file with mode: 0755]
src/catalogue/templatetags/catalogue_tags.py [new file with mode: 0755]
src/catalogue/tests.py [new file with mode: 0644]
src/catalogue/urls.py [new file with mode: 0755]
src/catalogue/views.py [new file with mode: 0644]
src/chunks/__init__.py [new file with mode: 0644]
src/chunks/admin.py [new file with mode: 0644]
src/chunks/fixtures/chunks.json [new file with mode: 0644]
src/chunks/locale/de/LC_MESSAGES/django.mo [new file with mode: 0644]
src/chunks/locale/de/LC_MESSAGES/django.po [new file with mode: 0644]
src/chunks/locale/en/LC_MESSAGES/django.mo [new file with mode: 0644]
src/chunks/locale/en/LC_MESSAGES/django.po [new file with mode: 0644]
src/chunks/locale/es/LC_MESSAGES/django.mo [new file with mode: 0644]
src/chunks/locale/es/LC_MESSAGES/django.po [new file with mode: 0644]
src/chunks/locale/fr/LC_MESSAGES/django.mo [new file with mode: 0644]
src/chunks/locale/fr/LC_MESSAGES/django.po [new file with mode: 0644]
src/chunks/locale/it/LC_MESSAGES/django.mo [new file with mode: 0644]
src/chunks/locale/it/LC_MESSAGES/django.po [new file with mode: 0644]
src/chunks/locale/jp/LC_MESSAGES/django.mo [new file with mode: 0644]
src/chunks/locale/jp/LC_MESSAGES/django.po [new file with mode: 0644]
src/chunks/locale/lt/LC_MESSAGES/django.mo [new file with mode: 0644]
src/chunks/locale/lt/LC_MESSAGES/django.po [new file with mode: 0644]
src/chunks/locale/pl/LC_MESSAGES/django.mo [new file with mode: 0644]
src/chunks/locale/pl/LC_MESSAGES/django.po [new file with mode: 0644]
src/chunks/locale/ru/LC_MESSAGES/django.mo [new file with mode: 0644]
src/chunks/locale/ru/LC_MESSAGES/django.po [new file with mode: 0644]
src/chunks/locale/uk/LC_MESSAGES/django.mo [new file with mode: 0644]
src/chunks/locale/uk/LC_MESSAGES/django.po [new file with mode: 0644]
src/chunks/models.py [new file with mode: 0644]
src/chunks/templatetags/__init__.py [new file with mode: 0644]
src/chunks/templatetags/chunks.py [new file with mode: 0644]
src/comment/__init__.py [new file with mode: 0644]
src/comment/admin.py [new file with mode: 0644]
src/comment/locale/pl/LC_MESSAGES/django.mo [new file with mode: 0644]
src/comment/locale/pl/LC_MESSAGES/django.po [new file with mode: 0644]
src/comment/migrations/0001_initial.py [new file with mode: 0644]
src/comment/migrations/0002_auto__add_field_commentdocument_language_code.py [new file with mode: 0644]
src/comment/migrations/__init__.py [new file with mode: 0644]
src/comment/models.py [new file with mode: 0644]
src/comment/templates/comment/commentdocument_detail.html [new file with mode: 0644]
src/comment/templates/comment/commentdocument_list.html [new file with mode: 0644]
src/comment/urls.py [new file with mode: 0644]
src/comment/views.py [new file with mode: 0644]
src/contact/__init__.py [new file with mode: 0644]
src/contact/admin.py [new file with mode: 0644]
src/contact/fields.py [new file with mode: 0644]
src/contact/forms.py [new file with mode: 0644]
src/contact/locale/pl/LC_MESSAGES/django.mo [new file with mode: 0644]
src/contact/locale/pl/LC_MESSAGES/django.po [new file with mode: 0644]
src/contact/mailing.py [new file with mode: 0644]
src/contact/management/__init__.py [new file with mode: 0644]
src/contact/management/commands/__init__.py [new file with mode: 0644]
src/contact/management/commands/export_newsletter.py [new file with mode: 0644]
src/contact/migrations/0001_initial.py [new file with mode: 0644]
src/contact/migrations/0002_auto__add_attachment.py [new file with mode: 0644]
src/contact/migrations/0003_auto__add_field_contact_key.py [new file with mode: 0644]
src/contact/migrations/__init__.py [new file with mode: 0644]
src/contact/models.py [new file with mode: 0644]
src/contact/templates/admin/contact/contact/change_list.html [new file with mode: 0644]
src/contact/templates/contact/disabled_contact_form.html [new file with mode: 0644]
src/contact/templates/contact/form.html [new file with mode: 0644]
src/contact/templates/contact/mail_body.txt [new file with mode: 0644]
src/contact/templates/contact/mail_managers_body.txt [new file with mode: 0644]
src/contact/templates/contact/mail_managers_subject.txt [new file with mode: 0644]
src/contact/templates/contact/mail_subject.txt [new file with mode: 0644]
src/contact/templates/contact/thanks.html [new file with mode: 0644]
src/contact/templatetags/__init__.py [new file with mode: 0755]
src/contact/templatetags/contact_tags.py [new file with mode: 0755]
src/contact/urls.py [new file with mode: 0644]
src/contact/views.py [new file with mode: 0644]
src/contact/widgets.py [new file with mode: 0644]
src/curriculum/__init__.py [new file with mode: 0644]
src/curriculum/admin.py [new file with mode: 0755]
src/curriculum/fixtures/competences.json [new file with mode: 0644]
src/curriculum/fixtures/curriculum.json [new file with mode: 0644]
src/curriculum/locale/pl/LC_MESSAGES/django.mo [new file with mode: 0644]
src/curriculum/locale/pl/LC_MESSAGES/django.po [new file with mode: 0644]
src/curriculum/migrations/0001_initial.py [new file with mode: 0644]
src/curriculum/migrations/0002_auto__add_field_level_group.py [new file with mode: 0644]
src/curriculum/migrations/0003_auto__chg_field_level_slug.py [new file with mode: 0644]
src/curriculum/migrations/0004_auto__add_curriculum__add_curriculumlevel__add_curriculumcourse.py [new file with mode: 0644]
src/curriculum/migrations/0005_auto__add_field_curriculumcourse_accusative.py [new file with mode: 0644]
src/curriculum/migrations/0006_auto__add_field_competencelevel_description_pl__add_field_competencele.py [new file with mode: 0644]
src/curriculum/migrations/0007_translatable_fields_data_migration.py [new file with mode: 0644]
src/curriculum/migrations/0008_auto__del_field_competencelevel_description__del_field_section_name__d.py [new file with mode: 0644]
src/curriculum/migrations/0009_auto__chg_field_competencelevel_description_en__chg_field_competencele.py [new file with mode: 0644]
src/curriculum/migrations/0010_auto__add_field_level_meta_name.py [new file with mode: 0644]
src/curriculum/migrations/0011_meta_name.py [new file with mode: 0644]
src/curriculum/migrations/0012_auto__add_unique_level_meta_name__add_unique_level_slug.py [new file with mode: 0644]
src/curriculum/migrations/0013_auto__add_field_level_package__add_field_level_student_package.py [new file with mode: 0644]
src/curriculum/migrations/0014_auto__add_unique_curriculum_identifier.py [new file with mode: 0644]
src/curriculum/migrations/0015_auto__chg_field_curriculum_title.py [new file with mode: 0644]
src/curriculum/migrations/0016_auto__add_field_curriculumlevel_verbose.py [new file with mode: 0644]
src/curriculum/migrations/0017_verbose_level.py [new file with mode: 0644]
src/curriculum/migrations/__init__.py [new file with mode: 0644]
src/curriculum/models.py [new file with mode: 0644]
src/curriculum/static/curriculum/curriculum.css [new file with mode: 0644]
src/curriculum/static/curriculum/curriculum.js [new file with mode: 0755]
src/curriculum/static/curriculum/curriculum.scss [new file with mode: 0755]
src/curriculum/templates/curriculum/competence_detail.html [new file with mode: 0755]
src/curriculum/templates/curriculum/competence_list.html [new file with mode: 0755]
src/curriculum/templates/curriculum/snippets/competence.html [new file with mode: 0755]
src/curriculum/templates/curriculum/snippets/course_box.html [new file with mode: 0755]
src/curriculum/templates/curriculum/snippets/course_boxes.html [new file with mode: 0755]
src/curriculum/templates/curriculum/snippets/course_boxes_toc.html [new file with mode: 0755]
src/curriculum/templates/curriculum/snippets/curriculum.html [new file with mode: 0755]
src/curriculum/templatetags/__init__.py [new file with mode: 0755]
src/curriculum/templatetags/curriculum_tags.py [new file with mode: 0755]
src/curriculum/tests.py [new file with mode: 0644]
src/curriculum/urls.py [new file with mode: 0755]
src/curriculum/views.py [new file with mode: 0644]
src/edumed/__init__.py [new file with mode: 0644]
src/edumed/contact_forms.py [new file with mode: 0644]
src/edumed/contact_forms_test.py [new file with mode: 0644]
src/edumed/context_processors.py [new file with mode: 0644]
src/edumed/forms.py [new file with mode: 0644]
src/edumed/forum.py [new file with mode: 0644]
src/edumed/locale-contrib/django.pot [new file with mode: 0644]
src/edumed/locale-contrib/pl/LC_MESSAGES/django.mo [new file with mode: 0644]
src/edumed/locale-contrib/pl/LC_MESSAGES/django.po [new file with mode: 0644]
src/edumed/locale/pl/LC_MESSAGES/django.mo [new file with mode: 0644]
src/edumed/locale/pl/LC_MESSAGES/django.po [new file with mode: 0644]
src/edumed/milurls.py [new file with mode: 0644]
src/edumed/settings/__init__.py [new file with mode: 0644]
src/edumed/settings/apps.py [new file with mode: 0644]
src/edumed/settings/auth.py [new file with mode: 0644]
src/edumed/settings/basic.py [new file with mode: 0644]
src/edumed/settings/cache.py [new file with mode: 0644]
src/edumed/settings/context.py [new file with mode: 0644]
src/edumed/settings/contrib.py [new file with mode: 0644]
src/edumed/settings/custom.py [new file with mode: 0644]
src/edumed/settings/locale.py [new file with mode: 0644]
src/edumed/settings/logging.py [new file with mode: 0644]
src/edumed/settings/middleware.py [new file with mode: 0644]
src/edumed/settings/paths.py [new file with mode: 0644]
src/edumed/settings/search.py [new file with mode: 0644]
src/edumed/settings/static.py [new file with mode: 0644]
src/edumed/static/css/_mixins.scss [new file with mode: 0644]
src/edumed/static/css/_vars.scss [new file with mode: 0644]
src/edumed/static/css/base.css [new file with mode: 0644]
src/edumed/static/css/base.scss [new file with mode: 0644]
src/edumed/static/css/form.css [new file with mode: 0644]
src/edumed/static/css/form.scss [new file with mode: 0755]
src/edumed/static/css/forum.css [new file with mode: 0644]
src/edumed/static/css/forum.scss [new file with mode: 0755]
src/edumed/static/css/main.css [new file with mode: 0644]
src/edumed/static/css/main.scss [new file with mode: 0755]
src/edumed/static/css/mil.css [new file with mode: 0644]
src/edumed/static/css/mil.scss [new file with mode: 0644]
src/edumed/static/css/promobox.css [new file with mode: 0644]
src/edumed/static/css/promobox.scss [new file with mode: 0755]
src/edumed/static/img/banners/440px_Forum.jpg [new file with mode: 0644]
src/edumed/static/img/banners/440px_Salon-1.jpg [new file with mode: 0644]
src/edumed/static/img/banners/960x150_edukacjaMedialna.jpg [new file with mode: 0644]
src/edumed/static/img/banners/OC_collegium_web_970x250.jpg [new file with mode: 0644]
src/edumed/static/img/banners/oc-banner.png [new file with mode: 0644]
src/edumed/static/img/favicon.png [new file with mode: 0644]
src/edumed/static/img/header-bar.png [new file with mode: 0644]
src/edumed/static/img/icons/activity-kind.png [new file with mode: 0644]
src/edumed/static/img/icons/activity-time.png [new file with mode: 0644]
src/edumed/static/img/icons/activity-tools.png [new file with mode: 0644]
src/edumed/static/img/icons/activity_dark.png [new file with mode: 0644]
src/edumed/static/img/icons/activity_orange.png [new file with mode: 0644]
src/edumed/static/img/icons/activity_white.png [new file with mode: 0644]
src/edumed/static/img/icons/announce_dark.png [new file with mode: 0644]
src/edumed/static/img/icons/announce_orange.png [new file with mode: 0644]
src/edumed/static/img/icons/announce_white.png [new file with mode: 0644]
src/edumed/static/img/icons/internet_black.png [new file with mode: 0644]
src/edumed/static/img/icons/knowledge_dark.png [new file with mode: 0644]
src/edumed/static/img/icons/knowledge_orange.png [new file with mode: 0644]
src/edumed/static/img/icons/knowledge_white.png [new file with mode: 0644]
src/edumed/static/img/icons/lesson-plan_dark.png [new file with mode: 0644]
src/edumed/static/img/icons/lesson-plan_orange.png [new file with mode: 0644]
src/edumed/static/img/icons/lesson-plan_white.png [new file with mode: 0644]
src/edumed/static/img/icons/nointernet_black.png [new file with mode: 0644]
src/edumed/static/img/icons/reference_dark.png [new file with mode: 0644]
src/edumed/static/img/icons/reference_orange.png [new file with mode: 0644]
src/edumed/static/img/icons/reference_white.png [new file with mode: 0644]
src/edumed/static/img/icons/time_dark.png [new file with mode: 0644]
src/edumed/static/img/icons/time_orange.png [new file with mode: 0644]
src/edumed/static/img/icons/time_white.png [new file with mode: 0644]
src/edumed/static/img/logo-mil.png [new file with mode: 0644]
src/edumed/static/img/logo-oc.png [new file with mode: 0644]
src/edumed/static/img/logo.png [new file with mode: 0644]
src/edumed/static/img/logo_fnp.png [new file with mode: 0644]
src/edumed/static/img/logo_fnp_white.png [new file with mode: 0644]
src/edumed/static/img/menu/dla-trenera.png [new file with mode: 0644]
src/edumed/static/img/menu/dla-trenera_active.png [new file with mode: 0644]
src/edumed/static/img/menu/dla-ucznia.png [new file with mode: 0644]
src/edumed/static/img/menu/dla-ucznia_active.png [new file with mode: 0644]
src/edumed/static/img/menu/kompetencje.png [new file with mode: 0644]
src/edumed/static/img/menu/kompetencje_active.png [new file with mode: 0644]
src/edumed/static/img/menu/lekcje.png [new file with mode: 0644]
src/edumed/static/img/menu/lekcje_active.png [new file with mode: 0644]
src/edumed/static/img/menu/mil/catalog.png [new file with mode: 0644]
src/edumed/static/img/menu/mil/consultations.png [new file with mode: 0644]
src/edumed/static/img/menu/mil/contact.png [new file with mode: 0644]
src/edumed/static/img/menu/mil/knowledgebase.png [new file with mode: 0644]
src/edumed/static/img/menu/mil/lang_en.png [new file with mode: 0644]
src/edumed/static/img/menu/mil/lang_pl.png [new file with mode: 0644]
src/edumed/static/img/menu/mil/takepart.png [new file with mode: 0644]
src/edumed/static/img/menu/o-nas.png [new file with mode: 0644]
src/edumed/static/img/menu/o-nas_active.png [new file with mode: 0644]
src/edumed/static/img/menu/old/katalog.png [new file with mode: 0644]
src/edumed/static/img/menu/old/katalog_active.png [new file with mode: 0644]
src/edumed/static/img/menu/old/kontakt.png [new file with mode: 0644]
src/edumed/static/img/menu/old/kontakt_active.png [new file with mode: 0644]
src/edumed/static/img/menu/old/lekcje.png [new file with mode: 0644]
src/edumed/static/img/menu/old/lekcje_active.png [new file with mode: 0644]
src/edumed/static/img/menu/old/o-nas.png [new file with mode: 0644]
src/edumed/static/img/menu/old/o-nas_active.png [new file with mode: 0644]
src/edumed/static/img/menu/old/szkolenia.png [new file with mode: 0644]
src/edumed/static/img/menu/old/szkolenia_active.png [new file with mode: 0644]
src/edumed/static/img/menu/old/wesprzyj.png [new file with mode: 0644]
src/edumed/static/img/menu/old/wesprzyj_active.png [new file with mode: 0644]
src/edumed/static/img/menu/old/wspolpraca.png [new file with mode: 0644]
src/edumed/static/img/menu/old/wspolpraca_active.png [new file with mode: 0644]
src/edumed/static/img/menu/olimpiada.png [new file with mode: 0644]
src/edumed/static/img/menu/olimpiada/harmonogram.png [new file with mode: 0644]
src/edumed/static/img/menu/olimpiada/harmonogram_active.png [new file with mode: 0644]
src/edumed/static/img/menu/olimpiada/komitet.png [new file with mode: 0644]
src/edumed/static/img/menu/olimpiada/komitet_active.png [new file with mode: 0644]
src/edumed/static/img/menu/olimpiada/kontakt.png [new file with mode: 0644]
src/edumed/static/img/menu/olimpiada/kontakt_active.png [new file with mode: 0644]
src/edumed/static/img/menu/olimpiada/literatura.png [new file with mode: 0644]
src/edumed/static/img/menu/olimpiada/literatura_active.png [new file with mode: 0644]
src/edumed/static/img/menu/olimpiada/program.png [new file with mode: 0644]
src/edumed/static/img/menu/olimpiada/program_active.png [new file with mode: 0644]
src/edumed/static/img/menu/olimpiada/regulamin.png [new file with mode: 0644]
src/edumed/static/img/menu/olimpiada/regulamin_active.png [new file with mode: 0644]
src/edumed/static/img/menu/olimpiada/svg/harmonogram.svg [new file with mode: 0644]
src/edumed/static/img/menu/olimpiada/svg/harmonogram_active.svg [new file with mode: 0644]
src/edumed/static/img/menu/olimpiada/svg/komitet.svg [new file with mode: 0644]
src/edumed/static/img/menu/olimpiada/svg/komitet_active.svg [new file with mode: 0644]
src/edumed/static/img/menu/olimpiada/svg/kontakt.svg [new file with mode: 0644]
src/edumed/static/img/menu/olimpiada/svg/kontakt_active.svg [new file with mode: 0644]
src/edumed/static/img/menu/olimpiada/svg/literatura.svg [new file with mode: 0644]
src/edumed/static/img/menu/olimpiada/svg/literatura_active.svg [new file with mode: 0644]
src/edumed/static/img/menu/olimpiada/svg/program.svg [new file with mode: 0644]
src/edumed/static/img/menu/olimpiada/svg/program_active.svg [new file with mode: 0644]
src/edumed/static/img/menu/olimpiada/svg/regulamin.svg [new file with mode: 0644]
src/edumed/static/img/menu/olimpiada/svg/regulamin_active.svg [new file with mode: 0644]
src/edumed/static/img/menu/olimpiada_active.png [new file with mode: 0644]
src/edumed/static/img/menu/svg/convert.txt [new file with mode: 0644]
src/edumed/static/img/menu/svg/dla-trenera.svg [new file with mode: 0644]
src/edumed/static/img/menu/svg/dla-trenera_active.svg [new file with mode: 0644]
src/edumed/static/img/menu/svg/dla-ucznia.svg [new file with mode: 0644]
src/edumed/static/img/menu/svg/dla-ucznia_active.svg [new file with mode: 0644]
src/edumed/static/img/menu/svg/kompetencje.svg [new file with mode: 0644]
src/edumed/static/img/menu/svg/kompetencje_active.svg [new file with mode: 0644]
src/edumed/static/img/menu/svg/lekcje.svg [new file with mode: 0644]
src/edumed/static/img/menu/svg/lekcje_active.svg [new file with mode: 0644]
src/edumed/static/img/menu/svg/o-nas.svg [new file with mode: 0644]
src/edumed/static/img/menu/svg/o-nas_active.svg [new file with mode: 0644]
src/edumed/static/img/menu/svg/olimpiada.svg [new file with mode: 0644]
src/edumed/static/img/menu/svg/olimpiada_active.svg [new file with mode: 0644]
src/edumed/static/img/nina-white.png [new file with mode: 0644]
src/edumed/static/img/nina.jpg [new file with mode: 0644]
src/edumed/static/img/ornaments/draggable.png [new file with mode: 0644]
src/edumed/static/img/sciezki-kopernika/cc.jpg [new file with mode: 0644]
src/edumed/static/img/sciezki-kopernika/fe.jpg [new file with mode: 0644]
src/edumed/static/img/sciezki-kopernika/fnp.png [new file with mode: 0644]
src/edumed/static/img/sciezki-kopernika/ue.jpg [new file with mode: 0644]
src/edumed/static/jquery/colorbox/colorbox.css [new file with mode: 0644]
src/edumed/static/jquery/colorbox/images/border.png [new file with mode: 0644]
src/edumed/static/jquery/colorbox/images/controls.png [new file with mode: 0644]
src/edumed/static/jquery/colorbox/images/ie6/borderBottomCenter.png [new file with mode: 0644]
src/edumed/static/jquery/colorbox/images/ie6/borderBottomLeft.png [new file with mode: 0644]
src/edumed/static/jquery/colorbox/images/ie6/borderBottomRight.png [new file with mode: 0644]
src/edumed/static/jquery/colorbox/images/ie6/borderMiddleLeft.png [new file with mode: 0644]
src/edumed/static/jquery/colorbox/images/ie6/borderMiddleRight.png [new file with mode: 0644]
src/edumed/static/jquery/colorbox/images/ie6/borderTopCenter.png [new file with mode: 0644]
src/edumed/static/jquery/colorbox/images/ie6/borderTopLeft.png [new file with mode: 0644]
src/edumed/static/jquery/colorbox/images/ie6/borderTopRight.png [new file with mode: 0644]
src/edumed/static/jquery/colorbox/images/loading.gif [new file with mode: 0644]
src/edumed/static/jquery/colorbox/images/loading_background.png [new file with mode: 0644]
src/edumed/static/jquery/colorbox/images/overlay.png [new file with mode: 0644]
src/edumed/static/jquery/colorbox/jquery.colorbox-min.js [new file with mode: 0644]
src/edumed/static/jquery/colorbox/jquery.colorbox-pl.js [new file with mode: 0644]
src/edumed/static/js/formset.js [new file with mode: 0755]
src/edumed/templates/404.html [new file with mode: 0644]
src/edumed/templates/404_mil.html [new file with mode: 0644]
src/edumed/templates/500.html [new file with mode: 0644]
src/edumed/templates/annoy.html [new file with mode: 0755]
src/edumed/templates/base.html [new file with mode: 0644]
src/edumed/templates/base_forum.html [new file with mode: 0755]
src/edumed/templates/base_mil.html [new file with mode: 0644]
src/edumed/templates/base_super.html [new file with mode: 0644]
src/edumed/templates/contact/collegium-mlodych-test/form.html [new file with mode: 0644]
src/edumed/templates/contact/collegium-mlodych-test/mail_subject.txt [new file with mode: 0644]
src/edumed/templates/contact/collegium-mlodych-test/results.html [new file with mode: 0644]
src/edumed/templates/contact/collegium-mlodych-test/results_email.txt [new file with mode: 0644]
src/edumed/templates/contact/collegium-mlodych/form.html [new file with mode: 0644]
src/edumed/templates/contact/collegium-mlodych/mail_body.txt [new file with mode: 0644]
src/edumed/templates/contact/collegium-mlodych/mail_subject.txt [new file with mode: 0644]
src/edumed/templates/contact/collegium-mlodych/on_hold.html [new file with mode: 0644]
src/edumed/templates/contact/collegium-mlodych/thanks.html [new file with mode: 0644]
src/edumed/templates/contact/konkurs/mail_body.txt [new file with mode: 0644]
src/edumed/templates/contact/konkurs/mail_subject.txt [new file with mode: 0644]
src/edumed/templates/contact/konkurs/thanks.html [new file with mode: 0644]
src/edumed/templates/contact/misja-cybernautow/mail_body.txt [new file with mode: 0644]
src/edumed/templates/contact/olimpiada/form.html [new file with mode: 0755]
src/edumed/templates/contact/olimpiada/mail_body.txt [new file with mode: 0755]
src/edumed/templates/contact/olimpiada/mail_subject.txt [new file with mode: 0755]
src/edumed/templates/contact/olimpiada/student_mail_body.html [new file with mode: 0644]
src/edumed/templates/contact/olimpiada/student_mail_subject.html [new file with mode: 0644]
src/edumed/templates/contact/olimpiada/thanks.html [new file with mode: 0755]
src/edumed/templates/contact/sciezki-kopernika-test/form.html [new file with mode: 0644]
src/edumed/templates/contact/sciezki-kopernika-test/mail_subject.txt [new file with mode: 0644]
src/edumed/templates/contact/sciezki-kopernika-test/results.html [new file with mode: 0644]
src/edumed/templates/contact/sciezki-kopernika-test/results_email.txt [new file with mode: 0644]
src/edumed/templates/contact/sciezki-kopernika/form.html [new file with mode: 0644]
src/edumed/templates/contact/sciezki-kopernika/mail_body.txt [new file with mode: 0644]
src/edumed/templates/contact/sciezki-kopernika/mail_subject.txt [new file with mode: 0644]
src/edumed/templates/contact/sciezki-kopernika/thanks.html [new file with mode: 0644]
src/edumed/templates/contact/sugestie/mail_body.txt [new file with mode: 0644]
src/edumed/templates/contact/sugestie/mail_subject.txt [new file with mode: 0644]
src/edumed/templates/contact/sugestie/thanks.html [new file with mode: 0644]
src/edumed/templates/contact/tem/mail_body.txt [new file with mode: 0755]
src/edumed/templates/contact/tem/mail_subject.txt [new file with mode: 0755]
src/edumed/templates/contact/tem/thanks.html [new file with mode: 0755]
src/edumed/templates/contact/trenerzy-cybernauci/mail_body.txt [new file with mode: 0644]
src/edumed/templates/contact/trenerzy-cybernauci/mail_subject.txt [new file with mode: 0644]
src/edumed/templates/contact/trenerzy-cybernauci2017 [new symlink]
src/edumed/templates/contact/wspolpraca/mail_body.txt [new file with mode: 0644]
src/edumed/templates/contact/wspolpraca/mail_subject.txt [new file with mode: 0644]
src/edumed/templates/contact/wspolpraca/thanks.html [new file with mode: 0644]
src/edumed/templates/contact/wtem/form.html [new file with mode: 0755]
src/edumed/templates/contact/wtem/mail_body.txt [new file with mode: 0755]
src/edumed/templates/contact/wtem/mail_subject.txt [new file with mode: 0755]
src/edumed/templates/contact/wtem/student_mail_body.html [new file with mode: 0644]
src/edumed/templates/contact/wtem/student_mail_subject.html [new file with mode: 0644]
src/edumed/templates/contact/wtem/thanks.html [new file with mode: 0755]
src/edumed/templates/flatpages/default.html [new file with mode: 0755]
src/edumed/templates/flatpages/mil.html [new file with mode: 0644]
src/edumed/templates/flatpages/sciezki.html [new file with mode: 0644]
src/edumed/templates/home.html [new file with mode: 0755]
src/edumed/templates/home_mil.html [new file with mode: 0644]
src/edumed/templates/olimpiada_teaser.html [new file with mode: 0644]
src/edumed/templates/pybb/_need_to_login_message.html [new file with mode: 0755]
src/edumed/templates/pybb/avatar.html [new file with mode: 0755]
src/edumed/templates/pybb/breadcrumb.html [new file with mode: 0755]
src/edumed/templates/pybb/breadcrumb_top_extra_crumb.html [new file with mode: 0755]
src/edumed/templates/sciezki_logos.html [new file with mode: 0644]
src/edumed/templates/search/search.html [new file with mode: 0755]
src/edumed/templatetags/__init__.py [new file with mode: 0644]
src/edumed/templatetags/inline_stylesheet.py [new file with mode: 0644]
src/edumed/urls.py [new file with mode: 0644]
src/edumed/utils.py [new file with mode: 0644]
src/edumed/views.py [new file with mode: 0644]
src/edumed/wsgi.py [new file with mode: 0644]
src/forum/__init__.py [new file with mode: 0644]
src/forum/forms.py [new file with mode: 0644]
src/forum/locale/pl/LC_MESSAGES/django.mo [new file with mode: 0644]
src/forum/locale/pl/LC_MESSAGES/django.po [new file with mode: 0644]
src/forum/middleware.py [new file with mode: 0644]
src/forum/migrations/0001_initial.py [new file with mode: 0644]
src/forum/migrations/__init__.py [new file with mode: 0644]
src/forum/models.py [new file with mode: 0644]
src/forum/search_indexes.py [new file with mode: 0644]
src/forum/templates/forum/related_lesson_info.html [new file with mode: 0644]
src/forum/templates/forum/search_results.html [new file with mode: 0644]
src/forum/templates/pybb/category.html [new file with mode: 0644]
src/forum/templates/pybb/forum_last_update_info.html [new file with mode: 0644]
src/forum/templates/pybb/post_form.html [new file with mode: 0644]
src/forum/templates/pybb/topic.html [new file with mode: 0644]
src/forum/templates/pybb/topic_last_message_info.html [new file with mode: 0644]
src/forum/templates/search/indexes/pybb/post_text.txt [new file with mode: 0644]
src/forum/urls.py [new file with mode: 0644]
src/forum/views.py [new file with mode: 0644]
src/lib/librarian [new submodule]
src/manage.py [new file with mode: 0755]
src/publishers/__init__.py [new file with mode: 0644]
src/publishers/admin.py [new file with mode: 0644]
src/publishers/migrations/0001_initial.py [new file with mode: 0644]
src/publishers/migrations/__init__.py [new file with mode: 0644]
src/publishers/models.py [new file with mode: 0644]
src/wtem/__init__.py [new file with mode: 0644]
src/wtem/admin.py [new file with mode: 0644]
src/wtem/fixtures/exercises-2013.json [new file with mode: 0644]
src/wtem/fixtures/exercises-2014.json [new file with mode: 0644]
src/wtem/fixtures/exercises-2015.json [new file with mode: 0644]
src/wtem/fixtures/exercises-tem.json [new file with mode: 0644]
src/wtem/fixtures/exercises-wlem.json [new file with mode: 0644]
src/wtem/fixtures/exercises.json [new file with mode: 0644]
src/wtem/forms.py [new file with mode: 0644]
src/wtem/management/__init__.py [new file with mode: 0644]
src/wtem/management/commands/__init__.py [new file with mode: 0644]
src/wtem/management/commands/wlem_generate_keys.py [new file with mode: 0644]
src/wtem/management/commands/wtem_assign_submissions.py [new file with mode: 0644]
src/wtem/management/commands/wtem_email_teachers.py [new file with mode: 0644]
src/wtem/management/commands/wtem_generate_keys.py [new file with mode: 0644]
src/wtem/management/commands/wtem_send_keys.py [new file with mode: 0644]
src/wtem/management/commands/wtem_send_results.py [new file with mode: 0644]
src/wtem/management/commands/wtem_send_results_csv.py [new file with mode: 0644]
src/wtem/middleware.py [new file with mode: 0644]
src/wtem/migrations/0001_initial.py [new file with mode: 0644]
src/wtem/migrations/0002_auto__add_field_submission_key_sent.py [new file with mode: 0644]
src/wtem/migrations/0003_auto__add_assignment.py [new file with mode: 0644]
src/wtem/migrations/0004_auto__add_unique_assignment_user.py [new file with mode: 0644]
src/wtem/migrations/0005_auto__add_field_submission_marks.py [new file with mode: 0644]
src/wtem/migrations/0006_auto__del_field_attachment_name__add_field_attachment_exercise_id.py [new file with mode: 0644]
src/wtem/migrations/0007_auto.py [new file with mode: 0644]
src/wtem/migrations/0008_auto__add_field_submission_end_time.py [new file with mode: 0644]
src/wtem/migrations/0009_auto__add_field_attachment_tag.py [new file with mode: 0644]
src/wtem/migrations/0010_auto__add_confirmation.py [new file with mode: 0644]
src/wtem/migrations/__init__.py [new file with mode: 0644]
src/wtem/models.py [new file with mode: 0644]
src/wtem/static/wtem/edumed.coffee [new file with mode: 0644]
src/wtem/static/wtem/edumed.js [new file with mode: 0644]
src/wtem/static/wtem/img/1.png [new file with mode: 0644]
src/wtem/static/wtem/img/1_small.png [new file with mode: 0644]
src/wtem/static/wtem/img/2.png [new file with mode: 0644]
src/wtem/static/wtem/img/2_small.png [new file with mode: 0644]
src/wtem/static/wtem/img/3.png [new file with mode: 0644]
src/wtem/static/wtem/img/3_small.png [new file with mode: 0644]
src/wtem/static/wtem/img/komunikat_policyjny.png [new file with mode: 0644]
src/wtem/static/wtem/img/krrit_zrzut_ekranu.png [new file with mode: 0644]
src/wtem/static/wtem/img/przyp/1.jpg [new file with mode: 0644]
src/wtem/static/wtem/img/przyp/2.jpg [new file with mode: 0644]
src/wtem/static/wtem/img/przyp/3.jpg [new file with mode: 0644]
src/wtem/static/wtem/img/przyp/4.jpg [new file with mode: 0644]
src/wtem/static/wtem/img/przyp/5.jpg [new file with mode: 0644]
src/wtem/static/wtem/img/przyp2/1.jpg [new file with mode: 0644]
src/wtem/static/wtem/img/przyp2/2.jpg [new file with mode: 0644]
src/wtem/static/wtem/img/przyp2/3.jpg [new file with mode: 0644]
src/wtem/static/wtem/img/przyp2/4.jpg [new file with mode: 0644]
src/wtem/static/wtem/img/przyp2/5.jpg [new file with mode: 0644]
src/wtem/static/wtem/json2.js [new file with mode: 0644]
src/wtem/static/wtem/spinner.gif [new file with mode: 0644]
src/wtem/static/wtem/wtem.js [new file with mode: 0644]
src/wtem/templates/admin/wtem/submission/change_list.html [new file with mode: 0644]
src/wtem/templates/wtem/admin_report.csv [new file with mode: 0644]
src/wtem/templates/wtem/disabled_contact_form.html [new file with mode: 0644]
src/wtem/templates/wtem/email_key.txt [new file with mode: 0644]
src/wtem/templates/wtem/email_teacher_before.txt [new file with mode: 0644]
src/wtem/templates/wtem/email_teacher_before_subject.txt [new file with mode: 0644]
src/wtem/templates/wtem/exercises/edumed_prawdafalsz.html [new file with mode: 0644]
src/wtem/templates/wtem/exercises/edumed_przyporzadkuj.html [new file with mode: 0644]
src/wtem/templates/wtem/exercises/edumed_uporzadkuj.html [new file with mode: 0644]
src/wtem/templates/wtem/exercises/edumed_wybor.html [new file with mode: 0644]
src/wtem/templates/wtem/exercises/exercise_no.html [new file with mode: 0644]
src/wtem/templates/wtem/exercises/file_upload.html [new file with mode: 0644]
src/wtem/templates/wtem/exercises/open.html [new file with mode: 0644]
src/wtem/templates/wtem/key_not_found.html [new file with mode: 0644]
src/wtem/templates/wtem/key_not_found_before.html [new file with mode: 0644]
src/wtem/templates/wtem/main.html [new file with mode: 0644]
src/wtem/templates/wtem/main_after.html [new file with mode: 0644]
src/wtem/templates/wtem/main_before.html [new file with mode: 0644]
src/wtem/templates/wtem/results_student_disqualified.txt [new file with mode: 0644]
src/wtem/templates/wtem/results_student_failed.txt [new file with mode: 0644]
src/wtem/templates/wtem/results_student_passed.txt [new file with mode: 0644]
src/wtem/templates/wtem/results_teacher.txt [new file with mode: 0644]
src/wtem/templates/wtem/thanks.html [new file with mode: 0644]
src/wtem/templates/wtem/title.html [new file with mode: 0644]
src/wtem/templatetags/__init__.py [new file with mode: 0644]
src/wtem/templatetags/wtem_csv.py [new file with mode: 0644]
src/wtem/urls.py [new file with mode: 0644]
src/wtem/views.py [new file with mode: 0644]
wtem/__init__.py [deleted file]
wtem/admin.py [deleted file]
wtem/fixtures/exercises-2013.json [deleted file]
wtem/fixtures/exercises-2014.json [deleted file]
wtem/fixtures/exercises-2015.json [deleted file]
wtem/fixtures/exercises-tem.json [deleted file]
wtem/fixtures/exercises-wlem.json [deleted file]
wtem/fixtures/exercises.json [deleted file]
wtem/forms.py [deleted file]
wtem/management/__init__.py [deleted file]
wtem/management/commands/__init__.py [deleted file]
wtem/management/commands/wlem_generate_keys.py [deleted file]
wtem/management/commands/wtem_assign_submissions.py [deleted file]
wtem/management/commands/wtem_email_teachers.py [deleted file]
wtem/management/commands/wtem_generate_keys.py [deleted file]
wtem/management/commands/wtem_send_keys.py [deleted file]
wtem/management/commands/wtem_send_results.py [deleted file]
wtem/management/commands/wtem_send_results_csv.py [deleted file]
wtem/middleware.py [deleted file]
wtem/migrations/0001_initial.py [deleted file]
wtem/migrations/0002_auto__add_field_submission_key_sent.py [deleted file]
wtem/migrations/0003_auto__add_assignment.py [deleted file]
wtem/migrations/0004_auto__add_unique_assignment_user.py [deleted file]
wtem/migrations/0005_auto__add_field_submission_marks.py [deleted file]
wtem/migrations/0006_auto__del_field_attachment_name__add_field_attachment_exercise_id.py [deleted file]
wtem/migrations/0007_auto.py [deleted file]
wtem/migrations/0008_auto__add_field_submission_end_time.py [deleted file]
wtem/migrations/0009_auto__add_field_attachment_tag.py [deleted file]
wtem/migrations/0010_auto__add_confirmation.py [deleted file]
wtem/migrations/__init__.py [deleted file]
wtem/models.py [deleted file]
wtem/static/wtem/edumed.coffee [deleted file]
wtem/static/wtem/edumed.js [deleted file]
wtem/static/wtem/img/1.png [deleted file]
wtem/static/wtem/img/1_small.png [deleted file]
wtem/static/wtem/img/2.png [deleted file]
wtem/static/wtem/img/2_small.png [deleted file]
wtem/static/wtem/img/3.png [deleted file]
wtem/static/wtem/img/3_small.png [deleted file]
wtem/static/wtem/img/komunikat_policyjny.png [deleted file]
wtem/static/wtem/img/krrit_zrzut_ekranu.png [deleted file]
wtem/static/wtem/img/przyp/1.jpg [deleted file]
wtem/static/wtem/img/przyp/2.jpg [deleted file]
wtem/static/wtem/img/przyp/3.jpg [deleted file]
wtem/static/wtem/img/przyp/4.jpg [deleted file]
wtem/static/wtem/img/przyp/5.jpg [deleted file]
wtem/static/wtem/img/przyp2/1.jpg [deleted file]
wtem/static/wtem/img/przyp2/2.jpg [deleted file]
wtem/static/wtem/img/przyp2/3.jpg [deleted file]
wtem/static/wtem/img/przyp2/4.jpg [deleted file]
wtem/static/wtem/img/przyp2/5.jpg [deleted file]
wtem/static/wtem/json2.js [deleted file]
wtem/static/wtem/spinner.gif [deleted file]
wtem/static/wtem/wtem.js [deleted file]
wtem/templates/admin/wtem/submission/change_list.html [deleted file]
wtem/templates/wtem/admin_report.csv [deleted file]
wtem/templates/wtem/disabled_contact_form.html [deleted file]
wtem/templates/wtem/email_key.txt [deleted file]
wtem/templates/wtem/email_teacher_before.txt [deleted file]
wtem/templates/wtem/email_teacher_before_subject.txt [deleted file]
wtem/templates/wtem/exercises/edumed_prawdafalsz.html [deleted file]
wtem/templates/wtem/exercises/edumed_przyporzadkuj.html [deleted file]
wtem/templates/wtem/exercises/edumed_uporzadkuj.html [deleted file]
wtem/templates/wtem/exercises/edumed_wybor.html [deleted file]
wtem/templates/wtem/exercises/exercise_no.html [deleted file]
wtem/templates/wtem/exercises/file_upload.html [deleted file]
wtem/templates/wtem/exercises/open.html [deleted file]
wtem/templates/wtem/key_not_found.html [deleted file]
wtem/templates/wtem/key_not_found_before.html [deleted file]
wtem/templates/wtem/main.html [deleted file]
wtem/templates/wtem/main_after.html [deleted file]
wtem/templates/wtem/main_before.html [deleted file]
wtem/templates/wtem/results_student_disqualified.txt [deleted file]
wtem/templates/wtem/results_student_failed.txt [deleted file]
wtem/templates/wtem/results_student_passed.txt [deleted file]
wtem/templates/wtem/results_teacher.txt [deleted file]
wtem/templates/wtem/thanks.html [deleted file]
wtem/templates/wtem/title.html [deleted file]
wtem/templatetags/__init__.py [deleted file]
wtem/templatetags/wtem_csv.py [deleted file]
wtem/urls.py [deleted file]
wtem/views.py [deleted file]

index 6c3faff..3eabac2 100644 (file)
@@ -1,3 +1,3 @@
 [submodule "lib/librarian"]
 [submodule "lib/librarian"]
-       path = lib/librarian
+       path = src/lib/librarian
        url = ssh://git@git.mdrn.pl/librarian.git
        url = ssh://git@git.mdrn.pl/librarian.git
index 2ee1cce..03fe177 100644 (file)
@@ -12,7 +12,7 @@ RUN apt-get update && apt-get install -y \
 COPY requirements.txt requirements.txt
 RUN pip install --no-cache-dir -r requirements.txt
 
 COPY requirements.txt requirements.txt
 RUN pip install --no-cache-dir -r requirements.txt
 
-WORKDIR /app
+WORKDIR /app/src
 
 
 FROM base AS dev
 
 
 FROM base AS dev
@@ -23,4 +23,4 @@ FROM base AS prod
 
 RUN pip install --no-cache-dir gunicorn psycopg2-binary
 
 
 RUN pip install --no-cache-dir gunicorn psycopg2-binary
 
-COPY . /app
+COPY src /app/src/
diff --git a/api/__init__.py b/api/__init__.py
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/api/admin.py b/api/admin.py
deleted file mode 100644 (file)
index 8c38f3f..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-from django.contrib import admin
-
-# Register your models here.
diff --git a/api/handlers.py b/api/handlers.py
deleted file mode 100644 (file)
index 5746b0c..0000000
+++ /dev/null
@@ -1,62 +0,0 @@
-# -*- coding: utf-8 -*-
-import json
-
-from django.contrib.sites.models import Site
-from django.core.urlresolvers import reverse
-from django.utils.functional import lazy
-from piston.handler import BaseHandler
-from piston.utils import rc
-
-from catalogue.forms import LessonImportForm
-from catalogue.models import Lesson
-
-API_BASE = EDUMED_BASE = MEDIA_BASE = lazy(
-    lambda: u'https://' + Site.objects.get_current().domain, unicode)()
-
-
-class LessonDetails(object):
-    """Custom fields used for representing Lessons."""
-
-    @classmethod
-    def href(cls, lesson):
-        """ Returns an URI for a Lesson in the API. """
-        return API_BASE + reverse("api_lesson", args=[lesson.slug])
-
-    @classmethod
-    def url(cls, lesson):
-        """ Returns Lesson's URL on the site. """
-        return EDUMED_BASE + lesson.get_absolute_url()
-
-
-class LessonDetailHandler(BaseHandler, LessonDetails):
-    """ Main handler for Lesson objects.
-
-    Responsible for single Lesson details.
-    """
-    allowed_methods = ['GET']
-    fields = ['title', 'url']
-
-    def read(self, request, lesson):
-        """ Returns details of a lesson, identified by a slug. """
-        try:
-            return Lesson.objects.get(slug=lesson)
-        except Lesson.DoesNotExist:
-            return rc.NOT_FOUND
-
-
-class LessonsHandler(LessonDetailHandler):
-    allowed_methods = ('GET', 'POST')
-    model = Lesson
-    fields = ['href', 'title', 'url']
-
-    def create(self, request, *args, **kwargs):
-        if not request.user.has_perm('catalogue.add_lesson'):
-            return rc.FORBIDDEN
-
-        data = json.loads(request.POST.get('data'))
-        form = LessonImportForm(data)
-        if form.is_valid():
-            form.save()
-            return rc.CREATED
-        else:
-            return rc.NOT_FOUND
diff --git a/api/helpers.py b/api/helpers.py
deleted file mode 100644 (file)
index a40373a..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-# -*- coding: utf-8 -*-
-from piston.resource import Resource
-
-
-class CsrfExemptResource(Resource):
-    """A Custom Resource that is csrf exempt"""
-    def __init__(self, handler, authentication=None):
-        super(CsrfExemptResource, self).__init__(handler, authentication)
-        self.csrf_exempt = getattr(self.handler, 'csrf_exempt', True)
\ No newline at end of file
diff --git a/api/models.py b/api/models.py
deleted file mode 100644 (file)
index 71a8362..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-from django.db import models
-
-# Create your models here.
diff --git a/api/templates/oauth/challenge.html b/api/templates/oauth/challenge.html
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/api/templates/piston/authorize_token.html b/api/templates/piston/authorize_token.html
deleted file mode 100644 (file)
index 0151b58..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-{% extends "base.html" %}
-{% load i18n %}
-
-{% block titleextra %}Zezwól na dostęp do Edukacji Medialnej{% endblock %}
-
-{% block body %}
-  <h1>Zezwól na dostęp do Edukacji Medialnej</h1>
-
-  <div class="normal-text">
-    <p>
-      Potwierdź dostęp do Edukacji Medialnej jako użytkownik <strong>{{ user }}</strong>.
-    </p>
-
-    <form action="{% url 'piston.authentication.oauth_user_auth' %}" method="POST">
-      {% csrf_token %}
-      {{ form.as_p }}
-      <button type="submit">Potwierdź</button>
-    </form>
-  </div>
-{% endblock %}
diff --git a/api/tests.py b/api/tests.py
deleted file mode 100644 (file)
index 7ce503c..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-from django.test import TestCase
-
-# Create your tests here.
diff --git a/api/urls.py b/api/urls.py
deleted file mode 100644 (file)
index a111872..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-# -*- coding: utf-8 -*-
-from django.conf.urls import patterns, url
-from django.views.decorators.csrf import csrf_exempt
-from piston.authentication import OAuthAuthentication, oauth_access_token
-from piston.resource import Resource
-
-from api import handlers
-from api.helpers import CsrfExemptResource
-
-auth = OAuthAuthentication(realm="Edukacja Medialna")
-
-lesson_list_resource = CsrfExemptResource(handler=handlers.LessonsHandler, authentication=auth)
-lesson_resource = Resource(handler=handlers.LessonDetailHandler)
-
-urlpatterns = patterns(
-    'piston.authentication',
-    url(r'^oauth/request_token/$', 'oauth_request_token'),
-    url(r'^oauth/authorize/$', 'oauth_user_auth'),
-    url(r'^oauth/access_token/$', csrf_exempt(oauth_access_token)),
-)
-
-urlpatterns += patterns(
-    '',
-    # url(r'^$', TemplateView.as_view(template_name='api/main.html'), name='api'),
-
-    # objects details
-    url(r'^lessons/(?P<lesson>[a-z0-9-]+)/$', lesson_resource, name="api_lesson"),
-
-    # lessons
-    url(r'^lessons/$', lesson_list_resource, name='api_lesson_list'),
-)
diff --git a/api/views.py b/api/views.py
deleted file mode 100644 (file)
index 91ea44a..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-from django.shortcuts import render
-
-# Create your views here.
diff --git a/catalogue/__init__.py b/catalogue/__init__.py
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/catalogue/admin.py b/catalogue/admin.py
deleted file mode 100755 (executable)
index 8256d66..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-# -*- coding: utf-8 -*-
-from django.contrib import admin
-from .models import Attachment, Section, Lesson, LessonStub
-
-
-class AttachmentInline(admin.TabularInline):
-    model = Attachment
-
-
-class LessonAdmin(admin.ModelAdmin):
-    inlines = [AttachmentInline]
-    list_display = ['title', 'section', 'type']
-    list_filter = ['level', 'type']
-
-admin.site.register(Section)
-admin.site.register(Lesson, LessonAdmin)
-admin.site.register(LessonStub)
diff --git a/catalogue/forms.py b/catalogue/forms.py
deleted file mode 100644 (file)
index 7230b23..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-# -*- coding: utf-8 -*-
-import json
-import os.path
-import shutil
-import urllib
-from tempfile import mkdtemp
-
-from django.forms import Form, CharField
-
-from librarian import IOFile
-from catalogue.models import Lesson
-
-
-class LessonImportForm(Form):
-    lesson_xml = CharField()
-    gallery_url = CharField(required=False)
-    attachments = CharField(required=False)
-
-    def save(self):
-        temp_dir = mkdtemp()
-        attachment_names = json.loads(self.cleaned_data['attachments'])
-        attachments = {}
-        remote_gallery_url = self.cleaned_data['gallery_url']
-        if remote_gallery_url and attachment_names:
-            for attachment_name in attachment_names:
-                attachment_url = ('%s%s' % (remote_gallery_url, attachment_name)).encode('utf-8')
-                temp_filename = os.path.join(temp_dir, attachment_name)
-                urllib.urlretrieve(attachment_url, temp_filename)
-                attachments[attachment_name] = IOFile.from_filename(temp_filename)
-
-        lesson = Lesson.publish(
-            IOFile.from_string(self.cleaned_data['lesson_xml'], attachments=attachments))
-        if os.path.isdir(temp_dir):
-            shutil.rmtree(temp_dir)
-        return lesson
diff --git a/catalogue/management/__init__.py b/catalogue/management/__init__.py
deleted file mode 100755 (executable)
index e69de29..0000000
diff --git a/catalogue/management/commands/__init__.py b/catalogue/management/commands/__init__.py
deleted file mode 100755 (executable)
index e69de29..0000000
diff --git a/catalogue/management/commands/extract_attachments.py b/catalogue/management/commands/extract_attachments.py
deleted file mode 100644 (file)
index 1735cbf..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-# -*- coding: utf-8 -*-
-# This file is part of EduMed, licensed under GNU Affero GPLv3 or later.
-# Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
-#
-import errno
-from optparse import make_option
-import os
-import shutil
-
-from django.core.management.base import BaseCommand
-
-
-def makedir(directory):
-    try:
-        os.makedirs(directory)
-    except OSError as e:
-        if e.errno != errno.EEXIST:
-            raise
-
-
-class Command(BaseCommand):
-    help = 'Extracts attachments from given lessons.'
-
-    option_list = BaseCommand.option_list + (
-        make_option('--slugs', dest='slugs_path', metavar="PATH", default=None,
-                    help='PATH to file with lesson slugs.'),
-    )
-
-    def handle(self, **options):
-        from catalogue.models import Lesson
-
-        lessons = Lesson.objects.order_by('slug')
-        if options.get('slugs_path'):
-            slugs = [line.strip() for line in open(options.get('slugs_path')) if line.strip()]
-            lessons = lessons.filter(slug__in=slugs)
-
-        for lesson in lessons:
-            makedir('materialy/%s' % lesson.slug)
-            for attachment in lesson.attachment_set.all():
-                shutil.copy(attachment.file.path, 'materialy/%s/%s.%s' % (lesson.slug, attachment.slug, attachment.ext))
-
diff --git a/catalogue/management/commands/importlessons.py b/catalogue/management/commands/importlessons.py
deleted file mode 100755 (executable)
index 296590b..0000000
+++ /dev/null
@@ -1,148 +0,0 @@
-# -*- coding: utf-8 -*-
-# This file is part of EduMed, licensed under GNU Affero GPLv3 or later.
-# Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
-#
-import os
-import sys
-from optparse import make_option
-
-from django.core.management.base import BaseCommand
-from django.db import transaction
-
-from catalogue.models import Lesson, Section
-from librarian import IOFile
-
-
-class Command(BaseCommand):
-    option_list = BaseCommand.option_list + (
-        make_option('-q', '--quiet', action='store_false', dest='verbose', default=True,
-                    help='Verbosity level; 0=minimal output, 1=normal output, 2=all output'),
-        make_option('-a', '--attachments', dest='attachments', metavar="PATH", default='materialy',
-                    help='Attachments dir path.'),
-        make_option('--ignore-incomplete', action='store_true', dest='ignore_incomplete', default=False,
-                    help='Attachments dir path.'),
-        make_option('--dont-repackage', action='store_false', dest='repackage', default=True,
-                    help='Don\'t refresh level packages.'),
-    )
-    help = 'Imports lessons from the specified directories.'
-    args = 'directory [directory ...]'
-
-    def __init__(self):
-        super(Command, self).__init__()
-        self.options = None
-        self.levels = None
-
-    @staticmethod
-    def all_attachments(path):
-        files = {}
-        if not os.path.isdir(path):
-            return files
-
-        def read_dir(path):
-            for name in os.listdir(path):
-                fullname = os.path.join(path, name)
-                if os.path.isdir(fullname):
-                    read_dir(fullname)
-                else:
-                    f = IOFile.from_filename(fullname)
-                    files[name.decode('utf-8')] = f
-                    files.setdefault(name.replace(" ", "").decode('utf-8'), f)
-
-        read_dir(path)
-        return files
-
-    @transaction.atomic
-    def handle(self, *directories, **options):
-
-        repackage = options.get('repackage')
-
-        self.levels = set()
-
-        curdir = os.path.abspath(os.curdir)
-        self.options = options
-
-        files_imported = 0
-        files_skipped = 0
-
-        for dir_name in directories:
-            abs_dir = os.path.join(curdir, dir_name)
-            if not os.path.isdir(abs_dir):
-                print self.style.ERROR("%s: Not a directory. Skipping." % abs_dir)
-            else:
-                files_imported_dir, files_skipped_dir = self.import_from_dir(abs_dir)
-                files_imported += files_imported_dir
-                files_skipped += files_skipped_dir
-
-        if self.levels and repackage:
-            print "Rebuilding level packages:"
-            for level in self.levels:
-                print level.name
-                level.build_packages()
-
-        # Print results
-        print
-        print "Results: %d files imported, %d skipped, %d total." % (
-            files_imported, files_skipped, files_imported + files_skipped)
-        print
-
-    def import_from_dir(self, abs_dir):
-        verbose = self.options.get('verbose')
-        files_imported = 0
-        files_skipped = 0
-        att_dir = os.path.join(abs_dir, self.options['attachments'])
-        attachments = self.all_attachments(att_dir)
-        # files queue
-        files = sorted(os.listdir(abs_dir))
-        postponed = {}
-        ignore_incomplete = set()
-        while files:
-            file_name = files.pop(0)
-            file_path = os.path.join(abs_dir, file_name)
-            file_base, ext = os.path.splitext(file_path)
-
-            if os.path.isdir(file_path):
-                dir_imported, dir_skipped = self.import_from_dir(file_path)
-                files_imported += dir_imported
-                files_skipped += files_skipped
-                continue
-
-            # Skip files that are not XML files
-            if not ext == '.xml':
-                continue
-
-            if verbose > 0:
-                print "Parsing '%s'" % file_path
-            else:
-                sys.stdout.write('.')
-                sys.stdout.flush()
-
-            try:
-                iofile = IOFile.from_filename(file_path)
-                iofile.attachments = attachments
-                lesson = Lesson.publish(iofile, file_name in ignore_incomplete)
-            except Section.IncompleteError:
-                if file_name not in postponed or postponed[file_name] < files_imported:
-                    # Push it back into the queue, maybe the missing lessons will show up.
-                    if verbose > 0:
-                        print self.style.NOTICE('Waiting for missing lessons.')
-                    files.append(file_name)
-                    postponed[file_name] = files_imported
-                elif self.options['ignore_incomplete'] and file_name not in ignore_incomplete:
-                    files.append(file_name)
-                    ignore_incomplete.add(file_name)
-                    postponed[file_name] = files_imported
-                else:
-                    # We're in a loop, nothing's being imported - some lesson is really missing.
-                    raise
-            except BaseException:
-                import traceback
-                traceback.print_exc()
-                files_skipped += 1
-            else:
-                files_imported += 1
-                if hasattr(lesson, 'level'):
-                    self.levels.add(lesson.level)
-            finally:
-                if verbose > 0:
-                    print
-        return files_imported, files_skipped
diff --git a/catalogue/management/commands/repackage.py b/catalogue/management/commands/repackage.py
deleted file mode 100755 (executable)
index a2851f6..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-# -*- coding: utf-8 -*-
-# This file is part of EduMed, licensed under GNU Affero GPLv3 or later.
-# Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
-#
-from django.core.management.base import BaseCommand
-
-
-class Command(BaseCommand):
-    help = 'Rebuilds downloadable packages.'
-
-    def handle(self, **options):
-        from curriculum.models import Level
-
-        for level in Level.objects.all():
-            level.build_packages()
diff --git a/catalogue/management/commands/republish.py b/catalogue/management/commands/republish.py
deleted file mode 100644 (file)
index 48f9345..0000000
+++ /dev/null
@@ -1,46 +0,0 @@
-# -*- coding: utf-8 -*-
-# This file is part of EduMed, licensed under GNU Affero GPLv3 or later.
-# Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
-#
-from optparse import make_option
-
-import librarian
-from django.core.management.base import BaseCommand
-
-
-class Command(BaseCommand):
-    help = 'Republishes all lessons.'
-
-    option_list = BaseCommand.option_list + (
-        make_option('--exclude', dest='exclude', metavar="PATH", default=None,
-                    help='PATH to file with excluded lesson slugs.'),
-        make_option('--ignore-incomplete', action='store_true', dest='ignore_incomplete', default=False,
-                    help='Attachments dir path.'),
-        make_option('--dont-repackage', action='store_false', dest='repackage', default=True,
-                    help='Don\'t refresh level packages.'),
-    )
-
-    def handle(self, **options):
-        from catalogue.models import Lesson
-        from curriculum.models import Level
-
-        lessons = Lesson.objects.order_by('slug')
-
-        if options.get('exclude'):
-            slugs = [line.strip() for line in open(options['exclude'])]
-            lessons = lessons.exclude(slug__in=slugs)
-
-        for lesson in lessons:
-            print
-            print 'Republishing: %s' % lesson.slug
-            try:
-                lesson.republish(repackage_level=False)
-            except librarian.ParseError as e:
-                print '!!!!!! PARSE ERROR !!!!!!'
-                print e
-
-        if options.get('repackage'):
-            print 'Rebuilding levels...'
-            for level in Level.objects.all():
-                print level.name
-                level.build_packages()
diff --git a/catalogue/migrations/0001_initial.py b/catalogue/migrations/0001_initial.py
deleted file mode 100644 (file)
index 846c559..0000000
+++ /dev/null
@@ -1,74 +0,0 @@
-# -*- coding: utf-8 -*-
-import datetime
-from south.db import db
-from south.v2 import SchemaMigration
-from django.db import models
-
-
-class Migration(SchemaMigration):
-
-    def forwards(self, orm):
-        # Adding model 'Section'
-        db.create_table('catalogue_section', (
-            ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
-            ('title', self.gf('django.db.models.fields.CharField')(max_length=255)),
-            ('order', self.gf('django.db.models.fields.IntegerField')()),
-        ))
-        db.send_create_signal('catalogue', ['Section'])
-
-        # Adding model 'Lesson'
-        db.create_table('catalogue_lesson', (
-            ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
-            ('section', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['catalogue.Section'])),
-            ('level', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['curriculum.Level'])),
-            ('title', self.gf('django.db.models.fields.CharField')(max_length=255)),
-            ('slug', self.gf('django.db.models.fields.SlugField')(unique=True, max_length=50)),
-            ('depth', self.gf('django.db.models.fields.IntegerField')()),
-            ('order', self.gf('django.db.models.fields.IntegerField')()),
-            ('xml_file', self.gf('django.db.models.fields.files.FileField')(max_length=100)),
-            ('package', self.gf('django.db.models.fields.files.FileField')(max_length=100)),
-            ('student_package', self.gf('django.db.models.fields.files.FileField')(max_length=100)),
-            ('html_file', self.gf('django.db.models.fields.files.FileField')(max_length=100)),
-        ))
-        db.send_create_signal('catalogue', ['Lesson'])
-
-
-    def backwards(self, orm):
-        # Deleting model 'Section'
-        db.delete_table('catalogue_section')
-
-        # Deleting model 'Lesson'
-        db.delete_table('catalogue_lesson')
-
-
-    models = {
-        'catalogue.lesson': {
-            'Meta': {'ordering': "['section', 'level', 'depth', 'order']", 'object_name': 'Lesson'},
-            'depth': ('django.db.models.fields.IntegerField', [], {}),
-            'html_file': ('django.db.models.fields.files.FileField', [], {'max_length': '100'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'level': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['curriculum.Level']"}),
-            'order': ('django.db.models.fields.IntegerField', [], {}),
-            'package': ('django.db.models.fields.files.FileField', [], {'max_length': '100'}),
-            'section': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['catalogue.Section']"}),
-            'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '50'}),
-            'student_package': ('django.db.models.fields.files.FileField', [], {'max_length': '100'}),
-            'title': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
-            'xml_file': ('django.db.models.fields.files.FileField', [], {'max_length': '100'})
-        },
-        'catalogue.section': {
-            'Meta': {'object_name': 'Section'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'order': ('django.db.models.fields.IntegerField', [], {}),
-            'title': ('django.db.models.fields.CharField', [], {'max_length': '255'})
-        },
-        'curriculum.level': {
-            'Meta': {'ordering': "['order']", 'object_name': 'Level'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
-            'order': ('django.db.models.fields.IntegerField', [], {}),
-            'slug': ('django.db.models.fields.SlugField', [], {'max_length': '50'})
-        }
-    }
-
-    complete_apps = ['catalogue']
\ No newline at end of file
diff --git a/catalogue/migrations/0002_auto__add_field_section_slug.py b/catalogue/migrations/0002_auto__add_field_section_slug.py
deleted file mode 100644 (file)
index 4b7ef4c..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-# -*- coding: utf-8 -*-
-import datetime
-from south.db import db
-from south.v2 import SchemaMigration
-from django.db import models
-
-
-class Migration(SchemaMigration):
-
-    def forwards(self, orm):
-        # Adding field 'Section.slug'
-        db.add_column('catalogue_section', 'slug',
-                      self.gf('django.db.models.fields.SlugField')(default='x', max_length=50),
-                      keep_default=False)
-
-
-    def backwards(self, orm):
-        # Deleting field 'Section.slug'
-        db.delete_column('catalogue_section', 'slug')
-
-
-    models = {
-        'catalogue.lesson': {
-            'Meta': {'ordering': "['section', 'level', 'depth', 'order']", 'object_name': 'Lesson'},
-            'depth': ('django.db.models.fields.IntegerField', [], {}),
-            'html_file': ('django.db.models.fields.files.FileField', [], {'max_length': '100'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'level': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['curriculum.Level']"}),
-            'order': ('django.db.models.fields.IntegerField', [], {}),
-            'package': ('django.db.models.fields.files.FileField', [], {'max_length': '100'}),
-            'section': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['catalogue.Section']"}),
-            'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '50'}),
-            'student_package': ('django.db.models.fields.files.FileField', [], {'max_length': '100'}),
-            'title': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
-            'xml_file': ('django.db.models.fields.files.FileField', [], {'max_length': '100'})
-        },
-        'catalogue.section': {
-            'Meta': {'object_name': 'Section'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'order': ('django.db.models.fields.IntegerField', [], {}),
-            'slug': ('django.db.models.fields.SlugField', [], {'max_length': '50'}),
-            'title': ('django.db.models.fields.CharField', [], {'max_length': '255'})
-        },
-        'curriculum.level': {
-            'Meta': {'ordering': "['order']", 'object_name': 'Level'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
-            'order': ('django.db.models.fields.IntegerField', [], {}),
-            'slug': ('django.db.models.fields.SlugField', [], {'max_length': '50'})
-        }
-    }
-
-    complete_apps = ['catalogue']
\ No newline at end of file
diff --git a/catalogue/migrations/0003_auto__chg_field_lesson_xml_file__chg_field_lesson_student_package__chg.py b/catalogue/migrations/0003_auto__chg_field_lesson_xml_file__chg_field_lesson_student_package__chg.py
deleted file mode 100644 (file)
index 8be90a8..0000000
+++ /dev/null
@@ -1,81 +0,0 @@
-# -*- coding: utf-8 -*-
-import datetime
-from south.db import db
-from south.v2 import SchemaMigration
-from django.db import models
-
-
-class Migration(SchemaMigration):
-
-    def forwards(self, orm):
-
-        # Changing field 'Lesson.xml_file'
-        db.alter_column('catalogue_lesson', 'xml_file', self.gf('django.db.models.fields.files.FileField')(max_length=100, null=True))
-
-        # Changing field 'Lesson.student_package'
-        db.alter_column('catalogue_lesson', 'student_package', self.gf('django.db.models.fields.files.FileField')(max_length=100, null=True))
-
-        # Changing field 'Lesson.package'
-        db.alter_column('catalogue_lesson', 'package', self.gf('django.db.models.fields.files.FileField')(max_length=100, null=True))
-
-        # Changing field 'Lesson.html_file'
-        db.alter_column('catalogue_lesson', 'html_file', self.gf('django.db.models.fields.files.FileField')(max_length=100, null=True))
-        # Adding unique constraint on 'Section', fields ['title']
-        db.create_unique('catalogue_section', ['title'])
-
-        # Adding unique constraint on 'Section', fields ['slug']
-        db.create_unique('catalogue_section', ['slug'])
-
-
-    def backwards(self, orm):
-        # Removing unique constraint on 'Section', fields ['slug']
-        db.delete_unique('catalogue_section', ['slug'])
-
-        # Removing unique constraint on 'Section', fields ['title']
-        db.delete_unique('catalogue_section', ['title'])
-
-
-        # User chose to not deal with backwards NULL issues for 'Lesson.xml_file'
-        raise RuntimeError("Cannot reverse this migration. 'Lesson.xml_file' and its values cannot be restored.")
-
-        # User chose to not deal with backwards NULL issues for 'Lesson.student_package'
-        raise RuntimeError("Cannot reverse this migration. 'Lesson.student_package' and its values cannot be restored.")
-
-        # User chose to not deal with backwards NULL issues for 'Lesson.package'
-        raise RuntimeError("Cannot reverse this migration. 'Lesson.package' and its values cannot be restored.")
-
-        # User chose to not deal with backwards NULL issues for 'Lesson.html_file'
-        raise RuntimeError("Cannot reverse this migration. 'Lesson.html_file' and its values cannot be restored.")
-
-    models = {
-        'catalogue.lesson': {
-            'Meta': {'ordering': "['section', 'level', 'depth', 'order']", 'object_name': 'Lesson'},
-            'depth': ('django.db.models.fields.IntegerField', [], {}),
-            'html_file': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'level': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['curriculum.Level']"}),
-            'order': ('django.db.models.fields.IntegerField', [], {}),
-            'package': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
-            'section': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['catalogue.Section']"}),
-            'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '50'}),
-            'student_package': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
-            'title': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
-            'xml_file': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'})
-        },
-        'catalogue.section': {
-            'Meta': {'object_name': 'Section'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'order': ('django.db.models.fields.IntegerField', [], {}),
-            'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '50'}),
-            'title': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'})
-        },
-        'curriculum.level': {
-            'Meta': {'ordering': "['order']", 'object_name': 'Level'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
-            'order': ('django.db.models.fields.IntegerField', [], {}),
-            'slug': ('django.db.models.fields.SlugField', [], {'max_length': '50'})
-        }
-    }
-
-    complete_apps = ['catalogue']
\ No newline at end of file
diff --git a/catalogue/migrations/0004_auto__add_part__add_attachment__add_field_lesson_pdf__add_field_lesson.py b/catalogue/migrations/0004_auto__add_part__add_attachment__add_field_lesson_pdf__add_field_lesson.py
deleted file mode 100644 (file)
index 59ae0d7..0000000
+++ /dev/null
@@ -1,99 +0,0 @@
-# -*- coding: utf-8 -*-
-import datetime
-from south.db import db
-from south.v2 import SchemaMigration
-from django.db import models
-
-
-class Migration(SchemaMigration):
-
-    def forwards(self, orm):
-        # Adding model 'Part'
-        db.create_table('catalogue_part', (
-            ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
-            ('lesson', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['catalogue.Lesson'])),
-            ('pdf', self.gf('django.db.models.fields.files.FileField')(max_length=100, null=True, blank=True)),
-            ('student_pdf', self.gf('django.db.models.fields.files.FileField')(max_length=100, null=True, blank=True)),
-        ))
-        db.send_create_signal('catalogue', ['Part'])
-
-        # Adding model 'Attachment'
-        db.create_table('catalogue_attachment', (
-            ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
-            ('lesson', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['catalogue.Lesson'])),
-            ('file', self.gf('django.db.models.fields.files.FileField')(max_length=100)),
-        ))
-        db.send_create_signal('catalogue', ['Attachment'])
-
-        # Adding field 'Lesson.pdf'
-        db.add_column('catalogue_lesson', 'pdf',
-                      self.gf('django.db.models.fields.files.FileField')(max_length=100, null=True, blank=True),
-                      keep_default=False)
-
-        # Adding field 'Lesson.student_pdf'
-        db.add_column('catalogue_lesson', 'student_pdf',
-                      self.gf('django.db.models.fields.files.FileField')(max_length=100, null=True, blank=True),
-                      keep_default=False)
-
-
-    def backwards(self, orm):
-        # Deleting model 'Part'
-        db.delete_table('catalogue_part')
-
-        # Deleting model 'Attachment'
-        db.delete_table('catalogue_attachment')
-
-        # Deleting field 'Lesson.pdf'
-        db.delete_column('catalogue_lesson', 'pdf')
-
-        # Deleting field 'Lesson.student_pdf'
-        db.delete_column('catalogue_lesson', 'student_pdf')
-
-
-    models = {
-        'catalogue.attachment': {
-            'Meta': {'object_name': 'Attachment'},
-            'file': ('django.db.models.fields.files.FileField', [], {'max_length': '100'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'lesson': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['catalogue.Lesson']"})
-        },
-        'catalogue.lesson': {
-            'Meta': {'ordering': "['section', 'level', 'depth', 'order']", 'object_name': 'Lesson'},
-            'depth': ('django.db.models.fields.IntegerField', [], {}),
-            'html_file': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'level': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['curriculum.Level']"}),
-            'order': ('django.db.models.fields.IntegerField', [], {}),
-            'package': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
-            'pdf': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
-            'section': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['catalogue.Section']"}),
-            'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '50'}),
-            'student_package': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
-            'student_pdf': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
-            'title': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
-            'xml_file': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'})
-        },
-        'catalogue.part': {
-            'Meta': {'object_name': 'Part'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'lesson': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['catalogue.Lesson']"}),
-            'pdf': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
-            'student_pdf': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'})
-        },
-        'catalogue.section': {
-            'Meta': {'ordering': "['order']", 'object_name': 'Section'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'order': ('django.db.models.fields.IntegerField', [], {}),
-            'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '50'}),
-            'title': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'})
-        },
-        'curriculum.level': {
-            'Meta': {'ordering': "['order']", 'object_name': 'Level'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
-            'order': ('django.db.models.fields.IntegerField', [], {}),
-            'slug': ('django.db.models.fields.SlugField', [], {'max_length': '50'})
-        }
-    }
-
-    complete_apps = ['catalogue']
\ No newline at end of file
diff --git a/catalogue/migrations/0005_auto__add_field_lesson_dc.py b/catalogue/migrations/0005_auto__add_field_lesson_dc.py
deleted file mode 100644 (file)
index ce7705f..0000000
+++ /dev/null
@@ -1,69 +0,0 @@
-# -*- coding: utf-8 -*-
-import datetime
-from south.db import db
-from south.v2 import SchemaMigration
-from django.db import models
-
-
-class Migration(SchemaMigration):
-
-    def forwards(self, orm):
-        # Adding field 'Lesson.dc'
-        db.add_column('catalogue_lesson', 'dc',
-                      self.gf('jsonfield.fields.JSONField')(default='{}'),
-                      keep_default=False)
-
-
-    def backwards(self, orm):
-        # Deleting field 'Lesson.dc'
-        db.delete_column('catalogue_lesson', 'dc')
-
-
-    models = {
-        'catalogue.attachment': {
-            'Meta': {'object_name': 'Attachment'},
-            'file': ('django.db.models.fields.files.FileField', [], {'max_length': '100'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'lesson': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['catalogue.Lesson']"})
-        },
-        'catalogue.lesson': {
-            'Meta': {'ordering': "['section', 'level', 'depth', 'order']", 'object_name': 'Lesson'},
-            'dc': ('jsonfield.fields.JSONField', [], {'default': "'{}'"}),
-            'depth': ('django.db.models.fields.IntegerField', [], {}),
-            'html_file': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'level': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['curriculum.Level']"}),
-            'order': ('django.db.models.fields.IntegerField', [], {}),
-            'package': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
-            'pdf': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
-            'section': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['catalogue.Section']"}),
-            'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '50'}),
-            'student_package': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
-            'student_pdf': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
-            'title': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
-            'xml_file': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'})
-        },
-        'catalogue.part': {
-            'Meta': {'object_name': 'Part'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'lesson': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['catalogue.Lesson']"}),
-            'pdf': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
-            'student_pdf': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'})
-        },
-        'catalogue.section': {
-            'Meta': {'ordering': "['order']", 'object_name': 'Section'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'order': ('django.db.models.fields.IntegerField', [], {}),
-            'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '50'}),
-            'title': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'})
-        },
-        'curriculum.level': {
-            'Meta': {'ordering': "['order']", 'object_name': 'Level'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
-            'order': ('django.db.models.fields.IntegerField', [], {}),
-            'slug': ('django.db.models.fields.SlugField', [], {'max_length': '50'})
-        }
-    }
-
-    complete_apps = ['catalogue']
\ No newline at end of file
diff --git a/catalogue/migrations/0006_auto__add_field_attachment_slug__add_field_attachment_ext__add_unique_.py b/catalogue/migrations/0006_auto__add_field_attachment_slug__add_field_attachment_ext__add_unique_.py
deleted file mode 100644 (file)
index 043627d..0000000
+++ /dev/null
@@ -1,85 +0,0 @@
-# -*- coding: utf-8 -*-
-import datetime
-from south.db import db
-from south.v2 import SchemaMigration
-from django.db import models
-
-
-class Migration(SchemaMigration):
-
-    def forwards(self, orm):
-        # Adding field 'Attachment.slug'
-        db.add_column('catalogue_attachment', 'slug',
-                      self.gf('django.db.models.fields.CharField')(default='', max_length=255),
-                      keep_default=False)
-
-        # Adding field 'Attachment.ext'
-        db.add_column('catalogue_attachment', 'ext',
-                      self.gf('django.db.models.fields.CharField')(default='', max_length=15),
-                      keep_default=False)
-
-        # Adding unique constraint on 'Attachment', fields ['ext', 'lesson', 'slug']
-        db.create_unique('catalogue_attachment', ['ext', 'lesson_id', 'slug'])
-
-
-    def backwards(self, orm):
-        # Removing unique constraint on 'Attachment', fields ['ext', 'lesson', 'slug']
-        db.delete_unique('catalogue_attachment', ['ext', 'lesson_id', 'slug'])
-
-        # Deleting field 'Attachment.slug'
-        db.delete_column('catalogue_attachment', 'slug')
-
-        # Deleting field 'Attachment.ext'
-        db.delete_column('catalogue_attachment', 'ext')
-
-
-    models = {
-        'catalogue.attachment': {
-            'Meta': {'unique_together': "(['lesson', 'slug', 'ext'],)", 'object_name': 'Attachment'},
-            'ext': ('django.db.models.fields.CharField', [], {'max_length': '15'}),
-            'file': ('django.db.models.fields.files.FileField', [], {'max_length': '100'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'lesson': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['catalogue.Lesson']"}),
-            'slug': ('django.db.models.fields.CharField', [], {'max_length': '255'})
-        },
-        'catalogue.lesson': {
-            'Meta': {'ordering': "['section', 'level', 'depth', 'order']", 'object_name': 'Lesson'},
-            'dc': ('jsonfield.fields.JSONField', [], {'default': "'{}'"}),
-            'depth': ('django.db.models.fields.IntegerField', [], {}),
-            'html_file': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'level': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['curriculum.Level']"}),
-            'order': ('django.db.models.fields.IntegerField', [], {}),
-            'package': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
-            'pdf': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
-            'section': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['catalogue.Section']"}),
-            'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '50'}),
-            'student_package': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
-            'student_pdf': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
-            'title': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
-            'xml_file': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'})
-        },
-        'catalogue.part': {
-            'Meta': {'object_name': 'Part'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'lesson': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['catalogue.Lesson']"}),
-            'pdf': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
-            'student_pdf': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'})
-        },
-        'catalogue.section': {
-            'Meta': {'ordering': "['order']", 'object_name': 'Section'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'order': ('django.db.models.fields.IntegerField', [], {}),
-            'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '50'}),
-            'title': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'})
-        },
-        'curriculum.level': {
-            'Meta': {'ordering': "['order']", 'object_name': 'Level'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
-            'order': ('django.db.models.fields.IntegerField', [], {}),
-            'slug': ('django.db.models.fields.SlugField', [], {'max_length': '50'})
-        }
-    }
-
-    complete_apps = ['catalogue']
\ No newline at end of file
diff --git a/catalogue/migrations/0007_auto__add_field_lesson_type__chg_field_lesson_section.py b/catalogue/migrations/0007_auto__add_field_lesson_type__chg_field_lesson_section.py
deleted file mode 100644 (file)
index 25204db..0000000
+++ /dev/null
@@ -1,96 +0,0 @@
-# -*- coding: utf-8 -*-
-import datetime
-from south.db import db
-from south.v2 import SchemaMigration
-from django.db import models
-
-
-class Migration(SchemaMigration):
-
-    def forwards(self, orm):
-        # Adding field 'Lesson.type'
-        db.add_column('catalogue_lesson', 'type',
-                      self.gf('django.db.models.fields.CharField')(default='course', max_length=15, db_index=True),
-                      keep_default=False)
-
-        # Changing field 'Lesson.section'
-        db.alter_column('catalogue_lesson', 'section_id', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['catalogue.Section'], null=True))
-        # Adding index on 'Lesson', fields ['order']
-        db.create_index('catalogue_lesson', ['order'])
-
-        if not db.dry_run:
-            orm.Lesson.objects.filter(depth=0).update(type='synthetic')
-
-
-    def backwards(self, orm):
-        # Removing index on 'Lesson', fields ['order']
-        db.delete_index('catalogue_lesson', ['order'])
-
-        # Deleting field 'Lesson.type'
-        db.delete_column('catalogue_lesson', 'type')
-
-        section = 0
-        if not db.dry_run:
-            orm.Lesson.objects.filter(type='synthetic').update(depth=0)
-            try:
-                section = orm.Section.objects.all()[0]
-            except orm.Section.DoesNotExist:
-                pass
-
-        # Changing field 'Lesson.section'
-        db.alter_column('catalogue_lesson', 'section_id',
-            self.gf('django.db.models.fields.related.ForeignKey')(default=section, to=orm['catalogue.Section']))
-
-
-    models = {
-        'catalogue.attachment': {
-            'Meta': {'ordering': "['slug', 'ext']", 'unique_together': "(['lesson', 'slug', 'ext'],)", 'object_name': 'Attachment'},
-            'ext': ('django.db.models.fields.CharField', [], {'max_length': '15'}),
-            'file': ('django.db.models.fields.files.FileField', [], {'max_length': '100'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'lesson': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['catalogue.Lesson']"}),
-            'slug': ('django.db.models.fields.CharField', [], {'max_length': '255'})
-        },
-        'catalogue.lesson': {
-            'Meta': {'ordering': "['section', 'level', 'order']", 'object_name': 'Lesson'},
-            'dc': ('jsonfield.fields.JSONField', [], {'default': "'{}'"}),
-            'depth': ('django.db.models.fields.IntegerField', [], {}),
-            'html_file': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'level': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['curriculum.Level']"}),
-            'order': ('django.db.models.fields.IntegerField', [], {'db_index': 'True'}),
-            'package': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
-            'pdf': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
-            'section': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['catalogue.Section']", 'null': 'True', 'blank': 'True'}),
-            'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '50'}),
-            'student_package': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
-            'student_pdf': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
-            'title': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
-            'type': ('django.db.models.fields.CharField', [], {'max_length': '15', 'db_index': 'True'}),
-            'xml_file': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'})
-        },
-        'catalogue.part': {
-            'Meta': {'object_name': 'Part'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'lesson': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['catalogue.Lesson']"}),
-            'pdf': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
-            'student_pdf': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'})
-        },
-        'catalogue.section': {
-            'Meta': {'ordering': "['order']", 'object_name': 'Section'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'order': ('django.db.models.fields.IntegerField', [], {}),
-            'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '50'}),
-            'title': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'})
-        },
-        'curriculum.level': {
-            'Meta': {'ordering': "['order']", 'object_name': 'Level'},
-            'group': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
-            'order': ('django.db.models.fields.IntegerField', [], {}),
-            'slug': ('django.db.models.fields.CharField', [], {'max_length': '255'})
-        }
-    }
-
-    complete_apps = ['catalogue']
diff --git a/catalogue/migrations/0008_auto__del_field_lesson_depth.py b/catalogue/migrations/0008_auto__del_field_lesson_depth.py
deleted file mode 100644 (file)
index 4bd650f..0000000
+++ /dev/null
@@ -1,72 +0,0 @@
-# -*- coding: utf-8 -*-
-import datetime
-from south.db import db
-from south.v2 import SchemaMigration
-from django.db import models
-
-
-class Migration(SchemaMigration):
-
-    def forwards(self, orm):
-        # Deleting field 'Lesson.depth'
-        db.delete_column('catalogue_lesson', 'depth')
-
-
-    def backwards(self, orm):
-        # Adding field 'Lesson.depth'
-        db.add_column('catalogue_lesson', 'depth',
-                      self.gf('django.db.models.fields.IntegerField')(default=1),
-                      keep_default=False)
-
-
-    models = {
-        'catalogue.attachment': {
-            'Meta': {'ordering': "['slug', 'ext']", 'unique_together': "(['lesson', 'slug', 'ext'],)", 'object_name': 'Attachment'},
-            'ext': ('django.db.models.fields.CharField', [], {'max_length': '15'}),
-            'file': ('django.db.models.fields.files.FileField', [], {'max_length': '100'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'lesson': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['catalogue.Lesson']"}),
-            'slug': ('django.db.models.fields.CharField', [], {'max_length': '255'})
-        },
-        'catalogue.lesson': {
-            'Meta': {'ordering': "['section', 'level', 'order']", 'object_name': 'Lesson'},
-            'dc': ('jsonfield.fields.JSONField', [], {'default': "'{}'"}),
-            'html_file': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'level': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['curriculum.Level']"}),
-            'order': ('django.db.models.fields.IntegerField', [], {'db_index': 'True'}),
-            'package': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
-            'pdf': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
-            'section': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['catalogue.Section']", 'null': 'True', 'blank': 'True'}),
-            'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '50'}),
-            'student_package': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
-            'student_pdf': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
-            'title': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
-            'type': ('django.db.models.fields.CharField', [], {'max_length': '15', 'db_index': 'True'}),
-            'xml_file': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'})
-        },
-        'catalogue.part': {
-            'Meta': {'object_name': 'Part'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'lesson': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['catalogue.Lesson']"}),
-            'pdf': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
-            'student_pdf': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'})
-        },
-        'catalogue.section': {
-            'Meta': {'ordering': "['order']", 'object_name': 'Section'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'order': ('django.db.models.fields.IntegerField', [], {}),
-            'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '50'}),
-            'title': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'})
-        },
-        'curriculum.level': {
-            'Meta': {'ordering': "['order']", 'object_name': 'Level'},
-            'group': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
-            'order': ('django.db.models.fields.IntegerField', [], {}),
-            'slug': ('django.db.models.fields.CharField', [], {'max_length': '255'})
-        }
-    }
-
-    complete_apps = ['catalogue']
diff --git a/catalogue/migrations/0009_auto__add_field_section_xml_file.py b/catalogue/migrations/0009_auto__add_field_section_xml_file.py
deleted file mode 100644 (file)
index 6686e5c..0000000
+++ /dev/null
@@ -1,73 +0,0 @@
-# -*- coding: utf-8 -*-
-import datetime
-from south.db import db
-from south.v2 import SchemaMigration
-from django.db import models
-
-
-class Migration(SchemaMigration):
-
-    def forwards(self, orm):
-        # Adding field 'Section.xml_file'
-        db.add_column('catalogue_section', 'xml_file',
-                      self.gf('django.db.models.fields.files.FileField')(max_length=100, null=True, blank=True),
-                      keep_default=False)
-
-
-    def backwards(self, orm):
-        # Deleting field 'Section.xml_file'
-        db.delete_column('catalogue_section', 'xml_file')
-
-
-    models = {
-        'catalogue.attachment': {
-            'Meta': {'ordering': "['slug', 'ext']", 'unique_together': "(['lesson', 'slug', 'ext'],)", 'object_name': 'Attachment'},
-            'ext': ('django.db.models.fields.CharField', [], {'max_length': '15'}),
-            'file': ('django.db.models.fields.files.FileField', [], {'max_length': '100'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'lesson': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['catalogue.Lesson']"}),
-            'slug': ('django.db.models.fields.CharField', [], {'max_length': '255'})
-        },
-        'catalogue.lesson': {
-            'Meta': {'ordering': "['section', 'level', 'order']", 'object_name': 'Lesson'},
-            'dc': ('jsonfield.fields.JSONField', [], {'default': "'{}'"}),
-            'html_file': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'level': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['curriculum.Level']"}),
-            'order': ('django.db.models.fields.IntegerField', [], {'db_index': 'True'}),
-            'package': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
-            'pdf': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
-            'section': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['catalogue.Section']", 'null': 'True', 'blank': 'True'}),
-            'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '50'}),
-            'student_package': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
-            'student_pdf': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
-            'title': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
-            'type': ('django.db.models.fields.CharField', [], {'max_length': '15', 'db_index': 'True'}),
-            'xml_file': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'})
-        },
-        'catalogue.part': {
-            'Meta': {'object_name': 'Part'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'lesson': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['catalogue.Lesson']"}),
-            'pdf': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
-            'student_pdf': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'})
-        },
-        'catalogue.section': {
-            'Meta': {'ordering': "['order']", 'object_name': 'Section'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'order': ('django.db.models.fields.IntegerField', [], {}),
-            'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '50'}),
-            'title': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'}),
-            'xml_file': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'})
-        },
-        'curriculum.level': {
-            'Meta': {'ordering': "['order']", 'object_name': 'Level'},
-            'group': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
-            'order': ('django.db.models.fields.IntegerField', [], {}),
-            'slug': ('django.db.models.fields.CharField', [], {'max_length': '255'})
-        }
-    }
-
-    complete_apps = ['catalogue']
\ No newline at end of file
diff --git a/catalogue/migrations/0010_auto.py b/catalogue/migrations/0010_auto.py
deleted file mode 100644 (file)
index 73602ca..0000000
+++ /dev/null
@@ -1,83 +0,0 @@
-# -*- coding: utf-8 -*-
-import datetime
-from south.db import db
-from south.v2 import SchemaMigration
-from django.db import models
-
-
-class Migration(SchemaMigration):
-
-    def forwards(self, orm):
-        # Adding M2M table for field curriculum_courses on 'Lesson'
-        db.create_table('catalogue_lesson_curriculum_courses', (
-            ('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)),
-            ('lesson', models.ForeignKey(orm['catalogue.lesson'], null=False)),
-            ('curriculumcourse', models.ForeignKey(orm['curriculum.curriculumcourse'], null=False))
-        ))
-        db.create_unique('catalogue_lesson_curriculum_courses', ['lesson_id', 'curriculumcourse_id'])
-
-
-    def backwards(self, orm):
-        # Removing M2M table for field curriculum_courses on 'Lesson'
-        db.delete_table('catalogue_lesson_curriculum_courses')
-
-
-    models = {
-        'catalogue.attachment': {
-            'Meta': {'ordering': "['slug', 'ext']", 'unique_together': "(['lesson', 'slug', 'ext'],)", 'object_name': 'Attachment'},
-            'ext': ('django.db.models.fields.CharField', [], {'max_length': '15'}),
-            'file': ('django.db.models.fields.files.FileField', [], {'max_length': '100'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'lesson': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['catalogue.Lesson']"}),
-            'slug': ('django.db.models.fields.CharField', [], {'max_length': '255'})
-        },
-        'catalogue.lesson': {
-            'Meta': {'ordering': "['section', 'level', 'order']", 'object_name': 'Lesson'},
-            'curriculum_courses': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['curriculum.CurriculumCourse']", 'symmetrical': 'False'}),
-            'dc': ('jsonfield.fields.JSONField', [], {'default': "'{}'"}),
-            'html_file': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'level': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['curriculum.Level']"}),
-            'order': ('django.db.models.fields.IntegerField', [], {'db_index': 'True'}),
-            'package': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
-            'pdf': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
-            'section': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['catalogue.Section']", 'null': 'True', 'blank': 'True'}),
-            'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '50'}),
-            'student_package': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
-            'student_pdf': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
-            'title': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
-            'type': ('django.db.models.fields.CharField', [], {'max_length': '15', 'db_index': 'True'}),
-            'xml_file': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'})
-        },
-        'catalogue.part': {
-            'Meta': {'object_name': 'Part'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'lesson': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['catalogue.Lesson']"}),
-            'pdf': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
-            'student_pdf': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'})
-        },
-        'catalogue.section': {
-            'Meta': {'ordering': "['order']", 'object_name': 'Section'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'order': ('django.db.models.fields.IntegerField', [], {}),
-            'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '50'}),
-            'title': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'}),
-            'xml_file': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'})
-        },
-        'curriculum.curriculumcourse': {
-            'Meta': {'object_name': 'CurriculumCourse'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'slug': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}),
-            'title': ('django.db.models.fields.CharField', [], {'max_length': '255'})
-        },
-        'curriculum.level': {
-            'Meta': {'ordering': "['order']", 'object_name': 'Level'},
-            'group': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
-            'order': ('django.db.models.fields.IntegerField', [], {}),
-            'slug': ('django.db.models.fields.CharField', [], {'max_length': '255'})
-        }
-    }
-
-    complete_apps = ['catalogue']
\ No newline at end of file
diff --git a/catalogue/migrations/0011_auto__chg_field_lesson_xml_file__chg_field_lesson_student_pdf__chg_fie.py b/catalogue/migrations/0011_auto__chg_field_lesson_xml_file__chg_field_lesson_student_pdf__chg_fie.py
deleted file mode 100644 (file)
index 5963f2b..0000000
+++ /dev/null
@@ -1,127 +0,0 @@
-# -*- coding: utf-8 -*-
-import datetime
-from south.db import db
-from south.v2 import SchemaMigration
-from django.db import models
-
-
-class Migration(SchemaMigration):
-
-    def forwards(self, orm):
-
-        # Changing field 'Lesson.xml_file'
-        db.alter_column('catalogue_lesson', 'xml_file', self.gf('django.db.models.fields.files.FileField')(max_length=255, null=True))
-
-        # Changing field 'Lesson.student_pdf'
-        db.alter_column('catalogue_lesson', 'student_pdf', self.gf('django.db.models.fields.files.FileField')(max_length=255, null=True))
-
-        # Changing field 'Lesson.student_package'
-        db.alter_column('catalogue_lesson', 'student_package', self.gf('django.db.models.fields.files.FileField')(max_length=255, null=True))
-
-        # Changing field 'Lesson.package'
-        db.alter_column('catalogue_lesson', 'package', self.gf('django.db.models.fields.files.FileField')(max_length=255, null=True))
-
-        # Changing field 'Lesson.html_file'
-        db.alter_column('catalogue_lesson', 'html_file', self.gf('django.db.models.fields.files.FileField')(max_length=255, null=True))
-
-        # Changing field 'Lesson.pdf'
-        db.alter_column('catalogue_lesson', 'pdf', self.gf('django.db.models.fields.files.FileField')(max_length=255, null=True))
-
-        # Changing field 'Lesson.slug'
-        db.alter_column('catalogue_lesson', 'slug', self.gf('django.db.models.fields.SlugField')(unique=True, max_length=255))
-
-        # Changing field 'Section.xml_file'
-        db.alter_column('catalogue_section', 'xml_file', self.gf('django.db.models.fields.files.FileField')(max_length=255, null=True))
-
-        # Changing field 'Section.slug'
-        db.alter_column('catalogue_section', 'slug', self.gf('django.db.models.fields.SlugField')(unique=True, max_length=255))
-
-    def backwards(self, orm):
-
-        # Changing field 'Lesson.xml_file'
-        db.alter_column('catalogue_lesson', 'xml_file', self.gf('django.db.models.fields.files.FileField')(max_length=100, null=True))
-
-        # Changing field 'Lesson.student_pdf'
-        db.alter_column('catalogue_lesson', 'student_pdf', self.gf('django.db.models.fields.files.FileField')(max_length=100, null=True))
-
-        # Changing field 'Lesson.student_package'
-        db.alter_column('catalogue_lesson', 'student_package', self.gf('django.db.models.fields.files.FileField')(max_length=100, null=True))
-
-        # Changing field 'Lesson.package'
-        db.alter_column('catalogue_lesson', 'package', self.gf('django.db.models.fields.files.FileField')(max_length=100, null=True))
-
-        # Changing field 'Lesson.html_file'
-        db.alter_column('catalogue_lesson', 'html_file', self.gf('django.db.models.fields.files.FileField')(max_length=100, null=True))
-
-        # Changing field 'Lesson.pdf'
-        db.alter_column('catalogue_lesson', 'pdf', self.gf('django.db.models.fields.files.FileField')(max_length=100, null=True))
-
-        # Changing field 'Lesson.slug'
-        db.alter_column('catalogue_lesson', 'slug', self.gf('django.db.models.fields.SlugField')(max_length=50, unique=True))
-
-        # Changing field 'Section.xml_file'
-        db.alter_column('catalogue_section', 'xml_file', self.gf('django.db.models.fields.files.FileField')(max_length=100, null=True))
-
-        # Changing field 'Section.slug'
-        db.alter_column('catalogue_section', 'slug', self.gf('django.db.models.fields.SlugField')(max_length=50, unique=True))
-
-    models = {
-        'catalogue.attachment': {
-            'Meta': {'ordering': "['slug', 'ext']", 'unique_together': "(['lesson', 'slug', 'ext'],)", 'object_name': 'Attachment'},
-            'ext': ('django.db.models.fields.CharField', [], {'max_length': '15'}),
-            'file': ('django.db.models.fields.files.FileField', [], {'max_length': '100'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'lesson': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['catalogue.Lesson']"}),
-            'slug': ('django.db.models.fields.CharField', [], {'max_length': '255'})
-        },
-        'catalogue.lesson': {
-            'Meta': {'ordering': "['section', 'level', 'order']", 'object_name': 'Lesson'},
-            'curriculum_courses': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['curriculum.CurriculumCourse']", 'symmetrical': 'False'}),
-            'dc': ('jsonfield.fields.JSONField', [], {'default': "'{}'"}),
-            'html_file': ('django.db.models.fields.files.FileField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'level': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['curriculum.Level']"}),
-            'order': ('django.db.models.fields.IntegerField', [], {'db_index': 'True'}),
-            'package': ('django.db.models.fields.files.FileField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
-            'pdf': ('django.db.models.fields.files.FileField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
-            'section': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['catalogue.Section']", 'null': 'True', 'blank': 'True'}),
-            'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '255'}),
-            'student_package': ('django.db.models.fields.files.FileField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
-            'student_pdf': ('django.db.models.fields.files.FileField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
-            'title': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
-            'type': ('django.db.models.fields.CharField', [], {'max_length': '15', 'db_index': 'True'}),
-            'xml_file': ('django.db.models.fields.files.FileField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'})
-        },
-        'catalogue.part': {
-            'Meta': {'object_name': 'Part'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'lesson': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['catalogue.Lesson']"}),
-            'pdf': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
-            'student_pdf': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'})
-        },
-        'catalogue.section': {
-            'Meta': {'ordering': "['order']", 'object_name': 'Section'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'order': ('django.db.models.fields.IntegerField', [], {}),
-            'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '255'}),
-            'title': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'}),
-            'xml_file': ('django.db.models.fields.files.FileField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'})
-        },
-        'curriculum.curriculumcourse': {
-            'Meta': {'ordering': "['slug']", 'object_name': 'CurriculumCourse'},
-            'accusative': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'slug': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}),
-            'title': ('django.db.models.fields.CharField', [], {'max_length': '255'})
-        },
-        'curriculum.level': {
-            'Meta': {'ordering': "['order']", 'object_name': 'Level'},
-            'group': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
-            'order': ('django.db.models.fields.IntegerField', [], {}),
-            'slug': ('django.db.models.fields.CharField', [], {'max_length': '255'})
-        }
-    }
-
-    complete_apps = ['catalogue']
\ No newline at end of file
diff --git a/catalogue/migrations/0012_auto__add_lessonstub.py b/catalogue/migrations/0012_auto__add_lessonstub.py
deleted file mode 100644 (file)
index d8e53bb..0000000
+++ /dev/null
@@ -1,96 +0,0 @@
-# -*- coding: utf-8 -*-
-import datetime
-from south.db import db
-from south.v2 import SchemaMigration
-from django.db import models
-
-
-class Migration(SchemaMigration):
-
-    def forwards(self, orm):
-        # Adding model 'LessonStub'
-        db.create_table('catalogue_lessonstub', (
-            ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
-            ('section', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['catalogue.Section'], null=True, blank=True)),
-            ('level', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['curriculum.Level'])),
-            ('title', self.gf('django.db.models.fields.CharField')(max_length=255)),
-            ('type', self.gf('django.db.models.fields.CharField')(max_length=15, db_index=True)),
-            ('order', self.gf('django.db.models.fields.IntegerField')(db_index=True)),
-        ))
-        db.send_create_signal('catalogue', ['LessonStub'])
-
-
-    def backwards(self, orm):
-        # Deleting model 'LessonStub'
-        db.delete_table('catalogue_lessonstub')
-
-
-    models = {
-        'catalogue.attachment': {
-            'Meta': {'ordering': "['slug', 'ext']", 'unique_together': "(['lesson', 'slug', 'ext'],)", 'object_name': 'Attachment'},
-            'ext': ('django.db.models.fields.CharField', [], {'max_length': '15'}),
-            'file': ('django.db.models.fields.files.FileField', [], {'max_length': '100'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'lesson': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['catalogue.Lesson']"}),
-            'slug': ('django.db.models.fields.CharField', [], {'max_length': '255'})
-        },
-        'catalogue.lesson': {
-            'Meta': {'ordering': "['section', 'level', 'order']", 'object_name': 'Lesson'},
-            'curriculum_courses': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['curriculum.CurriculumCourse']", 'symmetrical': 'False'}),
-            'dc': ('jsonfield.fields.JSONField', [], {'default': "'{}'"}),
-            'html_file': ('django.db.models.fields.files.FileField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'level': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['curriculum.Level']"}),
-            'order': ('django.db.models.fields.IntegerField', [], {'db_index': 'True'}),
-            'package': ('django.db.models.fields.files.FileField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
-            'pdf': ('django.db.models.fields.files.FileField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
-            'section': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['catalogue.Section']", 'null': 'True', 'blank': 'True'}),
-            'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '255'}),
-            'student_package': ('django.db.models.fields.files.FileField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
-            'student_pdf': ('django.db.models.fields.files.FileField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
-            'title': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
-            'type': ('django.db.models.fields.CharField', [], {'max_length': '15', 'db_index': 'True'}),
-            'xml_file': ('django.db.models.fields.files.FileField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'})
-        },
-        'catalogue.lessonstub': {
-            'Meta': {'ordering': "['section', 'level', 'order']", 'object_name': 'LessonStub'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'level': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['curriculum.Level']"}),
-            'order': ('django.db.models.fields.IntegerField', [], {'db_index': 'True'}),
-            'section': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['catalogue.Section']", 'null': 'True', 'blank': 'True'}),
-            'title': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
-            'type': ('django.db.models.fields.CharField', [], {'max_length': '15', 'db_index': 'True'})
-        },
-        'catalogue.part': {
-            'Meta': {'object_name': 'Part'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'lesson': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['catalogue.Lesson']"}),
-            'pdf': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
-            'student_pdf': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'})
-        },
-        'catalogue.section': {
-            'Meta': {'ordering': "['order']", 'object_name': 'Section'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'order': ('django.db.models.fields.IntegerField', [], {}),
-            'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '255'}),
-            'title': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'}),
-            'xml_file': ('django.db.models.fields.files.FileField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'})
-        },
-        'curriculum.curriculumcourse': {
-            'Meta': {'ordering': "['slug']", 'object_name': 'CurriculumCourse'},
-            'accusative': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'slug': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}),
-            'title': ('django.db.models.fields.CharField', [], {'max_length': '255'})
-        },
-        'curriculum.level': {
-            'Meta': {'ordering': "['order']", 'object_name': 'Level'},
-            'group': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
-            'order': ('django.db.models.fields.IntegerField', [], {}),
-            'slug': ('django.db.models.fields.CharField', [], {'max_length': '255'})
-        }
-    }
-
-    complete_apps = ['catalogue']
\ No newline at end of file
diff --git a/catalogue/migrations/0013_auto__add_field_section_image.py b/catalogue/migrations/0013_auto__add_field_section_image.py
deleted file mode 100644 (file)
index e097d57..0000000
+++ /dev/null
@@ -1,91 +0,0 @@
-# -*- coding: utf-8 -*-
-import datetime
-from south.db import db
-from south.v2 import SchemaMigration
-from django.db import models
-
-
-class Migration(SchemaMigration):
-
-    def forwards(self, orm):
-        # Adding field 'Section.image'
-        db.add_column(u'catalogue_section', 'image',
-                      self.gf('django.db.models.fields.files.ImageField')(max_length=100, null=True, blank=True),
-                      keep_default=False)
-
-
-    def backwards(self, orm):
-        # Deleting field 'Section.image'
-        db.delete_column(u'catalogue_section', 'image')
-
-
-    models = {
-        u'catalogue.attachment': {
-            'Meta': {'ordering': "['slug', 'ext']", 'unique_together': "(['lesson', 'slug', 'ext'],)", 'object_name': 'Attachment'},
-            'ext': ('django.db.models.fields.CharField', [], {'max_length': '15'}),
-            'file': ('django.db.models.fields.files.FileField', [], {'max_length': '100'}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'lesson': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['catalogue.Lesson']"}),
-            'slug': ('django.db.models.fields.CharField', [], {'max_length': '255'})
-        },
-        u'catalogue.lesson': {
-            'Meta': {'ordering': "['section', 'level', 'order']", 'object_name': 'Lesson'},
-            'curriculum_courses': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['curriculum.CurriculumCourse']", 'symmetrical': 'False', 'blank': 'True'}),
-            'dc': ('jsonfield.fields.JSONField', [], {'default': "'{}'"}),
-            'html_file': ('django.db.models.fields.files.FileField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'level': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['curriculum.Level']"}),
-            'order': ('django.db.models.fields.IntegerField', [], {'db_index': 'True'}),
-            'package': ('django.db.models.fields.files.FileField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
-            'pdf': ('django.db.models.fields.files.FileField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
-            'section': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['catalogue.Section']", 'null': 'True', 'blank': 'True'}),
-            'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '255'}),
-            'student_package': ('django.db.models.fields.files.FileField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
-            'student_pdf': ('django.db.models.fields.files.FileField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
-            'title': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
-            'type': ('django.db.models.fields.CharField', [], {'max_length': '15', 'db_index': 'True'}),
-            'xml_file': ('django.db.models.fields.files.FileField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'})
-        },
-        u'catalogue.lessonstub': {
-            'Meta': {'ordering': "['section', 'level', 'order']", 'object_name': 'LessonStub'},
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'level': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['curriculum.Level']"}),
-            'order': ('django.db.models.fields.IntegerField', [], {'db_index': 'True'}),
-            'section': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['catalogue.Section']", 'null': 'True', 'blank': 'True'}),
-            'title': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
-            'type': ('django.db.models.fields.CharField', [], {'max_length': '15', 'db_index': 'True'})
-        },
-        u'catalogue.part': {
-            'Meta': {'object_name': 'Part'},
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'lesson': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['catalogue.Lesson']"}),
-            'pdf': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
-            'student_pdf': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'})
-        },
-        u'catalogue.section': {
-            'Meta': {'ordering': "['order']", 'object_name': 'Section'},
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'image': ('django.db.models.fields.files.ImageField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
-            'order': ('django.db.models.fields.IntegerField', [], {}),
-            'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '255'}),
-            'title': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'}),
-            'xml_file': ('django.db.models.fields.files.FileField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'})
-        },
-        u'curriculum.curriculumcourse': {
-            'Meta': {'ordering': "['slug']", 'object_name': 'CurriculumCourse'},
-            'accusative': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'slug': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}),
-            'title': ('django.db.models.fields.CharField', [], {'max_length': '255'})
-        },
-        u'curriculum.level': {
-            'Meta': {'ordering': "['order']", 'object_name': 'Level'},
-            'group': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
-            'order': ('django.db.models.fields.IntegerField', [], {}),
-            'slug': ('django.db.models.fields.CharField', [], {'max_length': '255'})
-        }
-    }
-
-    complete_apps = ['catalogue']
\ No newline at end of file
diff --git a/catalogue/migrations/0014_auto__add_field_section_summary.py b/catalogue/migrations/0014_auto__add_field_section_summary.py
deleted file mode 100644 (file)
index 7805ec7..0000000
+++ /dev/null
@@ -1,94 +0,0 @@
-# -*- coding: utf-8 -*-
-import datetime
-from south.db import db
-from south.v2 import SchemaMigration
-from django.db import models
-
-
-class Migration(SchemaMigration):
-
-    def forwards(self, orm):
-        # Adding field 'Section.summary'
-        db.add_column(u'catalogue_section', 'summary',
-                      self.gf('django.db.models.fields.TextField')(null=True, blank=True),
-                      keep_default=False)
-
-
-    def backwards(self, orm):
-        # Deleting field 'Section.summary'
-        db.delete_column(u'catalogue_section', 'summary')
-
-
-    models = {
-        u'catalogue.attachment': {
-            'Meta': {'ordering': "['slug', 'ext']", 'unique_together': "(['lesson', 'slug', 'ext'],)", 'object_name': 'Attachment'},
-            'ext': ('django.db.models.fields.CharField', [], {'max_length': '15'}),
-            'file': ('django.db.models.fields.files.FileField', [], {'max_length': '100'}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'lesson': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['catalogue.Lesson']"}),
-            'slug': ('django.db.models.fields.CharField', [], {'max_length': '255'})
-        },
-        u'catalogue.lesson': {
-            'Meta': {'ordering': "['section', 'level', 'order']", 'object_name': 'Lesson'},
-            'curriculum_courses': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['curriculum.CurriculumCourse']", 'symmetrical': 'False', 'blank': 'True'}),
-            'dc': ('jsonfield.fields.JSONField', [], {'default': "'{}'"}),
-            'html_file': ('django.db.models.fields.files.FileField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'level': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['curriculum.Level']"}),
-            'order': ('django.db.models.fields.IntegerField', [], {'db_index': 'True'}),
-            'package': ('django.db.models.fields.files.FileField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
-            'pdf': ('django.db.models.fields.files.FileField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
-            'section': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['catalogue.Section']", 'null': 'True', 'blank': 'True'}),
-            'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '255'}),
-            'student_package': ('django.db.models.fields.files.FileField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
-            'student_pdf': ('django.db.models.fields.files.FileField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
-            'title': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
-            'type': ('django.db.models.fields.CharField', [], {'max_length': '15', 'db_index': 'True'}),
-            'xml_file': ('django.db.models.fields.files.FileField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'})
-        },
-        u'catalogue.lessonstub': {
-            'Meta': {'ordering': "['section', 'level', 'order']", 'object_name': 'LessonStub'},
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'level': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['curriculum.Level']"}),
-            'order': ('django.db.models.fields.IntegerField', [], {'db_index': 'True'}),
-            'section': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['catalogue.Section']", 'null': 'True', 'blank': 'True'}),
-            'title': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
-            'type': ('django.db.models.fields.CharField', [], {'max_length': '15', 'db_index': 'True'})
-        },
-        u'catalogue.part': {
-            'Meta': {'object_name': 'Part'},
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'lesson': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['catalogue.Lesson']"}),
-            'pdf': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
-            'student_pdf': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'})
-        },
-        u'catalogue.section': {
-            'Meta': {'ordering': "['order']", 'object_name': 'Section'},
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'image': ('django.db.models.fields.files.ImageField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
-            'order': ('django.db.models.fields.IntegerField', [], {}),
-            'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '255'}),
-            'summary': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
-            'title': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'}),
-            'xml_file': ('django.db.models.fields.files.FileField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'})
-        },
-        u'curriculum.curriculumcourse': {
-            'Meta': {'ordering': "['slug']", 'object_name': 'CurriculumCourse'},
-            'accusative': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'slug': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}),
-            'title': ('django.db.models.fields.CharField', [], {'max_length': '255'})
-        },
-        u'curriculum.level': {
-            'Meta': {'ordering': "['order']", 'object_name': 'Level'},
-            'group_en': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
-            'group_pl': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name_en': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
-            'name_pl': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
-            'order': ('django.db.models.fields.IntegerField', [], {}),
-            'slug': ('django.db.models.fields.CharField', [], {'max_length': '255'})
-        }
-    }
-
-    complete_apps = ['catalogue']
\ No newline at end of file
diff --git a/catalogue/migrations/0015_auto__add_field_lesson_description.py b/catalogue/migrations/0015_auto__add_field_lesson_description.py
deleted file mode 100644 (file)
index 6d7dd5d..0000000
+++ /dev/null
@@ -1,95 +0,0 @@
-# -*- coding: utf-8 -*-
-import datetime
-from south.db import db
-from south.v2 import SchemaMigration
-from django.db import models
-
-
-class Migration(SchemaMigration):
-
-    def forwards(self, orm):
-        # Adding field 'Lesson.description'
-        db.add_column(u'catalogue_lesson', 'description',
-                      self.gf('django.db.models.fields.TextField')(null=True, blank=True),
-                      keep_default=False)
-
-
-    def backwards(self, orm):
-        # Deleting field 'Lesson.description'
-        db.delete_column(u'catalogue_lesson', 'description')
-
-
-    models = {
-        u'catalogue.attachment': {
-            'Meta': {'ordering': "['slug', 'ext']", 'unique_together': "(['lesson', 'slug', 'ext'],)", 'object_name': 'Attachment'},
-            'ext': ('django.db.models.fields.CharField', [], {'max_length': '15'}),
-            'file': ('django.db.models.fields.files.FileField', [], {'max_length': '100'}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'lesson': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['catalogue.Lesson']"}),
-            'slug': ('django.db.models.fields.CharField', [], {'max_length': '255'})
-        },
-        u'catalogue.lesson': {
-            'Meta': {'ordering': "['section', 'level', 'order']", 'object_name': 'Lesson'},
-            'curriculum_courses': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['curriculum.CurriculumCourse']", 'symmetrical': 'False', 'blank': 'True'}),
-            'dc': ('jsonfield.fields.JSONField', [], {'default': "'{}'"}),
-            'description': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
-            'html_file': ('django.db.models.fields.files.FileField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'level': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['curriculum.Level']"}),
-            'order': ('django.db.models.fields.IntegerField', [], {'db_index': 'True'}),
-            'package': ('django.db.models.fields.files.FileField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
-            'pdf': ('django.db.models.fields.files.FileField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
-            'section': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['catalogue.Section']", 'null': 'True', 'blank': 'True'}),
-            'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '255'}),
-            'student_package': ('django.db.models.fields.files.FileField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
-            'student_pdf': ('django.db.models.fields.files.FileField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
-            'title': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
-            'type': ('django.db.models.fields.CharField', [], {'max_length': '15', 'db_index': 'True'}),
-            'xml_file': ('django.db.models.fields.files.FileField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'})
-        },
-        u'catalogue.lessonstub': {
-            'Meta': {'ordering': "['section', 'level', 'order']", 'object_name': 'LessonStub'},
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'level': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['curriculum.Level']"}),
-            'order': ('django.db.models.fields.IntegerField', [], {'db_index': 'True'}),
-            'section': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['catalogue.Section']", 'null': 'True', 'blank': 'True'}),
-            'title': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
-            'type': ('django.db.models.fields.CharField', [], {'max_length': '15', 'db_index': 'True'})
-        },
-        u'catalogue.part': {
-            'Meta': {'object_name': 'Part'},
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'lesson': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['catalogue.Lesson']"}),
-            'pdf': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
-            'student_pdf': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'})
-        },
-        u'catalogue.section': {
-            'Meta': {'ordering': "['order']", 'object_name': 'Section'},
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'image': ('django.db.models.fields.files.ImageField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
-            'order': ('django.db.models.fields.IntegerField', [], {}),
-            'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '255'}),
-            'summary': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
-            'title': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'}),
-            'xml_file': ('django.db.models.fields.files.FileField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'})
-        },
-        u'curriculum.curriculumcourse': {
-            'Meta': {'ordering': "['slug']", 'object_name': 'CurriculumCourse'},
-            'accusative': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'slug': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}),
-            'title': ('django.db.models.fields.CharField', [], {'max_length': '255'})
-        },
-        u'curriculum.level': {
-            'Meta': {'ordering': "['order']", 'object_name': 'Level'},
-            'group_en': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
-            'group_pl': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name_en': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
-            'name_pl': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
-            'order': ('django.db.models.fields.IntegerField', [], {}),
-            'slug': ('django.db.models.fields.CharField', [], {'max_length': '255'})
-        }
-    }
-
-    complete_apps = ['catalogue']
\ No newline at end of file
diff --git a/catalogue/migrations/0016_auto__add_field_section_pic__add_field_section_pic_attribution__add_fi.py b/catalogue/migrations/0016_auto__add_field_section_pic__add_field_section_pic_attribution__add_fi.py
deleted file mode 100644 (file)
index 6be3fcf..0000000
+++ /dev/null
@@ -1,114 +0,0 @@
-# -*- coding: utf-8 -*-
-import datetime
-from south.db import db
-from south.v2 import SchemaMigration
-from django.db import models
-
-
-class Migration(SchemaMigration):
-
-    def forwards(self, orm):
-        # Adding field 'Section.pic'
-        db.add_column(u'catalogue_section', 'pic',
-                      self.gf('django.db.models.fields.files.ImageField')(max_length=100, null=True, blank=True),
-                      keep_default=False)
-
-        # Adding field 'Section.pic_attribution'
-        db.add_column(u'catalogue_section', 'pic_attribution',
-                      self.gf('django.db.models.fields.CharField')(max_length=255, null=True, blank=True),
-                      keep_default=False)
-
-        # Adding field 'Section.pic_src'
-        db.add_column(u'catalogue_section', 'pic_src',
-                      self.gf('django.db.models.fields.URLField')(max_length=200, null=True, blank=True),
-                      keep_default=False)
-
-
-    def backwards(self, orm):
-        # Deleting field 'Section.pic'
-        db.delete_column(u'catalogue_section', 'pic')
-
-        # Deleting field 'Section.pic_attribution'
-        db.delete_column(u'catalogue_section', 'pic_attribution')
-
-        # Deleting field 'Section.pic_src'
-        db.delete_column(u'catalogue_section', 'pic_src')
-
-
-    models = {
-        u'catalogue.attachment': {
-            'Meta': {'ordering': "['slug', 'ext']", 'unique_together': "(['lesson', 'slug', 'ext'],)", 'object_name': 'Attachment'},
-            'ext': ('django.db.models.fields.CharField', [], {'max_length': '15'}),
-            'file': ('django.db.models.fields.files.FileField', [], {'max_length': '100'}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'lesson': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['catalogue.Lesson']"}),
-            'slug': ('django.db.models.fields.CharField', [], {'max_length': '255'})
-        },
-        u'catalogue.lesson': {
-            'Meta': {'ordering': "['section', 'level', 'order']", 'object_name': 'Lesson'},
-            'curriculum_courses': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['curriculum.CurriculumCourse']", 'symmetrical': 'False', 'blank': 'True'}),
-            'dc': ('jsonfield.fields.JSONField', [], {'default': "'{}'"}),
-            'description': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
-            'html_file': ('django.db.models.fields.files.FileField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'level': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['curriculum.Level']"}),
-            'order': ('django.db.models.fields.IntegerField', [], {'db_index': 'True'}),
-            'package': ('django.db.models.fields.files.FileField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
-            'pdf': ('django.db.models.fields.files.FileField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
-            'section': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['catalogue.Section']", 'null': 'True', 'blank': 'True'}),
-            'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '255'}),
-            'student_package': ('django.db.models.fields.files.FileField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
-            'student_pdf': ('django.db.models.fields.files.FileField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
-            'title': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
-            'type': ('django.db.models.fields.CharField', [], {'max_length': '15', 'db_index': 'True'}),
-            'xml_file': ('django.db.models.fields.files.FileField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'})
-        },
-        u'catalogue.lessonstub': {
-            'Meta': {'ordering': "['section', 'level', 'order']", 'object_name': 'LessonStub'},
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'level': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['curriculum.Level']"}),
-            'order': ('django.db.models.fields.IntegerField', [], {'db_index': 'True'}),
-            'section': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['catalogue.Section']", 'null': 'True', 'blank': 'True'}),
-            'title': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
-            'type': ('django.db.models.fields.CharField', [], {'max_length': '15', 'db_index': 'True'})
-        },
-        u'catalogue.part': {
-            'Meta': {'object_name': 'Part'},
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'lesson': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['catalogue.Lesson']"}),
-            'pdf': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
-            'student_pdf': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'})
-        },
-        u'catalogue.section': {
-            'Meta': {'ordering': "['order']", 'object_name': 'Section'},
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'image': ('django.db.models.fields.files.ImageField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
-            'order': ('django.db.models.fields.IntegerField', [], {}),
-            'pic': ('django.db.models.fields.files.ImageField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
-            'pic_attribution': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
-            'pic_src': ('django.db.models.fields.URLField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}),
-            'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '255'}),
-            'summary': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
-            'title': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'}),
-            'xml_file': ('django.db.models.fields.files.FileField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'})
-        },
-        u'curriculum.curriculumcourse': {
-            'Meta': {'ordering': "['slug']", 'object_name': 'CurriculumCourse'},
-            'accusative': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'slug': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}),
-            'title': ('django.db.models.fields.CharField', [], {'max_length': '255'})
-        },
-        u'curriculum.level': {
-            'Meta': {'ordering': "['order']", 'object_name': 'Level'},
-            'group_en': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
-            'group_pl': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name_en': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
-            'name_pl': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
-            'order': ('django.db.models.fields.IntegerField', [], {}),
-            'slug': ('django.db.models.fields.CharField', [], {'max_length': '255'})
-        }
-    }
-
-    complete_apps = ['catalogue']
\ No newline at end of file
diff --git a/catalogue/migrations/0017_auto__chg_field_attachment_file.py b/catalogue/migrations/0017_auto__chg_field_attachment_file.py
deleted file mode 100644 (file)
index dbe1123..0000000
+++ /dev/null
@@ -1,99 +0,0 @@
-# -*- coding: utf-8 -*-
-from south.utils import datetime_utils as datetime
-from south.db import db
-from south.v2 import SchemaMigration
-from django.db import models
-
-
-class Migration(SchemaMigration):
-
-    def forwards(self, orm):
-
-        # Changing field 'Attachment.file'
-        db.alter_column(u'catalogue_attachment', 'file', self.gf('django.db.models.fields.files.FileField')(max_length=255))
-
-    def backwards(self, orm):
-
-        # Changing field 'Attachment.file'
-        db.alter_column(u'catalogue_attachment', 'file', self.gf('django.db.models.fields.files.FileField')(max_length=100))
-
-    models = {
-        u'catalogue.attachment': {
-            'Meta': {'ordering': "['slug', 'ext']", 'unique_together': "(['lesson', 'slug', 'ext'],)", 'object_name': 'Attachment'},
-            'ext': ('django.db.models.fields.CharField', [], {'max_length': '15'}),
-            'file': ('django.db.models.fields.files.FileField', [], {'max_length': '255'}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'lesson': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['catalogue.Lesson']"}),
-            'slug': ('django.db.models.fields.CharField', [], {'max_length': '255'})
-        },
-        u'catalogue.lesson': {
-            'Meta': {'ordering': "['section', 'level', 'order']", 'object_name': 'Lesson'},
-            'curriculum_courses': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['curriculum.CurriculumCourse']", 'symmetrical': 'False', 'blank': 'True'}),
-            'dc': ('jsonfield.fields.JSONField', [], {'default': "'{}'"}),
-            'description': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
-            'html_file': ('django.db.models.fields.files.FileField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'level': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['curriculum.Level']"}),
-            'order': ('django.db.models.fields.IntegerField', [], {'db_index': 'True'}),
-            'package': ('django.db.models.fields.files.FileField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
-            'pdf': ('django.db.models.fields.files.FileField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
-            'section': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['catalogue.Section']", 'null': 'True', 'blank': 'True'}),
-            'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '255'}),
-            'student_package': ('django.db.models.fields.files.FileField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
-            'student_pdf': ('django.db.models.fields.files.FileField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
-            'title': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
-            'type': ('django.db.models.fields.CharField', [], {'max_length': '15', 'db_index': 'True'}),
-            'xml_file': ('django.db.models.fields.files.FileField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'})
-        },
-        u'catalogue.lessonstub': {
-            'Meta': {'ordering': "['section', 'level', 'order']", 'object_name': 'LessonStub'},
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'level': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['curriculum.Level']"}),
-            'order': ('django.db.models.fields.IntegerField', [], {'db_index': 'True'}),
-            'section': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['catalogue.Section']", 'null': 'True', 'blank': 'True'}),
-            'title': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
-            'type': ('django.db.models.fields.CharField', [], {'max_length': '15', 'db_index': 'True'})
-        },
-        u'catalogue.part': {
-            'Meta': {'object_name': 'Part'},
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'lesson': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['catalogue.Lesson']"}),
-            'pdf': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
-            'student_pdf': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'})
-        },
-        u'catalogue.section': {
-            'Meta': {'ordering': "['order']", 'object_name': 'Section'},
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'image': ('django.db.models.fields.files.ImageField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
-            'order': ('django.db.models.fields.IntegerField', [], {}),
-            'pic': ('django.db.models.fields.files.ImageField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
-            'pic_attribution': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
-            'pic_src': ('django.db.models.fields.URLField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}),
-            'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '255'}),
-            'summary': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
-            'title': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'}),
-            'xml_file': ('django.db.models.fields.files.FileField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'})
-        },
-        u'curriculum.curriculumcourse': {
-            'Meta': {'ordering': "['slug']", 'object_name': 'CurriculumCourse'},
-            'accusative': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'slug': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}),
-            'title': ('django.db.models.fields.CharField', [], {'max_length': '255'})
-        },
-        u'curriculum.level': {
-            'Meta': {'ordering': "['order']", 'object_name': 'Level'},
-            'group_en': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
-            'group_pl': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'meta_name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'}),
-            'name_en': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
-            'name_pl': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
-            'order': ('django.db.models.fields.IntegerField', [], {}),
-            'package': ('django.db.models.fields.files.FileField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
-            'slug': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'}),
-            'student_package': ('django.db.models.fields.files.FileField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'})
-        }
-    }
-
-    complete_apps = ['catalogue']
\ No newline at end of file
diff --git a/catalogue/migrations/0018_auto__add_field_lesson_weasy_pdf.py b/catalogue/migrations/0018_auto__add_field_lesson_weasy_pdf.py
deleted file mode 100644 (file)
index 440b908..0000000
+++ /dev/null
@@ -1,102 +0,0 @@
-# -*- coding: utf-8 -*-
-from south.utils import datetime_utils as datetime
-from south.db import db
-from south.v2 import SchemaMigration
-from django.db import models
-
-
-class Migration(SchemaMigration):
-
-    def forwards(self, orm):
-        # Adding field 'Lesson.weasy_pdf'
-        db.add_column(u'catalogue_lesson', 'weasy_pdf',
-                      self.gf('django.db.models.fields.files.FileField')(max_length=255, null=True, blank=True),
-                      keep_default=False)
-
-
-    def backwards(self, orm):
-        # Deleting field 'Lesson.weasy_pdf'
-        db.delete_column(u'catalogue_lesson', 'weasy_pdf')
-
-
-    models = {
-        u'catalogue.attachment': {
-            'Meta': {'ordering': "['slug', 'ext']", 'unique_together': "(['lesson', 'slug', 'ext'],)", 'object_name': 'Attachment'},
-            'ext': ('django.db.models.fields.CharField', [], {'max_length': '15'}),
-            'file': ('django.db.models.fields.files.FileField', [], {'max_length': '255'}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'lesson': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['catalogue.Lesson']"}),
-            'slug': ('django.db.models.fields.CharField', [], {'max_length': '255'})
-        },
-        u'catalogue.lesson': {
-            'Meta': {'ordering': "['section', 'level', 'order']", 'object_name': 'Lesson'},
-            'curriculum_courses': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['curriculum.CurriculumCourse']", 'symmetrical': 'False', 'blank': 'True'}),
-            'dc': ('jsonfield.fields.JSONField', [], {'default': "'{}'"}),
-            'description': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
-            'html_file': ('django.db.models.fields.files.FileField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'level': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['curriculum.Level']"}),
-            'order': ('django.db.models.fields.IntegerField', [], {'db_index': 'True'}),
-            'package': ('django.db.models.fields.files.FileField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
-            'pdf': ('django.db.models.fields.files.FileField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
-            'section': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['catalogue.Section']", 'null': 'True', 'blank': 'True'}),
-            'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '255'}),
-            'student_package': ('django.db.models.fields.files.FileField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
-            'student_pdf': ('django.db.models.fields.files.FileField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
-            'title': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
-            'type': ('django.db.models.fields.CharField', [], {'max_length': '15', 'db_index': 'True'}),
-            'weasy_pdf': ('django.db.models.fields.files.FileField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
-            'xml_file': ('django.db.models.fields.files.FileField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'})
-        },
-        u'catalogue.lessonstub': {
-            'Meta': {'ordering': "['section', 'level', 'order']", 'object_name': 'LessonStub'},
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'level': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['curriculum.Level']"}),
-            'order': ('django.db.models.fields.IntegerField', [], {'db_index': 'True'}),
-            'section': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['catalogue.Section']", 'null': 'True', 'blank': 'True'}),
-            'title': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
-            'type': ('django.db.models.fields.CharField', [], {'max_length': '15', 'db_index': 'True'})
-        },
-        u'catalogue.part': {
-            'Meta': {'object_name': 'Part'},
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'lesson': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['catalogue.Lesson']"}),
-            'pdf': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
-            'student_pdf': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'})
-        },
-        u'catalogue.section': {
-            'Meta': {'ordering': "['order']", 'object_name': 'Section'},
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'image': ('django.db.models.fields.files.ImageField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
-            'order': ('django.db.models.fields.IntegerField', [], {}),
-            'pic': ('django.db.models.fields.files.ImageField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
-            'pic_attribution': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
-            'pic_src': ('django.db.models.fields.URLField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}),
-            'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '255'}),
-            'summary': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
-            'title': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'}),
-            'xml_file': ('django.db.models.fields.files.FileField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'})
-        },
-        u'curriculum.curriculumcourse': {
-            'Meta': {'ordering': "['slug']", 'object_name': 'CurriculumCourse'},
-            'accusative': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'slug': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}),
-            'title': ('django.db.models.fields.CharField', [], {'max_length': '255'})
-        },
-        u'curriculum.level': {
-            'Meta': {'ordering': "['order']", 'object_name': 'Level'},
-            'group_en': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
-            'group_pl': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'meta_name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'}),
-            'name_en': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
-            'name_pl': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
-            'order': ('django.db.models.fields.IntegerField', [], {}),
-            'package': ('django.db.models.fields.files.FileField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
-            'slug': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'}),
-            'student_package': ('django.db.models.fields.files.FileField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'})
-        }
-    }
-
-    complete_apps = ['catalogue']
\ No newline at end of file
diff --git a/catalogue/migrations/__init__.py b/catalogue/migrations/__init__.py
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/catalogue/models.py b/catalogue/models.py
deleted file mode 100644 (file)
index c73c762..0000000
+++ /dev/null
@@ -1,350 +0,0 @@
-# -*- coding: utf-8
-from django.conf import settings
-from django.core.files import File
-from django.core.urlresolvers import reverse
-from django.db import models
-from jsonfield import JSONField
-from fnpdjango.storage import BofhFileSystemStorage
-
-from curriculum.models import Level, Curriculum, CurriculumCourse
-import logging
-
-bofh_storage = BofhFileSystemStorage()
-
-
-class Section(models.Model):
-    title = models.CharField(max_length=255, unique=True)
-    slug = models.SlugField(max_length=255, unique=True)
-    order = models.IntegerField()
-    xml_file = models.FileField(
-        upload_to="catalogue/section/xml",
-        null=True, blank=True, max_length=255,
-        storage=bofh_storage)
-    image = models.ImageField(upload_to="catalogue/section/image", null=True, blank=True)
-
-    pic = models.ImageField(upload_to="catalogue/section/pic", null=True, blank=True)
-    pic_attribution = models.CharField(max_length=255, null=True, blank=True)
-    pic_src = models.URLField(null=True, blank=True)
-    
-    summary = models.TextField(blank=True, null=True)
-
-    class Meta:
-        ordering = ['order']
-
-    class IncompleteError(BaseException):
-        pass
-
-    def __unicode__(self):
-        return self.title
-
-    def get_absolute_url(self):
-        return "%s#gimnazjum_%s" % (reverse("catalogue_lessons"), self.slug)
-
-    @classmethod
-    def publish(cls, infile, ignore_incomplete=False):
-        from librarian.parser import WLDocument
-        from django.core.files.base import ContentFile
-        xml = infile.get_string()
-        wldoc = WLDocument.from_string(xml)
-
-        lessons = []
-        for part in wldoc.book_info.parts:
-            try:
-                lessons.append(Lesson.objects.get(slug=part.slug))
-            except Lesson.DoesNotExist, e:
-                if not ignore_incomplete:
-                    raise cls.IncompleteError(part.slug)
-
-        slug = wldoc.book_info.url.slug
-        try:
-            section = cls.objects.get(slug=slug)
-        except cls.DoesNotExist:
-            section = cls(slug=slug, order=0)
-
-        # Save XML file
-        section.xml_file.save('%s.xml' % slug, ContentFile(xml), save=False)
-        section.title = wldoc.book_info.title
-        section.save()
-
-        section.lesson_set.all().update(section=None)
-        for i, lesson in enumerate(lessons):
-            lesson.section = section
-            lesson.order = i
-            lesson.save()
-
-        return section
-
-    def syntetic_lesson(self, level):
-        try:
-            return self.lesson_set.filter(type='synthetic', level=level)[0]
-        except IndexError:
-            return None
-
-
-class Lesson(models.Model):
-    section = models.ForeignKey(Section, null=True, blank=True)
-    level = models.ForeignKey(Level)
-    title = models.CharField(max_length=255)
-    slug = models.SlugField(max_length=255, unique=True)
-    type = models.CharField(max_length=15, db_index=True)
-    order = models.IntegerField(db_index=True)
-    dc = JSONField(default='{}')
-    curriculum_courses = models.ManyToManyField(CurriculumCourse, blank=True)
-    description = models.TextField(null=True, blank=True)
-
-    xml_file = models.FileField(
-        upload_to="catalogue/lesson/xml",
-        null=True, blank=True, max_length=255, storage=bofh_storage)
-    html_file = models.FileField(
-        upload_to="catalogue/lesson/html",
-        null=True, blank=True, max_length=255, storage=bofh_storage)
-    package = models.FileField(
-        upload_to="catalogue/lesson/pack",
-        null=True, blank=True, max_length=255, storage=bofh_storage)
-    student_package = models.FileField(
-        upload_to="catalogue/lesson/student_pack",
-        null=True, blank=True, max_length=255, storage=bofh_storage)
-    pdf = models.FileField(
-        upload_to="catalogue/lesson/pdf",
-        null=True, blank=True, max_length=255, storage=bofh_storage)
-    student_pdf = models.FileField(
-        upload_to="catalogue/lesson/student_pdf",
-        null=True, blank=True, max_length=255, storage=bofh_storage)
-    weasy_pdf = models.FileField(
-        upload_to="catalogue/lesson/weasy",
-        null=True, blank=True, max_length=255, storage=bofh_storage)
-
-    class Meta:
-        ordering = ['section', 'level', 'order']
-
-    def __unicode__(self):
-        return self.title
-
-    @models.permalink
-    def get_absolute_url(self):
-        return 'catalogue_lesson', [self.slug]
-
-    @classmethod
-    def publish(cls, infile, ignore_incomplete=False, repackage_level=False):
-        from librarian.parser import WLDocument
-        from django.core.files.base import ContentFile
-        wldoc = WLDocument(infile)
-
-        # Check if not section metadata block.
-        if wldoc.book_info.parts:
-            return Section.publish(infile, ignore_incomplete=ignore_incomplete)
-
-        slug = wldoc.book_info.url.slug
-        try:
-            lesson = cls.objects.get(slug=slug)
-            lesson.attachment_set.all().delete()
-        except cls.DoesNotExist:
-            lesson = cls(slug=slug, order=0)
-
-        # Save XML file
-        lesson.xml_file.save('%s.xml' % slug, ContentFile(infile.get_string()), save=False)
-        lesson.title = wldoc.book_info.title
-
-        lesson.level = Level.objects.get(meta_name=wldoc.book_info.audience)
-        lesson.populate_dc()
-        lesson.populate_description(wldoc=wldoc)
-        lesson.build_html(infile=infile)
-        lesson.build_pdf()
-        lesson.build_package()
-        if lesson.type != 'project':
-            lesson.build_pdf(student=True)
-            lesson.build_package(student=True)
-        if repackage_level:
-            lesson.level.build_packages()
-        return lesson
-
-    def republish(self, repackage_level=True, attachments=None):
-        from librarian import IOFile
-        import os.path
-        from django.conf import settings
-        if attachments is None:
-            attachments = {}
-            for attachment in self.attachment_set.all():
-                full_name = os.path.join(settings.MEDIA_ROOT, attachment.file.name)
-                f = IOFile.from_filename(full_name)
-                attachments['%s.%s' % (attachment.slug, attachment.ext)] = f
-        infile = IOFile.from_filename(self.xml_file.path, attachments=attachments)
-        Lesson.publish(infile, repackage_level=repackage_level)
-
-    def populate_dc(self):
-        from librarian.parser import WLDocument
-        wldoc = WLDocument.from_file(self.xml_file.path)
-        self.dc = wldoc.book_info.to_dict()
-        self.type = self.dc["type"]
-        assert self.type in ('appendix', 'course', 'synthetic', 'project', 'added', 'added-var'), \
-            u"Unknown lesson type: %s" % self.type
-        self.save()
-
-        courses = set()
-        for identifier in wldoc.book_info.curriculum:
-            identifier = (identifier or "").replace(' ', '')
-            if not identifier:
-                continue
-            try:
-                curr = Curriculum.objects.get(identifier__iexact=identifier)
-            except Curriculum.DoesNotExist:
-                logging.warn('Unknown curriculum course %s in lesson %s' % (identifier, self.slug))
-                pass
-            else:
-                courses.add(curr.course)
-        self.curriculum_courses = courses
-
-    def populate_description(self, wldoc=None, infile=None):
-        if wldoc is None:
-            wldoc = self.wldocument(infile)
-        if self.type == 'project':
-            lookup = u'Zadanie'
-        else:
-            lookup = u'Pomysł na lekcję'
-        for header in wldoc.edoc.findall('.//naglowek_rozdzial'):
-            if (header.text or '').strip() == lookup:
-                from lxml import etree
-                self.description = etree.tostring(
-                    header.getnext(), method='text', encoding='unicode').strip()
-                self.save()
-                return
-
-    def wldocument(self, infile=None):
-        from librarian import IOFile
-        from librarian.parser import WLDocument
-        from .publish import OrmDocProvider
-
-        if infile is None:
-            infile = IOFile.from_filename(self.xml_file.path)
-            for att in self.attachment_set.all():
-                infile.attachments["%s.%s" % (att.slug, att.ext)] = \
-                    IOFile.from_filename(att.file.path)
-        return WLDocument(infile, provider=OrmDocProvider())
-
-    def build_html(self, infile=None):
-        from .publish import HtmlFormat
-        wldoc = self.wldocument(infile)
-        html = HtmlFormat(wldoc).build()
-        self.html_file.save("%s.html" % self.slug, File(open(html.get_filename())))
-
-    def build_pdf(self, student=False):
-        from .publish import PdfFormat
-        # PDF uses document with attachments already saved as media,
-        # otherwise sorl.thumbnail complains about SuspiciousOperations.
-        wldoc = self.wldocument()
-        if student:
-            pdf = PdfFormat(wldoc).build()
-            self.student_pdf.save("%s.pdf" % self.slug, File(open(pdf.get_filename())))
-        else:
-            pdf = PdfFormat(wldoc, teacher=True).build()
-            self.pdf.save("%s.pdf" % self.slug, File(open(pdf.get_filename())))
-
-    def build_pdf_from_html(self, **kwargs):
-        from .publish import PdfFromHtmlFormat
-        wldoc = self.wldocument()
-        pdf = PdfFromHtmlFormat(
-            wldoc, media_root=settings.MEDIA_ROOT,
-            html_to_pdf_command=settings.HTML_TO_PDF_COMMAND,
-            **kwargs).build()
-        self.weasy_pdf.save("%s.pdf" % self.slug, File(open(pdf.get_filename())))
-
-    def add_to_zip(self, zipf, student=False, prefix=''):
-        pdf = self.student_pdf if student else self.pdf
-        if pdf:
-            zipf.write(pdf.path, "%s%s%s.pdf" % (prefix, self.slug, "_student" if student else ""))
-            for attachment in self.attachment_set.all():
-                zipf.write(attachment.file.path, u"%smaterialy/%s.%s" % (prefix, attachment.slug, attachment.ext))
-            zipf.write(self.xml_file.path, "%spliki-zrodlowe/%s.xml" % (prefix, self.slug))
-
-    def build_package(self, student=False):
-        from StringIO import StringIO
-        import zipfile
-        from django.core.files.base import ContentFile
-        buff = StringIO()
-        zipf = zipfile.ZipFile(buff, 'w', zipfile.ZIP_STORED)
-        self.add_to_zip(zipf, student)
-        zipf.close()
-        fieldname = "student_package" if student else "package"
-        getattr(self, fieldname).save(
-            "%s%s.zip" % (self.slug, "_student" if student else ""),
-            ContentFile(buff.getvalue()))
-
-    def get_syntetic(self):
-        if self.section is None:
-            return None
-        return self.section.syntetic_lesson(self.level)
-
-    def get_other_level(self):
-        if self.section is None:
-            return None
-        other_levels = self.section.lesson_set.exclude(level=self.level)
-        if other_levels.exists():
-            return other_levels[0].level
-
-    def get_previous(self):
-        if self.section is None:
-            return None
-        try:
-            return self.section.lesson_set.filter(
-                type=self.type, level=self.level,
-                order__lt=self.order).order_by('-order')[0]
-        except IndexError:
-            return None
-
-    def get_next(self):
-        if self.section is None:
-            return None
-        try:
-            return self.section.lesson_set.filter(
-                type=self.type, level=self.level,
-                order__gt=self.order).order_by('order')[0]
-        except IndexError:
-            return None
-
-    def requires_internet(self):
-        return any(requirement in self.dc.get('requires', []) for requirement in ('internet', 'Internet'))
-
-
-def attachment_path(instance, filename):
-    return 'catalogue/attachment/%s/%s' % (instance.lesson.slug, filename)
-
-
-class Attachment(models.Model):
-    slug = models.CharField(max_length=255)
-    ext = models.CharField(max_length=15)
-    lesson = models.ForeignKey(Lesson)
-    file = models.FileField(upload_to=attachment_path, storage=bofh_storage, max_length=255)
-
-    class Meta:
-        ordering = ['slug', 'ext']
-        unique_together = ['lesson', 'slug', 'ext']
-
-    def __unicode__(self):
-        return "%s.%s" % (self.slug, self.ext)
-
-
-class Part(models.Model):
-    lesson = models.ForeignKey(Lesson)
-    pdf = models.FileField(upload_to="catalogue/part/pdf", null=True, blank=True)
-    student_pdf = models.FileField(upload_to="catalogue/part/student_pdf", null=True, blank=True)
-
-
-class LessonStub(models.Model):
-    section = models.ForeignKey(Section, null=True, blank=True)
-    level = models.ForeignKey(Level)
-    title = models.CharField(max_length=255)
-    type = models.CharField(max_length=15, db_index=True)
-    order = models.IntegerField(db_index=True)
-
-    class Meta:
-        ordering = ['section', 'level', 'order']
-
-    def __unicode__(self):
-        return self.title
-
-    @property
-    def slug(self):
-        return ''
-
-    def add_to_zip(self, *args, **kwargs):
-        pass
diff --git a/catalogue/publish.py b/catalogue/publish.py
deleted file mode 100755 (executable)
index 293b89e..0000000
+++ /dev/null
@@ -1,174 +0,0 @@
-# -*- coding: utf-8
-from django.core.files import File
-from django.core.urlresolvers import reverse
-from librarian import DocProvider, IOFile
-from librarian.pyhtml import EduModuleFormat
-from librarian.pypdf import EduModulePDFFormat
-from librarian.pdf_from_html import EduModulePdfFromHtmlFormat
-from .models import Lesson, Attachment
-from fnpdjango.utils.text.slughifi import slughifi
-
-
-# TODO: Using sorl.thumbnail for now,
-# but this should be done in Librarian,
-# directly using convert or PIL as a fallback.
-def get_image(src_img_path, width=None, default_width=1600, formats=('PNG', 'JPEG', 'GIF')):
-    """ Returns an object with `url` and `storage` attributes,
-        or None if using the original image is OK.
-    """
-
-    from PIL import Image
-    from sorl.thumbnail import get_thumbnail
-
-    # Does it need converting?
-    # Yes, if width is given explicitly.
-    convert = width is not None
-    if not convert:
-        # Looks like it doesn't need converting.
-        # But let's try opening it and checking its type.
-        try:
-            simg = Image.open(src_img_path)
-        except IOError:
-            # It doesn't look like image,
-            # but maybe it's convertable to one.
-            convert = True
-        else:
-            if simg.format not in formats:
-                # It's an image, but it's in some weird format.
-                convert = True
-                width = simg.size[0]
-
-    if convert:
-        if width is None:
-            width = default_width
-        try:
-            return get_thumbnail(src_img_path, '%sx%s' % (width, 10*width))
-        except:
-            # hard to predict what solr raises on invalid image
-            return None
-    else:
-        return None
-
-
-class HtmlFormat(EduModuleFormat):
-    IMAGE_FORMATS = ('PNG', 'JPEG', 'GIF')
-    DEFAULT_IMAGE_WIDTH = 1600
-
-    def find_attachment(self, slug, fmt):
-        lesson_slug = self.wldoc.book_info.url.slug
-        try:
-            # If already saved, use it.
-            att = Attachment.objects.get(lesson__slug=lesson_slug,
-                                         slug=slug, ext=fmt)
-        except Attachment.DoesNotExist, e:
-            # If attached to source IOFile, save now.
-            att_name = "%s.%s" % (slug, fmt)
-            try:
-                att_file = self.wldoc.source.attachments[att_name]
-            except KeyError:
-                print u"ATTACHMENT MISSING:", att_name
-                raise self.MaterialNotFound()
-            else:
-                lesson = Lesson.objects.get(slug=lesson_slug)
-                att = lesson.attachment_set.create(slug=slug, ext=fmt)
-                att.file.save(att_name, File(att_file.get_file()))
-                return att
-        else:
-            return att
-
-    def url_for_material(self, slug, fmt):
-        return self.find_attachment(slug, fmt).file.url
-
-    def url_for_image(self, slug, fmt, width=None):
-        try:
-            src_img = self.find_attachment(slug, fmt).file
-        except self.MaterialNotFound:
-            return ''
-        img = get_image(src_img.path, width, self.DEFAULT_IMAGE_WIDTH, self.IMAGE_FORMATS)
-        return (img or src_img).url
-
-    def text_to_anchor(self, text):
-        return slughifi(text)
-
-    def get_forma_url(self, forma):
-        return '%s#%s' % (
-            reverse('catalogue_lesson', args=['metody']),
-            self.text_to_anchor(forma)
-        )
-
-    def get_help_url(self, naglowek):
-        return '%s%s#%s' % (
-            '//edukacjamedialna.edu.pl',
-            reverse('info', args=['jak-korzystac/']),
-            self.naglowek_to_anchor(naglowek)
-        )
-
-
-class PdfFormat(EduModulePDFFormat):
-    IMAGE_FORMATS = ('PNG', 'JPEG', 'GIF')
-    DEFAULT_IMAGE_WIDTH = 1600
-
-    def get_image(self, name):
-        src_img = super(PdfFormat, self).get_image(name)
-        img = get_image(
-            src_img.get_filename(),
-            default_width=self.DEFAULT_IMAGE_WIDTH,
-            formats=self.IMAGE_FORMATS)
-        if img:
-            return IOFile.from_filename(img.storage.path(img))
-        else:
-            return src_img
-
-
-class PdfFromHtmlFormat(EduModulePdfFromHtmlFormat):
-    IMAGE_FORMATS = ('PNG', 'JPEG', 'GIF')
-    DEFAULT_IMAGE_WIDTH = 1600
-
-    def find_attachment(self, slug, fmt):
-        lesson_slug = self.wldoc.book_info.url.slug
-        try:
-            # If already saved, use it.
-            att = Attachment.objects.get(lesson__slug=lesson_slug,
-                                         slug=slug, ext=fmt)
-        except Attachment.DoesNotExist, e:
-            # If attached to source IOFile, save now.
-            att_name = "%s.%s" % (slug, fmt)
-            try:
-                att_file = self.wldoc.source.attachments[att_name]
-            except KeyError:
-                print u"ATTACHMENT MISSING:", att_name
-                raise self.MaterialNotFound()
-            else:
-                lesson = Lesson.objects.get(slug=lesson_slug)
-                att = lesson.attachment_set.create(slug=slug, ext=fmt)
-                att.file.save(att_name, File(att_file.get_file()))
-                return att
-        else:
-            return att
-
-    def url_for_material(self, slug, fmt):
-        return self.find_attachment(slug, fmt).file.url
-
-    def image(self, slug, fmt, width=None):
-        try:
-            src_img = self.find_attachment(slug, fmt).file
-        except self.MaterialNotFound:
-            return None
-        img = get_image(src_img.path, width, self.DEFAULT_IMAGE_WIDTH, self.IMAGE_FORMATS)
-        return img or src_img
-
-    def url_for_image(self, slug, fmt, image=None, **kwargs):
-        img = image or self.image(slug, fmt, **kwargs)
-        if img:
-            return img.url
-        else:
-            return ''
-
-    def text_to_anchor(self, text):
-        return slughifi(text)
-
-
-class OrmDocProvider(DocProvider):
-    def by_slug(self, slug):
-        """Should return a file-like object with a WL document XML."""
-        return IOFile.from_filename(Lesson.objects.get(slug=slug).xml_file.path)
diff --git a/catalogue/search_indexes.py b/catalogue/search_indexes.py
deleted file mode 100755 (executable)
index 035ce98..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-# -*- coding: utf-8 -*-
-from haystack import indexes
-from .models import Lesson
-
-
-class LessonIndex(indexes.SearchIndex, indexes.Indexable):
-    text = indexes.CharField(document=True, use_template=True)
-
-    def get_model(self):
-        return Lesson
diff --git a/catalogue/static/catalogue/css/carousel.css b/catalogue/static/catalogue/css/carousel.css
deleted file mode 100644 (file)
index 992e285..0000000
+++ /dev/null
@@ -1,110 +0,0 @@
-#catalogue-carousel {
-  float: left;
-  position: relative;
-  width: 43.75em;
-  height: 14.6875em;
-  overflow: hidden;
-  border-radius: 0.9375em;
-}
-  #catalogue-carousel #catalogue-carousel-links {
-    width: 28.75em;
-    height: 14.6875em;
-    list-style: none;
-    margin: 0;
-    padding: 0; }
-    #catalogue-carousel #catalogue-carousel-links li {
-      display: block;
-      position: absolute;
-      top: 0;
-      left: 0;
-      height: 100%;
-      background-size: 100% 100%;
-      border-top-left-radius: 0.9375em 6.38%;
-      border-bottom-left-radius: 0.9375em 6.38%;
-      z-index: 100;
-      background-color: #888; }
-      #catalogue-carousel #catalogue-carousel-links li a.catalogue-carousel-link {
-        display: block;
-        overflow: hidden;
-        width: 28.75em;
-        height: 100%;
-        background: url(/static/catalogue/img/carousel-left.png) 100% 0 no-repeat;
-        background-size: 4.375em 100%; }
-        #catalogue-carousel #catalogue-carousel-links li a.catalogue-carousel-link .catalogue-carousel-note {
-          position: relative;
-          height: 100%;
-          color: white;
-          margin-top: 8.5em; }
-          #catalogue-carousel #catalogue-carousel-links li a.catalogue-carousel-link .catalogue-carousel-note div:before {
-            content: " ";
-            display: block;
-            position: absolute;
-            height: 100%;
-            width: 100%;
-            z-index: -1;
-            background-color: black;
-            opacity: 0.6; }
-          #catalogue-carousel #catalogue-carousel-links li a.catalogue-carousel-link .catalogue-carousel-note div p {
-            padding: .4em 3em 0 .5em; }
-            #catalogue-carousel #catalogue-carousel-links li a.catalogue-carousel-link .catalogue-carousel-note div p strong {
-              font-size: 1.2em;
-              display: block; }
-            #catalogue-carousel #catalogue-carousel-links li a.catalogue-carousel-link .catalogue-carousel-note div p .more {
-              position: absolute;
-              right: 4em;
-              top: 4.5em; }
-      #catalogue-carousel #catalogue-carousel-links li a.catalogue-carousel-link:active {
-        outline: none; }
-      #catalogue-carousel #catalogue-carousel-links li .attribution {
-        text-align: right;
-        font-size: .75em;
-        position: absolute;
-        right: 5em;
-        top: .1em;
-        color: white;
-        font-weight: bold;
-        text-shadow: 0 0 5px #000; }
-  #catalogue-carousel #catalogue-carousel-switcher {
-    margin: 0;
-    padding: 0.1875em 0 0 3.625em;
-    width: 11.375em;
-    height: 14.6875em;
-    position: absolute;
-    right: 0;
-    top: 0;
-    list-style: none;
-    border-radius: 0 0.9375em 0.9375em 0;
-    background-color: #ed7831;
-    background-image: url(/static/catalogue/img/carousel-right.png);
-    background-position: 0 0;
-    background-repeat: no-repeat;
-    background-size: auto 14.6875em;
-    /* right part of mask as background */ }
-    #catalogue-carousel #catalogue-carousel-switcher li {
-      margin-bottom: .4em;
-      font-size: .85em;
-      line-height: 1em; }
-      #catalogue-carousel #catalogue-carousel-switcher li a {
-        text-transform: uppercase;
-        color: #363a3e; }
-      #catalogue-carousel #catalogue-carousel-switcher li a:before {
-        vertical-align: top;
-        margin-right: 1.5em; }
-      #catalogue-carousel #catalogue-carousel-switcher li .knowledge:before {
-        content: url(/static/img/icons/knowledge_dark.png); }
-      #catalogue-carousel #catalogue-carousel-switcher li .activity:before {
-        content: url(/static/img/icons/activity_dark.png); }
-      #catalogue-carousel #catalogue-carousel-switcher li .lesson-plan:before {
-        content: url(/static/img/icons/lesson-plan_dark.png); }
-      #catalogue-carousel #catalogue-carousel-switcher li .reference:before {
-        content: url(/static/img/icons/reference_dark.png); }
-    #catalogue-carousel #catalogue-carousel-switcher li.activeSlide a {
-      color: white; }
-    #catalogue-carousel #catalogue-carousel-switcher li.activeSlide .knowledge:before {
-      content: url(/static/img/icons/knowledge_white.png); }
-    #catalogue-carousel #catalogue-carousel-switcher li.activeSlide .activity:before {
-      content: url(/static/img/icons/activity_white.png); }
-    #catalogue-carousel #catalogue-carousel-switcher li.activeSlide .lesson-plan:before {
-      content: url(/static/img/icons/lesson-plan_white.png); }
-    #catalogue-carousel #catalogue-carousel-switcher li.activeSlide .reference:before {
-      content: url(/static/img/icons/reference_white.png); }
diff --git a/catalogue/static/catalogue/css/carousel.scss b/catalogue/static/catalogue/css/carousel.scss
deleted file mode 100755 (executable)
index 299f95b..0000000
+++ /dev/null
@@ -1,140 +0,0 @@
-$px: .0625em;
-
-$ciemny: #363a3e;
-
-
-#catalogue-carousel {
-    float: left;
-    position: relative;
-    width: 700*$px;
-    height: 235*$px;
-    overflow: hidden;
-    border-radius: 15*$px;
-
-    #catalogue-carousel-links {
-        width: 460*$px;
-        height: 235*$px;
-        list-style: none;
-        margin: 0;
-        padding: 0;
-
-        li {
-            display: block;
-            position: absolute;
-            top: 0;
-            left: 0;
-            height: 100%;
-            background-size: 100% 100%;
-            border-top-left-radius: 15*$px 6.38%;
-            border-bottom-left-radius: 15*$px 6.38%;
-            z-index: 100;
-            background-color: #888;
-
-            a.catalogue-carousel-link {
-                display: block;
-                overflow: hidden;
-                width: 460*$px;
-                height: 100%;
-                background: url(/static/catalogue/img/carousel-left.png) 100% 0 no-repeat;
-                background-size: 70*$px 100%;
-                
-                .catalogue-carousel-note {
-                    position: relative;
-                    height: 100%;
-                    color: white;
-                    margin-top: 8.5em;
-
-                    div {
-                        &:before {
-                            content: " ";
-                            display: block;
-                            position: absolute;
-                            height: 100%;
-                            width: 100%;
-                            z-index: -1;
-                            background-color: black;
-                            opacity: 0.6;
-                        }
-
-                        p {
-                            padding: .4em 3em 0 .5em;
-
-                            strong {
-                                font-size: 1.2em;
-                                display: block;
-                            }
-
-                            .more {
-                                position: absolute;
-                                right: 4em;
-                                top: 4.5em;
-                            }
-                        }
-                    }
-                }
-            }
-            a.catalogue-carousel-link:active {
-                outline: none;
-            }
-            .attribution {
-                text-align: right;
-                font-size: .75em;
-                position: absolute;
-                right: 5em;
-                top: .1em;
-                color: white;
-                font-weight: bold;
-                text-shadow: 0 0 5px #000;
-            }
-
-        }
-    }
-    #catalogue-carousel-switcher {
-        margin: 0;
-        padding: 3*$px 0 0 58*$px;
-        width: 240*$px - 58*$px;
-        height: 243*$px - 8*$px;
-        position: absolute;
-        right: 0;
-        top: 0;
-        list-style: none;
-        border-radius: 0 15*$px 15*$px 0;
-        background-color: #ed7831;
-        background-image: url(/static/catalogue/img/carousel-right.png);
-        background-position: 0 0;
-        background-repeat: no-repeat;
-        background-size: auto 235*$px;
-        
-        /* right part of mask as background */
-
-        li {
-            margin-bottom: .4em;
-            font-size: .85em;
-            line-height: 1em;
-
-            a {
-                text-transform: uppercase;
-                color: $ciemny;
-            }
-            a:before {
-                vertical-align: top;
-                margin-right: 1.5em;
-            }
-            .knowledge:before {content: url(/static/img/icons/knowledge_dark.png);}
-            .activity:before {content: url(/static/img/icons/activity_dark.png);}
-            .lesson-plan:before {content: url(/static/img/icons/lesson-plan_dark.png);}
-            .reference:before {content: url(/static/img/icons/reference_dark.png);}
-        }
-        li.activeSlide {
-            a {
-                color: white;
-            }
-            .knowledge:before {content: url(/static/img/icons/knowledge_white.png);}
-            .activity:before {content: url(/static/img/icons/activity_white.png);}
-            .lesson-plan:before {content: url(/static/img/icons/lesson-plan_white.png);}
-            .reference:before {content: url(/static/img/icons/reference_white.png);}
-        }
-    }
-
-
-}
diff --git a/catalogue/static/catalogue/css/exercise.css b/catalogue/static/catalogue/css/exercise.css
deleted file mode 100644 (file)
index ce6f783..0000000
+++ /dev/null
@@ -1,231 +0,0 @@
-@charset "UTF-8";
-.exercise img {
-  vertical-align: top; }
-.exercise .question-piece {
-  border-radius: 0.6875em;
-  padding: 0.5em 0.6875em; }
-.exercise .lista.punkt {
-  list-style: none;
-  margin: 0;
-  padding: 0; }
-.exercise .lista li {
-  margin: 0.3125em 0; }
-.exercise .question-piece.correct {
-  background-color: #16a487;
-  color: white; }
-.exercise .question-piece.incorrect {
-  background-color: #f00;
-  color: white; }
-.exercise .placeholder.dragover {
-  background: #ed7831 !important; }
-.exercise .remove {
-  float: right;
-  display: inline-block;
-  border-radius: 0.5em;
-  padding: 0.25em 0.5em;
-  margin: -0.25em -0.5em -0.25em 0.5em;
-  background: #ed7831;
-  color: white; }
-.exercise .buttons {
-  background: #5e6165;
-  border-radius: 0.5625em;
-  height: 1.875em;
-  line-height: 1.875em;
-  overflow: hidden;
-  color: white;
-  margin-top: 1.875em; }
-  .exercise .buttons input {
-    height: 100%;
-    border: 0;
-    background: #8e9093;
-    color: white;
-    text-transform: uppercase;
-    font-weight: bold; }
-  .exercise .buttons .message {
-    float: right;
-    padding: 0 1.25em;
-    background: red; }
-  .exercise .buttons .maxscore {
-    background: #16a487; }
-  .exercise .buttons input.check {
-    background: #ed7831; }
-
-.exercise .instruction, .exercise-wtem .instruction {
-  display: block;
-  margin: .3em;
-  color: green;
-  font-size: .9em; }
-.exercise .instruction:before, .exercise-wtem .instruction:before {
-  content: "☞ "; }
-
-.luki .question-piece {
-  background-color: #d4d6d8;
-  color: #363a3e;
-  cursor: pointer;
-  z-index: 2;
-  display: inline-block;
-  margin: 0.3125em;
-  z-index: 2;
-  max-width: 38em; }
-.luki .question-piece.disabled {
-  background-color: #eee;
-  color: #d4d6d8; }
-.luki .placeholder {
-  border-radius: 0.6875em;
-  padding: 0.5em 0.6875em;
-  display: inline-block;
-  margin: 0.3125em;
-  z-index: 2;
-  width: 4em;
-  background-color: #eee;
-  z-index: 1; }
-.luki .placeholder:after {
-  content: "\0000a0"; }
-
-.zastap .question-piece {
-  background-color: #d4d6d8;
-  color: #363a3e;
-  cursor: pointer;
-  z-index: 2;
-  display: inline-block;
-  margin: 0.3125em;
-  z-index: 2; }
-.zastap .question-piece.disabled {
-  background-color: #eee;
-  color: #d4d6d8; }
-.zastap .question-piece.placeholder {
-  background-color: inherit;
-  color: inherit;
-  cursor: inherit;
-  z-index: inherit;
-  display: inline;
-  margin: 0;
-  padding: 0;
-  z-index: inherit;
-  border-radius: 0; }
-
-.uporzadkuj .question-piece {
-  background-color: #d4d6d8;
-  color: #363a3e;
-  cursor: pointer;
-  z-index: 2; }
-.uporzadkuj .question-piece.disabled {
-  background-color: #eee;
-  color: #d4d6d8; }
-.uporzadkuj .lista {
-  list-style: none;
-  margin: 0;
-  padding: 0;
-  counter-reset: answer; }
-  .uporzadkuj .lista li {
-    counter-increment: answer;
-    padding-right: 3em;
-    background-image: url(/static/img/ornaments/draggable.png);
-    background-repeat: no-repeat;
-    background-position: 100% 50%; }
-  .uporzadkuj .lista li:before {
-    border-radius: 0.6875em;
-    padding: 0.5em 0.6875em;
-    background-color: #d4d6d8;
-    color: #363a3e;
-    cursor: pointer;
-    z-index: 2;
-    content: counter(answer);
-    float: left;
-    margin: -.5em 0 0 -3em; }
-  .uporzadkuj .lista li.ui-sortable-placeholder {
-    counter-increment: answer 0; }
-  .uporzadkuj .lista li.ui-sortable-helper:before {
-    content: none; }
-
-.przyporzadkuj .question-piece {
-  background-color: #d4d6d8;
-  color: #363a3e;
-  cursor: pointer;
-  z-index: 2;
-  width: 38.625em; }
-.przyporzadkuj .question-piece.short {
-  display: inline-block;
-  margin: .2em .1em;
-  width: auto; }
-.przyporzadkuj span.question-piece {
-  display: inline-block;
-  margin: .1em;
-  width: auto; }
-.przyporzadkuj .question-piece.disabled {
-  background-color: #eee;
-  color: #d4d6d8; }
-.przyporzadkuj .predicate {
-  list-style: none;
-  margin: 0;
-  padding: 0; }
-  .przyporzadkuj .predicate > li {
-    border-radius: 0.6875em;
-    padding: 0.5em 0.6875em;
-    display: inline-block;
-    background-color: #5e6165;
-    color: white;
-    width: 11.75em;
-    position: relative;
-    vertical-align: top; }
-    .przyporzadkuj .predicate > li .subjects {
-      list-style: none;
-      margin: 0;
-      padding: 0;
-      min-height: 2.8125em;
-      position: relative;
-      margin: 0.5em -0.6875em -0.5em -0.6875em;
-      padding: 0.5em 0.6875em; }
-      .przyporzadkuj .predicate > li .subjects li {
-        width: auto; }
-      .przyporzadkuj .predicate > li .subjects .placeholder {
-        border-radius: 0.6875em;
-        padding: 0.5em 0.6875em;
-        text-align: right;
-        position: relative;
-        padding: 0.5em 0.6875em;
-        margin: 0 -0.6875em; }
-      .przyporzadkuj .predicate > li .subjects .multiple {
-        position: absolute;
-        z-index: -1;
-        top: 0;
-        bottom: 0;
-        left: 0;
-        right: 0;
-        margin: 0; }
-      .przyporzadkuj .predicate > li .subjects .placeholder.dragover {
-        z-index: 1; }
-      .przyporzadkuj .predicate > li .subjects .placeholder:after {
-        content: "upuść tutaj";
-        text-style: italic; }
-.przyporzadkuj .subject {
-  list-style: none;
-  margin: 0;
-  padding: 0; }
-
-.prawdafalsz .question li.question-piece {
-  position: relative;
-  padding-left: 11em; }
-.prawdafalsz .question .buttons {
-  margin-top: 0;
-  top: 0;
-  left: 0;
-  position: absolute;
-  background-color: #d4d6d8;
-  color: #363a3e;
-  display: inline-block; }
-  .prawdafalsz .question .buttons a {
-    color: #363a3e;
-    text-transform: uppercase;
-    font-weight: bold;
-    display: inline-block;
-    padding: 0 0.6875em; }
-  .prawdafalsz .question .buttons a.chosen {
-    background: #ed7831;
-    color: white; }
-
-.wybor .question .lista {
-  list-style: none;
-  padding: 0; }
-  .wybor .question .lista li {
-    margin: 0; }
diff --git a/catalogue/static/catalogue/css/exercise.scss b/catalogue/static/catalogue/css/exercise.scss
deleted file mode 100755 (executable)
index a9fc200..0000000
+++ /dev/null
@@ -1,320 +0,0 @@
-$px: 0.0625em;
-$oranji: #ed7831;
-$ciemny: #363a3e;
-$zielony: #16a487;
-
-
-@mixin bubble {
-    border-radius: 11*$px;
-    padding: 8*$px 11*$px;
-}
-@mixin bubble-drag {
-    background-color: #d4d6d8;
-    color: #363a3e;
-    cursor: pointer;
-    z-index: 2;
-}
-@mixin bubble-drag-disabled {
-    background-color: #eee;
-    color: #d4d6d8;
-}
-@mixin un-bubble-drag {
-    background-color: inherit;
-    color: inherit;
-    cursor: inherit;
-    z-index: inherit;
-}
-
-@mixin bubble-inline {
-    display: inline-block;
-    margin: 5*$px;
-    z-index: 2;
-}
-@mixin un-bubble-inline {
-    display: inline;
-    margin: 0;
-    padding: 0;
-    z-index: inherit;
-    border-radius: 0;
-}
-@mixin list-plain {
-    list-style: none;
-    margin: 0;
-    padding: 0;
-}
-
-
-.exercise {
-    img {
-        vertical-align: top;
-    }
-
-    .question-piece {
-        @include bubble;
-    }
-    .lista.punkt {
-        @include list-plain;
-    }
-    .lista {
-        li {
-            margin: 5*$px 0;
-        }
-    }
-
-    .question-piece.correct {
-        background-color: #16a487;
-        color: white;
-    }
-    .question-piece.incorrect {
-        background-color: #f00;
-        color: white;
-    }
-    
-    .placeholder.dragover {
-         background: #ed7831 !important;
-    }
-
-    .remove {
-        float: right;
-        display: inline-block;
-        border-radius: 8*$px;
-        padding: 4*$px 8*$px;
-        margin: -4*$px -8*$px -.25em 8*$px;
-        background: #ed7831;
-        color: white;
-    }
-
-    .buttons {
-        background: #5e6165;
-        border-radius: 9*$px;
-        height: 30*$px;
-        line-height: 30*$px;
-        overflow: hidden;
-        color: white;
-        margin-top: 30*$px;
-
-        input {
-            height: 100%;
-            border: 0;
-            background: #8e9093;
-            color: white;
-            text-transform: uppercase;
-            font-weight: bold;
-        }
-        .message {
-            float: right;
-            padding: 0 20*$px;
-            background: red;
-        }
-        .maxscore {
-            background: #16a487;
-        }
-
-        input.check {
-            background: #ed7831;
-            
-        }
-    }
-}
-
-
-.exercise, .exercise-wtem {
-    .instruction {
-        display: block;
-        margin: .3em;
-        color: green;
-        font-size: .9em;
-    }
-    .instruction:before {
-        content: "☞ ";
-    }
-}
-
-
-.luki {
-    .question-piece {
-        @include bubble-drag;
-        @include bubble-inline;
-        max-width: 608*$px;
-    }
-    .question-piece.disabled {
-        @include bubble-drag-disabled;
-    }
-
-    .placeholder {
-        @include bubble;
-        @include bubble-inline;
-
-        width: 4em;
-        background-color: #eee;
-        z-index: 1;
-    }
-    .placeholder:after {
-        content: "\0000a0";
-    }
-}
-
-
-.zastap {
-    .question-piece {
-        @include bubble-drag;
-        @include bubble-inline;
-    }
-    .question-piece.disabled {
-        @include bubble-drag-disabled;
-    }
-    .question-piece.placeholder {
-        @include un-bubble-drag;
-        @include un-bubble-inline;
-    }
-}
-
-.uporzadkuj {
-    .question-piece {
-        @include bubble-drag;
-    }
-    .question-piece.disabled {
-        @include bubble-drag-disabled;
-    }
-    .lista {
-        @include list-plain;
-        counter-reset: answer;
-        li {
-            counter-increment: answer;
-            padding-right: 3em;
-            background-image: url(/static/img/ornaments/draggable.png);
-            background-repeat: no-repeat;
-            background-position: 100% 50%;
-        }
-        li:before {
-            @include bubble;
-            @include bubble-drag;
-            content: counter(answer);
-            float: left;
-            margin: -.5em 0 0 -3em;
-        }
-        li.ui-sortable-placeholder {
-            counter-increment: answer 0;
-        }
-        li.ui-sortable-helper:before {
-            content: none;
-        }
-    }
-}
-
-.przyporzadkuj {
-    .question-piece {
-        @include bubble-drag;
-        width: 618*$px;
-    }
-    .question-piece.short {
-        display: inline-block;
-        margin: .2em .1em;
-        width: auto;
-    }
-    span.question-piece {
-        display: inline-block;
-        margin: .1em;
-        width: auto;
-    }
-    .question-piece.disabled {
-        @include bubble-drag-disabled;
-    }
-    .predicate {
-        @include list-plain;
-
-        > li {
-            @include bubble;
-            display: inline-block;
-            background-color: #5e6165;
-            color: white;
-            width: 188*$px;
-            position: relative;
-            vertical-align: top;
-
-            .subjects {
-                @include list-plain;
-                min-height: 45*$px;
-                position: relative;
-                margin: 8*$px -11*$px -8*$px -11*$px;
-                padding: 8*$px 11*$px;
-
-                li {
-                    width: auto;
-                }
-
-                .placeholder {
-                    @include bubble;
-                    text-align: right;
-                    position:relative;
-                    padding: 8*$px 11*$px;
-                    margin: 0 -11*$px;
-                }
-                .multiple {
-                    position: absolute;
-                    z-index: -1;
-                    top: 0;
-                    bottom: 0;
-                    left: 0;
-                    right: 0;
-                    margin: 0;
-                }
-                
-                .placeholder.dragover {
-                    z-index: 1;
-                }
-                .placeholder:after {
-                    content: "upuść tutaj";
-                    text-style: italic;
-                }
-            }
-        }
-        .comment {
-        }
-    }
-    .subject {
-        @include list-plain;
-    }
-
-}
-
-
-.prawdafalsz .question {
-    li.question-piece {
-        position: relative;
-        padding-left: 11em;
-    }
-
-    .buttons {
-        margin-top: 0;
-        top: 0;
-        left: 0;
-        position: absolute;
-        
-        background-color: #d4d6d8;
-        color: #363a3e;
-        display: inline-block;
-
-        a {
-            color: #363a3e;
-            text-transform: uppercase;
-            font-weight: bold;
-            display: inline-block;
-            padding: 0 11*$px;
-        }
-        a.chosen {
-            background: #ed7831;
-            color: white;
-        }
-    }
-}
-
-.wybor .question {
-    .lista {
-        list-style: none;
-        padding: 0;
-        li {
-            margin: 0;
-        }
-    }
-}
diff --git a/catalogue/static/catalogue/css/layout.css b/catalogue/static/catalogue/css/layout.css
deleted file mode 100644 (file)
index 883d77b..0000000
+++ /dev/null
@@ -1,99 +0,0 @@
-@charset "UTF-8";
-.box-button {
-  background-color: #ed7831;
-  border-radius: 0.9375em; }
-  .box-button .dl-button, .box-button .nice-button {
-    color: white;
-    padding: 1.0625em 0.75em 1.0625em 0.75em; }
-
-.dl-button, .nice-button {
-  color: #363a3e;
-  display: block;
-  font-weight: bold;
-  text-align: center;
-  text-transform: uppercase;
-  font-size: .9em; }
-
-.dl-button:after {
-  content: " ↓"; }
-
-#main-bar section.button {
-  margin-bottom: 1.0625em; }
-
-#sidebar {
-  position: absolute;
-  right: 0;
-  top: 0;
-  width: 13.75em;
-  color: #363a3e; }
-  #sidebar section {
-    margin-bottom: 1.0625em; }
-    #sidebar section h1 {
-      margin: 0; }
-    #sidebar section h1.realisation {
-      font-weight: normal; }
-  #sidebar .section {
-    border-top: 1px solid #c9ccce;
-    padding-top: 1.0625em; }
-  #sidebar .section-minor {
-    border-top: 1px solid #c9ccce;
-    padding-top: 1.0625em; }
-    #sidebar .section-minor h1 {
-      font-weight: normal;
-      font-size: 1em; }
-  #sidebar .section-micro {
-    font-size: .8em;
-    color: #888;
-    border-top: 1px solid #c9ccce;
-    padding-top: 1.0625em; }
-    #sidebar .section-micro h1 {
-      font-weight: normal;
-      font-size: 1em; }
-    #sidebar .section-micro .link-list a {
-      color: #888; }
-  #sidebar section:first-child {
-    border-top: 0;
-    padding-top: 0; }
-
-#main-bar {
-  width: 40em; }
-  #main-bar .top-link {
-    float: right; }
-  #main-bar .box {
-    background-color: #d4d6d8;
-    border-radius: 0.9375em;
-    padding: 1.0625em; }
-    #main-bar .box h1 {
-      font-size: 1em;
-      text-transform: uppercase; }
-    #main-bar .box p {
-      margin: 0; }
-    #main-bar .box .box-icon {
-      margin: -.2em 0 -.2em 1em;
-      float: right;
-      text-align: center; }
-
-.lesson-footer {
-  clear: both;
-  border-top: 1px solid #777;
-  margin-top: 2em;
-  padding-top: 1em; }
-  .lesson-footer .section-info {
-    text-align: center; }
-  .lesson-footer .previous-lesson {
-    float: left; }
-  .lesson-footer .next-lesson {
-    float: right; }
-
-ol.alpha {
-  counter-reset: list; }
-  ol.alpha > li {
-    list-style: none;
-    position: relative; }
-  ol.alpha > li:before {
-    counter-increment: list;
-    content: counter(list,lower-alpha) ") ";
-    position: absolute;
-    left: -1.4em; }
-
-/*# sourceMappingURL=layout.css.map */
diff --git a/catalogue/static/catalogue/css/layout.scss b/catalogue/static/catalogue/css/layout.scss
deleted file mode 100755 (executable)
index a941469..0000000
+++ /dev/null
@@ -1,126 +0,0 @@
-$px: .0625em;
-$new_black: #363a3e;
-
-.box-button {
-    background-color: #ed7831;
-    border-radius: 15*$px;
-    .dl-button, .nice-button {
-        color: white;
-        padding: 17*$px 12*$px 17*$px 12*$px;
-    }
-}
-.dl-button, .nice-button {
-    color: $new_black;
-    display: block;
-    font-weight: bold;
-    text-align: center;
-    text-transform: uppercase;
-    font-size: .9em;
-}
-.dl-button:after {
-    content: " ↓";
-}
-
-#main-bar section.button {
-    margin-bottom: 17*$px;
-}
-
-#sidebar {
-    position: absolute;
-    right: 0;
-    top: 0;
-    width: 220*$px;
-    color: $new_black;
-
-    section {
-        margin-bottom: 17*$px;
-        h1 {
-            margin: 0;
-        }
-        h1.realisation {
-            font-weight: normal;
-        }
-    }
-
-    .section {
-        border-top: 1px solid #c9ccce;
-        padding-top: 17*$px;
-    }
-    .section-minor {
-        border-top: 1px solid #c9ccce;
-        padding-top: 17*$px;
-        h1 {
-            font-weight: normal;
-            font-size: 1em;
-        }
-    }
-    .section-micro {
-        font-size: .8em;
-        color: #888;
-        border-top: 1px solid #c9ccce;
-        padding-top: 17*$px;
-        h1 {
-            font-weight: normal;
-            font-size: 1em;
-        }
-        .link-list a {
-            color: #888;
-        }
-    }
-    section:first-child {
-        border-top: 0;
-        padding-top: 0;
-    }
-}
-#main-bar {
-    width: 640*$px;
-
-    .top-link {
-        float:right;
-    }
-
-    .box {
-        background-color: #d4d6d8;
-        border-radius: 15*$px;
-        padding: 17*$px;
-        h1 {
-            font-size: 1em;
-            text-transform: uppercase;
-        }
-        p {
-            margin: 0;
-        }
-        .box-icon {
-            margin: -.2em 0 -.2em 1em;
-            float: right;
-            text-align: center;
-        }
-    }
-}
-
-.lesson-footer {
-    clear: both;
-    border-top: 1px solid #777;
-    margin-top: 2em;
-    padding-top: 1em;
-
-    .section-info {
-        text-align: center;
-    }
-    .previous-lesson {float: left;}
-    .next-lesson {float: right;}
-}
-
-ol.alpha {
-    counter-reset: list;
-    > li {
-        list-style: none;
-        position: relative;
-    }
-    > li:before {
-        counter-increment: list;
-        content: counter(list, lower-alpha) ") ";
-        position: absolute;
-        left: -1.4em;
-    }
-}
diff --git a/catalogue/static/catalogue/css/lesson.css b/catalogue/static/catalogue/css/lesson.css
deleted file mode 100644 (file)
index fb7aa08..0000000
+++ /dev/null
@@ -1,262 +0,0 @@
-/* =================================================== */
-/* = Common elements: headings, paragraphs and lines = */
-/* =================================================== */
-/*h1 {
-    font-size: 3em;
-    margin: 1.5em 0;
-    text-align: center;
-    line-height: 1.5em;
-    font-weight: bold;
-}
-
-h2 {
-    font-size: 2em;
-    margin: 1.5em 0 0;
-    font-weight: bold;
-    line-height: 1.5em;
-}
-
-h3 {
-    font-size: 1.5em;
-    margin: 1.5em 0 0;
-    font-weight: normal;
-    line-height: 1.5em;
-}
-
-h4 {
-    font-size: 1em;
-    margin: 1.5em 0 0;
-    line-height: 1.5em;
-}
-
-p {
-    margin: 0;
-}
-*/
-/* ======================== */
-/* = Footnotes and themes = */
-/* ======================== */
-.annotation {
-  font-style: normal;
-  font-weight: normal;
-  font-size: 12px;
-  padding-left: 2px;
-  position: relative;
-  top: -4px; }
-
-#footnotes {
-  margin-top: 3em; }
-
-#footnotes .annotation {
-  display: block;
-  float: left;
-  width: 2.5em;
-  clear: both; }
-
-#footnotes div {
-  margin: 1.5em 0 0 0; }
-
-#footnotes p, #footnotes ul {
-  margin-left: 2.5em;
-  font-size: 0.875em; }
-
-#footnotes .permalink {
-  font-size: .75em; }
-
-blockquote {
-  font-size: 0.875em; }
-
-/* ============= */
-/* = Numbering = */
-/* ============= */
-.verse, .paragraph {
-  position: relative; }
-
-.anchor {
-  position: absolute;
-  margin: -0.25em -0.5em;
-  left: -3em;
-  color: #777;
-  font-size: 12px;
-  width: 2em;
-  text-align: center;
-  padding: 0.25em 0.5em;
-  line-height: 1.5em; }
-
-.anchor:hover, #book-text .anchor:active {
-  color: #FFF;
-  background-color: #CCC; }
-
-/* =================== */
-/* = Custom elements = */
-/* =================== */
-span.author {
-  font-size: 0.5em;
-  display: block;
-  line-height: 1.5em;
-  margin-bottom: 0.25em; }
-
-span.collection {
-  font-size: 0.375em;
-  display: block;
-  line-height: 1.5em;
-  margin-bottom: -0.25em; }
-
-span.subtitle {
-  font-size: 0.5em;
-  display: block;
-  line-height: 1.5em;
-  margin-top: -0.25em; }
-
-span.translator {
-  font-size: 0.375em;
-  display: block;
-  line-height: 1.5em;
-  margin-top: 0.25em; }
-
-div.didaskalia {
-  font-style: italic;
-  margin: 0.5em 0 0 1.5em; }
-
-div.kwestia {
-  margin: 0.5em 0 0; }
-
-div.stanza {
-  margin: 1.5em 0 0; }
-
-div.kwestia div.stanza {
-  margin: 0; }
-
-p.paragraph {
-  text-align: justify;
-  margin: 1.5em 0 0; }
-
-p.motto {
-  text-align: justify;
-  font-style: italic;
-  margin: 1.5em 0 0; }
-
-p.motto_podpis {
-  font-size: 0.875em;
-  text-align: right; }
-
-div.fragment {
-  border-bottom: 0.1em solid #999;
-  padding-bottom: 1.5em; }
-
-div.note p, div.dedication p, div.note p.paragraph, div.dedication p.paragraph {
-  text-align: right;
-  font-style: italic; }
-
-hr.spacer {
-  height: 3em;
-  visibility: hidden; }
-
-hr.spacer-line {
-  margin: 1.5em 0;
-  border: none;
-  border-bottom: 0.1em solid #000; }
-
-p.spacer-asterisk {
-  padding: 0;
-  margin: 1.5em 0;
-  text-align: center; }
-
-div.person-list ol {
-  list-style: none;
-  padding: 0 0 0 1.5em; }
-
-p.place-and-time {
-  font-style: italic; }
-
-em.math, em.foreign-word, em.book-title, em.didaskalia {
-  font-style: italic; }
-
-em.author-emphasis {
-  letter-spacing: 0.1em; }
-
-em.person {
-  font-style: normal;
-  font-variant: small-caps; }
-
-.verse:after {
-  content: "\feff"; }
-
-table.framed {
-  border-collapse: collapse;
-}
-
-table.framed td, table.framed.th {
-  border: 1px #888 solid;
-}
-
-/* =================================== */
-/* = Hide some elements for printing = */
-/* =================================== */
-@media print {
-  #menu {
-    display: none; } }
-.activity {
-  clear: both; }
-
-.activity .text {
-  width: 27.5em;
-  margin-right: 20px;
-  float: left; }
-
-.activity .description p:first-child {
-  margin-top: 0; }
-
-.activity {
-  margin-top: 2em; }
-  .activity .act_counter {
-    float: left;
-    margin-right: .5em;
-    font-size: 2em; }
-  .activity .info {
-    float: right;
-    width: 8.4375em; }
-    .activity .info .infobox {
-      padding: 1em 0;
-      border-top: 1px solid #c9ccce; }
-      .activity .info .infobox h1 {
-        text-transform: uppercase;
-        font-weight: bold;
-        margin: 0 0 0.5em -2.1875em;
-        padding-left: 2.1875em;
-        line-height: 24px;
-        font-size: 1em; }
-      .activity .info .infobox p {
-        margin: 0; }
-    .activity .info .time h1 {
-      background: url(/static/img/icons/activity-time.png) 0 0 no-repeat; }
-    .activity .info .kind h1 {
-      background: url(/static/img/icons/activity-kind.png) 0 0 no-repeat; }
-    .activity .info .materials h1 {
-      background: url(/static/img/icons/activity-tools.png) 0 0 no-repeat; }
-
-.lista .paragraph {
-  margin: .3em 0; }
-.lista li {
-  margin: .75em 0; }
-
-.clearboth {
-  clear: both; }
-
-#book-text .caption {
-  margin: 1.5em; }
-  #book-text .caption p {
-    margin: 0; }
-
-/* utils */
-.clr {
-  clear: both; }
-
-#book-text .top-link {
-  margin-top: 1em; }
-
-.help {
-  font-size: .7em;
-  padding: 0 .5em;
-  color: #888;
-  vertical-align: super; }
diff --git a/catalogue/static/catalogue/css/lesson.scss b/catalogue/static/catalogue/css/lesson.scss
deleted file mode 100755 (executable)
index d98f1a3..0000000
+++ /dev/null
@@ -1,327 +0,0 @@
-$px: .0625em;
-
-/* =================================================== */
-/* = Common elements: headings, paragraphs and lines = */
-/* =================================================== */
-
-/*h1 {
-    font-size: 3em;
-    margin: 1.5em 0;
-    text-align: center;
-    line-height: 1.5em;
-    font-weight: bold;
-}
-
-h2 {
-    font-size: 2em;
-    margin: 1.5em 0 0;
-    font-weight: bold;
-    line-height: 1.5em;
-}
-
-h3 {
-    font-size: 1.5em;
-    margin: 1.5em 0 0;
-    font-weight: normal;
-    line-height: 1.5em;
-}
-
-h4 {
-    font-size: 1em;
-    margin: 1.5em 0 0;
-    line-height: 1.5em;
-}
-
-p {
-    margin: 0;
-}
-*/
-
-/* ======================== */
-/* = Footnotes and themes = */
-/* ======================== */
-
-.annotation {
-    font-style: normal;
-    font-weight: normal;
-    font-size: 12px;
-    padding-left: 2px;
-    position: relative;
-    top: -4px;
-}
-
-#footnotes {
-    margin-top: 3em;
-}
-
-#footnotes .annotation {
-    display: block;
-    float: left;
-    width: 2.5em;
-    clear: both;
-}
-
-#footnotes div {
-    margin: 1.5em 0 0 0;
-}
-
-#footnotes p, #footnotes ul {
-    margin-left: 2.5em;
-    font-size: 0.875em;
-}
-
-#footnotes .permalink {
-    font-size: .75em;
-}
-
-blockquote {
-    font-size: 0.875em;
-}
-
-/* ============= */
-/* = Numbering = */
-/* ============= */
-.verse, .paragraph {
-    position:relative;
-}
-.anchor {
-    position: absolute;
-    margin: -0.25em -0.5em;
-    left: -3em;
-    color: #777;
-    font-size: 12px;
-    width: 2em;
-    text-align: center;
-    padding: 0.25em 0.5em;
-    line-height: 1.5em;
-}
-
-.anchor:hover, #book-text .anchor:active {
-    color: #FFF;
-    background-color: #CCC;
-}
-
-/* =================== */
-/* = Custom elements = */
-/* =================== */
-span.author {
-    font-size: 0.5em;
-    display: block;
-    line-height: 1.5em;
-    margin-bottom: 0.25em;
-}
-
-span.collection {
-    font-size: 0.375em;
-    display: block;
-    line-height: 1.5em;
-    margin-bottom: -0.25em;
-}
-
-span.subtitle {
-    font-size: 0.5em;
-    display: block;
-    line-height: 1.5em;
-    margin-top: -0.25em;
-}
-
-span.translator {
-    font-size: 0.375em;
-    display: block;
-    line-height: 1.5em;
-    margin-top: 0.25em;
-}
-
-div.didaskalia {
-    font-style: italic;
-    margin: 0.5em 0 0 1.5em;
-}
-
-div.kwestia {
-    margin: 0.5em 0 0;
-}
-
-div.stanza {
-    margin: 1.5em 0 0;
-}
-
-div.kwestia div.stanza {
-    margin: 0;
-}
-
-p.paragraph {
-    text-align: justify;
-    margin: 1.5em 0 0;
-}
-
-p.motto {
-    text-align: justify;
-    font-style: italic;
-    margin: 1.5em 0 0;
-}
-
-p.motto_podpis {
-    font-size: 0.875em;
-    text-align: right;
-}
-
-div.fragment {
-    border-bottom: 0.1em solid #999;
-    padding-bottom: 1.5em;
-}
-
-div.note p, div.dedication p, div.note p.paragraph, div.dedication p.paragraph {
-    text-align: right;
-    font-style: italic;
-}
-
-hr.spacer {
-    height: 3em;
-    visibility: hidden;
-}
-
-hr.spacer-line {
-    margin: 1.5em 0;
-    border: none;
-    border-bottom: 0.1em solid #000;
-}
-
-p.spacer-asterisk {
-    padding: 0;
-    margin: 1.5em 0;
-    text-align: center;
-}
-
-div.person-list ol {
-    list-style: none;
-    padding: 0 0 0 1.5em;
-}
-
-p.place-and-time {
-    font-style: italic;
-}
-
-em.math, em.foreign-word, em.book-title, em.didaskalia {
-    font-style: italic;
-}
-
-em.author-emphasis {
-    letter-spacing: 0.1em;
-}
-
-em.person {
-    font-style: normal;
-    font-variant: small-caps;
-}
-
-.verse:after {
-    content: "\feff";
-}
-
-
-/* =================================== */
-/* = Hide some elements for printing = */
-/* =================================== */
-
-@media print {
-    #menu {display: none;}
-}
-
-
-
-.activity {
- clear:both;
-}
-
-.activity .text {
-    width: 440*$px;
-    margin-right: 20px;
-    float: left;
-}
-
-.activity .description p:first-child {
-  margin-top: 0;
-}
-
-
-
-.activity {
-    margin-top: 2em;
-
-    .act_counter {
-        float: left;
-        margin-right: .5em;
-        font-size: 2em;
-    }
-
-    .info {
-        float: right;
-        width: 135*$px;
-
-        .infobox {
-            padding: 1em 0;
-            border-top: 1px solid #c9ccce;
-            h1 {
-                text-transform: uppercase;
-                font-weight: bold;
-                margin: 0 0 .5em -35*$px;
-                padding-left: 35*$px;
-                line-height: 24px;
-                font-size: 1em;
-            }
-            p {
-                margin: 0;
-            }
-
-        }
-        .time h1 {
-            background: url(/static/img/icons/activity-time.png) 0 0 no-repeat;
-        }
-        .kind h1 {
-            background: url(/static/img/icons/activity-kind.png) 0 0 no-repeat;
-        }
-        .materials h1 {
-            background: url(/static/img/icons/activity-tools.png) 0 0 no-repeat;
-        }
-    }
-}
-
-.lista {
-    .paragraph {
-        margin: .3em 0;
-    }
-    li {
-        margin: .75em 0;
-    }
-}
-
-
-.clearboth {
- clear: both;
-}
-
-#book-text {
-    .caption {
-        margin: 1.5em;
-        p {
-            margin: 0;
-        }
-    }
-}
-
-/* utils */
-
-.clr {
-    clear: both;
-}
-
-#book-text .top-link {
-    margin-top: 1em;
-}
-
-.help {
-    font-size: .7em;
-    padding: 0 .5em;
-    color: #888;
-    vertical-align: super;
-}
diff --git a/catalogue/static/catalogue/css/section_list.css b/catalogue/static/catalogue/css/section_list.css
deleted file mode 100644 (file)
index bd68dee..0000000
+++ /dev/null
@@ -1,58 +0,0 @@
-#level-chooser-place {
-  min-height: 5.9375em;
-  margin-top: 2em; }
-  #level-chooser-place ul#level-chooser {
-    margin: 0;
-    padding: 1em 0 1em 8.75em;
-    background-color: white;
-    width: 31.25em;
-    z-index: 300;
-    position: relative;
-    text-transform: uppercase;
-    text-align: right; }
-    #level-chooser-place ul#level-chooser .home {
-      display: none;
-      position: absolute;
-      top: 1.5em;
-      left: 0; }
-      #level-chooser-place ul#level-chooser .home a {
-        background: none;
-        padding: 0; }
-        #level-chooser-place ul#level-chooser .home a img {
-          width: 7.5em; }
-    #level-chooser-place ul#level-chooser.fixed {
-      position: fixed;
-      top: 0;
-      border-bottom: 1px solid #c9ccce; }
-      #level-chooser-place ul#level-chooser.fixed .home {
-        display: block; }
-    #level-chooser-place ul#level-chooser li {
-      display: inline-block;
-      list-style: none;
-      max-width: 175px; }
-      #level-chooser-place ul#level-chooser li a {
-        display: table-cell;
-        padding: .5em 1em;
-        border-radius: 0.3125em;
-        background: #eee;
-        height: 2.625em;
-        vertical-align: middle; }
-        #level-chooser-place ul#level-chooser li a.active {
-          color: white;
-          background: #ED7831; }
-
-.level .link-list {
-  margin-left: 1em; }
-.level .level-toc {
-  overflow: hidden;
-  /* Because we're changing bg color lower. */ }
-  .level .level-toc.fixed {
-    position: fixed; }
-  .level .level-toc .link-list {
-    margin-left: 1em; }
-    .level .level-toc .link-list li {
-      margin-bottom: 0; }
-      .level .level-toc .link-list li.curriculumcourses {
-        margin: 10px -17px -17px;
-        padding: 10px 16px 16px;
-        background-color: #eee; }
diff --git a/catalogue/static/catalogue/css/section_list.scss b/catalogue/static/catalogue/css/section_list.scss
deleted file mode 100755 (executable)
index fda2be3..0000000
+++ /dev/null
@@ -1,90 +0,0 @@
-$px: 0.0625em;
-
-#level-chooser-place {
-    min-height: 95*$px;
-    margin-top: 2em;
-
-    ul#level-chooser {
-        margin: 0;
-        padding: 16*$px 0 16*$px 140*$px;
-        background-color: white;
-        width: 500*$px;
-        z-index: 300;
-        position: relative;
-        text-transform: uppercase;
-        text-align: right;
-
-        .home {
-            display: none;
-            position: absolute;
-            top: 1.5em;
-            left: 0;
-
-            a {
-                background: none;
-                padding: 0;
-                img {
-                    width: 120*$px;
-                }
-            }
-        }
-
-        &.fixed {
-            position: fixed;
-            top: 0;
-            border-bottom: 1px solid #c9ccce;
-
-            .home {
-                display: block;
-            }
-        }
-
-        li {
-            display: inline-block;
-            list-style: none;
-            max-width: 175px;
-
-            a {
-                display: table-cell;
-                padding: .5em 1em;
-                border-radius: 5*$px;
-                background: #eee;
-                height: 42*$px;
-                vertical-align: middle;
-
-                &.active {
-                    color: white;
-                    background: #ED7831;
-                }
-            }
-        }
-    }
-}
-
-.level {
-    .link-list {
-        margin-left: 1em;
-    }
-
-    .level-toc {
-        overflow: hidden; /* Because we're changing bg color lower. */
-
-        &.fixed {
-            position: fixed;
-        }
-
-        .link-list {
-            margin-left: 1em;
-
-            li {
-                margin-bottom: 0;
-
-                &.curriculumcourses {
-                    margin: 10px -17px -17px;
-                    padding: 10px 16px 16px;
-                    background-color: #eee;
-                }
-            }
-        }
-    }
-}
diff --git a/catalogue/static/catalogue/img/carousel-left.png b/catalogue/static/catalogue/img/carousel-left.png
deleted file mode 100644 (file)
index 3f6090b..0000000
Binary files a/catalogue/static/catalogue/img/carousel-left.png and /dev/null differ
diff --git a/catalogue/static/catalogue/img/carousel-right.png b/catalogue/static/catalogue/img/carousel-right.png
deleted file mode 100644 (file)
index 3987678..0000000
Binary files a/catalogue/static/catalogue/img/carousel-right.png and /dev/null differ
diff --git a/catalogue/static/catalogue/img/carousel/katarzyna-wlodarczyk.jpg b/catalogue/static/catalogue/img/carousel/katarzyna-wlodarczyk.jpg
deleted file mode 100644 (file)
index 93b81f2..0000000
Binary files a/catalogue/static/catalogue/img/carousel/katarzyna-wlodarczyk.jpg and /dev/null differ
diff --git a/catalogue/static/catalogue/js/carousel.js b/catalogue/static/catalogue/js/carousel.js
deleted file mode 100755 (executable)
index b2484be..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-(function($){
-$(function() {
-
-
-$("#catalogue-carousel-links").each(function() {
-    $slides = $(this); 
-
-    $slides.cycle({
-        fx: 'fade',
-        speed: 1000,
-        timeout: 5000,
-        pager: '#catalogue-carousel-switcher',
-        pagerAnchorBuilder: function() {},
-    });
-
-    $("#catalogue-carousel-switcher li").each(function(i, e) {
-        $("a", e).click(function(ev) {
-            ev.preventDefault();
-            $slides.cycle(i);
-        });
-    });
-
-});
-
-
-});
-})(jQuery);
diff --git a/catalogue/static/catalogue/js/edumed.js b/catalogue/static/catalogue/js/edumed.js
deleted file mode 100644 (file)
index ec1eabc..0000000
+++ /dev/null
@@ -1,665 +0,0 @@
-// Generated by CoffeeScript 1.4.0
-(function() {
-  var $, Binding, EduModule, Exercise, Luki, PrawdaFalsz, Przyporzadkuj, Uporzadkuj, Wybor, Zastap, exercise,
-    __hasProp = {}.hasOwnProperty,
-    __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
-
-  $ = jQuery;
-
-  Binding = (function() {
-
-    function Binding(handler, element) {
-      this.handler = handler;
-      this.element = element;
-      $(this.element).data(this.handler, this);
-    }
-
-    return Binding;
-
-  })();
-
-  EduModule = (function(_super) {
-
-    __extends(EduModule, _super);
-
-    function EduModule(element) {
-      EduModule.__super__.constructor.call(this, 'edumodule', element);
-    }
-
-    return EduModule;
-
-  })(Binding);
-
-  Exercise = (function(_super) {
-
-    __extends(Exercise, _super);
-
-    function Exercise(element) {
-      var _this = this;
-      Exercise.__super__.constructor.call(this, 'exercise', element);
-      $(this.element).data("exercise-html", $(this.element).html());
-      $(".check", this.element).click(function(ev) {
-        _this.check();
-        $(".retry", _this.element).show();
-        return $(".check", _this.element).hide();
-      });
-      $(".retry", this.element).click(function(ev) {
-        return _this.retry();
-      });
-      $('.solutions', this.element).click(function() {
-        _this.show_solutions();
-        return $(".comment", _this.element).show();
-      });
-      $('.reset', this.element).click(function() {
-        return _this.reset();
-      });
-    }
-
-    Exercise.prototype.retry = function() {
-      $(".correct, .incorrect", this.element).removeClass("correct incorrect");
-      $(".check", this.element).show();
-      return $(".retry", this.element).hide();
-    };
-
-    Exercise.prototype.reset = function() {
-      $(this.element).html($(this.element).data('exercise-html'));
-      return exercise(this.element);
-    };
-
-    Exercise.prototype.piece_correct = function(qpiece) {
-      return $(qpiece).removeClass('incorrect').addClass('correct');
-    };
-
-    Exercise.prototype.piece_incorrect = function(qpiece) {
-      return $(qpiece).removeClass('correct').addClass('incorrect');
-    };
-
-    Exercise.prototype.check = function() {
-      var score, scores,
-        _this = this;
-      scores = [];
-      $(".question", this.element).each(function(i, question) {
-        return scores.push(_this.check_question(question));
-      });
-      score = [0, 0, 0];
-      $.each(scores, function(i, s) {
-        score[0] += s[0];
-        score[1] += s[1];
-        return score[2] += s[2];
-      });
-      return this.show_score(score);
-    };
-
-    Exercise.prototype.show_solutions = function() {
-      var _this = this;
-      this.reset();
-      return $(".question", this.element).each(function(i, question) {
-        return _this.solve_question(question);
-      });
-    };
-
-    Exercise.prototype.get_value_list = function(elem, data_key, numbers) {
-      var vl;
-      vl = $(elem).attr("data-" + data_key).split(/[ ,]+/).map($.trim);
-      if (numbers) {
-        vl = vl.map(function(x) {
-          return parseInt(x);
-        });
-      }
-      return vl;
-    };
-
-    Exercise.prototype.get_value_optional_list = function(elem, data_key) {
-      var mandat, opt, v, vals, _i, _len;
-      vals = this.get_value_list(elem, data_key);
-      mandat = [];
-      opt = [];
-      for (_i = 0, _len = vals.length; _i < _len; _i++) {
-        v = vals[_i];
-        if (v.slice(-1) === "?") {
-          opt.push(v.slice(0, -1));
-        } else {
-          mandat.push(v);
-        }
-      }
-      return [mandat, opt];
-    };
-
-    Exercise.prototype.show_score = function(score) {
-      var $msg;
-      $msg = $(".message", this.element);
-      $msg.text("Wynik: " + score[0] + " / " + score[2]);
-      if (score[0] >= score[2] && score[1] === 0) {
-        return $msg.addClass("maxscore");
-      } else {
-        return $msg.removeClass("maxscore");
-      }
-    };
-
-    Exercise.prototype.draggable_equal = function($draggable1, $draggable2) {
-      return false;
-    };
-
-    Exercise.prototype.draggable_accept = function($draggable, $droppable) {
-      var d, dropped, _i, _len;
-      dropped = $droppable.closest("ul, ol").find(".draggable");
-      for (_i = 0, _len = dropped.length; _i < _len; _i++) {
-        d = dropped[_i];
-        if (this.draggable_equal($draggable, $(d))) {
-          return false;
-        }
-      }
-      return true;
-    };
-
-    Exercise.prototype.draggable_move = function($draggable, $placeholder, ismultiple) {
-      var $added,
-        _this = this;
-      $added = $draggable.clone();
-      $added.data("original", $draggable.get(0));
-      if (!ismultiple) {
-        $draggable.addClass('disabled').draggable('disable');
-      }
-      $placeholder.after($added);
-      if (!$placeholder.hasClass('multiple')) {
-        $placeholder.hide();
-      }
-      if ($added.is(".add-li")) {
-        $added.wrap("<li/>");
-      }
-      $added.append('<span class="remove">x</span><div class="clr"></div>');
-      return $('.remove', $added).click(function(ev) {
-        _this.retry();
-        if (!ismultiple) {
-          $($added.data('original')).removeClass('disabled').draggable('enable');
-        }
-        if ($added.is(".add-li")) {
-          $added = $added.closest('li');
-        }
-        $added.prev(".placeholder:not(.multiple)").show();
-        return $added.remove();
-      });
-    };
-
-    Exercise.prototype.dragging = function(ismultiple, issortable) {
-      var _this = this;
-      return $(".question", this.element).each(function(i, question) {
-        var draggable_opts, self;
-        draggable_opts = {
-          revert: 'invalid',
-          helper: 'clone',
-          start: _this.retry
-        };
-        $(".draggable", question).draggable(draggable_opts);
-        self = _this;
-        return $(".placeholder", question).droppable({
-          accept: function(draggable) {
-            var $draggable, is_accepted;
-            $draggable = $(draggable);
-            is_accepted = true;
-            if (!$draggable.is(".draggable")) {
-              is_accepted = false;
-            }
-            if (is_accepted) {
-              is_accepted = self.draggable_accept($draggable, $(this));
-            }
-            if (is_accepted) {
-              $(this).addClass('accepting');
-            } else {
-              $(this).removeClass('accepting');
-            }
-            return is_accepted;
-          },
-          drop: function(ev, ui) {
-            $(ev.target).removeClass('accepting dragover');
-            return _this.draggable_move($(ui.draggable), $(ev.target), ismultiple);
-          },
-          over: function(ev, ui) {
-            return $(ev.target).addClass('dragover');
-          },
-          out: function(ev, ui) {
-            return $(ev.target).removeClass('dragover');
-          }
-        });
-      });
-    };
-
-    return Exercise;
-
-  })(Binding);
-
-  Wybor = (function(_super) {
-
-    __extends(Wybor, _super);
-
-    function Wybor(element) {
-      Wybor.__super__.constructor.call(this, element);
-      $(".question-piece input", element).change(this.retry);
-    }
-
-    Wybor.prototype.check_question = function(question) {
-      var all = 0, bad = 0, good = 0, _this = this;
-      var single = $(question).closest('.exercise').attr('data-subtype') === 'single';
-
-      $(".question-piece", question).each(function(i, qpiece) {
-        var is_checked, should_be_checked;
-        should_be_checked = $(qpiece).attr('data-sol') === 'prawda';
-        is_checked = $("input", qpiece).is(":checked");
-        if (!single || should_be_checked)
-          all += 1;
-        if (single) {
-          if (is_checked) {
-            if (should_be_checked) {
-              good += 1;
-              return _this.piece_correct(qpiece);
-            } else {
-              bad += 1;
-              return _this.piece_incorrect(qpiece);
-            }
-          } else {
-            return $(qpiece).removeClass("correct,incorrect");
-          }
-        } else {
-          if (is_checked !== should_be_checked) {
-            bad += 1;
-            return _this.piece_incorrect(qpiece);
-          } else {
-            good += 1;
-            return _this.piece_correct(qpiece);
-          }
-        }
-      });
-      return [good, bad, all];
-    };
-
-    Wybor.prototype.solve_question = function(question) {
-      var solution,
-        _this = this;
-      return $(".question-piece", question).each(function(i, qpiece) {
-        var should_be_checked;
-        should_be_checked = $(qpiece).attr('data-sol') === 'prawda';
-        return $("input[type=checkbox],input[type=radio]", qpiece).prop('checked', should_be_checked);
-      });
-    };
-
-    return Wybor;
-
-  })(Exercise);
-
-  Uporzadkuj = (function(_super) {
-
-    __extends(Uporzadkuj, _super);
-
-    function Uporzadkuj(element) {
-      Uporzadkuj.__super__.constructor.call(this, element);
-      $('ol, ul', this.element).sortable({
-        items: "> li",
-        start: this.retry
-      });
-    }
-
-    Uporzadkuj.prototype.check_question = function(question) {
-      var all, bad, correct, pkt, pkts, positions, sorted, _i, _ref;
-      positions = this.get_value_list(question, 'original', true);
-      sorted = positions.sort(function(a, b) {
-        return a - b;
-      });
-      pkts = $('.question-piece', question);
-      correct = 0;
-      bad = 0;
-      all = 0;
-      for (pkt = _i = 0, _ref = pkts.length; 0 <= _ref ? _i < _ref : _i > _ref; pkt = 0 <= _ref ? ++_i : --_i) {
-        all += 1;
-        if (pkts.eq(pkt).data('pos') === sorted[pkt]) {
-          correct += 1;
-          this.piece_correct(pkts.eq(pkt));
-        } else {
-          bad += 1;
-          this.piece_incorrect(pkts.eq(pkt));
-        }
-      }
-      return [correct, bad, all];
-    };
-
-    Uporzadkuj.prototype.solve_question = function(question) {
-      var p, parent, pkts, _i, _len, _results;
-      pkts = $('.question-piece', question);
-      pkts.sort(function(a, b) {
-        return $(a).data('pos') - $(b).data('pos');
-      });
-      parent = pkts.eq(0).parent();
-      _results = [];
-      for (_i = 0, _len = pkts.length; _i < _len; _i++) {
-        p = pkts[_i];
-        _results.push(parent.append(p));
-      }
-      return _results;
-    };
-
-    return Uporzadkuj;
-
-  })(Exercise);
-
-  Luki = (function(_super) {
-
-    __extends(Luki, _super);
-
-    function Luki(element) {
-      Luki.__super__.constructor.call(this, element);
-      this.dragging(false, false);
-    }
-
-    Luki.prototype.check = function() {
-      var all, bad, correct,
-        _this = this;
-      all = $(".placeholder", this.element).length;
-      correct = 0;
-      bad = 0;
-      $(".placeholder + .question-piece", this.element).each(function(i, qpiece) {
-        var $placeholder;
-        $placeholder = $(qpiece).prev(".placeholder");
-        if ($placeholder.data('solution') === $(qpiece).data('no')) {
-          _this.piece_correct(qpiece);
-          return correct += 1;
-        } else {
-          bad += 1;
-          return _this.piece_incorrect(qpiece);
-        }
-      });
-      return this.show_score([correct, bad, all]);
-    };
-
-    Luki.prototype.solve_question = function(question) {
-      var _this = this;
-      return $(".placeholder", question).each(function(i, placeholder) {
-        var $qp;
-        $qp = $(".question-piece[data-no=" + $(placeholder).data('solution') + "]", question);
-        return _this.draggable_move($qp, $(placeholder), false);
-      });
-    };
-
-    return Luki;
-
-  })(Exercise);
-
-  Zastap = (function(_super) {
-
-    __extends(Zastap, _super);
-
-    function Zastap(element) {
-      var _this = this;
-      Zastap.__super__.constructor.call(this, element);
-      $(".paragraph", this.element).each(function(i, par) {
-        return _this.wrap_words($(par), $('<span class="placeholder zastap"/>'));
-      });
-      this.dragging(false, false);
-    }
-
-    Zastap.prototype.check = function() {
-      var all, bad, correct,
-        _this = this;
-      all = 0;
-      correct = 0;
-      bad = 0;
-      $(".paragraph", this.element).each(function(i, par) {
-        return $(".placeholder", par).each(function(j, qpiece) {
-          var $dragged, $qp;
-          $qp = $(qpiece);
-          $dragged = $qp.next(".draggable");
-          if ($qp.data("solution")) {
-            if ($dragged && $qp.data("solution") === $dragged.data("no")) {
-              _this.piece_correct($dragged);
-              correct += 1;
-            }
-            return all += 1;
-          }
-        });
-      });
-      return this.show_score([correct, bad, all]);
-    };
-
-    Zastap.prototype.show_solutions = function() {
-      var _this = this;
-      this.reset();
-      return $(".paragraph", this.element).each(function(i, par) {
-        return $(".placeholder[data-solution]", par).each(function(j, qpiece) {
-          var $dr, $qp;
-          $qp = $(qpiece);
-          $dr = $(".draggable[data-no=" + $qp.data('solution') + "]", _this.element);
-          return _this.draggable_move($dr, $qp, false);
-        });
-      });
-    };
-
-    Zastap.prototype.wrap_words = function(element, wrapper) {
-      var chld, i, ignore, insertWrapped, j, len, space, wordb, _i, _ref, _results;
-      ignore = /^[ \t.,:;()]+/;
-      insertWrapped = function(txt, elem) {
-        var nw;
-        nw = wrapper.clone();
-        return $(document.createTextNode(txt)).wrap(nw).parent().attr("data-original", txt).insertBefore(elem);
-      };
-      _results = [];
-      for (j = _i = _ref = element.get(0).childNodes.length - 1; _ref <= 0 ? _i <= 0 : _i >= 0; j = _ref <= 0 ? ++_i : --_i) {
-        chld = element.get(0).childNodes[j];
-        if (chld.nodeType === document.TEXT_NODE) {
-          len = chld.textContent.length;
-          wordb = 0;
-          i = 0;
-          while (i < len) {
-            space = ignore.exec(chld.textContent.substr(i));
-            if (space != null) {
-              if (wordb < i) {
-                insertWrapped(chld.textContent.substr(wordb, i - wordb), chld);
-              }
-              $(document.createTextNode(space[0])).insertBefore(chld);
-              i += space[0].length;
-              wordb = i;
-            } else {
-              i = i + 1;
-            }
-          }
-          if (wordb < len - 1) {
-            insertWrapped(chld.textContent.substr(wordb, len - 1 - wordb), chld);
-          }
-          _results.push($(chld).remove());
-        } else {
-          _results.push(void 0);
-        }
-      }
-      return _results;
-    };
-
-    return Zastap;
-
-  })(Exercise);
-
-  Przyporzadkuj = (function(_super) {
-
-    __extends(Przyporzadkuj, _super);
-
-    Przyporzadkuj.prototype.is_multiple = function() {
-      var qp, _i, _len, _ref;
-      _ref = $(".question-piece", this.element);
-      for (_i = 0, _len = _ref.length; _i < _len; _i++) {
-        qp = _ref[_i];
-        if ($(qp).attr('data-solution').split(/[ ,]+/).length > 1) {
-          return true;
-        }
-      }
-      return false;
-    };
-
-    function Przyporzadkuj(element) {
-      Przyporzadkuj.__super__.constructor.call(this, element);
-      this.multiple = this.is_multiple();
-      this.dragging(this.multiple, true);
-    }
-
-    Przyporzadkuj.prototype.draggable_equal = function(d1, d2) {
-      return d1.data("no") === d2.data("no");
-    };
-
-    Przyporzadkuj.prototype.check_question = function(question) {
-      var all, bad_count, count, mandatory, minimum, optional, pn, pred, qp, self, v, _i, _j, _len, _len1, _ref, _ref1;
-      minimum = $(question).data("minimum");
-      count = 0;
-      bad_count = 0;
-      all = 0;
-      if (!minimum) {
-        self = this;
-        $(".subject .question-piece", question).each(function(i, el) {
-          var mandatory, v;
-          v = self.get_value_optional_list(el, 'solution');
-          mandatory = v[0];
-          return all += mandatory.length;
-        });
-      }
-      _ref = $(".predicate [data-predicate]", question);
-      for (_i = 0, _len = _ref.length; _i < _len; _i++) {
-        pred = _ref[_i];
-        pn = $(pred).attr('data-predicate');
-        _ref1 = $(".question-piece", pred);
-        for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) {
-          qp = _ref1[_j];
-          v = this.get_value_optional_list(qp, 'solution');
-          mandatory = v[0];
-          optional = v[1];
-          if (mandatory.indexOf(pn) >= 0 || (minimum && optional.indexOf(pn) >= 0)) {
-            count += 1;
-            this.piece_correct(qp);
-          } else {
-            bad_count += 1;
-            this.piece_incorrect(qp);
-          }
-        }
-      }
-      return [count, bad_count, all];
-    };
-
-    Przyporzadkuj.prototype.solve_question = function(question) {
-      var $ph, $pr, draggables, m, mandatory, minimum, optional, qp, v, _i, _len, _ref, _results;
-      minimum = $(question).data("min");
-      _ref = $(".subject .question-piece", question);
-      _results = [];
-      for (_i = 0, _len = _ref.length; _i < _len; _i++) {
-        qp = _ref[_i];
-        v = this.get_value_optional_list(qp, 'solution');
-        mandatory = v[0];
-        optional = v[1];
-        if (minimum) {
-          draggables = mandatory.count(optional).slice(0, minimum);
-        } else {
-          draggables = mandatory;
-        }
-        _results.push((function() {
-          var _j, _len1, _results1;
-          _results1 = [];
-          for (_j = 0, _len1 = draggables.length; _j < _len1; _j++) {
-            m = draggables[_j];
-            $pr = $(".predicate [data-predicate=" + m + "]", question);
-            $ph = $pr.find(".placeholder:visible");
-            _results1.push(this.draggable_move($(qp), $ph.eq(0), this.multiple));
-          }
-          return _results1;
-        }).call(this));
-      }
-      return _results;
-    };
-
-    return Przyporzadkuj;
-
-  })(Exercise);
-
-  PrawdaFalsz = (function(_super) {
-
-    __extends(PrawdaFalsz, _super);
-
-    function PrawdaFalsz(element) {
-      var qp, _i, _len, _ref,
-        _this = this;
-      PrawdaFalsz.__super__.constructor.call(this, element);
-      _ref = $(".question-piece", this.element);
-      for (_i = 0, _len = _ref.length; _i < _len; _i++) {
-        qp = _ref[_i];
-        $(".true", qp).click(function(ev) {
-          ev.preventDefault();
-          _this.retry();
-          $(ev.target).closest(".question-piece").data("value", "true");
-          return $(ev.target).addClass('chosen').siblings('a').removeClass('chosen');
-        });
-        $(".false", qp).click(function(ev) {
-          ev.preventDefault();
-          _this.retry();
-          $(ev.target).closest(".question-piece").data("value", "false");
-          return $(ev.target).addClass('chosen').siblings('a').removeClass('chosen');
-        });
-      }
-    }
-
-    PrawdaFalsz.prototype.check_question = function() {
-      var all, bad, good, qp, _i, _len, _ref;
-      all = 0;
-      good = 0;
-      bad = 0;
-      _ref = $(".question-piece", this.element);
-      for (_i = 0, _len = _ref.length; _i < _len; _i++) {
-        qp = _ref[_i];
-        if ($(qp).data("solution").toString() === $(qp).data("value")) {
-          good += 1;
-          this.piece_correct(qp);
-        } else {
-          bad += 1;
-          this.piece_incorrect(qp);
-        }
-        all += 1;
-      }
-      return [good, bad, all];
-    };
-
-    PrawdaFalsz.prototype.show_solutions = function() {
-      var qp, _i, _len, _ref, _results;
-      this.reset();
-      _ref = $(".question-piece", this.element);
-      _results = [];
-      for (_i = 0, _len = _ref.length; _i < _len; _i++) {
-        qp = _ref[_i];
-        if ($(qp).data('solution') === true) {
-          _results.push($(".true", qp).click());
-        } else {
-          _results.push($(".false", qp).click());
-        }
-      }
-      return _results;
-    };
-
-    return PrawdaFalsz;
-
-  })(Exercise);
-
-  exercise = function(ele) {
-    var cls, es;
-    es = {
-      wybor: Wybor,
-      uporzadkuj: Uporzadkuj,
-      luki: Luki,
-      zastap: Zastap,
-      przyporzadkuj: Przyporzadkuj,
-      prawdafalsz: PrawdaFalsz
-    };
-    cls = es[$(ele).attr('data-type')];
-    return new cls(ele);
-  };
-
-  window.edumed = {
-    'EduModule': EduModule
-  };
-
-  $(document).ready(function() {
-    new EduModule($("#book-text"));
-    return $(".exercise").each(function(i, el) {
-      return exercise(this);
-    });
-  });
-
-}).call(this);
diff --git a/catalogue/static/catalogue/js/jquery-ui-1.10.0.custom.js b/catalogue/static/catalogue/js/jquery-ui-1.10.0.custom.js
deleted file mode 100644 (file)
index d31460a..0000000
+++ /dev/null
@@ -1,5027 +0,0 @@
-/*! jQuery UI - v1.10.0 - 2013-01-24
-* http://jqueryui.com
-* Includes: jquery.ui.core.js, jquery.ui.widget.js, jquery.ui.mouse.js, jquery.ui.draggable.js, jquery.ui.droppable.js, jquery.ui.selectable.js, jquery.ui.sortable.js, jquery.ui.effect.js
-* Copyright (c) 2013 jQuery Foundation and other contributors Licensed MIT */
-
-(function( $, undefined ) {
-
-var uuid = 0,
-       runiqueId = /^ui-id-\d+$/;
-
-// prevent duplicate loading
-// this is only a problem because we proxy existing functions
-// and we don't want to double proxy them
-$.ui = $.ui || {};
-if ( $.ui.version ) {
-       return;
-}
-
-$.extend( $.ui, {
-       version: "1.10.0",
-
-       keyCode: {
-               BACKSPACE: 8,
-               COMMA: 188,
-               DELETE: 46,
-               DOWN: 40,
-               END: 35,
-               ENTER: 13,
-               ESCAPE: 27,
-               HOME: 36,
-               LEFT: 37,
-               NUMPAD_ADD: 107,
-               NUMPAD_DECIMAL: 110,
-               NUMPAD_DIVIDE: 111,
-               NUMPAD_ENTER: 108,
-               NUMPAD_MULTIPLY: 106,
-               NUMPAD_SUBTRACT: 109,
-               PAGE_DOWN: 34,
-               PAGE_UP: 33,
-               PERIOD: 190,
-               RIGHT: 39,
-               SPACE: 32,
-               TAB: 9,
-               UP: 38
-       }
-});
-
-// plugins
-$.fn.extend({
-       _focus: $.fn.focus,
-       focus: function( delay, fn ) {
-               return typeof delay === "number" ?
-                       this.each(function() {
-                               var elem = this;
-                               setTimeout(function() {
-                                       $( elem ).focus();
-                                       if ( fn ) {
-                                               fn.call( elem );
-                                       }
-                               }, delay );
-                       }) :
-                       this._focus.apply( this, arguments );
-       },
-
-       scrollParent: function() {
-               var scrollParent;
-               if (($.ui.ie && (/(static|relative)/).test(this.css("position"))) || (/absolute/).test(this.css("position"))) {
-                       scrollParent = this.parents().filter(function() {
-                               return (/(relative|absolute|fixed)/).test($.css(this,"position")) && (/(auto|scroll)/).test($.css(this,"overflow")+$.css(this,"overflow-y")+$.css(this,"overflow-x"));
-                       }).eq(0);
-               } else {
-                       scrollParent = this.parents().filter(function() {
-                               return (/(auto|scroll)/).test($.css(this,"overflow")+$.css(this,"overflow-y")+$.css(this,"overflow-x"));
-                       }).eq(0);
-               }
-
-               return (/fixed/).test(this.css("position")) || !scrollParent.length ? $(document) : scrollParent;
-       },
-
-       zIndex: function( zIndex ) {
-               if ( zIndex !== undefined ) {
-                       return this.css( "zIndex", zIndex );
-               }
-
-               if ( this.length ) {
-                       var elem = $( this[ 0 ] ), position, value;
-                       while ( elem.length && elem[ 0 ] !== document ) {
-                               // Ignore z-index if position is set to a value where z-index is ignored by the browser
-                               // This makes behavior of this function consistent across browsers
-                               // WebKit always returns auto if the element is positioned
-                               position = elem.css( "position" );
-                               if ( position === "absolute" || position === "relative" || position === "fixed" ) {
-                                       // IE returns 0 when zIndex is not specified
-                                       // other browsers return a string
-                                       // we ignore the case of nested elements with an explicit value of 0
-                                       // <div style="z-index: -10;"><div style="z-index: 0;"></div></div>
-                                       value = parseInt( elem.css( "zIndex" ), 10 );
-                                       if ( !isNaN( value ) && value !== 0 ) {
-                                               return value;
-                                       }
-                               }
-                               elem = elem.parent();
-                       }
-               }
-
-               return 0;
-       },
-
-       uniqueId: function() {
-               return this.each(function() {
-                       if ( !this.id ) {
-                               this.id = "ui-id-" + (++uuid);
-                       }
-               });
-       },
-
-       removeUniqueId: function() {
-               return this.each(function() {
-                       if ( runiqueId.test( this.id ) ) {
-                               $( this ).removeAttr( "id" );
-                       }
-               });
-       }
-});
-
-// selectors
-function focusable( element, isTabIndexNotNaN ) {
-       var map, mapName, img,
-               nodeName = element.nodeName.toLowerCase();
-       if ( "area" === nodeName ) {
-               map = element.parentNode;
-               mapName = map.name;
-               if ( !element.href || !mapName || map.nodeName.toLowerCase() !== "map" ) {
-                       return false;
-               }
-               img = $( "img[usemap=#" + mapName + "]" )[0];
-               return !!img && visible( img );
-       }
-       return ( /input|select|textarea|button|object/.test( nodeName ) ?
-               !element.disabled :
-               "a" === nodeName ?
-                       element.href || isTabIndexNotNaN :
-                       isTabIndexNotNaN) &&
-               // the element and all of its ancestors must be visible
-               visible( element );
-}
-
-function visible( element ) {
-       return $.expr.filters.visible( element ) &&
-               !$( element ).parents().addBack().filter(function() {
-                       return $.css( this, "visibility" ) === "hidden";
-               }).length;
-}
-
-$.extend( $.expr[ ":" ], {
-       data: $.expr.createPseudo ?
-               $.expr.createPseudo(function( dataName ) {
-                       return function( elem ) {
-                               return !!$.data( elem, dataName );
-                       };
-               }) :
-               // support: jQuery <1.8
-               function( elem, i, match ) {
-                       return !!$.data( elem, match[ 3 ] );
-               },
-
-       focusable: function( element ) {
-               return focusable( element, !isNaN( $.attr( element, "tabindex" ) ) );
-       },
-
-       tabbable: function( element ) {
-               var tabIndex = $.attr( element, "tabindex" ),
-                       isTabIndexNaN = isNaN( tabIndex );
-               return ( isTabIndexNaN || tabIndex >= 0 ) && focusable( element, !isTabIndexNaN );
-       }
-});
-
-// support: jQuery <1.8
-if ( !$( "<a>" ).outerWidth( 1 ).jquery ) {
-       $.each( [ "Width", "Height" ], function( i, name ) {
-               var side = name === "Width" ? [ "Left", "Right" ] : [ "Top", "Bottom" ],
-                       type = name.toLowerCase(),
-                       orig = {
-                               innerWidth: $.fn.innerWidth,
-                               innerHeight: $.fn.innerHeight,
-                               outerWidth: $.fn.outerWidth,
-                               outerHeight: $.fn.outerHeight
-                       };
-
-               function reduce( elem, size, border, margin ) {
-                       $.each( side, function() {
-                               size -= parseFloat( $.css( elem, "padding" + this ) ) || 0;
-                               if ( border ) {
-                                       size -= parseFloat( $.css( elem, "border" + this + "Width" ) ) || 0;
-                               }
-                               if ( margin ) {
-                                       size -= parseFloat( $.css( elem, "margin" + this ) ) || 0;
-                               }
-                       });
-                       return size;
-               }
-
-               $.fn[ "inner" + name ] = function( size ) {
-                       if ( size === undefined ) {
-                               return orig[ "inner" + name ].call( this );
-                       }
-
-                       return this.each(function() {
-                               $( this ).css( type, reduce( this, size ) + "px" );
-                       });
-               };
-
-               $.fn[ "outer" + name] = function( size, margin ) {
-                       if ( typeof size !== "number" ) {
-                               return orig[ "outer" + name ].call( this, size );
-                       }
-
-                       return this.each(function() {
-                               $( this).css( type, reduce( this, size, true, margin ) + "px" );
-                       });
-               };
-       });
-}
-
-// support: jQuery <1.8
-if ( !$.fn.addBack ) {
-       $.fn.addBack = function( selector ) {
-               return this.add( selector == null ?
-                       this.prevObject : this.prevObject.filter( selector )
-               );
-       };
-}
-
-// support: jQuery 1.6.1, 1.6.2 (http://bugs.jquery.com/ticket/9413)
-if ( $( "<a>" ).data( "a-b", "a" ).removeData( "a-b" ).data( "a-b" ) ) {
-       $.fn.removeData = (function( removeData ) {
-               return function( key ) {
-                       if ( arguments.length ) {
-                               return removeData.call( this, $.camelCase( key ) );
-                       } else {
-                               return removeData.call( this );
-                       }
-               };
-       })( $.fn.removeData );
-}
-
-
-
-
-
-// deprecated
-$.ui.ie = !!/msie [\w.]+/.exec( navigator.userAgent.toLowerCase() );
-
-$.support.selectstart = "onselectstart" in document.createElement( "div" );
-$.fn.extend({
-       disableSelection: function() {
-               return this.bind( ( $.support.selectstart ? "selectstart" : "mousedown" ) +
-                       ".ui-disableSelection", function( event ) {
-                               event.preventDefault();
-                       });
-       },
-
-       enableSelection: function() {
-               return this.unbind( ".ui-disableSelection" );
-       }
-});
-
-$.extend( $.ui, {
-       // $.ui.plugin is deprecated.  Use the proxy pattern instead.
-       plugin: {
-               add: function( module, option, set ) {
-                       var i,
-                               proto = $.ui[ module ].prototype;
-                       for ( i in set ) {
-                               proto.plugins[ i ] = proto.plugins[ i ] || [];
-                               proto.plugins[ i ].push( [ option, set[ i ] ] );
-                       }
-               },
-               call: function( instance, name, args ) {
-                       var i,
-                               set = instance.plugins[ name ];
-                       if ( !set || !instance.element[ 0 ].parentNode || instance.element[ 0 ].parentNode.nodeType === 11 ) {
-                               return;
-                       }
-
-                       for ( i = 0; i < set.length; i++ ) {
-                               if ( instance.options[ set[ i ][ 0 ] ] ) {
-                                       set[ i ][ 1 ].apply( instance.element, args );
-                               }
-                       }
-               }
-       },
-
-       // only used by resizable
-       hasScroll: function( el, a ) {
-
-               //If overflow is hidden, the element might have extra content, but the user wants to hide it
-               if ( $( el ).css( "overflow" ) === "hidden") {
-                       return false;
-               }
-
-               var scroll = ( a && a === "left" ) ? "scrollLeft" : "scrollTop",
-                       has = false;
-
-               if ( el[ scroll ] > 0 ) {
-                       return true;
-               }
-
-               // TODO: determine which cases actually cause this to happen
-               // if the element doesn't have the scroll set, see if it's possible to
-               // set the scroll
-               el[ scroll ] = 1;
-               has = ( el[ scroll ] > 0 );
-               el[ scroll ] = 0;
-               return has;
-       }
-});
-
-})( jQuery );
-(function( $, undefined ) {
-
-var uuid = 0,
-       slice = Array.prototype.slice,
-       _cleanData = $.cleanData;
-$.cleanData = function( elems ) {
-       for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) {
-               try {
-                       $( elem ).triggerHandler( "remove" );
-               // http://bugs.jquery.com/ticket/8235
-               } catch( e ) {}
-       }
-       _cleanData( elems );
-};
-
-$.widget = function( name, base, prototype ) {
-       var fullName, existingConstructor, constructor, basePrototype,
-               // proxiedPrototype allows the provided prototype to remain unmodified
-               // so that it can be used as a mixin for multiple widgets (#8876)
-               proxiedPrototype = {},
-               namespace = name.split( "." )[ 0 ];
-
-       name = name.split( "." )[ 1 ];
-       fullName = namespace + "-" + name;
-
-       if ( !prototype ) {
-               prototype = base;
-               base = $.Widget;
-       }
-
-       // create selector for plugin
-       $.expr[ ":" ][ fullName.toLowerCase() ] = function( elem ) {
-               return !!$.data( elem, fullName );
-       };
-
-       $[ namespace ] = $[ namespace ] || {};
-       existingConstructor = $[ namespace ][ name ];
-       constructor = $[ namespace ][ name ] = function( options, element ) {
-               // allow instantiation without "new" keyword
-               if ( !this._createWidget ) {
-                       return new constructor( options, element );
-               }
-
-               // allow instantiation without initializing for simple inheritance
-               // must use "new" keyword (the code above always passes args)
-               if ( arguments.length ) {
-                       this._createWidget( options, element );
-               }
-       };
-       // extend with the existing constructor to carry over any static properties
-       $.extend( constructor, existingConstructor, {
-               version: prototype.version,
-               // copy the object used to create the prototype in case we need to
-               // redefine the widget later
-               _proto: $.extend( {}, prototype ),
-               // track widgets that inherit from this widget in case this widget is
-               // redefined after a widget inherits from it
-               _childConstructors: []
-       });
-
-       basePrototype = new base();
-       // we need to make the options hash a property directly on the new instance
-       // otherwise we'll modify the options hash on the prototype that we're
-       // inheriting from
-       basePrototype.options = $.widget.extend( {}, basePrototype.options );
-       $.each( prototype, function( prop, value ) {
-               if ( !$.isFunction( value ) ) {
-                       proxiedPrototype[ prop ] = value;
-                       return;
-               }
-               proxiedPrototype[ prop ] = (function() {
-                       var _super = function() {
-                                       return base.prototype[ prop ].apply( this, arguments );
-                               },
-                               _superApply = function( args ) {
-                                       return base.prototype[ prop ].apply( this, args );
-                               };
-                       return function() {
-                               var __super = this._super,
-                                       __superApply = this._superApply,
-                                       returnValue;
-
-                               this._super = _super;
-                               this._superApply = _superApply;
-
-                               returnValue = value.apply( this, arguments );
-
-                               this._super = __super;
-                               this._superApply = __superApply;
-
-                               return returnValue;
-                       };
-               })();
-       });
-       constructor.prototype = $.widget.extend( basePrototype, {
-               // TODO: remove support for widgetEventPrefix
-               // always use the name + a colon as the prefix, e.g., draggable:start
-               // don't prefix for widgets that aren't DOM-based
-               widgetEventPrefix: existingConstructor ? basePrototype.widgetEventPrefix : name
-       }, proxiedPrototype, {
-               constructor: constructor,
-               namespace: namespace,
-               widgetName: name,
-               widgetFullName: fullName
-       });
-
-       // If this widget is being redefined then we need to find all widgets that
-       // are inheriting from it and redefine all of them so that they inherit from
-       // the new version of this widget. We're essentially trying to replace one
-       // level in the prototype chain.
-       if ( existingConstructor ) {
-               $.each( existingConstructor._childConstructors, function( i, child ) {
-                       var childPrototype = child.prototype;
-
-                       // redefine the child widget using the same prototype that was
-                       // originally used, but inherit from the new version of the base
-                       $.widget( childPrototype.namespace + "." + childPrototype.widgetName, constructor, child._proto );
-               });
-               // remove the list of existing child constructors from the old constructor
-               // so the old child constructors can be garbage collected
-               delete existingConstructor._childConstructors;
-       } else {
-               base._childConstructors.push( constructor );
-       }
-
-       $.widget.bridge( name, constructor );
-};
-
-$.widget.extend = function( target ) {
-       var input = slice.call( arguments, 1 ),
-               inputIndex = 0,
-               inputLength = input.length,
-               key,
-               value;
-       for ( ; inputIndex < inputLength; inputIndex++ ) {
-               for ( key in input[ inputIndex ] ) {
-                       value = input[ inputIndex ][ key ];
-                       if ( input[ inputIndex ].hasOwnProperty( key ) && value !== undefined ) {
-                               // Clone objects
-                               if ( $.isPlainObject( value ) ) {
-                                       target[ key ] = $.isPlainObject( target[ key ] ) ?
-                                               $.widget.extend( {}, target[ key ], value ) :
-                                               // Don't extend strings, arrays, etc. with objects
-                                               $.widget.extend( {}, value );
-                               // Copy everything else by reference
-                               } else {
-                                       target[ key ] = value;
-                               }
-                       }
-               }
-       }
-       return target;
-};
-
-$.widget.bridge = function( name, object ) {
-       var fullName = object.prototype.widgetFullName || name;
-       $.fn[ name ] = function( options ) {
-               var isMethodCall = typeof options === "string",
-                       args = slice.call( arguments, 1 ),
-                       returnValue = this;
-
-               // allow multiple hashes to be passed on init
-               options = !isMethodCall && args.length ?
-                       $.widget.extend.apply( null, [ options ].concat(args) ) :
-                       options;
-
-               if ( isMethodCall ) {
-                       this.each(function() {
-                               var methodValue,
-                                       instance = $.data( this, fullName );
-                               if ( !instance ) {
-                                       return $.error( "cannot call methods on " + name + " prior to initialization; " +
-                                               "attempted to call method '" + options + "'" );
-                               }
-                               if ( !$.isFunction( instance[options] ) || options.charAt( 0 ) === "_" ) {
-                                       return $.error( "no such method '" + options + "' for " + name + " widget instance" );
-                               }
-                               methodValue = instance[ options ].apply( instance, args );
-                               if ( methodValue !== instance && methodValue !== undefined ) {
-                                       returnValue = methodValue && methodValue.jquery ?
-                                               returnValue.pushStack( methodValue.get() ) :
-                                               methodValue;
-                                       return false;
-                               }
-                       });
-               } else {
-                       this.each(function() {
-                               var instance = $.data( this, fullName );
-                               if ( instance ) {
-                                       instance.option( options || {} )._init();
-                               } else {
-                                       $.data( this, fullName, new object( options, this ) );
-                               }
-                       });
-               }
-
-               return returnValue;
-       };
-};
-
-$.Widget = function( /* options, element */ ) {};
-$.Widget._childConstructors = [];
-
-$.Widget.prototype = {
-       widgetName: "widget",
-       widgetEventPrefix: "",
-       defaultElement: "<div>",
-       options: {
-               disabled: false,
-
-               // callbacks
-               create: null
-       },
-       _createWidget: function( options, element ) {
-               element = $( element || this.defaultElement || this )[ 0 ];
-               this.element = $( element );
-               this.uuid = uuid++;
-               this.eventNamespace = "." + this.widgetName + this.uuid;
-               this.options = $.widget.extend( {},
-                       this.options,
-                       this._getCreateOptions(),
-                       options );
-
-               this.bindings = $();
-               this.hoverable = $();
-               this.focusable = $();
-
-               if ( element !== this ) {
-                       $.data( element, this.widgetFullName, this );
-                       this._on( true, this.element, {
-                               remove: function( event ) {
-                                       if ( event.target === element ) {
-                                               this.destroy();
-                                       }
-                               }
-                       });
-                       this.document = $( element.style ?
-                               // element within the document
-                               element.ownerDocument :
-                               // element is window or document
-                               element.document || element );
-                       this.window = $( this.document[0].defaultView || this.document[0].parentWindow );
-               }
-
-               this._create();
-               this._trigger( "create", null, this._getCreateEventData() );
-               this._init();
-       },
-       _getCreateOptions: $.noop,
-       _getCreateEventData: $.noop,
-       _create: $.noop,
-       _init: $.noop,
-
-       destroy: function() {
-               this._destroy();
-               // we can probably remove the unbind calls in 2.0
-               // all event bindings should go through this._on()
-               this.element
-                       .unbind( this.eventNamespace )
-                       // 1.9 BC for #7810
-                       // TODO remove dual storage
-                       .removeData( this.widgetName )
-                       .removeData( this.widgetFullName )
-                       // support: jquery <1.6.3
-                       // http://bugs.jquery.com/ticket/9413
-                       .removeData( $.camelCase( this.widgetFullName ) );
-               this.widget()
-                       .unbind( this.eventNamespace )
-                       .removeAttr( "aria-disabled" )
-                       .removeClass(
-                               this.widgetFullName + "-disabled " +
-                               "ui-state-disabled" );
-
-               // clean up events and states
-               this.bindings.unbind( this.eventNamespace );
-               this.hoverable.removeClass( "ui-state-hover" );
-               this.focusable.removeClass( "ui-state-focus" );
-       },
-       _destroy: $.noop,
-
-       widget: function() {
-               return this.element;
-       },
-
-       option: function( key, value ) {
-               var options = key,
-                       parts,
-                       curOption,
-                       i;
-
-               if ( arguments.length === 0 ) {
-                       // don't return a reference to the internal hash
-                       return $.widget.extend( {}, this.options );
-               }
-
-               if ( typeof key === "string" ) {
-                       // handle nested keys, e.g., "foo.bar" => { foo: { bar: ___ } }
-                       options = {};
-                       parts = key.split( "." );
-                       key = parts.shift();
-                       if ( parts.length ) {
-                               curOption = options[ key ] = $.widget.extend( {}, this.options[ key ] );
-                               for ( i = 0; i < parts.length - 1; i++ ) {
-                                       curOption[ parts[ i ] ] = curOption[ parts[ i ] ] || {};
-                                       curOption = curOption[ parts[ i ] ];
-                               }
-                               key = parts.pop();
-                               if ( value === undefined ) {
-                                       return curOption[ key ] === undefined ? null : curOption[ key ];
-                               }
-                               curOption[ key ] = value;
-                       } else {
-                               if ( value === undefined ) {
-                                       return this.options[ key ] === undefined ? null : this.options[ key ];
-                               }
-                               options[ key ] = value;
-                       }
-               }
-
-               this._setOptions( options );
-
-               return this;
-       },
-       _setOptions: function( options ) {
-               var key;
-
-               for ( key in options ) {
-                       this._setOption( key, options[ key ] );
-               }
-
-               return this;
-       },
-       _setOption: function( key, value ) {
-               this.options[ key ] = value;
-
-               if ( key === "disabled" ) {
-                       this.widget()
-                               .toggleClass( this.widgetFullName + "-disabled ui-state-disabled", !!value )
-                               .attr( "aria-disabled", value );
-                       this.hoverable.removeClass( "ui-state-hover" );
-                       this.focusable.removeClass( "ui-state-focus" );
-               }
-
-               return this;
-       },
-
-       enable: function() {
-               return this._setOption( "disabled", false );
-       },
-       disable: function() {
-               return this._setOption( "disabled", true );
-       },
-
-       _on: function( suppressDisabledCheck, element, handlers ) {
-               var delegateElement,
-                       instance = this;
-
-               // no suppressDisabledCheck flag, shuffle arguments
-               if ( typeof suppressDisabledCheck !== "boolean" ) {
-                       handlers = element;
-                       element = suppressDisabledCheck;
-                       suppressDisabledCheck = false;
-               }
-
-               // no element argument, shuffle and use this.element
-               if ( !handlers ) {
-                       handlers = element;
-                       element = this.element;
-                       delegateElement = this.widget();
-               } else {
-                       // accept selectors, DOM elements
-                       element = delegateElement = $( element );
-                       this.bindings = this.bindings.add( element );
-               }
-
-               $.each( handlers, function( event, handler ) {
-                       function handlerProxy() {
-                               // allow widgets to customize the disabled handling
-                               // - disabled as an array instead of boolean
-                               // - disabled class as method for disabling individual parts
-                               if ( !suppressDisabledCheck &&
-                                               ( instance.options.disabled === true ||
-                                                       $( this ).hasClass( "ui-state-disabled" ) ) ) {
-                                       return;
-                               }
-                               return ( typeof handler === "string" ? instance[ handler ] : handler )
-                                       .apply( instance, arguments );
-                       }
-
-                       // copy the guid so direct unbinding works
-                       if ( typeof handler !== "string" ) {
-                               handlerProxy.guid = handler.guid =
-                                       handler.guid || handlerProxy.guid || $.guid++;
-                       }
-
-                       var match = event.match( /^(\w+)\s*(.*)$/ ),
-                               eventName = match[1] + instance.eventNamespace,
-                               selector = match[2];
-                       if ( selector ) {
-                               delegateElement.delegate( selector, eventName, handlerProxy );
-                       } else {
-                               element.bind( eventName, handlerProxy );
-                       }
-               });
-       },
-
-       _off: function( element, eventName ) {
-               eventName = (eventName || "").split( " " ).join( this.eventNamespace + " " ) + this.eventNamespace;
-               element.unbind( eventName ).undelegate( eventName );
-       },
-
-       _delay: function( handler, delay ) {
-               function handlerProxy() {
-                       return ( typeof handler === "string" ? instance[ handler ] : handler )
-                               .apply( instance, arguments );
-               }
-               var instance = this;
-               return setTimeout( handlerProxy, delay || 0 );
-       },
-
-       _hoverable: function( element ) {
-               this.hoverable = this.hoverable.add( element );
-               this._on( element, {
-                       mouseenter: function( event ) {
-                               $( event.currentTarget ).addClass( "ui-state-hover" );
-                       },
-                       mouseleave: function( event ) {
-                               $( event.currentTarget ).removeClass( "ui-state-hover" );
-                       }
-               });
-       },
-
-       _focusable: function( element ) {
-               this.focusable = this.focusable.add( element );
-               this._on( element, {
-                       focusin: function( event ) {
-                               $( event.currentTarget ).addClass( "ui-state-focus" );
-                       },
-                       focusout: function( event ) {
-                               $( event.currentTarget ).removeClass( "ui-state-focus" );
-                       }
-               });
-       },
-
-       _trigger: function( type, event, data ) {
-               var prop, orig,
-                       callback = this.options[ type ];
-
-               data = data || {};
-               event = $.Event( event );
-               event.type = ( type === this.widgetEventPrefix ?
-                       type :
-                       this.widgetEventPrefix + type ).toLowerCase();
-               // the original event may come from any element
-               // so we need to reset the target on the new event
-               event.target = this.element[ 0 ];
-
-               // copy original event properties over to the new event
-               orig = event.originalEvent;
-               if ( orig ) {
-                       for ( prop in orig ) {
-                               if ( !( prop in event ) ) {
-                                       event[ prop ] = orig[ prop ];
-                               }
-                       }
-               }
-
-               this.element.trigger( event, data );
-               return !( $.isFunction( callback ) &&
-                       callback.apply( this.element[0], [ event ].concat( data ) ) === false ||
-                       event.isDefaultPrevented() );
-       }
-};
-
-$.each( { show: "fadeIn", hide: "fadeOut" }, function( method, defaultEffect ) {
-       $.Widget.prototype[ "_" + method ] = function( element, options, callback ) {
-               if ( typeof options === "string" ) {
-                       options = { effect: options };
-               }
-               var hasOptions,
-                       effectName = !options ?
-                               method :
-                               options === true || typeof options === "number" ?
-                                       defaultEffect :
-                                       options.effect || defaultEffect;
-               options = options || {};
-               if ( typeof options === "number" ) {
-                       options = { duration: options };
-               }
-               hasOptions = !$.isEmptyObject( options );
-               options.complete = callback;
-               if ( options.delay ) {
-                       element.delay( options.delay );
-               }
-               if ( hasOptions && $.effects && $.effects.effect[ effectName ] ) {
-                       element[ method ]( options );
-               } else if ( effectName !== method && element[ effectName ] ) {
-                       element[ effectName ]( options.duration, options.easing, callback );
-               } else {
-                       element.queue(function( next ) {
-                               $( this )[ method ]();
-                               if ( callback ) {
-                                       callback.call( element[ 0 ] );
-                               }
-                               next();
-                       });
-               }
-       };
-});
-
-})( jQuery );
-(function( $, undefined ) {
-
-var mouseHandled = false;
-$( document ).mouseup( function() {
-       mouseHandled = false;
-});
-
-$.widget("ui.mouse", {
-       version: "1.10.0",
-       options: {
-               cancel: "input,textarea,button,select,option",
-               distance: 1,
-               delay: 0
-       },
-       _mouseInit: function() {
-               var that = this;
-
-               this.element
-                       .bind("mousedown."+this.widgetName, function(event) {
-                               return that._mouseDown(event);
-                       })
-                       .bind("click."+this.widgetName, function(event) {
-                               if (true === $.data(event.target, that.widgetName + ".preventClickEvent")) {
-                                       $.removeData(event.target, that.widgetName + ".preventClickEvent");
-                                       event.stopImmediatePropagation();
-                                       return false;
-                               }
-                       });
-
-               this.started = false;
-       },
-
-       // TODO: make sure destroying one instance of mouse doesn't mess with
-       // other instances of mouse
-       _mouseDestroy: function() {
-               this.element.unbind("."+this.widgetName);
-               if ( this._mouseMoveDelegate ) {
-                       $(document)
-                               .unbind("mousemove."+this.widgetName, this._mouseMoveDelegate)
-                               .unbind("mouseup."+this.widgetName, this._mouseUpDelegate);
-               }
-       },
-
-       _mouseDown: function(event) {
-               // don't let more than one widget handle mouseStart
-               if( mouseHandled ) { return; }
-
-               // we may have missed mouseup (out of window)
-               (this._mouseStarted && this._mouseUp(event));
-
-               this._mouseDownEvent = event;
-
-               var that = this,
-                       btnIsLeft = (event.which === 1),
-                       // event.target.nodeName works around a bug in IE 8 with
-                       // disabled inputs (#7620)
-                       elIsCancel = (typeof this.options.cancel === "string" && event.target.nodeName ? $(event.target).closest(this.options.cancel).length : false);
-               if (!btnIsLeft || elIsCancel || !this._mouseCapture(event)) {
-                       return true;
-               }
-
-               this.mouseDelayMet = !this.options.delay;
-               if (!this.mouseDelayMet) {
-                       this._mouseDelayTimer = setTimeout(function() {
-                               that.mouseDelayMet = true;
-                       }, this.options.delay);
-               }
-
-               if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) {
-                       this._mouseStarted = (this._mouseStart(event) !== false);
-                       if (!this._mouseStarted) {
-                               event.preventDefault();
-                               return true;
-                       }
-               }
-
-               // Click event may never have fired (Gecko & Opera)
-               if (true === $.data(event.target, this.widgetName + ".preventClickEvent")) {
-                       $.removeData(event.target, this.widgetName + ".preventClickEvent");
-               }
-
-               // these delegates are required to keep context
-               this._mouseMoveDelegate = function(event) {
-                       return that._mouseMove(event);
-               };
-               this._mouseUpDelegate = function(event) {
-                       return that._mouseUp(event);
-               };
-               $(document)
-                       .bind("mousemove."+this.widgetName, this._mouseMoveDelegate)
-                       .bind("mouseup."+this.widgetName, this._mouseUpDelegate);
-
-               event.preventDefault();
-
-               mouseHandled = true;
-               return true;
-       },
-
-       _mouseMove: function(event) {
-               // IE mouseup check - mouseup happened when mouse was out of window
-               if ($.ui.ie && ( !document.documentMode || document.documentMode < 9 ) && !event.button) {
-                       return this._mouseUp(event);
-               }
-
-               if (this._mouseStarted) {
-                       this._mouseDrag(event);
-                       return event.preventDefault();
-               }
-
-               if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) {
-                       this._mouseStarted =
-                               (this._mouseStart(this._mouseDownEvent, event) !== false);
-                       (this._mouseStarted ? this._mouseDrag(event) : this._mouseUp(event));
-               }
-
-               return !this._mouseStarted;
-       },
-
-       _mouseUp: function(event) {
-               $(document)
-                       .unbind("mousemove."+this.widgetName, this._mouseMoveDelegate)
-                       .unbind("mouseup."+this.widgetName, this._mouseUpDelegate);
-
-               if (this._mouseStarted) {
-                       this._mouseStarted = false;
-
-                       if (event.target === this._mouseDownEvent.target) {
-                               $.data(event.target, this.widgetName + ".preventClickEvent", true);
-                       }
-
-                       this._mouseStop(event);
-               }
-
-               return false;
-       },
-
-       _mouseDistanceMet: function(event) {
-               return (Math.max(
-                               Math.abs(this._mouseDownEvent.pageX - event.pageX),
-                               Math.abs(this._mouseDownEvent.pageY - event.pageY)
-                       ) >= this.options.distance
-               );
-       },
-
-       _mouseDelayMet: function(/* event */) {
-               return this.mouseDelayMet;
-       },
-
-       // These are placeholder methods, to be overriden by extending plugin
-       _mouseStart: function(/* event */) {},
-       _mouseDrag: function(/* event */) {},
-       _mouseStop: function(/* event */) {},
-       _mouseCapture: function(/* event */) { return true; }
-});
-
-})(jQuery);
-(function( $, undefined ) {
-
-$.widget("ui.draggable", $.ui.mouse, {
-       version: "1.10.0",
-       widgetEventPrefix: "drag",
-       options: {
-               addClasses: true,
-               appendTo: "parent",
-               axis: false,
-               connectToSortable: false,
-               containment: false,
-               cursor: "auto",
-               cursorAt: false,
-               grid: false,
-               handle: false,
-               helper: "original",
-               iframeFix: false,
-               opacity: false,
-               refreshPositions: false,
-               revert: false,
-               revertDuration: 500,
-               scope: "default",
-               scroll: true,
-               scrollSensitivity: 20,
-               scrollSpeed: 20,
-               snap: false,
-               snapMode: "both",
-               snapTolerance: 20,
-               stack: false,
-               zIndex: false,
-
-               // callbacks
-               drag: null,
-               start: null,
-               stop: null
-       },
-       _create: function() {
-
-               if (this.options.helper === "original" && !(/^(?:r|a|f)/).test(this.element.css("position"))) {
-                       this.element[0].style.position = "relative";
-               }
-               if (this.options.addClasses){
-                       this.element.addClass("ui-draggable");
-               }
-               if (this.options.disabled){
-                       this.element.addClass("ui-draggable-disabled");
-               }
-
-               this._mouseInit();
-
-       },
-
-       _destroy: function() {
-               this.element.removeClass( "ui-draggable ui-draggable-dragging ui-draggable-disabled" );
-               this._mouseDestroy();
-       },
-
-       _mouseCapture: function(event) {
-
-               var o = this.options;
-
-               // among others, prevent a drag on a resizable-handle
-               if (this.helper || o.disabled || $(event.target).closest(".ui-resizable-handle").length > 0) {
-                       return false;
-               }
-
-               //Quit if we're not on a valid handle
-               this.handle = this._getHandle(event);
-               if (!this.handle) {
-                       return false;
-               }
-
-               $(o.iframeFix === true ? "iframe" : o.iframeFix).each(function() {
-                       $("<div class='ui-draggable-iframeFix' style='background: #fff;'></div>")
-                       .css({
-                               width: this.offsetWidth+"px", height: this.offsetHeight+"px",
-                               position: "absolute", opacity: "0.001", zIndex: 1000
-                       })
-                       .css($(this).offset())
-                       .appendTo("body");
-               });
-
-               return true;
-
-       },
-
-       _mouseStart: function(event) {
-
-               var o = this.options;
-
-               //Create and append the visible helper
-               this.helper = this._createHelper(event);
-
-               this.helper.addClass("ui-draggable-dragging");
-
-               //Cache the helper size
-               this._cacheHelperProportions();
-
-               //If ddmanager is used for droppables, set the global draggable
-               if($.ui.ddmanager) {
-                       $.ui.ddmanager.current = this;
-               }
-
-               /*
-                * - Position generation -
-                * This block generates everything position related - it's the core of draggables.
-                */
-
-               //Cache the margins of the original element
-               this._cacheMargins();
-
-               //Store the helper's css position
-               this.cssPosition = this.helper.css("position");
-               this.scrollParent = this.helper.scrollParent();
-
-               //The element's absolute position on the page minus margins
-               this.offset = this.positionAbs = this.element.offset();
-               this.offset = {
-                       top: this.offset.top - this.margins.top,
-                       left: this.offset.left - this.margins.left
-               };
-
-               $.extend(this.offset, {
-                       click: { //Where the click happened, relative to the element
-                               left: event.pageX - this.offset.left,
-                               top: event.pageY - this.offset.top
-                       },
-                       parent: this._getParentOffset(),
-                       relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper
-               });
-
-               //Generate the original position
-               this.originalPosition = this.position = this._generatePosition(event);
-               this.originalPageX = event.pageX;
-               this.originalPageY = event.pageY;
-
-               //Adjust the mouse offset relative to the helper if "cursorAt" is supplied
-               (o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt));
-
-               //Set a containment if given in the options
-               if(o.containment) {
-                       this._setContainment();
-               }
-
-               //Trigger event + callbacks
-               if(this._trigger("start", event) === false) {
-                       this._clear();
-                       return false;
-               }
-
-               //Recache the helper size
-               this._cacheHelperProportions();
-
-               //Prepare the droppable offsets
-               if ($.ui.ddmanager && !o.dropBehaviour) {
-                       $.ui.ddmanager.prepareOffsets(this, event);
-               }
-
-
-               this._mouseDrag(event, true); //Execute the drag once - this causes the helper not to be visible before getting its correct position
-
-               //If the ddmanager is used for droppables, inform the manager that dragging has started (see #5003)
-               if ( $.ui.ddmanager ) {
-                       $.ui.ddmanager.dragStart(this, event);
-               }
-
-               return true;
-       },
-
-       _mouseDrag: function(event, noPropagation) {
-
-               //Compute the helpers position
-               this.position = this._generatePosition(event);
-               this.positionAbs = this._convertPositionTo("absolute");
-
-               //Call plugins and callbacks and use the resulting position if something is returned
-               if (!noPropagation) {
-                       var ui = this._uiHash();
-                       if(this._trigger("drag", event, ui) === false) {
-                               this._mouseUp({});
-                               return false;
-                       }
-                       this.position = ui.position;
-               }
-
-               if(!this.options.axis || this.options.axis !== "y") {
-                       this.helper[0].style.left = this.position.left+"px";
-               }
-               if(!this.options.axis || this.options.axis !== "x") {
-                       this.helper[0].style.top = this.position.top+"px";
-               }
-               if($.ui.ddmanager) {
-                       $.ui.ddmanager.drag(this, event);
-               }
-
-               return false;
-       },
-
-       _mouseStop: function(event) {
-
-               //If we are using droppables, inform the manager about the drop
-               var element,
-                       that = this,
-                       elementInDom = false,
-                       dropped = false;
-               if ($.ui.ddmanager && !this.options.dropBehaviour) {
-                       dropped = $.ui.ddmanager.drop(this, event);
-               }
-
-               //if a drop comes from outside (a sortable)
-               if(this.dropped) {
-                       dropped = this.dropped;
-                       this.dropped = false;
-               }
-
-               //if the original element is no longer in the DOM don't bother to continue (see #8269)
-               element = this.element[0];
-               while ( element && (element = element.parentNode) ) {
-                       if (element === document ) {
-                               elementInDom = true;
-                       }
-               }
-               if ( !elementInDom && this.options.helper === "original" ) {
-                       return false;
-               }
-
-               if((this.options.revert === "invalid" && !dropped) || (this.options.revert === "valid" && dropped) || this.options.revert === true || ($.isFunction(this.options.revert) && this.options.revert.call(this.element, dropped))) {
-                       $(this.helper).animate(this.originalPosition, parseInt(this.options.revertDuration, 10), function() {
-                               if(that._trigger("stop", event) !== false) {
-                                       that._clear();
-                               }
-                       });
-               } else {
-                       if(this._trigger("stop", event) !== false) {
-                               this._clear();
-                       }
-               }
-
-               return false;
-       },
-
-       _mouseUp: function(event) {
-               //Remove frame helpers
-               $("div.ui-draggable-iframeFix").each(function() {
-                       this.parentNode.removeChild(this);
-               });
-
-               //If the ddmanager is used for droppables, inform the manager that dragging has stopped (see #5003)
-               if( $.ui.ddmanager ) {
-                       $.ui.ddmanager.dragStop(this, event);
-               }
-
-               return $.ui.mouse.prototype._mouseUp.call(this, event);
-       },
-
-       cancel: function() {
-
-               if(this.helper.is(".ui-draggable-dragging")) {
-                       this._mouseUp({});
-               } else {
-                       this._clear();
-               }
-
-               return this;
-
-       },
-
-       _getHandle: function(event) {
-
-               var handle = !this.options.handle || !$(this.options.handle, this.element).length ? true : false;
-               $(this.options.handle, this.element)
-                       .find("*")
-                       .addBack()
-                       .each(function() {
-                               if(this === event.target) {
-                                       handle = true;
-                               }
-                       });
-
-               return handle;
-
-       },
-
-       _createHelper: function(event) {
-
-               var o = this.options,
-                       helper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[0], [event])) : (o.helper === "clone" ? this.element.clone().removeAttr("id") : this.element);
-
-               if(!helper.parents("body").length) {
-                       helper.appendTo((o.appendTo === "parent" ? this.element[0].parentNode : o.appendTo));
-               }
-
-               if(helper[0] !== this.element[0] && !(/(fixed|absolute)/).test(helper.css("position"))) {
-                       helper.css("position", "absolute");
-               }
-
-               return helper;
-
-       },
-
-       _adjustOffsetFromHelper: function(obj) {
-               if (typeof obj === "string") {
-                       obj = obj.split(" ");
-               }
-               if ($.isArray(obj)) {
-                       obj = {left: +obj[0], top: +obj[1] || 0};
-               }
-               if ("left" in obj) {
-                       this.offset.click.left = obj.left + this.margins.left;
-               }
-               if ("right" in obj) {
-                       this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
-               }
-               if ("top" in obj) {
-                       this.offset.click.top = obj.top + this.margins.top;
-               }
-               if ("bottom" in obj) {
-                       this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
-               }
-       },
-
-       _getParentOffset: function() {
-
-               //Get the offsetParent and cache its position
-               this.offsetParent = this.helper.offsetParent();
-               var po = this.offsetParent.offset();
-
-               // This is a special case where we need to modify a offset calculated on start, since the following happened:
-               // 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent
-               // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that
-               //    the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag
-               if(this.cssPosition === "absolute" && this.scrollParent[0] !== document && $.contains(this.scrollParent[0], this.offsetParent[0])) {
-                       po.left += this.scrollParent.scrollLeft();
-                       po.top += this.scrollParent.scrollTop();
-               }
-
-               //This needs to be actually done for all browsers, since pageX/pageY includes this information
-               //Ugly IE fix
-               if((this.offsetParent[0] === document.body) ||
-                       (this.offsetParent[0].tagName && this.offsetParent[0].tagName.toLowerCase() === "html" && $.ui.ie)) {
-                       po = { top: 0, left: 0 };
-               }
-
-               return {
-                       top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"),10) || 0),
-                       left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"),10) || 0)
-               };
-
-       },
-
-       _getRelativeOffset: function() {
-
-               if(this.cssPosition === "relative") {
-                       var p = this.element.position();
-                       return {
-                               top: p.top - (parseInt(this.helper.css("top"),10) || 0) + this.scrollParent.scrollTop(),
-                               left: p.left - (parseInt(this.helper.css("left"),10) || 0) + this.scrollParent.scrollLeft()
-                       };
-               } else {
-                       return { top: 0, left: 0 };
-               }
-
-       },
-
-       _cacheMargins: function() {
-               this.margins = {
-                       left: (parseInt(this.element.css("marginLeft"),10) || 0),
-                       top: (parseInt(this.element.css("marginTop"),10) || 0),
-                       right: (parseInt(this.element.css("marginRight"),10) || 0),
-                       bottom: (parseInt(this.element.css("marginBottom"),10) || 0)
-               };
-       },
-
-       _cacheHelperProportions: function() {
-               this.helperProportions = {
-                       width: this.helper.outerWidth(),
-                       height: this.helper.outerHeight()
-               };
-       },
-
-       _setContainment: function() {
-
-               var over, c, ce,
-                       o = this.options;
-
-               if(o.containment === "parent") {
-                       o.containment = this.helper[0].parentNode;
-               }
-               if(o.containment === "document" || o.containment === "window") {
-                       this.containment = [
-                               o.containment === "document" ? 0 : $(window).scrollLeft() - this.offset.relative.left - this.offset.parent.left,
-                               o.containment === "document" ? 0 : $(window).scrollTop() - this.offset.relative.top - this.offset.parent.top,
-                               (o.containment === "document" ? 0 : $(window).scrollLeft()) + $(o.containment === "document" ? document : window).width() - this.helperProportions.width - this.margins.left,
-                               (o.containment === "document" ? 0 : $(window).scrollTop()) + ($(o.containment === "document" ? document : window).height() || document.body.parentNode.scrollHeight) - this.helperProportions.height - this.margins.top
-                       ];
-               }
-
-               if(!(/^(document|window|parent)$/).test(o.containment) && o.containment.constructor !== Array) {
-                       c = $(o.containment);
-                       ce = c[0];
-
-                       if(!ce) {
-                               return;
-                       }
-
-                       over = ($(ce).css("overflow") !== "hidden");
-
-                       this.containment = [
-                               (parseInt($(ce).css("borderLeftWidth"),10) || 0) + (parseInt($(ce).css("paddingLeft"),10) || 0),
-                               (parseInt($(ce).css("borderTopWidth"),10) || 0) + (parseInt($(ce).css("paddingTop"),10) || 0),
-                               (over ? Math.max(ce.scrollWidth,ce.offsetWidth) : ce.offsetWidth) - (parseInt($(ce).css("borderLeftWidth"),10) || 0) - (parseInt($(ce).css("paddingRight"),10) || 0) - this.helperProportions.width - this.margins.left - this.margins.right,
-                               (over ? Math.max(ce.scrollHeight,ce.offsetHeight) : ce.offsetHeight) - (parseInt($(ce).css("borderTopWidth"),10) || 0) - (parseInt($(ce).css("paddingBottom"),10) || 0) - this.helperProportions.height - this.margins.top  - this.margins.bottom
-                       ];
-                       this.relative_container = c;
-
-               } else if(o.containment.constructor === Array) {
-                       this.containment = o.containment;
-               }
-
-       },
-
-       _convertPositionTo: function(d, pos) {
-
-               if(!pos) {
-                       pos = this.position;
-               }
-
-               var mod = d === "absolute" ? 1 : -1,
-                       scroll = this.cssPosition === "absolute" && !(this.scrollParent[0] !== document && $.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName);
-
-               return {
-                       top: (
-                               pos.top +                                                                                                                               // The absolute mouse position
-                               this.offset.relative.top * mod +                                                                                // Only for relative positioned nodes: Relative offset from element to offset parent
-                               this.offset.parent.top * mod -                                                                          // The offsetParent's offset without borders (offset + border)
-                               ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod)
-                       ),
-                       left: (
-                               pos.left +                                                                                                                              // The absolute mouse position
-                               this.offset.relative.left * mod +                                                                               // Only for relative positioned nodes: Relative offset from element to offset parent
-                               this.offset.parent.left * mod   -                                                                               // The offsetParent's offset without borders (offset + border)
-                               ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ) * mod)
-                       )
-               };
-
-       },
-
-       _generatePosition: function(event) {
-
-               var containment, co, top, left,
-                       o = this.options,
-                       scroll = this.cssPosition === "absolute" && !(this.scrollParent[0] !== document && $.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent,
-                       scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName),
-                       pageX = event.pageX,
-                       pageY = event.pageY;
-
-               /*
-                * - Position constraining -
-                * Constrain the position to a mix of grid, containment.
-                */
-
-               if(this.originalPosition) { //If we are not dragging yet, we won't check for options
-                       if(this.containment) {
-                       if (this.relative_container){
-                               co = this.relative_container.offset();
-                               containment = [ this.containment[0] + co.left,
-                                       this.containment[1] + co.top,
-                                       this.containment[2] + co.left,
-                                       this.containment[3] + co.top ];
-                       }
-                       else {
-                               containment = this.containment;
-                       }
-
-                               if(event.pageX - this.offset.click.left < containment[0]) {
-                                       pageX = containment[0] + this.offset.click.left;
-                               }
-                               if(event.pageY - this.offset.click.top < containment[1]) {
-                                       pageY = containment[1] + this.offset.click.top;
-                               }
-                               if(event.pageX - this.offset.click.left > containment[2]) {
-                                       pageX = containment[2] + this.offset.click.left;
-                               }
-                               if(event.pageY - this.offset.click.top > containment[3]) {
-                                       pageY = containment[3] + this.offset.click.top;
-                               }
-                       }
-
-                       if(o.grid) {
-                               //Check for grid elements set to 0 to prevent divide by 0 error causing invalid argument errors in IE (see ticket #6950)
-                               top = o.grid[1] ? this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1] : this.originalPageY;
-                               pageY = containment ? ((top - this.offset.click.top >= containment[1] || top - this.offset.click.top > containment[3]) ? top : ((top - this.offset.click.top >= containment[1]) ? top - o.grid[1] : top + o.grid[1])) : top;
-
-                               left = o.grid[0] ? this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0] : this.originalPageX;
-                               pageX = containment ? ((left - this.offset.click.left >= containment[0] || left - this.offset.click.left > containment[2]) ? left : ((left - this.offset.click.left >= containment[0]) ? left - o.grid[0] : left + o.grid[0])) : left;
-                       }
-
-               }
-
-               return {
-                       top: (
-                               pageY -                                                                                                                                 // The absolute mouse position
-                               this.offset.click.top   -                                                                                               // Click offset (relative to the element)
-                               this.offset.relative.top -                                                                                              // Only for relative positioned nodes: Relative offset from element to offset parent
-                               this.offset.parent.top +                                                                                                // The offsetParent's offset without borders (offset + border)
-                               ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ))
-                       ),
-                       left: (
-                               pageX -                                                                                                                                 // The absolute mouse position
-                               this.offset.click.left -                                                                                                // Click offset (relative to the element)
-                               this.offset.relative.left -                                                                                             // Only for relative positioned nodes: Relative offset from element to offset parent
-                               this.offset.parent.left +                                                                                               // The offsetParent's offset without borders (offset + border)
-                               ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ))
-                       )
-               };
-
-       },
-
-       _clear: function() {
-               this.helper.removeClass("ui-draggable-dragging");
-               if(this.helper[0] !== this.element[0] && !this.cancelHelperRemoval) {
-                       this.helper.remove();
-               }
-               this.helper = null;
-               this.cancelHelperRemoval = false;
-       },
-
-       // From now on bulk stuff - mainly helpers
-
-       _trigger: function(type, event, ui) {
-               ui = ui || this._uiHash();
-               $.ui.plugin.call(this, type, [event, ui]);
-               //The absolute position has to be recalculated after plugins
-               if(type === "drag") {
-                       this.positionAbs = this._convertPositionTo("absolute");
-               }
-               return $.Widget.prototype._trigger.call(this, type, event, ui);
-       },
-
-       plugins: {},
-
-       _uiHash: function() {
-               return {
-                       helper: this.helper,
-                       position: this.position,
-                       originalPosition: this.originalPosition,
-                       offset: this.positionAbs
-               };
-       }
-
-});
-
-$.ui.plugin.add("draggable", "connectToSortable", {
-       start: function(event, ui) {
-
-               var inst = $(this).data("ui-draggable"), o = inst.options,
-                       uiSortable = $.extend({}, ui, { item: inst.element });
-               inst.sortables = [];
-               $(o.connectToSortable).each(function() {
-                       var sortable = $.data(this, "ui-sortable");
-                       if (sortable && !sortable.options.disabled) {
-                               inst.sortables.push({
-                                       instance: sortable,
-                                       shouldRevert: sortable.options.revert
-                               });
-                               sortable.refreshPositions();    // Call the sortable's refreshPositions at drag start to refresh the containerCache since the sortable container cache is used in drag and needs to be up to date (this will ensure it's initialised as well as being kept in step with any changes that might have happened on the page).
-                               sortable._trigger("activate", event, uiSortable);
-                       }
-               });
-
-       },
-       stop: function(event, ui) {
-
-               //If we are still over the sortable, we fake the stop event of the sortable, but also remove helper
-               var inst = $(this).data("ui-draggable"),
-                       uiSortable = $.extend({}, ui, { item: inst.element });
-
-               $.each(inst.sortables, function() {
-                       if(this.instance.isOver) {
-
-                               this.instance.isOver = 0;
-
-                               inst.cancelHelperRemoval = true; //Don't remove the helper in the draggable instance
-                               this.instance.cancelHelperRemoval = false; //Remove it in the sortable instance (so sortable plugins like revert still work)
-
-                               //The sortable revert is supported, and we have to set a temporary dropped variable on the draggable to support revert: "valid/invalid"
-                               if(this.shouldRevert) {
-                                       this.instance.options.revert = true;
-                               }
-
-                               //Trigger the stop of the sortable
-                               this.instance._mouseStop(event);
-
-                               this.instance.options.helper = this.instance.options._helper;
-
-                               //If the helper has been the original item, restore properties in the sortable
-                               if(inst.options.helper === "original") {
-                                       this.instance.currentItem.css({ top: "auto", left: "auto" });
-                               }
-
-                       } else {
-                               this.instance.cancelHelperRemoval = false; //Remove the helper in the sortable instance
-                               this.instance._trigger("deactivate", event, uiSortable);
-                       }
-
-               });
-
-       },
-       drag: function(event, ui) {
-
-               var inst = $(this).data("ui-draggable"), that = this;
-
-               $.each(inst.sortables, function() {
-
-                       var innermostIntersecting = false,
-                               thisSortable = this;
-
-                       //Copy over some variables to allow calling the sortable's native _intersectsWith
-                       this.instance.positionAbs = inst.positionAbs;
-                       this.instance.helperProportions = inst.helperProportions;
-                       this.instance.offset.click = inst.offset.click;
-
-                       if(this.instance._intersectsWith(this.instance.containerCache)) {
-                               innermostIntersecting = true;
-                               $.each(inst.sortables, function () {
-                                       this.instance.positionAbs = inst.positionAbs;
-                                       this.instance.helperProportions = inst.helperProportions;
-                                       this.instance.offset.click = inst.offset.click;
-                                       if (this !== thisSortable &&
-                                               this.instance._intersectsWith(this.instance.containerCache) &&
-                                               $.ui.contains(thisSortable.instance.element[0], this.instance.element[0])
-                                       ) {
-                                               innermostIntersecting = false;
-                                       }
-                                       return innermostIntersecting;
-                               });
-                       }
-
-
-                       if(innermostIntersecting) {
-                               //If it intersects, we use a little isOver variable and set it once, so our move-in stuff gets fired only once
-                               if(!this.instance.isOver) {
-
-                                       this.instance.isOver = 1;
-                                       //Now we fake the start of dragging for the sortable instance,
-                                       //by cloning the list group item, appending it to the sortable and using it as inst.currentItem
-                                       //We can then fire the start event of the sortable with our passed browser event, and our own helper (so it doesn't create a new one)
-                                       this.instance.currentItem = $(that).clone().removeAttr("id").appendTo(this.instance.element).data("ui-sortable-item", true);
-                                       this.instance.options._helper = this.instance.options.helper; //Store helper option to later restore it
-                                       this.instance.options.helper = function() { return ui.helper[0]; };
-
-                                       event.target = this.instance.currentItem[0];
-                                       this.instance._mouseCapture(event, true);
-                                       this.instance._mouseStart(event, true, true);
-
-                                       //Because the browser event is way off the new appended portlet, we modify a couple of variables to reflect the changes
-                                       this.instance.offset.click.top = inst.offset.click.top;
-                                       this.instance.offset.click.left = inst.offset.click.left;
-                                       this.instance.offset.parent.left -= inst.offset.parent.left - this.instance.offset.parent.left;
-                                       this.instance.offset.parent.top -= inst.offset.parent.top - this.instance.offset.parent.top;
-
-                                       inst._trigger("toSortable", event);
-                                       inst.dropped = this.instance.element; //draggable revert needs that
-                                       //hack so receive/update callbacks work (mostly)
-                                       inst.currentItem = inst.element;
-                                       this.instance.fromOutside = inst;
-
-                               }
-
-                               //Provided we did all the previous steps, we can fire the drag event of the sortable on every draggable drag, when it intersects with the sortable
-                               if(this.instance.currentItem) {
-                                       this.instance._mouseDrag(event);
-                               }
-
-                       } else {
-
-                               //If it doesn't intersect with the sortable, and it intersected before,
-                               //we fake the drag stop of the sortable, but make sure it doesn't remove the helper by using cancelHelperRemoval
-                               if(this.instance.isOver) {
-
-                                       this.instance.isOver = 0;
-                                       this.instance.cancelHelperRemoval = true;
-
-                                       //Prevent reverting on this forced stop
-                                       this.instance.options.revert = false;
-
-                                       // The out event needs to be triggered independently
-                                       this.instance._trigger("out", event, this.instance._uiHash(this.instance));
-
-                                       this.instance._mouseStop(event, true);
-                                       this.instance.options.helper = this.instance.options._helper;
-
-                                       //Now we remove our currentItem, the list group clone again, and the placeholder, and animate the helper back to it's original size
-                                       this.instance.currentItem.remove();
-                                       if(this.instance.placeholder) {
-                                               this.instance.placeholder.remove();
-                                       }
-
-                                       inst._trigger("fromSortable", event);
-                                       inst.dropped = false; //draggable revert needs that
-                               }
-
-                       }
-
-               });
-
-       }
-});
-
-$.ui.plugin.add("draggable", "cursor", {
-       start: function() {
-               var t = $("body"), o = $(this).data("ui-draggable").options;
-               if (t.css("cursor")) {
-                       o._cursor = t.css("cursor");
-               }
-               t.css("cursor", o.cursor);
-       },
-       stop: function() {
-               var o = $(this).data("ui-draggable").options;
-               if (o._cursor) {
-                       $("body").css("cursor", o._cursor);
-               }
-       }
-});
-
-$.ui.plugin.add("draggable", "opacity", {
-       start: function(event, ui) {
-               var t = $(ui.helper), o = $(this).data("ui-draggable").options;
-               if(t.css("opacity")) {
-                       o._opacity = t.css("opacity");
-               }
-               t.css("opacity", o.opacity);
-       },
-       stop: function(event, ui) {
-               var o = $(this).data("ui-draggable").options;
-               if(o._opacity) {
-                       $(ui.helper).css("opacity", o._opacity);
-               }
-       }
-});
-
-$.ui.plugin.add("draggable", "scroll", {
-       start: function() {
-               var i = $(this).data("ui-draggable");
-               if(i.scrollParent[0] !== document && i.scrollParent[0].tagName !== "HTML") {
-                       i.overflowOffset = i.scrollParent.offset();
-               }
-       },
-       drag: function( event ) {
-
-               var i = $(this).data("ui-draggable"), o = i.options, scrolled = false;
-
-               if(i.scrollParent[0] !== document && i.scrollParent[0].tagName !== "HTML") {
-
-                       if(!o.axis || o.axis !== "x") {
-                               if((i.overflowOffset.top + i.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity) {
-                                       i.scrollParent[0].scrollTop = scrolled = i.scrollParent[0].scrollTop + o.scrollSpeed;
-                               } else if(event.pageY - i.overflowOffset.top < o.scrollSensitivity) {
-                                       i.scrollParent[0].scrollTop = scrolled = i.scrollParent[0].scrollTop - o.scrollSpeed;
-                               }
-                       }
-
-                       if(!o.axis || o.axis !== "y") {
-                               if((i.overflowOffset.left + i.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity) {
-                                       i.scrollParent[0].scrollLeft = scrolled = i.scrollParent[0].scrollLeft + o.scrollSpeed;
-                               } else if(event.pageX - i.overflowOffset.left < o.scrollSensitivity) {
-                                       i.scrollParent[0].scrollLeft = scrolled = i.scrollParent[0].scrollLeft - o.scrollSpeed;
-                               }
-                       }
-
-               } else {
-
-                       if(!o.axis || o.axis !== "x") {
-                               if(event.pageY - $(document).scrollTop() < o.scrollSensitivity) {
-                                       scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed);
-                               } else if($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity) {
-                                       scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed);
-                               }
-                       }
-
-                       if(!o.axis || o.axis !== "y") {
-                               if(event.pageX - $(document).scrollLeft() < o.scrollSensitivity) {
-                                       scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed);
-                               } else if($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity) {
-                                       scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed);
-                               }
-                       }
-
-               }
-
-               if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour) {
-                       $.ui.ddmanager.prepareOffsets(i, event);
-               }
-
-       }
-});
-
-$.ui.plugin.add("draggable", "snap", {
-       start: function() {
-
-               var i = $(this).data("ui-draggable"),
-                       o = i.options;
-
-               i.snapElements = [];
-
-               $(o.snap.constructor !== String ? ( o.snap.items || ":data(ui-draggable)" ) : o.snap).each(function() {
-                       var $t = $(this),
-                               $o = $t.offset();
-                       if(this !== i.element[0]) {
-                               i.snapElements.push({
-                                       item: this,
-                                       width: $t.outerWidth(), height: $t.outerHeight(),
-                                       top: $o.top, left: $o.left
-                               });
-                       }
-               });
-
-       },
-       drag: function(event, ui) {
-
-               var ts, bs, ls, rs, l, r, t, b, i, first,
-                       inst = $(this).data("ui-draggable"),
-                       o = inst.options,
-                       d = o.snapTolerance,
-                       x1 = ui.offset.left, x2 = x1 + inst.helperProportions.width,
-                       y1 = ui.offset.top, y2 = y1 + inst.helperProportions.height;
-
-               for (i = inst.snapElements.length - 1; i >= 0; i--){
-
-                       l = inst.snapElements[i].left;
-                       r = l + inst.snapElements[i].width;
-                       t = inst.snapElements[i].top;
-                       b = t + inst.snapElements[i].height;
-
-                       //Yes, I know, this is insane ;)
-                       if(!((l-d < x1 && x1 < r+d && t-d < y1 && y1 < b+d) || (l-d < x1 && x1 < r+d && t-d < y2 && y2 < b+d) || (l-d < x2 && x2 < r+d && t-d < y1 && y1 < b+d) || (l-d < x2 && x2 < r+d && t-d < y2 && y2 < b+d))) {
-                               if(inst.snapElements[i].snapping) {
-                                       (inst.options.snap.release && inst.options.snap.release.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item })));
-                               }
-                               inst.snapElements[i].snapping = false;
-                               continue;
-                       }
-
-                       if(o.snapMode !== "inner") {
-                               ts = Math.abs(t - y2) <= d;
-                               bs = Math.abs(b - y1) <= d;
-                               ls = Math.abs(l - x2) <= d;
-                               rs = Math.abs(r - x1) <= d;
-                               if(ts) {
-                                       ui.position.top = inst._convertPositionTo("relative", { top: t - inst.helperProportions.height, left: 0 }).top - inst.margins.top;
-                               }
-                               if(bs) {
-                                       ui.position.top = inst._convertPositionTo("relative", { top: b, left: 0 }).top - inst.margins.top;
-                               }
-                               if(ls) {
-                                       ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l - inst.helperProportions.width }).left - inst.margins.left;
-                               }
-                               if(rs) {
-                                       ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r }).left - inst.margins.left;
-                               }
-                       }
-
-                       first = (ts || bs || ls || rs);
-
-                       if(o.snapMode !== "outer") {
-                               ts = Math.abs(t - y1) <= d;
-                               bs = Math.abs(b - y2) <= d;
-                               ls = Math.abs(l - x1) <= d;
-                               rs = Math.abs(r - x2) <= d;
-                               if(ts) {
-                                       ui.position.top = inst._convertPositionTo("relative", { top: t, left: 0 }).top - inst.margins.top;
-                               }
-                               if(bs) {
-                                       ui.position.top = inst._convertPositionTo("relative", { top: b - inst.helperProportions.height, left: 0 }).top - inst.margins.top;
-                               }
-                               if(ls) {
-                                       ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l }).left - inst.margins.left;
-                               }
-                               if(rs) {
-                                       ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r - inst.helperProportions.width }).left - inst.margins.left;
-                               }
-                       }
-
-                       if(!inst.snapElements[i].snapping && (ts || bs || ls || rs || first)) {
-                               (inst.options.snap.snap && inst.options.snap.snap.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item })));
-                       }
-                       inst.snapElements[i].snapping = (ts || bs || ls || rs || first);
-
-               }
-
-       }
-});
-
-$.ui.plugin.add("draggable", "stack", {
-       start: function() {
-
-               var min,
-                       o = $(this).data("ui-draggable").options,
-                       group = $.makeArray($(o.stack)).sort(function(a,b) {
-                               return (parseInt($(a).css("zIndex"),10) || 0) - (parseInt($(b).css("zIndex"),10) || 0);
-                       });
-
-               if (!group.length) { return; }
-
-               min = parseInt(group[0].style.zIndex, 10) || 0;
-               $(group).each(function(i) {
-                       this.style.zIndex = min + i;
-               });
-
-               this[0].style.zIndex = min + group.length;
-
-       }
-});
-
-$.ui.plugin.add("draggable", "zIndex", {
-       start: function(event, ui) {
-               var t = $(ui.helper), o = $(this).data("ui-draggable").options;
-               if(t.css("zIndex")) {
-                       o._zIndex = t.css("zIndex");
-               }
-               t.css("zIndex", o.zIndex);
-       },
-       stop: function(event, ui) {
-               var o = $(this).data("ui-draggable").options;
-               if(o._zIndex) {
-                       $(ui.helper).css("zIndex", o._zIndex);
-               }
-       }
-});
-
-})(jQuery);
-(function( $, undefined ) {
-
-function isOverAxis( x, reference, size ) {
-       return ( x > reference ) && ( x < ( reference + size ) );
-}
-
-$.widget("ui.droppable", {
-       version: "1.10.0",
-       widgetEventPrefix: "drop",
-       options: {
-               accept: "*",
-               activeClass: false,
-               addClasses: true,
-               greedy: false,
-               hoverClass: false,
-               scope: "default",
-               tolerance: "intersect",
-
-               // callbacks
-               activate: null,
-               deactivate: null,
-               drop: null,
-               out: null,
-               over: null
-       },
-       _create: function() {
-
-               var o = this.options,
-                       accept = o.accept;
-
-               this.isover = false;
-               this.isout = true;
-
-               this.accept = $.isFunction(accept) ? accept : function(d) {
-                       return d.is(accept);
-               };
-
-               //Store the droppable's proportions
-               this.proportions = { width: this.element[0].offsetWidth, height: this.element[0].offsetHeight };
-
-               // Add the reference and positions to the manager
-               $.ui.ddmanager.droppables[o.scope] = $.ui.ddmanager.droppables[o.scope] || [];
-               $.ui.ddmanager.droppables[o.scope].push(this);
-
-               (o.addClasses && this.element.addClass("ui-droppable"));
-
-       },
-
-       _destroy: function() {
-               var i = 0,
-                       drop = $.ui.ddmanager.droppables[this.options.scope];
-
-               for ( ; i < drop.length; i++ ) {
-                       if ( drop[i] === this ) {
-                               drop.splice(i, 1);
-                       }
-               }
-
-               this.element.removeClass("ui-droppable ui-droppable-disabled");
-       },
-
-       _setOption: function(key, value) {
-
-               if(key === "accept") {
-                       this.accept = $.isFunction(value) ? value : function(d) {
-                               return d.is(value);
-                       };
-               }
-               $.Widget.prototype._setOption.apply(this, arguments);
-       },
-
-       _activate: function(event) {
-               var draggable = $.ui.ddmanager.current;
-               if(this.options.activeClass) {
-                       this.element.addClass(this.options.activeClass);
-               }
-               if(draggable){
-                       this._trigger("activate", event, this.ui(draggable));
-               }
-       },
-
-       _deactivate: function(event) {
-               var draggable = $.ui.ddmanager.current;
-               if(this.options.activeClass) {
-                       this.element.removeClass(this.options.activeClass);
-               }
-               if(draggable){
-                       this._trigger("deactivate", event, this.ui(draggable));
-               }
-       },
-
-       _over: function(event) {
-
-               var draggable = $.ui.ddmanager.current;
-
-               // Bail if draggable and droppable are same element
-               if (!draggable || (draggable.currentItem || draggable.element)[0] === this.element[0]) {
-                       return;
-               }
-
-               if (this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
-                       if(this.options.hoverClass) {
-                               this.element.addClass(this.options.hoverClass);
-                       }
-                       this._trigger("over", event, this.ui(draggable));
-               }
-
-       },
-
-       _out: function(event) {
-
-               var draggable = $.ui.ddmanager.current;
-
-               // Bail if draggable and droppable are same element
-               if (!draggable || (draggable.currentItem || draggable.element)[0] === this.element[0]) {
-                       return;
-               }
-
-               if (this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
-                       if(this.options.hoverClass) {
-                               this.element.removeClass(this.options.hoverClass);
-                       }
-                       this._trigger("out", event, this.ui(draggable));
-               }
-
-       },
-
-       _drop: function(event,custom) {
-
-               var draggable = custom || $.ui.ddmanager.current,
-                       childrenIntersection = false;
-
-               // Bail if draggable and droppable are same element
-               if (!draggable || (draggable.currentItem || draggable.element)[0] === this.element[0]) {
-                       return false;
-               }
-
-               this.element.find(":data(ui-droppable)").not(".ui-draggable-dragging").each(function() {
-                       var inst = $.data(this, "ui-droppable");
-                       if(
-                               inst.options.greedy &&
-                               !inst.options.disabled &&
-                               inst.options.scope === draggable.options.scope &&
-                               inst.accept.call(inst.element[0], (draggable.currentItem || draggable.element)) &&
-                               $.ui.intersect(draggable, $.extend(inst, { offset: inst.element.offset() }), inst.options.tolerance)
-                       ) { childrenIntersection = true; return false; }
-               });
-               if(childrenIntersection) {
-                       return false;
-               }
-
-               if(this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
-                       if(this.options.activeClass) {
-                               this.element.removeClass(this.options.activeClass);
-                       }
-                       if(this.options.hoverClass) {
-                               this.element.removeClass(this.options.hoverClass);
-                       }
-                       this._trigger("drop", event, this.ui(draggable));
-                       return this.element;
-               }
-
-               return false;
-
-       },
-
-       ui: function(c) {
-               return {
-                       draggable: (c.currentItem || c.element),
-                       helper: c.helper,
-                       position: c.position,
-                       offset: c.positionAbs
-               };
-       }
-
-});
-
-$.ui.intersect = function(draggable, droppable, toleranceMode) {
-
-       if (!droppable.offset) {
-               return false;
-       }
-
-       var draggableLeft, draggableTop,
-               x1 = (draggable.positionAbs || draggable.position.absolute).left, x2 = x1 + draggable.helperProportions.width,
-               y1 = (draggable.positionAbs || draggable.position.absolute).top, y2 = y1 + draggable.helperProportions.height,
-               l = droppable.offset.left, r = l + droppable.proportions.width,
-               t = droppable.offset.top, b = t + droppable.proportions.height;
-
-       switch (toleranceMode) {
-               case "fit":
-                       return (l <= x1 && x2 <= r && t <= y1 && y2 <= b);
-               case "intersect":
-                       return (l < x1 + (draggable.helperProportions.width / 2) && // Right Half
-                               x2 - (draggable.helperProportions.width / 2) < r && // Left Half
-                               t < y1 + (draggable.helperProportions.height / 2) && // Bottom Half
-                               y2 - (draggable.helperProportions.height / 2) < b ); // Top Half
-               case "pointer":
-                       draggableLeft = ((draggable.positionAbs || draggable.position.absolute).left + (draggable.clickOffset || draggable.offset.click).left);
-                       draggableTop = ((draggable.positionAbs || draggable.position.absolute).top + (draggable.clickOffset || draggable.offset.click).top);
-                       return isOverAxis( draggableTop, t, droppable.proportions.height ) && isOverAxis( draggableLeft, l, droppable.proportions.width );
-               case "touch":
-                       return (
-                               (y1 >= t && y1 <= b) || // Top edge touching
-                               (y2 >= t && y2 <= b) || // Bottom edge touching
-                               (y1 < t && y2 > b)              // Surrounded vertically
-                       ) && (
-                               (x1 >= l && x1 <= r) || // Left edge touching
-                               (x2 >= l && x2 <= r) || // Right edge touching
-                               (x1 < l && x2 > r)              // Surrounded horizontally
-                       );
-               default:
-                       return false;
-               }
-
-};
-
-/*
-       This manager tracks offsets of draggables and droppables
-*/
-$.ui.ddmanager = {
-       current: null,
-       droppables: { "default": [] },
-       prepareOffsets: function(t, event) {
-
-               var i, j,
-                       m = $.ui.ddmanager.droppables[t.options.scope] || [],
-                       type = event ? event.type : null, // workaround for #2317
-                       list = (t.currentItem || t.element).find(":data(ui-droppable)").addBack();
-
-               droppablesLoop: for (i = 0; i < m.length; i++) {
-
-                       //No disabled and non-accepted
-                       if(m[i].options.disabled || (t && !m[i].accept.call(m[i].element[0],(t.currentItem || t.element)))) {
-                               continue;
-                       }
-
-                       // Filter out elements in the current dragged item
-                       for (j=0; j < list.length; j++) {
-                               if(list[j] === m[i].element[0]) {
-                                       m[i].proportions.height = 0;
-                                       continue droppablesLoop;
-                               }
-                       }
-
-                       m[i].visible = m[i].element.css("display") !== "none";
-                       if(!m[i].visible) {
-                               continue;
-                       }
-
-                       //Activate the droppable if used directly from draggables
-                       if(type === "mousedown") {
-                               m[i]._activate.call(m[i], event);
-                       }
-
-                       m[i].offset = m[i].element.offset();
-                       m[i].proportions = { width: m[i].element[0].offsetWidth, height: m[i].element[0].offsetHeight };
-
-               }
-
-       },
-       drop: function(draggable, event) {
-
-               var dropped = false;
-               $.each($.ui.ddmanager.droppables[draggable.options.scope] || [], function() {
-
-                       if(!this.options) {
-                               return;
-                       }
-                       if (!this.options.disabled && this.visible && $.ui.intersect(draggable, this, this.options.tolerance)) {
-                               dropped = this._drop.call(this, event) || dropped;
-                       }
-
-                       if (!this.options.disabled && this.visible && this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
-                               this.isout = true;
-                               this.isover = false;
-                               this._deactivate.call(this, event);
-                       }
-
-               });
-               return dropped;
-
-       },
-       dragStart: function( draggable, event ) {
-               //Listen for scrolling so that if the dragging causes scrolling the position of the droppables can be recalculated (see #5003)
-               draggable.element.parentsUntil( "body" ).bind( "scroll.droppable", function() {
-                       if( !draggable.options.refreshPositions ) {
-                               $.ui.ddmanager.prepareOffsets( draggable, event );
-                       }
-               });
-       },
-       drag: function(draggable, event) {
-
-               //If you have a highly dynamic page, you might try this option. It renders positions every time you move the mouse.
-               if(draggable.options.refreshPositions) {
-                       $.ui.ddmanager.prepareOffsets(draggable, event);
-               }
-
-               //Run through all droppables and check their positions based on specific tolerance options
-               $.each($.ui.ddmanager.droppables[draggable.options.scope] || [], function() {
-
-                       if(this.options.disabled || this.greedyChild || !this.visible) {
-                               return;
-                       }
-
-                       var parentInstance, scope, parent,
-                               intersects = $.ui.intersect(draggable, this, this.options.tolerance),
-                               c = !intersects && this.isover ? "isout" : (intersects && !this.isover ? "isover" : null);
-                       if(!c) {
-                               return;
-                       }
-
-                       if (this.options.greedy) {
-                               // find droppable parents with same scope
-                               scope = this.options.scope;
-                               parent = this.element.parents(":data(ui-droppable)").filter(function () {
-                                       return $.data(this, "ui-droppable").options.scope === scope;
-                               });
-
-                               if (parent.length) {
-                                       parentInstance = $.data(parent[0], "ui-droppable");
-                                       parentInstance.greedyChild = (c === "isover");
-                               }
-                       }
-
-                       // we just moved into a greedy child
-                       if (parentInstance && c === "isover") {
-                               parentInstance.isover = false;
-                               parentInstance.isout = true;
-                               parentInstance._out.call(parentInstance, event);
-                       }
-
-                       this[c] = true;
-                       this[c === "isout" ? "isover" : "isout"] = false;
-                       this[c === "isover" ? "_over" : "_out"].call(this, event);
-
-                       // we just moved out of a greedy child
-                       if (parentInstance && c === "isout") {
-                               parentInstance.isout = false;
-                               parentInstance.isover = true;
-                               parentInstance._over.call(parentInstance, event);
-                       }
-               });
-
-       },
-       dragStop: function( draggable, event ) {
-               draggable.element.parentsUntil( "body" ).unbind( "scroll.droppable" );
-               //Call prepareOffsets one final time since IE does not fire return scroll events when overflow was caused by drag (see #5003)
-               if( !draggable.options.refreshPositions ) {
-                       $.ui.ddmanager.prepareOffsets( draggable, event );
-               }
-       }
-};
-
-})(jQuery);
-(function( $, undefined ) {
-
-$.widget("ui.selectable", $.ui.mouse, {
-       version: "1.10.0",
-       options: {
-               appendTo: "body",
-               autoRefresh: true,
-               distance: 0,
-               filter: "*",
-               tolerance: "touch",
-
-               // callbacks
-               selected: null,
-               selecting: null,
-               start: null,
-               stop: null,
-               unselected: null,
-               unselecting: null
-       },
-       _create: function() {
-               var selectees,
-                       that = this;
-
-               this.element.addClass("ui-selectable");
-
-               this.dragged = false;
-
-               // cache selectee children based on filter
-               this.refresh = function() {
-                       selectees = $(that.options.filter, that.element[0]);
-                       selectees.addClass("ui-selectee");
-                       selectees.each(function() {
-                               var $this = $(this),
-                                       pos = $this.offset();
-                               $.data(this, "selectable-item", {
-                                       element: this,
-                                       $element: $this,
-                                       left: pos.left,
-                                       top: pos.top,
-                                       right: pos.left + $this.outerWidth(),
-                                       bottom: pos.top + $this.outerHeight(),
-                                       startselected: false,
-                                       selected: $this.hasClass("ui-selected"),
-                                       selecting: $this.hasClass("ui-selecting"),
-                                       unselecting: $this.hasClass("ui-unselecting")
-                               });
-                       });
-               };
-               this.refresh();
-
-               this.selectees = selectees.addClass("ui-selectee");
-
-               this._mouseInit();
-
-               this.helper = $("<div class='ui-selectable-helper'></div>");
-       },
-
-       _destroy: function() {
-               this.selectees
-                       .removeClass("ui-selectee")
-                       .removeData("selectable-item");
-               this.element
-                       .removeClass("ui-selectable ui-selectable-disabled");
-               this._mouseDestroy();
-       },
-
-       _mouseStart: function(event) {
-               var that = this,
-                       options = this.options;
-
-               this.opos = [event.pageX, event.pageY];
-
-               if (this.options.disabled) {
-                       return;
-               }
-
-               this.selectees = $(options.filter, this.element[0]);
-
-               this._trigger("start", event);
-
-               $(options.appendTo).append(this.helper);
-               // position helper (lasso)
-               this.helper.css({
-                       "left": event.pageX,
-                       "top": event.pageY,
-                       "width": 0,
-                       "height": 0
-               });
-
-               if (options.autoRefresh) {
-                       this.refresh();
-               }
-
-               this.selectees.filter(".ui-selected").each(function() {
-                       var selectee = $.data(this, "selectable-item");
-                       selectee.startselected = true;
-                       if (!event.metaKey && !event.ctrlKey) {
-                               selectee.$element.removeClass("ui-selected");
-                               selectee.selected = false;
-                               selectee.$element.addClass("ui-unselecting");
-                               selectee.unselecting = true;
-                               // selectable UNSELECTING callback
-                               that._trigger("unselecting", event, {
-                                       unselecting: selectee.element
-                               });
-                       }
-               });
-
-               $(event.target).parents().addBack().each(function() {
-                       var doSelect,
-                               selectee = $.data(this, "selectable-item");
-                       if (selectee) {
-                               doSelect = (!event.metaKey && !event.ctrlKey) || !selectee.$element.hasClass("ui-selected");
-                               selectee.$element
-                                       .removeClass(doSelect ? "ui-unselecting" : "ui-selected")
-                                       .addClass(doSelect ? "ui-selecting" : "ui-unselecting");
-                               selectee.unselecting = !doSelect;
-                               selectee.selecting = doSelect;
-                               selectee.selected = doSelect;
-                               // selectable (UN)SELECTING callback
-                               if (doSelect) {
-                                       that._trigger("selecting", event, {
-                                               selecting: selectee.element
-                                       });
-                               } else {
-                                       that._trigger("unselecting", event, {
-                                               unselecting: selectee.element
-                                       });
-                               }
-                               return false;
-                       }
-               });
-
-       },
-
-       _mouseDrag: function(event) {
-
-               this.dragged = true;
-
-               if (this.options.disabled) {
-                       return;
-               }
-
-               var tmp,
-                       that = this,
-                       options = this.options,
-                       x1 = this.opos[0],
-                       y1 = this.opos[1],
-                       x2 = event.pageX,
-                       y2 = event.pageY;
-
-               if (x1 > x2) { tmp = x2; x2 = x1; x1 = tmp; }
-               if (y1 > y2) { tmp = y2; y2 = y1; y1 = tmp; }
-               this.helper.css({left: x1, top: y1, width: x2-x1, height: y2-y1});
-
-               this.selectees.each(function() {
-                       var selectee = $.data(this, "selectable-item"),
-                               hit = false;
-
-                       //prevent helper from being selected if appendTo: selectable
-                       if (!selectee || selectee.element === that.element[0]) {
-                               return;
-                       }
-
-                       if (options.tolerance === "touch") {
-                               hit = ( !(selectee.left > x2 || selectee.right < x1 || selectee.top > y2 || selectee.bottom < y1) );
-                       } else if (options.tolerance === "fit") {
-                               hit = (selectee.left > x1 && selectee.right < x2 && selectee.top > y1 && selectee.bottom < y2);
-                       }
-
-                       if (hit) {
-                               // SELECT
-                               if (selectee.selected) {
-                                       selectee.$element.removeClass("ui-selected");
-                                       selectee.selected = false;
-                               }
-                               if (selectee.unselecting) {
-                                       selectee.$element.removeClass("ui-unselecting");
-                                       selectee.unselecting = false;
-                               }
-                               if (!selectee.selecting) {
-                                       selectee.$element.addClass("ui-selecting");
-                                       selectee.selecting = true;
-                                       // selectable SELECTING callback
-                                       that._trigger("selecting", event, {
-                                               selecting: selectee.element
-                                       });
-                               }
-                       } else {
-                               // UNSELECT
-                               if (selectee.selecting) {
-                                       if ((event.metaKey || event.ctrlKey) && selectee.startselected) {
-                                               selectee.$element.removeClass("ui-selecting");
-                                               selectee.selecting = false;
-                                               selectee.$element.addClass("ui-selected");
-                                               selectee.selected = true;
-                                       } else {
-                                               selectee.$element.removeClass("ui-selecting");
-                                               selectee.selecting = false;
-                                               if (selectee.startselected) {
-                                                       selectee.$element.addClass("ui-unselecting");
-                                                       selectee.unselecting = true;
-                                               }
-                                               // selectable UNSELECTING callback
-                                               that._trigger("unselecting", event, {
-                                                       unselecting: selectee.element
-                                               });
-                                       }
-                               }
-                               if (selectee.selected) {
-                                       if (!event.metaKey && !event.ctrlKey && !selectee.startselected) {
-                                               selectee.$element.removeClass("ui-selected");
-                                               selectee.selected = false;
-
-                                               selectee.$element.addClass("ui-unselecting");
-                                               selectee.unselecting = true;
-                                               // selectable UNSELECTING callback
-                                               that._trigger("unselecting", event, {
-                                                       unselecting: selectee.element
-                                               });
-                                       }
-                               }
-                       }
-               });
-
-               return false;
-       },
-
-       _mouseStop: function(event) {
-               var that = this;
-
-               this.dragged = false;
-
-               $(".ui-unselecting", this.element[0]).each(function() {
-                       var selectee = $.data(this, "selectable-item");
-                       selectee.$element.removeClass("ui-unselecting");
-                       selectee.unselecting = false;
-                       selectee.startselected = false;
-                       that._trigger("unselected", event, {
-                               unselected: selectee.element
-                       });
-               });
-               $(".ui-selecting", this.element[0]).each(function() {
-                       var selectee = $.data(this, "selectable-item");
-                       selectee.$element.removeClass("ui-selecting").addClass("ui-selected");
-                       selectee.selecting = false;
-                       selectee.selected = true;
-                       selectee.startselected = true;
-                       that._trigger("selected", event, {
-                               selected: selectee.element
-                       });
-               });
-               this._trigger("stop", event);
-
-               this.helper.remove();
-
-               return false;
-       }
-
-});
-
-})(jQuery);
-(function( $, undefined ) {
-
-/*jshint loopfunc: true */
-
-function isOverAxis( x, reference, size ) {
-       return ( x > reference ) && ( x < ( reference + size ) );
-}
-
-$.widget("ui.sortable", $.ui.mouse, {
-       version: "1.10.0",
-       widgetEventPrefix: "sort",
-       ready: false,
-       options: {
-               appendTo: "parent",
-               axis: false,
-               connectWith: false,
-               containment: false,
-               cursor: "auto",
-               cursorAt: false,
-               dropOnEmpty: true,
-               forcePlaceholderSize: false,
-               forceHelperSize: false,
-               grid: false,
-               handle: false,
-               helper: "original",
-               items: "> *",
-               opacity: false,
-               placeholder: false,
-               revert: false,
-               scroll: true,
-               scrollSensitivity: 20,
-               scrollSpeed: 20,
-               scope: "default",
-               tolerance: "intersect",
-               zIndex: 1000,
-
-               // callbacks
-               activate: null,
-               beforeStop: null,
-               change: null,
-               deactivate: null,
-               out: null,
-               over: null,
-               receive: null,
-               remove: null,
-               sort: null,
-               start: null,
-               stop: null,
-               update: null
-       },
-       _create: function() {
-
-               var o = this.options;
-               this.containerCache = {};
-               this.element.addClass("ui-sortable");
-
-               //Get the items
-               this.refresh();
-
-               //Let's determine if the items are being displayed horizontally
-               this.floating = this.items.length ? o.axis === "x" || (/left|right/).test(this.items[0].item.css("float")) || (/inline|table-cell/).test(this.items[0].item.css("display")) : false;
-
-               //Let's determine the parent's offset
-               this.offset = this.element.offset();
-
-               //Initialize mouse events for interaction
-               this._mouseInit();
-
-               //We're ready to go
-               this.ready = true;
-
-       },
-
-       _destroy: function() {
-               this.element
-                       .removeClass("ui-sortable ui-sortable-disabled");
-               this._mouseDestroy();
-
-               for ( var i = this.items.length - 1; i >= 0; i-- ) {
-                       this.items[i].item.removeData(this.widgetName + "-item");
-               }
-
-               return this;
-       },
-
-       _setOption: function(key, value){
-               if ( key === "disabled" ) {
-                       this.options[ key ] = value;
-
-                       this.widget().toggleClass( "ui-sortable-disabled", !!value );
-               } else {
-                       // Don't call widget base _setOption for disable as it adds ui-state-disabled class
-                       $.Widget.prototype._setOption.apply(this, arguments);
-               }
-       },
-
-       _mouseCapture: function(event, overrideHandle) {
-               var currentItem = null,
-                       validHandle = false,
-                       that = this;
-
-               if (this.reverting) {
-                       return false;
-               }
-
-               if(this.options.disabled || this.options.type === "static") {
-                       return false;
-               }
-
-               //We have to refresh the items data once first
-               this._refreshItems(event);
-
-               //Find out if the clicked node (or one of its parents) is a actual item in this.items
-               $(event.target).parents().each(function() {
-                       if($.data(this, that.widgetName + "-item") === that) {
-                               currentItem = $(this);
-                               return false;
-                       }
-               });
-               if($.data(event.target, that.widgetName + "-item") === that) {
-                       currentItem = $(event.target);
-               }
-
-               if(!currentItem) {
-                       return false;
-               }
-               if(this.options.handle && !overrideHandle) {
-                       $(this.options.handle, currentItem).find("*").addBack().each(function() {
-                               if(this === event.target) {
-                                       validHandle = true;
-                               }
-                       });
-                       if(!validHandle) {
-                               return false;
-                       }
-               }
-
-               this.currentItem = currentItem;
-               this._removeCurrentsFromItems();
-               return true;
-
-       },
-
-       _mouseStart: function(event, overrideHandle, noActivation) {
-
-               var i,
-                       o = this.options;
-
-               this.currentContainer = this;
-
-               //We only need to call refreshPositions, because the refreshItems call has been moved to mouseCapture
-               this.refreshPositions();
-
-               //Create and append the visible helper
-               this.helper = this._createHelper(event);
-
-               //Cache the helper size
-               this._cacheHelperProportions();
-
-               /*
-                * - Position generation -
-                * This block generates everything position related - it's the core of draggables.
-                */
-
-               //Cache the margins of the original element
-               this._cacheMargins();
-
-               //Get the next scrolling parent
-               this.scrollParent = this.helper.scrollParent();
-
-               //The element's absolute position on the page minus margins
-               this.offset = this.currentItem.offset();
-               this.offset = {
-                       top: this.offset.top - this.margins.top,
-                       left: this.offset.left - this.margins.left
-               };
-
-               $.extend(this.offset, {
-                       click: { //Where the click happened, relative to the element
-                               left: event.pageX - this.offset.left,
-                               top: event.pageY - this.offset.top
-                       },
-                       parent: this._getParentOffset(),
-                       relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper
-               });
-
-               // Only after we got the offset, we can change the helper's position to absolute
-               // TODO: Still need to figure out a way to make relative sorting possible
-               this.helper.css("position", "absolute");
-               this.cssPosition = this.helper.css("position");
-
-               //Generate the original position
-               this.originalPosition = this._generatePosition(event);
-               this.originalPageX = event.pageX;
-               this.originalPageY = event.pageY;
-
-               //Adjust the mouse offset relative to the helper if "cursorAt" is supplied
-               (o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt));
-
-               //Cache the former DOM position
-               this.domPosition = { prev: this.currentItem.prev()[0], parent: this.currentItem.parent()[0] };
-
-               //If the helper is not the original, hide the original so it's not playing any role during the drag, won't cause anything bad this way
-               if(this.helper[0] !== this.currentItem[0]) {
-                       this.currentItem.hide();
-               }
-
-               //Create the placeholder
-               this._createPlaceholder();
-
-               //Set a containment if given in the options
-               if(o.containment) {
-                       this._setContainment();
-               }
-
-               if(o.cursor) { // cursor option
-                       if ($("body").css("cursor")) {
-                               this._storedCursor = $("body").css("cursor");
-                       }
-                       $("body").css("cursor", o.cursor);
-               }
-
-               if(o.opacity) { // opacity option
-                       if (this.helper.css("opacity")) {
-                               this._storedOpacity = this.helper.css("opacity");
-                       }
-                       this.helper.css("opacity", o.opacity);
-               }
-
-               if(o.zIndex) { // zIndex option
-                       if (this.helper.css("zIndex")) {
-                               this._storedZIndex = this.helper.css("zIndex");
-                       }
-                       this.helper.css("zIndex", o.zIndex);
-               }
-
-               //Prepare scrolling
-               if(this.scrollParent[0] !== document && this.scrollParent[0].tagName !== "HTML") {
-                       this.overflowOffset = this.scrollParent.offset();
-               }
-
-               //Call callbacks
-               this._trigger("start", event, this._uiHash());
-
-               //Recache the helper size
-               if(!this._preserveHelperProportions) {
-                       this._cacheHelperProportions();
-               }
-
-
-               //Post "activate" events to possible containers
-               if( !noActivation ) {
-                       for ( i = this.containers.length - 1; i >= 0; i-- ) {
-                               this.containers[ i ]._trigger( "activate", event, this._uiHash( this ) );
-                       }
-               }
-
-               //Prepare possible droppables
-               if($.ui.ddmanager) {
-                       $.ui.ddmanager.current = this;
-               }
-
-               if ($.ui.ddmanager && !o.dropBehaviour) {
-                       $.ui.ddmanager.prepareOffsets(this, event);
-               }
-
-               this.dragging = true;
-
-               this.helper.addClass("ui-sortable-helper");
-               this._mouseDrag(event); //Execute the drag once - this causes the helper not to be visible before getting its correct position
-               return true;
-
-       },
-
-       _mouseDrag: function(event) {
-               var i, item, itemElement, intersection,
-                       o = this.options,
-                       scrolled = false;
-
-               //Compute the helpers position
-               this.position = this._generatePosition(event);
-               this.positionAbs = this._convertPositionTo("absolute");
-
-               if (!this.lastPositionAbs) {
-                       this.lastPositionAbs = this.positionAbs;
-               }
-
-               //Do scrolling
-               if(this.options.scroll) {
-                       if(this.scrollParent[0] !== document && this.scrollParent[0].tagName !== "HTML") {
-
-                               if((this.overflowOffset.top + this.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity) {
-                                       this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop + o.scrollSpeed;
-                               } else if(event.pageY - this.overflowOffset.top < o.scrollSensitivity) {
-                                       this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop - o.scrollSpeed;
-                               }
-
-                               if((this.overflowOffset.left + this.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity) {
-                                       this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft + o.scrollSpeed;
-                               } else if(event.pageX - this.overflowOffset.left < o.scrollSensitivity) {
-                                       this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft - o.scrollSpeed;
-                               }
-
-                       } else {
-
-                               if(event.pageY - $(document).scrollTop() < o.scrollSensitivity) {
-                                       scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed);
-                               } else if($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity) {
-                                       scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed);
-                               }
-
-                               if(event.pageX - $(document).scrollLeft() < o.scrollSensitivity) {
-                                       scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed);
-                               } else if($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity) {
-                                       scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed);
-                               }
-
-                       }
-
-                       if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour) {
-                               $.ui.ddmanager.prepareOffsets(this, event);
-                       }
-               }
-
-               //Regenerate the absolute position used for position checks
-               this.positionAbs = this._convertPositionTo("absolute");
-
-               //Set the helper position
-               if(!this.options.axis || this.options.axis !== "y") {
-                       this.helper[0].style.left = this.position.left+"px";
-               }
-               if(!this.options.axis || this.options.axis !== "x") {
-                       this.helper[0].style.top = this.position.top+"px";
-               }
-
-               //Rearrange
-               for (i = this.items.length - 1; i >= 0; i--) {
-
-                       //Cache variables and intersection, continue if no intersection
-                       item = this.items[i];
-                       itemElement = item.item[0];
-                       intersection = this._intersectsWithPointer(item);
-                       if (!intersection) {
-                               continue;
-                       }
-
-                       // Only put the placeholder inside the current Container, skip all
-                       // items form other containers. This works because when moving
-                       // an item from one container to another the
-                       // currentContainer is switched before the placeholder is moved.
-                       //
-                       // Without this moving items in "sub-sortables" can cause the placeholder to jitter
-                       // beetween the outer and inner container.
-                       if (item.instance !== this.currentContainer) {
-                               continue;
-                       }
-
-                       // cannot intersect with itself
-                       // no useless actions that have been done before
-                       // no action if the item moved is the parent of the item checked
-                       if (itemElement !== this.currentItem[0] &&
-                               this.placeholder[intersection === 1 ? "next" : "prev"]()[0] !== itemElement &&
-                               !$.contains(this.placeholder[0], itemElement) &&
-                               (this.options.type === "semi-dynamic" ? !$.contains(this.element[0], itemElement) : true)
-                       ) {
-
-                               this.direction = intersection === 1 ? "down" : "up";
-
-                               if (this.options.tolerance === "pointer" || this._intersectsWithSides(item)) {
-                                       this._rearrange(event, item);
-                               } else {
-                                       break;
-                               }
-
-                               this._trigger("change", event, this._uiHash());
-                               break;
-                       }
-               }
-
-               //Post events to containers
-               this._contactContainers(event);
-
-               //Interconnect with droppables
-               if($.ui.ddmanager) {
-                       $.ui.ddmanager.drag(this, event);
-               }
-
-               //Call callbacks
-               this._trigger("sort", event, this._uiHash());
-
-               this.lastPositionAbs = this.positionAbs;
-               return false;
-
-       },
-
-       _mouseStop: function(event, noPropagation) {
-
-               if(!event) {
-                       return;
-               }
-
-               //If we are using droppables, inform the manager about the drop
-               if ($.ui.ddmanager && !this.options.dropBehaviour) {
-                       $.ui.ddmanager.drop(this, event);
-               }
-
-               if(this.options.revert) {
-                       var that = this,
-                               cur = this.placeholder.offset();
-
-                       this.reverting = true;
-
-                       $(this.helper).animate({
-                               left: cur.left - this.offset.parent.left - this.margins.left + (this.offsetParent[0] === document.body ? 0 : this.offsetParent[0].scrollLeft),
-                               top: cur.top - this.offset.parent.top - this.margins.top + (this.offsetParent[0] === document.body ? 0 : this.offsetParent[0].scrollTop)
-                       }, parseInt(this.options.revert, 10) || 500, function() {
-                               that._clear(event);
-                       });
-               } else {
-                       this._clear(event, noPropagation);
-               }
-
-               return false;
-
-       },
-
-       cancel: function() {
-
-               if(this.dragging) {
-
-                       this._mouseUp({ target: null });
-
-                       if(this.options.helper === "original") {
-                               this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper");
-                       } else {
-                               this.currentItem.show();
-                       }
-
-                       //Post deactivating events to containers
-                       for (var i = this.containers.length - 1; i >= 0; i--){
-                               this.containers[i]._trigger("deactivate", null, this._uiHash(this));
-                               if(this.containers[i].containerCache.over) {
-                                       this.containers[i]._trigger("out", null, this._uiHash(this));
-                                       this.containers[i].containerCache.over = 0;
-                               }
-                       }
-
-               }
-
-               if (this.placeholder) {
-                       //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node!
-                       if(this.placeholder[0].parentNode) {
-                               this.placeholder[0].parentNode.removeChild(this.placeholder[0]);
-                       }
-                       if(this.options.helper !== "original" && this.helper && this.helper[0].parentNode) {
-                               this.helper.remove();
-                       }
-
-                       $.extend(this, {
-                               helper: null,
-                               dragging: false,
-                               reverting: false,
-                               _noFinalSort: null
-                       });
-
-                       if(this.domPosition.prev) {
-                               $(this.domPosition.prev).after(this.currentItem);
-                       } else {
-                               $(this.domPosition.parent).prepend(this.currentItem);
-                       }
-               }
-
-               return this;
-
-       },
-
-       serialize: function(o) {
-
-               var items = this._getItemsAsjQuery(o && o.connected),
-                       str = [];
-               o = o || {};
-
-               $(items).each(function() {
-                       var res = ($(o.item || this).attr(o.attribute || "id") || "").match(o.expression || (/(.+)[\-=_](.+)/));
-                       if (res) {
-                               str.push((o.key || res[1]+"[]")+"="+(o.key && o.expression ? res[1] : res[2]));
-                       }
-               });
-
-               if(!str.length && o.key) {
-                       str.push(o.key + "=");
-               }
-
-               return str.join("&");
-
-       },
-
-       toArray: function(o) {
-
-               var items = this._getItemsAsjQuery(o && o.connected),
-                       ret = [];
-
-               o = o || {};
-
-               items.each(function() { ret.push($(o.item || this).attr(o.attribute || "id") || ""); });
-               return ret;
-
-       },
-
-       /* Be careful with the following core functions */
-       _intersectsWith: function(item) {
-
-               var x1 = this.positionAbs.left,
-                       x2 = x1 + this.helperProportions.width,
-                       y1 = this.positionAbs.top,
-                       y2 = y1 + this.helperProportions.height,
-                       l = item.left,
-                       r = l + item.width,
-                       t = item.top,
-                       b = t + item.height,
-                       dyClick = this.offset.click.top,
-                       dxClick = this.offset.click.left,
-                       isOverElement = (y1 + dyClick) > t && (y1 + dyClick) < b && (x1 + dxClick) > l && (x1 + dxClick) < r;
-
-               if ( this.options.tolerance === "pointer" ||
-                       this.options.forcePointerForContainers ||
-                       (this.options.tolerance !== "pointer" && this.helperProportions[this.floating ? "width" : "height"] > item[this.floating ? "width" : "height"])
-               ) {
-                       return isOverElement;
-               } else {
-
-                       return (l < x1 + (this.helperProportions.width / 2) && // Right Half
-                               x2 - (this.helperProportions.width / 2) < r && // Left Half
-                               t < y1 + (this.helperProportions.height / 2) && // Bottom Half
-                               y2 - (this.helperProportions.height / 2) < b ); // Top Half
-
-               }
-       },
-
-       _intersectsWithPointer: function(item) {
-
-               var isOverElementHeight = (this.options.axis === "x") || isOverAxis(this.positionAbs.top + this.offset.click.top, item.top, item.height),
-                       isOverElementWidth = (this.options.axis === "y") || isOverAxis(this.positionAbs.left + this.offset.click.left, item.left, item.width),
-                       isOverElement = isOverElementHeight && isOverElementWidth,
-                       verticalDirection = this._getDragVerticalDirection(),
-                       horizontalDirection = this._getDragHorizontalDirection();
-
-               if (!isOverElement) {
-                       return false;
-               }
-
-               return this.floating ?
-                       ( ((horizontalDirection && horizontalDirection === "right") || verticalDirection === "down") ? 2 : 1 )
-                       : ( verticalDirection && (verticalDirection === "down" ? 2 : 1) );
-
-       },
-
-       _intersectsWithSides: function(item) {
-
-               var isOverBottomHalf = isOverAxis(this.positionAbs.top + this.offset.click.top, item.top + (item.height/2), item.height),
-                       isOverRightHalf = isOverAxis(this.positionAbs.left + this.offset.click.left, item.left + (item.width/2), item.width),
-                       verticalDirection = this._getDragVerticalDirection(),
-                       horizontalDirection = this._getDragHorizontalDirection();
-
-               if (this.floating && horizontalDirection) {
-                       return ((horizontalDirection === "right" && isOverRightHalf) || (horizontalDirection === "left" && !isOverRightHalf));
-               } else {
-                       return verticalDirection && ((verticalDirection === "down" && isOverBottomHalf) || (verticalDirection === "up" && !isOverBottomHalf));
-               }
-
-       },
-
-       _getDragVerticalDirection: function() {
-               var delta = this.positionAbs.top - this.lastPositionAbs.top;
-               return delta !== 0 && (delta > 0 ? "down" : "up");
-       },
-
-       _getDragHorizontalDirection: function() {
-               var delta = this.positionAbs.left - this.lastPositionAbs.left;
-               return delta !== 0 && (delta > 0 ? "right" : "left");
-       },
-
-       refresh: function(event) {
-               this._refreshItems(event);
-               this.refreshPositions();
-               return this;
-       },
-
-       _connectWith: function() {
-               var options = this.options;
-               return options.connectWith.constructor === String ? [options.connectWith] : options.connectWith;
-       },
-
-       _getItemsAsjQuery: function(connected) {
-
-               var i, j, cur, inst,
-                       items = [],
-                       queries = [],
-                       connectWith = this._connectWith();
-
-               if(connectWith && connected) {
-                       for (i = connectWith.length - 1; i >= 0; i--){
-                               cur = $(connectWith[i]);
-                               for ( j = cur.length - 1; j >= 0; j--){
-                                       inst = $.data(cur[j], this.widgetFullName);
-                                       if(inst && inst !== this && !inst.options.disabled) {
-                                               queries.push([$.isFunction(inst.options.items) ? inst.options.items.call(inst.element) : $(inst.options.items, inst.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"), inst]);
-                                       }
-                               }
-                       }
-               }
-
-               queries.push([$.isFunction(this.options.items) ? this.options.items.call(this.element, null, { options: this.options, item: this.currentItem }) : $(this.options.items, this.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"), this]);
-
-               for (i = queries.length - 1; i >= 0; i--){
-                       queries[i][0].each(function() {
-                               items.push(this);
-                       });
-               }
-
-               return $(items);
-
-       },
-
-       _removeCurrentsFromItems: function() {
-
-               var list = this.currentItem.find(":data(" + this.widgetName + "-item)");
-
-               this.items = $.grep(this.items, function (item) {
-                       for (var j=0; j < list.length; j++) {
-                               if(list[j] === item.item[0]) {
-                                       return false;
-                               }
-                       }
-                       return true;
-               });
-
-       },
-
-       _refreshItems: function(event) {
-
-               this.items = [];
-               this.containers = [this];
-
-               var i, j, cur, inst, targetData, _queries, item, queriesLength,
-                       items = this.items,
-                       queries = [[$.isFunction(this.options.items) ? this.options.items.call(this.element[0], event, { item: this.currentItem }) : $(this.options.items, this.element), this]],
-                       connectWith = this._connectWith();
-
-               if(connectWith && this.ready) { //Shouldn't be run the first time through due to massive slow-down
-                       for (i = connectWith.length - 1; i >= 0; i--){
-                               cur = $(connectWith[i]);
-                               for (j = cur.length - 1; j >= 0; j--){
-                                       inst = $.data(cur[j], this.widgetFullName);
-                                       if(inst && inst !== this && !inst.options.disabled) {
-                                               queries.push([$.isFunction(inst.options.items) ? inst.options.items.call(inst.element[0], event, { item: this.currentItem }) : $(inst.options.items, inst.element), inst]);
-                                               this.containers.push(inst);
-                                       }
-                               }
-                       }
-               }
-
-               for (i = queries.length - 1; i >= 0; i--) {
-                       targetData = queries[i][1];
-                       _queries = queries[i][0];
-
-                       for (j=0, queriesLength = _queries.length; j < queriesLength; j++) {
-                               item = $(_queries[j]);
-
-                               item.data(this.widgetName + "-item", targetData); // Data for target checking (mouse manager)
-
-                               items.push({
-                                       item: item,
-                                       instance: targetData,
-                                       width: 0, height: 0,
-                                       left: 0, top: 0
-                               });
-                       }
-               }
-
-       },
-
-       refreshPositions: function(fast) {
-
-               //This has to be redone because due to the item being moved out/into the offsetParent, the offsetParent's position will change
-               if(this.offsetParent && this.helper) {
-                       this.offset.parent = this._getParentOffset();
-               }
-
-               var i, item, t, p;
-
-               for (i = this.items.length - 1; i >= 0; i--){
-                       item = this.items[i];
-
-                       //We ignore calculating positions of all connected containers when we're not over them
-                       if(item.instance !== this.currentContainer && this.currentContainer && item.item[0] !== this.currentItem[0]) {
-                               continue;
-                       }
-
-                       t = this.options.toleranceElement ? $(this.options.toleranceElement, item.item) : item.item;
-
-                       if (!fast) {
-                               item.width = t.outerWidth();
-                               item.height = t.outerHeight();
-                       }
-
-                       p = t.offset();
-                       item.left = p.left;
-                       item.top = p.top;
-               }
-
-               if(this.options.custom && this.options.custom.refreshContainers) {
-                       this.options.custom.refreshContainers.call(this);
-               } else {
-                       for (i = this.containers.length - 1; i >= 0; i--){
-                               p = this.containers[i].element.offset();
-                               this.containers[i].containerCache.left = p.left;
-                               this.containers[i].containerCache.top = p.top;
-                               this.containers[i].containerCache.width = this.containers[i].element.outerWidth();
-                               this.containers[i].containerCache.height = this.containers[i].element.outerHeight();
-                       }
-               }
-
-               return this;
-       },
-
-       _createPlaceholder: function(that) {
-               that = that || this;
-               var className,
-                       o = that.options;
-
-               if(!o.placeholder || o.placeholder.constructor === String) {
-                       className = o.placeholder;
-                       o.placeholder = {
-                               element: function() {
-
-                                       var el = $(document.createElement(that.currentItem[0].nodeName))
-                                               .addClass(className || that.currentItem[0].className+" ui-sortable-placeholder")
-                                               .removeClass("ui-sortable-helper")[0];
-
-                                       if(!className) {
-                                               el.style.visibility = "hidden";
-                                       }
-
-                                       return el;
-                               },
-                               update: function(container, p) {
-
-                                       // 1. If a className is set as 'placeholder option, we don't force sizes - the class is responsible for that
-                                       // 2. The option 'forcePlaceholderSize can be enabled to force it even if a class name is specified
-                                       if(className && !o.forcePlaceholderSize) {
-                                               return;
-                                       }
-
-                                       //If the element doesn't have a actual height by itself (without styles coming from a stylesheet), it receives the inline height from the dragged item
-                                       if(!p.height()) { p.height(that.currentItem.innerHeight() - parseInt(that.currentItem.css("paddingTop")||0, 10) - parseInt(that.currentItem.css("paddingBottom")||0, 10)); }
-                                       if(!p.width()) { p.width(that.currentItem.innerWidth() - parseInt(that.currentItem.css("paddingLeft")||0, 10) - parseInt(that.currentItem.css("paddingRight")||0, 10)); }
-                               }
-                       };
-               }
-
-               //Create the placeholder
-               that.placeholder = $(o.placeholder.element.call(that.element, that.currentItem));
-
-               //Append it after the actual current item
-               that.currentItem.after(that.placeholder);
-
-               //Update the size of the placeholder (TODO: Logic to fuzzy, see line 316/317)
-               o.placeholder.update(that, that.placeholder);
-
-       },
-
-       _contactContainers: function(event) {
-               var i, j, dist, itemWithLeastDistance, posProperty, sizeProperty, base, cur, nearBottom,
-                       innermostContainer = null,
-                       innermostIndex = null;
-
-               // get innermost container that intersects with item
-               for (i = this.containers.length - 1; i >= 0; i--) {
-
-                       // never consider a container that's located within the item itself
-                       if($.contains(this.currentItem[0], this.containers[i].element[0])) {
-                               continue;
-                       }
-
-                       if(this._intersectsWith(this.containers[i].containerCache)) {
-
-                               // if we've already found a container and it's more "inner" than this, then continue
-                               if(innermostContainer && $.contains(this.containers[i].element[0], innermostContainer.element[0])) {
-                                       continue;
-                               }
-
-                               innermostContainer = this.containers[i];
-                               innermostIndex = i;
-
-                       } else {
-                               // container doesn't intersect. trigger "out" event if necessary
-                               if(this.containers[i].containerCache.over) {
-                                       this.containers[i]._trigger("out", event, this._uiHash(this));
-                                       this.containers[i].containerCache.over = 0;
-                               }
-                       }
-
-               }
-
-               // if no intersecting containers found, return
-               if(!innermostContainer) {
-                       return;
-               }
-
-               // move the item into the container if it's not there already
-               if(this.containers.length === 1) {
-                       this.containers[innermostIndex]._trigger("over", event, this._uiHash(this));
-                       this.containers[innermostIndex].containerCache.over = 1;
-               } else {
-
-                       //When entering a new container, we will find the item with the least distance and append our item near it
-                       dist = 10000;
-                       itemWithLeastDistance = null;
-                       posProperty = this.containers[innermostIndex].floating ? "left" : "top";
-                       sizeProperty = this.containers[innermostIndex].floating ? "width" : "height";
-                       base = this.positionAbs[posProperty] + this.offset.click[posProperty];
-                       for (j = this.items.length - 1; j >= 0; j--) {
-                               if(!$.contains(this.containers[innermostIndex].element[0], this.items[j].item[0])) {
-                                       continue;
-                               }
-                               if(this.items[j].item[0] === this.currentItem[0]) {
-                                       continue;
-                               }
-                               cur = this.items[j].item.offset()[posProperty];
-                               nearBottom = false;
-                               if(Math.abs(cur - base) > Math.abs(cur + this.items[j][sizeProperty] - base)){
-                                       nearBottom = true;
-                                       cur += this.items[j][sizeProperty];
-                               }
-
-                               if(Math.abs(cur - base) < dist) {
-                                       dist = Math.abs(cur - base); itemWithLeastDistance = this.items[j];
-                                       this.direction = nearBottom ? "up": "down";
-                               }
-                       }
-
-                       //Check if dropOnEmpty is enabled
-                       if(!itemWithLeastDistance && !this.options.dropOnEmpty) {
-                               return;
-                       }
-
-                       this.currentContainer = this.containers[innermostIndex];
-                       itemWithLeastDistance ? this._rearrange(event, itemWithLeastDistance, null, true) : this._rearrange(event, null, this.containers[innermostIndex].element, true);
-                       this._trigger("change", event, this._uiHash());
-                       this.containers[innermostIndex]._trigger("change", event, this._uiHash(this));
-
-                       //Update the placeholder
-                       this.options.placeholder.update(this.currentContainer, this.placeholder);
-
-                       this.containers[innermostIndex]._trigger("over", event, this._uiHash(this));
-                       this.containers[innermostIndex].containerCache.over = 1;
-               }
-
-
-       },
-
-       _createHelper: function(event) {
-
-               var o = this.options,
-                       helper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[0], [event, this.currentItem])) : (o.helper === "clone" ? this.currentItem.clone() : this.currentItem);
-
-               //Add the helper to the DOM if that didn't happen already
-               if(!helper.parents("body").length) {
-                       $(o.appendTo !== "parent" ? o.appendTo : this.currentItem[0].parentNode)[0].appendChild(helper[0]);
-               }
-
-               if(helper[0] === this.currentItem[0]) {
-                       this._storedCSS = { width: this.currentItem[0].style.width, height: this.currentItem[0].style.height, position: this.currentItem.css("position"), top: this.currentItem.css("top"), left: this.currentItem.css("left") };
-               }
-
-               if(!helper[0].style.width || o.forceHelperSize) {
-                       helper.width(this.currentItem.width());
-               }
-               if(!helper[0].style.height || o.forceHelperSize) {
-                       helper.height(this.currentItem.height());
-               }
-
-               return helper;
-
-       },
-
-       _adjustOffsetFromHelper: function(obj) {
-               if (typeof obj === "string") {
-                       obj = obj.split(" ");
-               }
-               if ($.isArray(obj)) {
-                       obj = {left: +obj[0], top: +obj[1] || 0};
-               }
-               if ("left" in obj) {
-                       this.offset.click.left = obj.left + this.margins.left;
-               }
-               if ("right" in obj) {
-                       this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
-               }
-               if ("top" in obj) {
-                       this.offset.click.top = obj.top + this.margins.top;
-               }
-               if ("bottom" in obj) {
-                       this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
-               }
-       },
-
-       _getParentOffset: function() {
-
-
-               //Get the offsetParent and cache its position
-               this.offsetParent = this.helper.offsetParent();
-               var po = this.offsetParent.offset();
-
-               // This is a special case where we need to modify a offset calculated on start, since the following happened:
-               // 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent
-               // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that
-               //    the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag
-               if(this.cssPosition === "absolute" && this.scrollParent[0] !== document && $.contains(this.scrollParent[0], this.offsetParent[0])) {
-                       po.left += this.scrollParent.scrollLeft();
-                       po.top += this.scrollParent.scrollTop();
-               }
-
-               // This needs to be actually done for all browsers, since pageX/pageY includes this information
-               // with an ugly IE fix
-               if( this.offsetParent[0] === document.body || (this.offsetParent[0].tagName && this.offsetParent[0].tagName.toLowerCase() === "html" && $.ui.ie)) {
-                       po = { top: 0, left: 0 };
-               }
-
-               return {
-                       top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"),10) || 0),
-                       left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"),10) || 0)
-               };
-
-       },
-
-       _getRelativeOffset: function() {
-
-               if(this.cssPosition === "relative") {
-                       var p = this.currentItem.position();
-                       return {
-                               top: p.top - (parseInt(this.helper.css("top"),10) || 0) + this.scrollParent.scrollTop(),
-                               left: p.left - (parseInt(this.helper.css("left"),10) || 0) + this.scrollParent.scrollLeft()
-                       };
-               } else {
-                       return { top: 0, left: 0 };
-               }
-
-       },
-
-       _cacheMargins: function() {
-               this.margins = {
-                       left: (parseInt(this.currentItem.css("marginLeft"),10) || 0),
-                       top: (parseInt(this.currentItem.css("marginTop"),10) || 0)
-               };
-       },
-
-       _cacheHelperProportions: function() {
-               this.helperProportions = {
-                       width: this.helper.outerWidth(),
-                       height: this.helper.outerHeight()
-               };
-       },
-
-       _setContainment: function() {
-
-               var ce, co, over,
-                       o = this.options;
-               if(o.containment === "parent") {
-                       o.containment = this.helper[0].parentNode;
-               }
-               if(o.containment === "document" || o.containment === "window") {
-                       this.containment = [
-                               0 - this.offset.relative.left - this.offset.parent.left,
-                               0 - this.offset.relative.top - this.offset.parent.top,
-                               $(o.containment === "document" ? document : window).width() - this.helperProportions.width - this.margins.left,
-                               ($(o.containment === "document" ? document : window).height() || document.body.parentNode.scrollHeight) - this.helperProportions.height - this.margins.top
-                       ];
-               }
-
-               if(!(/^(document|window|parent)$/).test(o.containment)) {
-                       ce = $(o.containment)[0];
-                       co = $(o.containment).offset();
-                       over = ($(ce).css("overflow") !== "hidden");
-
-                       this.containment = [
-                               co.left + (parseInt($(ce).css("borderLeftWidth"),10) || 0) + (parseInt($(ce).css("paddingLeft"),10) || 0) - this.margins.left,
-                               co.top + (parseInt($(ce).css("borderTopWidth"),10) || 0) + (parseInt($(ce).css("paddingTop"),10) || 0) - this.margins.top,
-                               co.left+(over ? Math.max(ce.scrollWidth,ce.offsetWidth) : ce.offsetWidth) - (parseInt($(ce).css("borderLeftWidth"),10) || 0) - (parseInt($(ce).css("paddingRight"),10) || 0) - this.helperProportions.width - this.margins.left,
-                               co.top+(over ? Math.max(ce.scrollHeight,ce.offsetHeight) : ce.offsetHeight) - (parseInt($(ce).css("borderTopWidth"),10) || 0) - (parseInt($(ce).css("paddingBottom"),10) || 0) - this.helperProportions.height - this.margins.top
-                       ];
-               }
-
-       },
-
-       _convertPositionTo: function(d, pos) {
-
-               if(!pos) {
-                       pos = this.position;
-               }
-               var mod = d === "absolute" ? 1 : -1,
-                       scroll = this.cssPosition === "absolute" && !(this.scrollParent[0] !== document && $.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent,
-                       scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName);
-
-               return {
-                       top: (
-                               pos.top +                                                                                                                               // The absolute mouse position
-                               this.offset.relative.top * mod +                                                                                // Only for relative positioned nodes: Relative offset from element to offset parent
-                               this.offset.parent.top * mod -                                                                                  // The offsetParent's offset without borders (offset + border)
-                               ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod)
-                       ),
-                       left: (
-                               pos.left +                                                                                                                              // The absolute mouse position
-                               this.offset.relative.left * mod +                                                                               // Only for relative positioned nodes: Relative offset from element to offset parent
-                               this.offset.parent.left * mod   -                                                                               // The offsetParent's offset without borders (offset + border)
-                               ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ) * mod)
-                       )
-               };
-
-       },
-
-       _generatePosition: function(event) {
-
-               var top, left,
-                       o = this.options,
-                       pageX = event.pageX,
-                       pageY = event.pageY,
-                       scroll = this.cssPosition === "absolute" && !(this.scrollParent[0] !== document && $.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName);
-
-               // This is another very weird special case that only happens for relative elements:
-               // 1. If the css position is relative
-               // 2. and the scroll parent is the document or similar to the offset parent
-               // we have to refresh the relative offset during the scroll so there are no jumps
-               if(this.cssPosition === "relative" && !(this.scrollParent[0] !== document && this.scrollParent[0] !== this.offsetParent[0])) {
-                       this.offset.relative = this._getRelativeOffset();
-               }
-
-               /*
-                * - Position constraining -
-                * Constrain the position to a mix of grid, containment.
-                */
-
-               if(this.originalPosition) { //If we are not dragging yet, we won't check for options
-
-                       if(this.containment) {
-                               if(event.pageX - this.offset.click.left < this.containment[0]) {
-                                       pageX = this.containment[0] + this.offset.click.left;
-                               }
-                               if(event.pageY - this.offset.click.top < this.containment[1]) {
-                                       pageY = this.containment[1] + this.offset.click.top;
-                               }
-                               if(event.pageX - this.offset.click.left > this.containment[2]) {
-                                       pageX = this.containment[2] + this.offset.click.left;
-                               }
-                               if(event.pageY - this.offset.click.top > this.containment[3]) {
-                                       pageY = this.containment[3] + this.offset.click.top;
-                               }
-                       }
-
-                       if(o.grid) {
-                               top = this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1];
-                               pageY = this.containment ? ( (top - this.offset.click.top >= this.containment[1] && top - this.offset.click.top <= this.containment[3]) ? top : ((top - this.offset.click.top >= this.containment[1]) ? top - o.grid[1] : top + o.grid[1])) : top;
-
-                               left = this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0];
-                               pageX = this.containment ? ( (left - this.offset.click.left >= this.containment[0] && left - this.offset.click.left <= this.containment[2]) ? left : ((left - this.offset.click.left >= this.containment[0]) ? left - o.grid[0] : left + o.grid[0])) : left;
-                       }
-
-               }
-
-               return {
-                       top: (
-                               pageY -                                                                                                                         // The absolute mouse position
-                               this.offset.click.top -                                                                                                 // Click offset (relative to the element)
-                               this.offset.relative.top        -                                                                                       // Only for relative positioned nodes: Relative offset from element to offset parent
-                               this.offset.parent.top +                                                                                                // The offsetParent's offset without borders (offset + border)
-                               ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ))
-                       ),
-                       left: (
-                               pageX -                                                                                                                         // The absolute mouse position
-                               this.offset.click.left -                                                                                                // Click offset (relative to the element)
-                               this.offset.relative.left       -                                                                                       // Only for relative positioned nodes: Relative offset from element to offset parent
-                               this.offset.parent.left +                                                                                               // The offsetParent's offset without borders (offset + border)
-                               ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ))
-                       )
-               };
-
-       },
-
-       _rearrange: function(event, i, a, hardRefresh) {
-
-               a ? a[0].appendChild(this.placeholder[0]) : i.item[0].parentNode.insertBefore(this.placeholder[0], (this.direction === "down" ? i.item[0] : i.item[0].nextSibling));
-
-               //Various things done here to improve the performance:
-               // 1. we create a setTimeout, that calls refreshPositions
-               // 2. on the instance, we have a counter variable, that get's higher after every append
-               // 3. on the local scope, we copy the counter variable, and check in the timeout, if it's still the same
-               // 4. this lets only the last addition to the timeout stack through
-               this.counter = this.counter ? ++this.counter : 1;
-               var counter = this.counter;
-
-               this._delay(function() {
-                       if(counter === this.counter) {
-                               this.refreshPositions(!hardRefresh); //Precompute after each DOM insertion, NOT on mousemove
-                       }
-               });
-
-       },
-
-       _clear: function(event, noPropagation) {
-
-               this.reverting = false;
-               // We delay all events that have to be triggered to after the point where the placeholder has been removed and
-               // everything else normalized again
-               var i,
-                       delayedTriggers = [];
-
-               // We first have to update the dom position of the actual currentItem
-               // Note: don't do it if the current item is already removed (by a user), or it gets reappended (see #4088)
-               if(!this._noFinalSort && this.currentItem.parent().length) {
-                       this.placeholder.before(this.currentItem);
-               }
-               this._noFinalSort = null;
-
-               if(this.helper[0] === this.currentItem[0]) {
-                       for(i in this._storedCSS) {
-                               if(this._storedCSS[i] === "auto" || this._storedCSS[i] === "static") {
-                                       this._storedCSS[i] = "";
-                               }
-                       }
-                       this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper");
-               } else {
-                       this.currentItem.show();
-               }
-
-               if(this.fromOutside && !noPropagation) {
-                       delayedTriggers.push(function(event) { this._trigger("receive", event, this._uiHash(this.fromOutside)); });
-               }
-               if((this.fromOutside || this.domPosition.prev !== this.currentItem.prev().not(".ui-sortable-helper")[0] || this.domPosition.parent !== this.currentItem.parent()[0]) && !noPropagation) {
-                       delayedTriggers.push(function(event) { this._trigger("update", event, this._uiHash()); }); //Trigger update callback if the DOM position has changed
-               }
-
-               // Check if the items Container has Changed and trigger appropriate
-               // events.
-               if (this !== this.currentContainer) {
-                       if(!noPropagation) {
-                               delayedTriggers.push(function(event) { this._trigger("remove", event, this._uiHash()); });
-                               delayedTriggers.push((function(c) { return function(event) { c._trigger("receive", event, this._uiHash(this)); };  }).call(this, this.currentContainer));
-                               delayedTriggers.push((function(c) { return function(event) { c._trigger("update", event, this._uiHash(this));  }; }).call(this, this.currentContainer));
-                       }
-               }
-
-
-               //Post events to containers
-               for (i = this.containers.length - 1; i >= 0; i--){
-                       if(!noPropagation) {
-                               delayedTriggers.push((function(c) { return function(event) { c._trigger("deactivate", event, this._uiHash(this)); };  }).call(this, this.containers[i]));
-                       }
-                       if(this.containers[i].containerCache.over) {
-                               delayedTriggers.push((function(c) { return function(event) { c._trigger("out", event, this._uiHash(this)); };  }).call(this, this.containers[i]));
-                               this.containers[i].containerCache.over = 0;
-                       }
-               }
-
-               //Do what was originally in plugins
-               if(this._storedCursor) {
-                       $("body").css("cursor", this._storedCursor);
-               }
-               if(this._storedOpacity) {
-                       this.helper.css("opacity", this._storedOpacity);
-               }
-               if(this._storedZIndex) {
-                       this.helper.css("zIndex", this._storedZIndex === "auto" ? "" : this._storedZIndex);
-               }
-
-               this.dragging = false;
-               if(this.cancelHelperRemoval) {
-                       if(!noPropagation) {
-                               this._trigger("beforeStop", event, this._uiHash());
-                               for (i=0; i < delayedTriggers.length; i++) {
-                                       delayedTriggers[i].call(this, event);
-                               } //Trigger all delayed events
-                               this._trigger("stop", event, this._uiHash());
-                       }
-
-                       this.fromOutside = false;
-                       return false;
-               }
-
-               if(!noPropagation) {
-                       this._trigger("beforeStop", event, this._uiHash());
-               }
-
-               //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node!
-               this.placeholder[0].parentNode.removeChild(this.placeholder[0]);
-
-               if(this.helper[0] !== this.currentItem[0]) {
-                       this.helper.remove();
-               }
-               this.helper = null;
-
-               if(!noPropagation) {
-                       for (i=0; i < delayedTriggers.length; i++) {
-                               delayedTriggers[i].call(this, event);
-                       } //Trigger all delayed events
-                       this._trigger("stop", event, this._uiHash());
-               }
-
-               this.fromOutside = false;
-               return true;
-
-       },
-
-       _trigger: function() {
-               if ($.Widget.prototype._trigger.apply(this, arguments) === false) {
-                       this.cancel();
-               }
-       },
-
-       _uiHash: function(_inst) {
-               var inst = _inst || this;
-               return {
-                       helper: inst.helper,
-                       placeholder: inst.placeholder || $([]),
-                       position: inst.position,
-                       originalPosition: inst.originalPosition,
-                       offset: inst.positionAbs,
-                       item: inst.currentItem,
-                       sender: _inst ? _inst.element : null
-               };
-       }
-
-});
-
-})(jQuery);
-;(jQuery.effects || (function($, undefined) {
-
-var dataSpace = "ui-effects-";
-
-$.effects = {
-       effect: {}
-};
-
-/*!
- * jQuery Color Animations v2.1.2
- * https://github.com/jquery/jquery-color
- *
- * Copyright 2013 jQuery Foundation and other contributors
- * Released under the MIT license.
- * http://jquery.org/license
- *
- * Date: Wed Jan 16 08:47:09 2013 -0600
- */
-(function( jQuery, undefined ) {
-
-       var stepHooks = "backgroundColor borderBottomColor borderLeftColor borderRightColor borderTopColor color columnRuleColor outlineColor textDecorationColor textEmphasisColor",
-
-       // plusequals test for += 100 -= 100
-       rplusequals = /^([\-+])=\s*(\d+\.?\d*)/,
-       // a set of RE's that can match strings and generate color tuples.
-       stringParsers = [{
-                       re: /rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,
-                       parse: function( execResult ) {
-                               return [
-                                       execResult[ 1 ],
-                                       execResult[ 2 ],
-                                       execResult[ 3 ],
-                                       execResult[ 4 ]
-                               ];
-                       }
-               }, {
-                       re: /rgba?\(\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,
-                       parse: function( execResult ) {
-                               return [
-                                       execResult[ 1 ] * 2.55,
-                                       execResult[ 2 ] * 2.55,
-                                       execResult[ 3 ] * 2.55,
-                                       execResult[ 4 ]
-                               ];
-                       }
-               }, {
-                       // this regex ignores A-F because it's compared against an already lowercased string
-                       re: /#([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})/,
-                       parse: function( execResult ) {
-                               return [
-                                       parseInt( execResult[ 1 ], 16 ),
-                                       parseInt( execResult[ 2 ], 16 ),
-                                       parseInt( execResult[ 3 ], 16 )
-                               ];
-                       }
-               }, {
-                       // this regex ignores A-F because it's compared against an already lowercased string
-                       re: /#([a-f0-9])([a-f0-9])([a-f0-9])/,
-                       parse: function( execResult ) {
-                               return [
-                                       parseInt( execResult[ 1 ] + execResult[ 1 ], 16 ),
-                                       parseInt( execResult[ 2 ] + execResult[ 2 ], 16 ),
-                                       parseInt( execResult[ 3 ] + execResult[ 3 ], 16 )
-                               ];
-                       }
-               }, {
-                       re: /hsla?\(\s*(\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,
-                       space: "hsla",
-                       parse: function( execResult ) {
-                               return [
-                                       execResult[ 1 ],
-                                       execResult[ 2 ] / 100,
-                                       execResult[ 3 ] / 100,
-                                       execResult[ 4 ]
-                               ];
-                       }
-               }],
-
-       // jQuery.Color( )
-       color = jQuery.Color = function( color, green, blue, alpha ) {
-               return new jQuery.Color.fn.parse( color, green, blue, alpha );
-       },
-       spaces = {
-               rgba: {
-                       props: {
-                               red: {
-                                       idx: 0,
-                                       type: "byte"
-                               },
-                               green: {
-                                       idx: 1,
-                                       type: "byte"
-                               },
-                               blue: {
-                                       idx: 2,
-                                       type: "byte"
-                               }
-                       }
-               },
-
-               hsla: {
-                       props: {
-                               hue: {
-                                       idx: 0,
-                                       type: "degrees"
-                               },
-                               saturation: {
-                                       idx: 1,
-                                       type: "percent"
-                               },
-                               lightness: {
-                                       idx: 2,
-                                       type: "percent"
-                               }
-                       }
-               }
-       },
-       propTypes = {
-               "byte": {
-                       floor: true,
-                       max: 255
-               },
-               "percent": {
-                       max: 1
-               },
-               "degrees": {
-                       mod: 360,
-                       floor: true
-               }
-       },
-       support = color.support = {},
-
-       // element for support tests
-       supportElem = jQuery( "<p>" )[ 0 ],
-
-       // colors = jQuery.Color.names
-       colors,
-
-       // local aliases of functions called often
-       each = jQuery.each;
-
-// determine rgba support immediately
-supportElem.style.cssText = "background-color:rgba(1,1,1,.5)";
-support.rgba = supportElem.style.backgroundColor.indexOf( "rgba" ) > -1;
-
-// define cache name and alpha properties
-// for rgba and hsla spaces
-each( spaces, function( spaceName, space ) {
-       space.cache = "_" + spaceName;
-       space.props.alpha = {
-               idx: 3,
-               type: "percent",
-               def: 1
-       };
-});
-
-function clamp( value, prop, allowEmpty ) {
-       var type = propTypes[ prop.type ] || {};
-
-       if ( value == null ) {
-               return (allowEmpty || !prop.def) ? null : prop.def;
-       }
-
-       // ~~ is an short way of doing floor for positive numbers
-       value = type.floor ? ~~value : parseFloat( value );
-
-       // IE will pass in empty strings as value for alpha,
-       // which will hit this case
-       if ( isNaN( value ) ) {
-               return prop.def;
-       }
-
-       if ( type.mod ) {
-               // we add mod before modding to make sure that negatives values
-               // get converted properly: -10 -> 350
-               return (value + type.mod) % type.mod;
-       }
-
-       // for now all property types without mod have min and max
-       return 0 > value ? 0 : type.max < value ? type.max : value;
-}
-
-function stringParse( string ) {
-       var inst = color(),
-               rgba = inst._rgba = [];
-
-       string = string.toLowerCase();
-
-       each( stringParsers, function( i, parser ) {
-               var parsed,
-                       match = parser.re.exec( string ),
-                       values = match && parser.parse( match ),
-                       spaceName = parser.space || "rgba";
-
-               if ( values ) {
-                       parsed = inst[ spaceName ]( values );
-
-                       // if this was an rgba parse the assignment might happen twice
-                       // oh well....
-                       inst[ spaces[ spaceName ].cache ] = parsed[ spaces[ spaceName ].cache ];
-                       rgba = inst._rgba = parsed._rgba;
-
-                       // exit each( stringParsers ) here because we matched
-                       return false;
-               }
-       });
-
-       // Found a stringParser that handled it
-       if ( rgba.length ) {
-
-               // if this came from a parsed string, force "transparent" when alpha is 0
-               // chrome, (and maybe others) return "transparent" as rgba(0,0,0,0)
-               if ( rgba.join() === "0,0,0,0" ) {
-                       jQuery.extend( rgba, colors.transparent );
-               }
-               return inst;
-       }
-
-       // named colors
-       return colors[ string ];
-}
-
-color.fn = jQuery.extend( color.prototype, {
-       parse: function( red, green, blue, alpha ) {
-               if ( red === undefined ) {
-                       this._rgba = [ null, null, null, null ];
-                       return this;
-               }
-               if ( red.jquery || red.nodeType ) {
-                       red = jQuery( red ).css( green );
-                       green = undefined;
-               }
-
-               var inst = this,
-                       type = jQuery.type( red ),
-                       rgba = this._rgba = [];
-
-               // more than 1 argument specified - assume ( red, green, blue, alpha )
-               if ( green !== undefined ) {
-                       red = [ red, green, blue, alpha ];
-                       type = "array";
-               }
-
-               if ( type === "string" ) {
-                       return this.parse( stringParse( red ) || colors._default );
-               }
-
-               if ( type === "array" ) {
-                       each( spaces.rgba.props, function( key, prop ) {
-                               rgba[ prop.idx ] = clamp( red[ prop.idx ], prop );
-                       });
-                       return this;
-               }
-
-               if ( type === "object" ) {
-                       if ( red instanceof color ) {
-                               each( spaces, function( spaceName, space ) {
-                                       if ( red[ space.cache ] ) {
-                                               inst[ space.cache ] = red[ space.cache ].slice();
-                                       }
-                               });
-                       } else {
-                               each( spaces, function( spaceName, space ) {
-                                       var cache = space.cache;
-                                       each( space.props, function( key, prop ) {
-
-                                               // if the cache doesn't exist, and we know how to convert
-                                               if ( !inst[ cache ] && space.to ) {
-
-                                                       // if the value was null, we don't need to copy it
-                                                       // if the key was alpha, we don't need to copy it either
-                                                       if ( key === "alpha" || red[ key ] == null ) {
-                                                               return;
-                                                       }
-                                                       inst[ cache ] = space.to( inst._rgba );
-                                               }
-
-                                               // this is the only case where we allow nulls for ALL properties.
-                                               // call clamp with alwaysAllowEmpty
-                                               inst[ cache ][ prop.idx ] = clamp( red[ key ], prop, true );
-                                       });
-
-                                       // everything defined but alpha?
-                                       if ( inst[ cache ] && jQuery.inArray( null, inst[ cache ].slice( 0, 3 ) ) < 0 ) {
-                                               // use the default of 1
-                                               inst[ cache ][ 3 ] = 1;
-                                               if ( space.from ) {
-                                                       inst._rgba = space.from( inst[ cache ] );
-                                               }
-                                       }
-                               });
-                       }
-                       return this;
-               }
-       },
-       is: function( compare ) {
-               var is = color( compare ),
-                       same = true,
-                       inst = this;
-
-               each( spaces, function( _, space ) {
-                       var localCache,
-                               isCache = is[ space.cache ];
-                       if (isCache) {
-                               localCache = inst[ space.cache ] || space.to && space.to( inst._rgba ) || [];
-                               each( space.props, function( _, prop ) {
-                                       if ( isCache[ prop.idx ] != null ) {
-                                               same = ( isCache[ prop.idx ] === localCache[ prop.idx ] );
-                                               return same;
-                                       }
-                               });
-                       }
-                       return same;
-               });
-               return same;
-       },
-       _space: function() {
-               var used = [],
-                       inst = this;
-               each( spaces, function( spaceName, space ) {
-                       if ( inst[ space.cache ] ) {
-                               used.push( spaceName );
-                       }
-               });
-               return used.pop();
-       },
-       transition: function( other, distance ) {
-               var end = color( other ),
-                       spaceName = end._space(),
-                       space = spaces[ spaceName ],
-                       startColor = this.alpha() === 0 ? color( "transparent" ) : this,
-                       start = startColor[ space.cache ] || space.to( startColor._rgba ),
-                       result = start.slice();
-
-               end = end[ space.cache ];
-               each( space.props, function( key, prop ) {
-                       var index = prop.idx,
-                               startValue = start[ index ],
-                               endValue = end[ index ],
-                               type = propTypes[ prop.type ] || {};
-
-                       // if null, don't override start value
-                       if ( endValue === null ) {
-                               return;
-                       }
-                       // if null - use end
-                       if ( startValue === null ) {
-                               result[ index ] = endValue;
-                       } else {
-                               if ( type.mod ) {
-                                       if ( endValue - startValue > type.mod / 2 ) {
-                                               startValue += type.mod;
-                                       } else if ( startValue - endValue > type.mod / 2 ) {
-                                               startValue -= type.mod;
-                                       }
-                               }
-                               result[ index ] = clamp( ( endValue - startValue ) * distance + startValue, prop );
-                       }
-               });
-               return this[ spaceName ]( result );
-       },
-       blend: function( opaque ) {
-               // if we are already opaque - return ourself
-               if ( this._rgba[ 3 ] === 1 ) {
-                       return this;
-               }
-
-               var rgb = this._rgba.slice(),
-                       a = rgb.pop(),
-                       blend = color( opaque )._rgba;
-
-               return color( jQuery.map( rgb, function( v, i ) {
-                       return ( 1 - a ) * blend[ i ] + a * v;
-               }));
-       },
-       toRgbaString: function() {
-               var prefix = "rgba(",
-                       rgba = jQuery.map( this._rgba, function( v, i ) {
-                               return v == null ? ( i > 2 ? 1 : 0 ) : v;
-                       });
-
-               if ( rgba[ 3 ] === 1 ) {
-                       rgba.pop();
-                       prefix = "rgb(";
-               }
-
-               return prefix + rgba.join() + ")";
-       },
-       toHslaString: function() {
-               var prefix = "hsla(",
-                       hsla = jQuery.map( this.hsla(), function( v, i ) {
-                               if ( v == null ) {
-                                       v = i > 2 ? 1 : 0;
-                               }
-
-                               // catch 1 and 2
-                               if ( i && i < 3 ) {
-                                       v = Math.round( v * 100 ) + "%";
-                               }
-                               return v;
-                       });
-
-               if ( hsla[ 3 ] === 1 ) {
-                       hsla.pop();
-                       prefix = "hsl(";
-               }
-               return prefix + hsla.join() + ")";
-       },
-       toHexString: function( includeAlpha ) {
-               var rgba = this._rgba.slice(),
-                       alpha = rgba.pop();
-
-               if ( includeAlpha ) {
-                       rgba.push( ~~( alpha * 255 ) );
-               }
-
-               return "#" + jQuery.map( rgba, function( v ) {
-
-                       // default to 0 when nulls exist
-                       v = ( v || 0 ).toString( 16 );
-                       return v.length === 1 ? "0" + v : v;
-               }).join("");
-       },
-       toString: function() {
-               return this._rgba[ 3 ] === 0 ? "transparent" : this.toRgbaString();
-       }
-});
-color.fn.parse.prototype = color.fn;
-
-// hsla conversions adapted from:
-// https://code.google.com/p/maashaack/source/browse/packages/graphics/trunk/src/graphics/colors/HUE2RGB.as?r=5021
-
-function hue2rgb( p, q, h ) {
-       h = ( h + 1 ) % 1;
-       if ( h * 6 < 1 ) {
-               return p + (q - p) * h * 6;
-       }
-       if ( h * 2 < 1) {
-               return q;
-       }
-       if ( h * 3 < 2 ) {
-               return p + (q - p) * ((2/3) - h) * 6;
-       }
-       return p;
-}
-
-spaces.hsla.to = function ( rgba ) {
-       if ( rgba[ 0 ] == null || rgba[ 1 ] == null || rgba[ 2 ] == null ) {
-               return [ null, null, null, rgba[ 3 ] ];
-       }
-       var r = rgba[ 0 ] / 255,
-               g = rgba[ 1 ] / 255,
-               b = rgba[ 2 ] / 255,
-               a = rgba[ 3 ],
-               max = Math.max( r, g, b ),
-               min = Math.min( r, g, b ),
-               diff = max - min,
-               add = max + min,
-               l = add * 0.5,
-               h, s;
-
-       if ( min === max ) {
-               h = 0;
-       } else if ( r === max ) {
-               h = ( 60 * ( g - b ) / diff ) + 360;
-       } else if ( g === max ) {
-               h = ( 60 * ( b - r ) / diff ) + 120;
-       } else {
-               h = ( 60 * ( r - g ) / diff ) + 240;
-       }
-
-       // chroma (diff) == 0 means greyscale which, by definition, saturation = 0%
-       // otherwise, saturation is based on the ratio of chroma (diff) to lightness (add)
-       if ( diff === 0 ) {
-               s = 0;
-       } else if ( l <= 0.5 ) {
-               s = diff / add;
-       } else {
-               s = diff / ( 2 - add );
-       }
-       return [ Math.round(h) % 360, s, l, a == null ? 1 : a ];
-};
-
-spaces.hsla.from = function ( hsla ) {
-       if ( hsla[ 0 ] == null || hsla[ 1 ] == null || hsla[ 2 ] == null ) {
-               return [ null, null, null, hsla[ 3 ] ];
-       }
-       var h = hsla[ 0 ] / 360,
-               s = hsla[ 1 ],
-               l = hsla[ 2 ],
-               a = hsla[ 3 ],
-               q = l <= 0.5 ? l * ( 1 + s ) : l + s - l * s,
-               p = 2 * l - q;
-
-       return [
-               Math.round( hue2rgb( p, q, h + ( 1 / 3 ) ) * 255 ),
-               Math.round( hue2rgb( p, q, h ) * 255 ),
-               Math.round( hue2rgb( p, q, h - ( 1 / 3 ) ) * 255 ),
-               a
-       ];
-};
-
-
-each( spaces, function( spaceName, space ) {
-       var props = space.props,
-               cache = space.cache,
-               to = space.to,
-               from = space.from;
-
-       // makes rgba() and hsla()
-       color.fn[ spaceName ] = function( value ) {
-
-               // generate a cache for this space if it doesn't exist
-               if ( to && !this[ cache ] ) {
-                       this[ cache ] = to( this._rgba );
-               }
-               if ( value === undefined ) {
-                       return this[ cache ].slice();
-               }
-
-               var ret,
-                       type = jQuery.type( value ),
-                       arr = ( type === "array" || type === "object" ) ? value : arguments,
-                       local = this[ cache ].slice();
-
-               each( props, function( key, prop ) {
-                       var val = arr[ type === "object" ? key : prop.idx ];
-                       if ( val == null ) {
-                               val = local[ prop.idx ];
-                       }
-                       local[ prop.idx ] = clamp( val, prop );
-               });
-
-               if ( from ) {
-                       ret = color( from( local ) );
-                       ret[ cache ] = local;
-                       return ret;
-               } else {
-                       return color( local );
-               }
-       };
-
-       // makes red() green() blue() alpha() hue() saturation() lightness()
-       each( props, function( key, prop ) {
-               // alpha is included in more than one space
-               if ( color.fn[ key ] ) {
-                       return;
-               }
-               color.fn[ key ] = function( value ) {
-                       var vtype = jQuery.type( value ),
-                               fn = ( key === "alpha" ? ( this._hsla ? "hsla" : "rgba" ) : spaceName ),
-                               local = this[ fn ](),
-                               cur = local[ prop.idx ],
-                               match;
-
-                       if ( vtype === "undefined" ) {
-                               return cur;
-                       }
-
-                       if ( vtype === "function" ) {
-                               value = value.call( this, cur );
-                               vtype = jQuery.type( value );
-                       }
-                       if ( value == null && prop.empty ) {
-                               return this;
-                       }
-                       if ( vtype === "string" ) {
-                               match = rplusequals.exec( value );
-                               if ( match ) {
-                                       value = cur + parseFloat( match[ 2 ] ) * ( match[ 1 ] === "+" ? 1 : -1 );
-                               }
-                       }
-                       local[ prop.idx ] = value;
-                       return this[ fn ]( local );
-               };
-       });
-});
-
-// add cssHook and .fx.step function for each named hook.
-// accept a space separated string of properties
-color.hook = function( hook ) {
-       var hooks = hook.split( " " );
-       each( hooks, function( i, hook ) {
-               jQuery.cssHooks[ hook ] = {
-                       set: function( elem, value ) {
-                               var parsed, curElem,
-                                       backgroundColor = "";
-
-                               if ( value !== "transparent" && ( jQuery.type( value ) !== "string" || ( parsed = stringParse( value ) ) ) ) {
-                                       value = color( parsed || value );
-                                       if ( !support.rgba && value._rgba[ 3 ] !== 1 ) {
-                                               curElem = hook === "backgroundColor" ? elem.parentNode : elem;
-                                               while (
-                                                       (backgroundColor === "" || backgroundColor === "transparent") &&
-                                                       curElem && curElem.style
-                                               ) {
-                                                       try {
-                                                               backgroundColor = jQuery.css( curElem, "backgroundColor" );
-                                                               curElem = curElem.parentNode;
-                                                       } catch ( e ) {
-                                                       }
-                                               }
-
-                                               value = value.blend( backgroundColor && backgroundColor !== "transparent" ?
-                                                       backgroundColor :
-                                                       "_default" );
-                                       }
-
-                                       value = value.toRgbaString();
-                               }
-                               try {
-                                       elem.style[ hook ] = value;
-                               } catch( e ) {
-                                       // wrapped to prevent IE from throwing errors on "invalid" values like 'auto' or 'inherit'
-                               }
-                       }
-               };
-               jQuery.fx.step[ hook ] = function( fx ) {
-                       if ( !fx.colorInit ) {
-                               fx.start = color( fx.elem, hook );
-                               fx.end = color( fx.end );
-                               fx.colorInit = true;
-                       }
-                       jQuery.cssHooks[ hook ].set( fx.elem, fx.start.transition( fx.end, fx.pos ) );
-               };
-       });
-
-};
-
-color.hook( stepHooks );
-
-jQuery.cssHooks.borderColor = {
-       expand: function( value ) {
-               var expanded = {};
-
-               each( [ "Top", "Right", "Bottom", "Left" ], function( i, part ) {
-                       expanded[ "border" + part + "Color" ] = value;
-               });
-               return expanded;
-       }
-};
-
-// Basic color names only.
-// Usage of any of the other color names requires adding yourself or including
-// jquery.color.svg-names.js.
-colors = jQuery.Color.names = {
-       // 4.1. Basic color keywords
-       aqua: "#00ffff",
-       black: "#000000",
-       blue: "#0000ff",
-       fuchsia: "#ff00ff",
-       gray: "#808080",
-       green: "#008000",
-       lime: "#00ff00",
-       maroon: "#800000",
-       navy: "#000080",
-       olive: "#808000",
-       purple: "#800080",
-       red: "#ff0000",
-       silver: "#c0c0c0",
-       teal: "#008080",
-       white: "#ffffff",
-       yellow: "#ffff00",
-
-       // 4.2.3. "transparent" color keyword
-       transparent: [ null, null, null, 0 ],
-
-       _default: "#ffffff"
-};
-
-})( jQuery );
-
-
-/******************************************************************************/
-/****************************** CLASS ANIMATIONS ******************************/
-/******************************************************************************/
-(function() {
-
-var classAnimationActions = [ "add", "remove", "toggle" ],
-       shorthandStyles = {
-               border: 1,
-               borderBottom: 1,
-               borderColor: 1,
-               borderLeft: 1,
-               borderRight: 1,
-               borderTop: 1,
-               borderWidth: 1,
-               margin: 1,
-               padding: 1
-       };
-
-$.each([ "borderLeftStyle", "borderRightStyle", "borderBottomStyle", "borderTopStyle" ], function( _, prop ) {
-       $.fx.step[ prop ] = function( fx ) {
-               if ( fx.end !== "none" && !fx.setAttr || fx.pos === 1 && !fx.setAttr ) {
-                       jQuery.style( fx.elem, prop, fx.end );
-                       fx.setAttr = true;
-               }
-       };
-});
-
-function getElementStyles( elem ) {
-       var key, len,
-               style = elem.ownerDocument.defaultView ?
-                       elem.ownerDocument.defaultView.getComputedStyle( elem, null ) :
-                       elem.currentStyle,
-               styles = {};
-
-       if ( style && style.length && style[ 0 ] && style[ style[ 0 ] ] ) {
-               len = style.length;
-               while ( len-- ) {
-                       key = style[ len ];
-                       if ( typeof style[ key ] === "string" ) {
-                               styles[ $.camelCase( key ) ] = style[ key ];
-                       }
-               }
-       // support: Opera, IE <9
-       } else {
-               for ( key in style ) {
-                       if ( typeof style[ key ] === "string" ) {
-                               styles[ key ] = style[ key ];
-                       }
-               }
-       }
-
-       return styles;
-}
-
-
-function styleDifference( oldStyle, newStyle ) {
-       var diff = {},
-               name, value;
-
-       for ( name in newStyle ) {
-               value = newStyle[ name ];
-               if ( oldStyle[ name ] !== value ) {
-                       if ( !shorthandStyles[ name ] ) {
-                               if ( $.fx.step[ name ] || !isNaN( parseFloat( value ) ) ) {
-                                       diff[ name ] = value;
-                               }
-                       }
-               }
-       }
-
-       return diff;
-}
-
-// support: jQuery <1.8
-if ( !$.fn.addBack ) {
-       $.fn.addBack = function( selector ) {
-               return this.add( selector == null ?
-                       this.prevObject : this.prevObject.filter( selector )
-               );
-       };
-}
-
-$.effects.animateClass = function( value, duration, easing, callback ) {
-       var o = $.speed( duration, easing, callback );
-
-       return this.queue( function() {
-               var animated = $( this ),
-                       baseClass = animated.attr( "class" ) || "",
-                       applyClassChange,
-                       allAnimations = o.children ? animated.find( "*" ).addBack() : animated;
-
-               // map the animated objects to store the original styles.
-               allAnimations = allAnimations.map(function() {
-                       var el = $( this );
-                       return {
-                               el: el,
-                               start: getElementStyles( this )
-                       };
-               });
-
-               // apply class change
-               applyClassChange = function() {
-                       $.each( classAnimationActions, function(i, action) {
-                               if ( value[ action ] ) {
-                                       animated[ action + "Class" ]( value[ action ] );
-                               }
-                       });
-               };
-               applyClassChange();
-
-               // map all animated objects again - calculate new styles and diff
-               allAnimations = allAnimations.map(function() {
-                       this.end = getElementStyles( this.el[ 0 ] );
-                       this.diff = styleDifference( this.start, this.end );
-                       return this;
-               });
-
-               // apply original class
-               animated.attr( "class", baseClass );
-
-               // map all animated objects again - this time collecting a promise
-               allAnimations = allAnimations.map(function() {
-                       var styleInfo = this,
-                               dfd = $.Deferred(),
-                               opts = $.extend({}, o, {
-                                       queue: false,
-                                       complete: function() {
-                                               dfd.resolve( styleInfo );
-                                       }
-                               });
-
-                       this.el.animate( this.diff, opts );
-                       return dfd.promise();
-               });
-
-               // once all animations have completed:
-               $.when.apply( $, allAnimations.get() ).done(function() {
-
-                       // set the final class
-                       applyClassChange();
-
-                       // for each animated element,
-                       // clear all css properties that were animated
-                       $.each( arguments, function() {
-                               var el = this.el;
-                               $.each( this.diff, function(key) {
-                                       el.css( key, "" );
-                               });
-                       });
-
-                       // this is guarnteed to be there if you use jQuery.speed()
-                       // it also handles dequeuing the next anim...
-                       o.complete.call( animated[ 0 ] );
-               });
-       });
-};
-
-$.fn.extend({
-       _addClass: $.fn.addClass,
-       addClass: function( classNames, speed, easing, callback ) {
-               return speed ?
-                       $.effects.animateClass.call( this,
-                               { add: classNames }, speed, easing, callback ) :
-                       this._addClass( classNames );
-       },
-
-       _removeClass: $.fn.removeClass,
-       removeClass: function( classNames, speed, easing, callback ) {
-               return speed ?
-                       $.effects.animateClass.call( this,
-                               { remove: classNames }, speed, easing, callback ) :
-                       this._removeClass( classNames );
-       },
-
-       _toggleClass: $.fn.toggleClass,
-       toggleClass: function( classNames, force, speed, easing, callback ) {
-               if ( typeof force === "boolean" || force === undefined ) {
-                       if ( !speed ) {
-                               // without speed parameter
-                               return this._toggleClass( classNames, force );
-                       } else {
-                               return $.effects.animateClass.call( this,
-                                       (force ? { add: classNames } : { remove: classNames }),
-                                       speed, easing, callback );
-                       }
-               } else {
-                       // without force parameter
-                       return $.effects.animateClass.call( this,
-                               { toggle: classNames }, force, speed, easing );
-               }
-       },
-
-       switchClass: function( remove, add, speed, easing, callback) {
-               return $.effects.animateClass.call( this, {
-                       add: add,
-                       remove: remove
-               }, speed, easing, callback );
-       }
-});
-
-})();
-
-/******************************************************************************/
-/*********************************** EFFECTS **********************************/
-/******************************************************************************/
-
-(function() {
-
-$.extend( $.effects, {
-       version: "1.10.0",
-
-       // Saves a set of properties in a data storage
-       save: function( element, set ) {
-               for( var i=0; i < set.length; i++ ) {
-                       if ( set[ i ] !== null ) {
-                               element.data( dataSpace + set[ i ], element[ 0 ].style[ set[ i ] ] );
-                       }
-               }
-       },
-
-       // Restores a set of previously saved properties from a data storage
-       restore: function( element, set ) {
-               var val, i;
-               for( i=0; i < set.length; i++ ) {
-                       if ( set[ i ] !== null ) {
-                               val = element.data( dataSpace + set[ i ] );
-                               // support: jQuery 1.6.2
-                               // http://bugs.jquery.com/ticket/9917
-                               // jQuery 1.6.2 incorrectly returns undefined for any falsy value.
-                               // We can't differentiate between "" and 0 here, so we just assume
-                               // empty string since it's likely to be a more common value...
-                               if ( val === undefined ) {
-                                       val = "";
-                               }
-                               element.css( set[ i ], val );
-                       }
-               }
-       },
-
-       setMode: function( el, mode ) {
-               if (mode === "toggle") {
-                       mode = el.is( ":hidden" ) ? "show" : "hide";
-               }
-               return mode;
-       },
-
-       // Translates a [top,left] array into a baseline value
-       // this should be a little more flexible in the future to handle a string & hash
-       getBaseline: function( origin, original ) {
-               var y, x;
-               switch ( origin[ 0 ] ) {
-                       case "top": y = 0; break;
-                       case "middle": y = 0.5; break;
-                       case "bottom": y = 1; break;
-                       default: y = origin[ 0 ] / original.height;
-               }
-               switch ( origin[ 1 ] ) {
-                       case "left": x = 0; break;
-                       case "center": x = 0.5; break;
-                       case "right": x = 1; break;
-                       default: x = origin[ 1 ] / original.width;
-               }
-               return {
-                       x: x,
-                       y: y
-               };
-       },
-
-       // Wraps the element around a wrapper that copies position properties
-       createWrapper: function( element ) {
-
-               // if the element is already wrapped, return it
-               if ( element.parent().is( ".ui-effects-wrapper" )) {
-                       return element.parent();
-               }
-
-               // wrap the element
-               var props = {
-                               width: element.outerWidth(true),
-                               height: element.outerHeight(true),
-                               "float": element.css( "float" )
-                       },
-                       wrapper = $( "<div></div>" )
-                               .addClass( "ui-effects-wrapper" )
-                               .css({
-                                       fontSize: "100%",
-                                       background: "transparent",
-                                       border: "none",
-                                       margin: 0,
-                                       padding: 0
-                               }),
-                       // Store the size in case width/height are defined in % - Fixes #5245
-                       size = {
-                               width: element.width(),
-                               height: element.height()
-                       },
-                       active = document.activeElement;
-
-               // support: Firefox
-               // Firefox incorrectly exposes anonymous content
-               // https://bugzilla.mozilla.org/show_bug.cgi?id=561664
-               try {
-                       active.id;
-               } catch( e ) {
-                       active = document.body;
-               }
-
-               element.wrap( wrapper );
-
-               // Fixes #7595 - Elements lose focus when wrapped.
-               if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) {
-                       $( active ).focus();
-               }
-
-               wrapper = element.parent(); //Hotfix for jQuery 1.4 since some change in wrap() seems to actually lose the reference to the wrapped element
-
-               // transfer positioning properties to the wrapper
-               if ( element.css( "position" ) === "static" ) {
-                       wrapper.css({ position: "relative" });
-                       element.css({ position: "relative" });
-               } else {
-                       $.extend( props, {
-                               position: element.css( "position" ),
-                               zIndex: element.css( "z-index" )
-                       });
-                       $.each([ "top", "left", "bottom", "right" ], function(i, pos) {
-                               props[ pos ] = element.css( pos );
-                               if ( isNaN( parseInt( props[ pos ], 10 ) ) ) {
-                                       props[ pos ] = "auto";
-                               }
-                       });
-                       element.css({
-                               position: "relative",
-                               top: 0,
-                               left: 0,
-                               right: "auto",
-                               bottom: "auto"
-                       });
-               }
-               element.css(size);
-
-               return wrapper.css( props ).show();
-       },
-
-       removeWrapper: function( element ) {
-               var active = document.activeElement;
-
-               if ( element.parent().is( ".ui-effects-wrapper" ) ) {
-                       element.parent().replaceWith( element );
-
-                       // Fixes #7595 - Elements lose focus when wrapped.
-                       if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) {
-                               $( active ).focus();
-                       }
-               }
-
-
-               return element;
-       },
-
-       setTransition: function( element, list, factor, value ) {
-               value = value || {};
-               $.each( list, function( i, x ) {
-                       var unit = element.cssUnit( x );
-                       if ( unit[ 0 ] > 0 ) {
-                               value[ x ] = unit[ 0 ] * factor + unit[ 1 ];
-                       }
-               });
-               return value;
-       }
-});
-
-// return an effect options object for the given parameters:
-function _normalizeArguments( effect, options, speed, callback ) {
-
-       // allow passing all options as the first parameter
-       if ( $.isPlainObject( effect ) ) {
-               options = effect;
-               effect = effect.effect;
-       }
-
-       // convert to an object
-       effect = { effect: effect };
-
-       // catch (effect, null, ...)
-       if ( options == null ) {
-               options = {};
-       }
-
-       // catch (effect, callback)
-       if ( $.isFunction( options ) ) {
-               callback = options;
-               speed = null;
-               options = {};
-       }
-
-       // catch (effect, speed, ?)
-       if ( typeof options === "number" || $.fx.speeds[ options ] ) {
-               callback = speed;
-               speed = options;
-               options = {};
-       }
-
-       // catch (effect, options, callback)
-       if ( $.isFunction( speed ) ) {
-               callback = speed;
-               speed = null;
-       }
-
-       // add options to effect
-       if ( options ) {
-               $.extend( effect, options );
-       }
-
-       speed = speed || options.duration;
-       effect.duration = $.fx.off ? 0 :
-               typeof speed === "number" ? speed :
-               speed in $.fx.speeds ? $.fx.speeds[ speed ] :
-               $.fx.speeds._default;
-
-       effect.complete = callback || options.complete;
-
-       return effect;
-}
-
-function standardSpeed( speed ) {
-       // valid standard speeds
-       if ( !speed || typeof speed === "number" || $.fx.speeds[ speed ] ) {
-               return true;
-       }
-
-       // invalid strings - treat as "normal" speed
-       return typeof speed === "string" && !$.effects.effect[ speed ];
-}
-
-$.fn.extend({
-       effect: function( /* effect, options, speed, callback */ ) {
-               var args = _normalizeArguments.apply( this, arguments ),
-                       mode = args.mode,
-                       queue = args.queue,
-                       effectMethod = $.effects.effect[ args.effect ];
-
-               if ( $.fx.off || !effectMethod ) {
-                       // delegate to the original method (e.g., .show()) if possible
-                       if ( mode ) {
-                               return this[ mode ]( args.duration, args.complete );
-                       } else {
-                               return this.each( function() {
-                                       if ( args.complete ) {
-                                               args.complete.call( this );
-                                       }
-                               });
-                       }
-               }
-
-               function run( next ) {
-                       var elem = $( this ),
-                               complete = args.complete,
-                               mode = args.mode;
-
-                       function done() {
-                               if ( $.isFunction( complete ) ) {
-                                       complete.call( elem[0] );
-                               }
-                               if ( $.isFunction( next ) ) {
-                                       next();
-                               }
-                       }
-
-                       // if the element is hiddden and mode is hide,
-                       // or element is visible and mode is show
-                       if ( elem.is( ":hidden" ) ? mode === "hide" : mode === "show" ) {
-                               done();
-                       } else {
-                               effectMethod.call( elem[0], args, done );
-                       }
-               }
-
-               return queue === false ? this.each( run ) : this.queue( queue || "fx", run );
-       },
-
-       _show: $.fn.show,
-       show: function( speed ) {
-               if ( standardSpeed( speed ) ) {
-                       return this._show.apply( this, arguments );
-               } else {
-                       var args = _normalizeArguments.apply( this, arguments );
-                       args.mode = "show";
-                       return this.effect.call( this, args );
-               }
-       },
-
-       _hide: $.fn.hide,
-       hide: function( speed ) {
-               if ( standardSpeed( speed ) ) {
-                       return this._hide.apply( this, arguments );
-               } else {
-                       var args = _normalizeArguments.apply( this, arguments );
-                       args.mode = "hide";
-                       return this.effect.call( this, args );
-               }
-       },
-
-       // jQuery core overloads toggle and creates _toggle
-       __toggle: $.fn.toggle,
-       toggle: function( speed ) {
-               if ( standardSpeed( speed ) || typeof speed === "boolean" || $.isFunction( speed ) ) {
-                       return this.__toggle.apply( this, arguments );
-               } else {
-                       var args = _normalizeArguments.apply( this, arguments );
-                       args.mode = "toggle";
-                       return this.effect.call( this, args );
-               }
-       },
-
-       // helper functions
-       cssUnit: function(key) {
-               var style = this.css( key ),
-                       val = [];
-
-               $.each( [ "em", "px", "%", "pt" ], function( i, unit ) {
-                       if ( style.indexOf( unit ) > 0 ) {
-                               val = [ parseFloat( style ), unit ];
-                       }
-               });
-               return val;
-       }
-});
-
-})();
-
-/******************************************************************************/
-/*********************************** EASING ***********************************/
-/******************************************************************************/
-
-(function() {
-
-// based on easing equations from Robert Penner (http://www.robertpenner.com/easing)
-
-var baseEasings = {};
-
-$.each( [ "Quad", "Cubic", "Quart", "Quint", "Expo" ], function( i, name ) {
-       baseEasings[ name ] = function( p ) {
-               return Math.pow( p, i + 2 );
-       };
-});
-
-$.extend( baseEasings, {
-       Sine: function ( p ) {
-               return 1 - Math.cos( p * Math.PI / 2 );
-       },
-       Circ: function ( p ) {
-               return 1 - Math.sqrt( 1 - p * p );
-       },
-       Elastic: function( p ) {
-               return p === 0 || p === 1 ? p :
-                       -Math.pow( 2, 8 * (p - 1) ) * Math.sin( ( (p - 1) * 80 - 7.5 ) * Math.PI / 15 );
-       },
-       Back: function( p ) {
-               return p * p * ( 3 * p - 2 );
-       },
-       Bounce: function ( p ) {
-               var pow2,
-                       bounce = 4;
-
-               while ( p < ( ( pow2 = Math.pow( 2, --bounce ) ) - 1 ) / 11 ) {}
-               return 1 / Math.pow( 4, 3 - bounce ) - 7.5625 * Math.pow( ( pow2 * 3 - 2 ) / 22 - p, 2 );
-       }
-});
-
-$.each( baseEasings, function( name, easeIn ) {
-       $.easing[ "easeIn" + name ] = easeIn;
-       $.easing[ "easeOut" + name ] = function( p ) {
-               return 1 - easeIn( 1 - p );
-       };
-       $.easing[ "easeInOut" + name ] = function( p ) {
-               return p < 0.5 ?
-                       easeIn( p * 2 ) / 2 :
-                       1 - easeIn( p * -2 + 2 ) / 2;
-       };
-});
-
-})();
-
-})(jQuery));
diff --git a/catalogue/static/catalogue/js/jquery.cycle.all.js b/catalogue/static/catalogue/js/jquery.cycle.all.js
deleted file mode 100644 (file)
index 666afda..0000000
+++ /dev/null
@@ -1,1538 +0,0 @@
-/*!
- * jQuery Cycle Plugin (with Transition Definitions)
- * Examples and documentation at: http://jquery.malsup.com/cycle/
- * Copyright (c) 2007-2012 M. Alsup
- * Version: 2.9999.81 (15-JAN-2013)
- * Dual licensed under the MIT and GPL licenses.
- * http://jquery.malsup.com/license.html
- * Requires: jQuery v1.7.1 or later
- */
-;(function($, undefined) {
-"use strict";
-
-var ver = '2.9999.81';
-
-function debug(s) {
-       if ($.fn.cycle.debug)
-               log(s);
-}              
-function log() {
-       if (window.console && console.log)
-               console.log('[cycle] ' + Array.prototype.join.call(arguments,' '));
-}
-$.expr[':'].paused = function(el) {
-       return el.cyclePause;
-};
-
-
-// the options arg can be...
-//   a number  - indicates an immediate transition should occur to the given slide index
-//   a string  - 'pause', 'resume', 'toggle', 'next', 'prev', 'stop', 'destroy' or the name of a transition effect (ie, 'fade', 'zoom', etc)
-//   an object - properties to control the slideshow
-//
-// the arg2 arg can be...
-//   the name of an fx (only used in conjunction with a numeric value for 'options')
-//   the value true (only used in first arg == 'resume') and indicates
-//      that the resume should occur immediately (not wait for next timeout)
-
-$.fn.cycle = function(options, arg2) {
-       var o = { s: this.selector, c: this.context };
-
-       // in 1.3+ we can fix mistakes with the ready state
-       if (this.length === 0 && options != 'stop') {
-               if (!$.isReady && o.s) {
-                       log('DOM not ready, queuing slideshow');
-                       $(function() {
-                               $(o.s,o.c).cycle(options,arg2);
-                       });
-                       return this;
-               }
-               // is your DOM ready?  http://docs.jquery.com/Tutorials:Introducing_$(document).ready()
-               log('terminating; zero elements found by selector' + ($.isReady ? '' : ' (DOM not ready)'));
-               return this;
-       }
-
-       // iterate the matched nodeset
-       return this.each(function() {
-               var opts = handleArguments(this, options, arg2);
-               if (opts === false)
-                       return;
-
-               opts.updateActivePagerLink = opts.updateActivePagerLink || $.fn.cycle.updateActivePagerLink;
-               
-               // stop existing slideshow for this container (if there is one)
-               if (this.cycleTimeout)
-                       clearTimeout(this.cycleTimeout);
-               this.cycleTimeout = this.cyclePause = 0;
-               this.cycleStop = 0; // issue #108
-
-               var $cont = $(this);
-               var $slides = opts.slideExpr ? $(opts.slideExpr, this) : $cont.children();
-               var els = $slides.get();
-
-               if (els.length < 2) {
-                       log('terminating; too few slides: ' + els.length);
-                       return;
-               }
-
-               var opts2 = buildOptions($cont, $slides, els, opts, o);
-               if (opts2 === false)
-                       return;
-
-               var startTime = opts2.continuous ? 10 : getTimeout(els[opts2.currSlide], els[opts2.nextSlide], opts2, !opts2.backwards);
-
-               // if it's an auto slideshow, kick it off
-               if (startTime) {
-                       startTime += (opts2.delay || 0);
-                       if (startTime < 10)
-                               startTime = 10;
-                       debug('first timeout: ' + startTime);
-                       this.cycleTimeout = setTimeout(function(){go(els,opts2,0,!opts.backwards);}, startTime);
-               }
-       });
-};
-
-function triggerPause(cont, byHover, onPager) {
-       var opts = $(cont).data('cycle.opts');
-       if (!opts)
-               return;
-       var paused = !!cont.cyclePause;
-       if (paused && opts.paused)
-               opts.paused(cont, opts, byHover, onPager);
-       else if (!paused && opts.resumed)
-               opts.resumed(cont, opts, byHover, onPager);
-}
-
-// process the args that were passed to the plugin fn
-function handleArguments(cont, options, arg2) {
-       if (cont.cycleStop === undefined)
-               cont.cycleStop = 0;
-       if (options === undefined || options === null)
-               options = {};
-       if (options.constructor == String) {
-               switch(options) {
-               case 'destroy':
-               case 'stop':
-                       var opts = $(cont).data('cycle.opts');
-                       if (!opts)
-                               return false;
-                       cont.cycleStop++; // callbacks look for change
-                       if (cont.cycleTimeout)
-                               clearTimeout(cont.cycleTimeout);
-                       cont.cycleTimeout = 0;
-                       if (opts.elements)
-                               $(opts.elements).stop();
-                       $(cont).removeData('cycle.opts');
-                       if (options == 'destroy')
-                               destroy(cont, opts);
-                       return false;
-               case 'toggle':
-                       cont.cyclePause = (cont.cyclePause === 1) ? 0 : 1;
-                       checkInstantResume(cont.cyclePause, arg2, cont);
-                       triggerPause(cont);
-                       return false;
-               case 'pause':
-                       cont.cyclePause = 1;
-                       triggerPause(cont);
-                       return false;
-               case 'resume':
-                       cont.cyclePause = 0;
-                       checkInstantResume(false, arg2, cont);
-                       triggerPause(cont);
-                       return false;
-               case 'prev':
-               case 'next':
-                       opts = $(cont).data('cycle.opts');
-                       if (!opts) {
-                               log('options not found, "prev/next" ignored');
-                               return false;
-                       }
-                       $.fn.cycle[options](opts);
-                       return false;
-               default:
-                       options = { fx: options };
-               }
-               return options;
-       }
-       else if (options.constructor == Number) {
-               // go to the requested slide
-               var num = options;
-               options = $(cont).data('cycle.opts');
-               if (!options) {
-                       log('options not found, can not advance slide');
-                       return false;
-               }
-               if (num < 0 || num >= options.elements.length) {
-                       log('invalid slide index: ' + num);
-                       return false;
-               }
-               options.nextSlide = num;
-               if (cont.cycleTimeout) {
-                       clearTimeout(cont.cycleTimeout);
-                       cont.cycleTimeout = 0;
-               }
-               if (typeof arg2 == 'string')
-                       options.oneTimeFx = arg2;
-               go(options.elements, options, 1, num >= options.currSlide);
-               return false;
-       }
-       return options;
-       
-       function checkInstantResume(isPaused, arg2, cont) {
-               if (!isPaused && arg2 === true) { // resume now!
-                       var options = $(cont).data('cycle.opts');
-                       if (!options) {
-                               log('options not found, can not resume');
-                               return false;
-                       }
-                       if (cont.cycleTimeout) {
-                               clearTimeout(cont.cycleTimeout);
-                               cont.cycleTimeout = 0;
-                       }
-                       go(options.elements, options, 1, !options.backwards);
-               }
-       }
-}
-
-function removeFilter(el, opts) {
-       if (!$.support.opacity && opts.cleartype && el.style.filter) {
-               try { el.style.removeAttribute('filter'); }
-               catch(smother) {} // handle old opera versions
-       }
-}
-
-// unbind event handlers
-function destroy(cont, opts) {
-       if (opts.next)
-               $(opts.next).unbind(opts.prevNextEvent);
-       if (opts.prev)
-               $(opts.prev).unbind(opts.prevNextEvent);
-       
-       if (opts.pager || opts.pagerAnchorBuilder)
-               $.each(opts.pagerAnchors || [], function() {
-                       this.unbind().remove();
-               });
-       opts.pagerAnchors = null;
-       $(cont).unbind('mouseenter.cycle mouseleave.cycle');
-       if (opts.destroy) // callback
-               opts.destroy(opts);
-}
-
-// one-time initialization
-function buildOptions($cont, $slides, els, options, o) {
-       var startingSlideSpecified;
-       // support metadata plugin (v1.0 and v2.0)
-       var opts = $.extend({}, $.fn.cycle.defaults, options || {}, $.metadata ? $cont.metadata() : $.meta ? $cont.data() : {});
-       var meta = $.isFunction($cont.data) ? $cont.data(opts.metaAttr) : null;
-       if (meta)
-               opts = $.extend(opts, meta);
-       if (opts.autostop)
-               opts.countdown = opts.autostopCount || els.length;
-
-       var cont = $cont[0];
-       $cont.data('cycle.opts', opts);
-       opts.$cont = $cont;
-       opts.stopCount = cont.cycleStop;
-       opts.elements = els;
-       opts.before = opts.before ? [opts.before] : [];
-       opts.after = opts.after ? [opts.after] : [];
-
-       // push some after callbacks
-       if (!$.support.opacity && opts.cleartype)
-               opts.after.push(function() { removeFilter(this, opts); });
-       if (opts.continuous)
-               opts.after.push(function() { go(els,opts,0,!opts.backwards); });
-
-       saveOriginalOpts(opts);
-
-       // clearType corrections
-       if (!$.support.opacity && opts.cleartype && !opts.cleartypeNoBg)
-               clearTypeFix($slides);
-
-       // container requires non-static position so that slides can be position within
-       if ($cont.css('position') == 'static')
-               $cont.css('position', 'relative');
-       if (opts.width)
-               $cont.width(opts.width);
-       if (opts.height && opts.height != 'auto')
-               $cont.height(opts.height);
-
-       if (opts.startingSlide !== undefined) {
-               opts.startingSlide = parseInt(opts.startingSlide,10);
-               if (opts.startingSlide >= els.length || opts.startSlide < 0)
-                       opts.startingSlide = 0; // catch bogus input
-               else 
-                       startingSlideSpecified = true;
-       }
-       else if (opts.backwards)
-               opts.startingSlide = els.length - 1;
-       else
-               opts.startingSlide = 0;
-
-       // if random, mix up the slide array
-       if (opts.random) {
-               opts.randomMap = [];
-               for (var i = 0; i < els.length; i++)
-                       opts.randomMap.push(i);
-               opts.randomMap.sort(function(a,b) {return Math.random() - 0.5;});
-               if (startingSlideSpecified) {
-                       // try to find the specified starting slide and if found set start slide index in the map accordingly
-                       for ( var cnt = 0; cnt < els.length; cnt++ ) {
-                               if ( opts.startingSlide == opts.randomMap[cnt] ) {
-                                       opts.randomIndex = cnt;
-                               }
-                       }
-               }
-               else {
-                       opts.randomIndex = 1;
-                       opts.startingSlide = opts.randomMap[1];
-               }
-       }
-       else if (opts.startingSlide >= els.length)
-               opts.startingSlide = 0; // catch bogus input
-       opts.currSlide = opts.startingSlide || 0;
-       var first = opts.startingSlide;
-
-       // set position and zIndex on all the slides
-       $slides.css({position: 'absolute', top:0, left:0}).hide().each(function(i) {
-               var z;
-               if (opts.backwards)
-                       z = first ? i <= first ? els.length + (i-first) : first-i : els.length-i;
-               else
-                       z = first ? i >= first ? els.length - (i-first) : first-i : els.length-i;
-               $(this).css('z-index', z);
-       });
-
-       // make sure first slide is visible
-       $(els[first]).css('opacity',1).show(); // opacity bit needed to handle restart use case
-       removeFilter(els[first], opts);
-
-       // stretch slides
-       if (opts.fit) {
-               if (!opts.aspect) {
-               if (opts.width)
-                   $slides.width(opts.width);
-               if (opts.height && opts.height != 'auto')
-                   $slides.height(opts.height);
-               } else {
-                       $slides.each(function(){
-                               var $slide = $(this);
-                               var ratio = (opts.aspect === true) ? $slide.width()/$slide.height() : opts.aspect;
-                               if( opts.width && $slide.width() != opts.width ) {
-                                       $slide.width( opts.width );
-                                       $slide.height( opts.width / ratio );
-                               }
-
-                               if( opts.height && $slide.height() < opts.height ) {
-                                       $slide.height( opts.height );
-                                       $slide.width( opts.height * ratio );
-                               }
-                       });
-               }
-       }
-
-       if (opts.center && ((!opts.fit) || opts.aspect)) {
-               $slides.each(function(){
-                       var $slide = $(this);
-                       $slide.css({
-                               "margin-left": opts.width ?
-                                       ((opts.width - $slide.width()) / 2) + "px" :
-                                       0,
-                               "margin-top": opts.height ?
-                                       ((opts.height - $slide.height()) / 2) + "px" :
-                                       0
-                       });
-               });
-       }
-
-       if (opts.center && !opts.fit && !opts.slideResize) {
-               $slides.each(function(){
-                       var $slide = $(this);
-                       $slide.css({
-                               "margin-left": opts.width ? ((opts.width - $slide.width()) / 2) + "px" : 0,
-                               "margin-top": opts.height ? ((opts.height - $slide.height()) / 2) + "px" : 0
-                       });
-               });
-       }
-               
-       // stretch container
-       var reshape = (opts.containerResize || opts.containerResizeHeight) && !$cont.innerHeight();
-       if (reshape) { // do this only if container has no size http://tinyurl.com/da2oa9
-               var maxw = 0, maxh = 0;
-               for(var j=0; j < els.length; j++) {
-                       var $e = $(els[j]), e = $e[0], w = $e.outerWidth(), h = $e.outerHeight();
-                       if (!w) w = e.offsetWidth || e.width || $e.attr('width');
-                       if (!h) h = e.offsetHeight || e.height || $e.attr('height');
-                       maxw = w > maxw ? w : maxw;
-                       maxh = h > maxh ? h : maxh;
-               }
-               if (opts.containerResize && maxw > 0 && maxh > 0)
-                       $cont.css({width:maxw+'px',height:maxh+'px'});
-               if (opts.containerResizeHeight && maxh > 0)
-                       $cont.css({height:maxh+'px'});
-       }
-
-       var pauseFlag = false;  // https://github.com/malsup/cycle/issues/44
-       if (opts.pause)
-               $cont.bind('mouseenter.cycle', function(){
-                       pauseFlag = true;
-                       this.cyclePause++;
-                       triggerPause(cont, true);
-               }).bind('mouseleave.cycle', function(){
-                               if (pauseFlag)
-                                       this.cyclePause--;
-                               triggerPause(cont, true);
-               });
-
-       if (supportMultiTransitions(opts) === false)
-               return false;
-
-       // apparently a lot of people use image slideshows without height/width attributes on the images.
-       // Cycle 2.50+ requires the sizing info for every slide; this block tries to deal with that.
-       var requeue = false;
-       options.requeueAttempts = options.requeueAttempts || 0;
-       $slides.each(function() {
-               // try to get height/width of each slide
-               var $el = $(this);
-               this.cycleH = (opts.fit && opts.height) ? opts.height : ($el.height() || this.offsetHeight || this.height || $el.attr('height') || 0);
-               this.cycleW = (opts.fit && opts.width) ? opts.width : ($el.width() || this.offsetWidth || this.width || $el.attr('width') || 0);
-
-               if ( $el.is('img') ) {
-                       var loading = (this.cycleH === 0 && this.cycleW === 0 && !this.complete);
-                       // don't requeue for images that are still loading but have a valid size
-                       if (loading) {
-                               if (o.s && opts.requeueOnImageNotLoaded && ++options.requeueAttempts < 100) { // track retry count so we don't loop forever
-                                       log(options.requeueAttempts,' - img slide not loaded, requeuing slideshow: ', this.src, this.cycleW, this.cycleH);
-                                       setTimeout(function() {$(o.s,o.c).cycle(options);}, opts.requeueTimeout);
-                                       requeue = true;
-                                       return false; // break each loop
-                               }
-                               else {
-                                       log('could not determine size of image: '+this.src, this.cycleW, this.cycleH);
-                               }
-                       }
-               }
-               return true;
-       });
-
-       if (requeue)
-               return false;
-
-       opts.cssBefore = opts.cssBefore || {};
-       opts.cssAfter = opts.cssAfter || {};
-       opts.cssFirst = opts.cssFirst || {};
-       opts.animIn = opts.animIn || {};
-       opts.animOut = opts.animOut || {};
-
-       $slides.not(':eq('+first+')').css(opts.cssBefore);
-       $($slides[first]).css(opts.cssFirst);
-
-       if (opts.timeout) {
-               opts.timeout = parseInt(opts.timeout,10);
-               // ensure that timeout and speed settings are sane
-               if (opts.speed.constructor == String)
-                       opts.speed = $.fx.speeds[opts.speed] || parseInt(opts.speed,10);
-               if (!opts.sync)
-                       opts.speed = opts.speed / 2;
-               
-               var buffer = opts.fx == 'none' ? 0 : opts.fx == 'shuffle' ? 500 : 250;
-               while((opts.timeout - opts.speed) < buffer) // sanitize timeout
-                       opts.timeout += opts.speed;
-       }
-       if (opts.easing)
-               opts.easeIn = opts.easeOut = opts.easing;
-       if (!opts.speedIn)
-               opts.speedIn = opts.speed;
-       if (!opts.speedOut)
-               opts.speedOut = opts.speed;
-
-       opts.slideCount = els.length;
-       opts.currSlide = opts.lastSlide = first;
-       if (opts.random) {
-               if (++opts.randomIndex == els.length)
-                       opts.randomIndex = 0;
-               opts.nextSlide = opts.randomMap[opts.randomIndex];
-       }
-       else if (opts.backwards)
-               opts.nextSlide = opts.startingSlide === 0 ? (els.length-1) : opts.startingSlide-1;
-       else
-               opts.nextSlide = opts.startingSlide >= (els.length-1) ? 0 : opts.startingSlide+1;
-
-       // run transition init fn
-       if (!opts.multiFx) {
-               var init = $.fn.cycle.transitions[opts.fx];
-               if ($.isFunction(init))
-                       init($cont, $slides, opts);
-               else if (opts.fx != 'custom' && !opts.multiFx) {
-                       log('unknown transition: ' + opts.fx,'; slideshow terminating');
-                       return false;
-               }
-       }
-
-       // fire artificial events
-       var e0 = $slides[first];
-       if (!opts.skipInitializationCallbacks) {
-               if (opts.before.length)
-                       opts.before[0].apply(e0, [e0, e0, opts, true]);
-               if (opts.after.length)
-                       opts.after[0].apply(e0, [e0, e0, opts, true]);
-       }
-       if (opts.next)
-               $(opts.next).bind(opts.prevNextEvent,function(){return advance(opts,1);});
-       if (opts.prev)
-               $(opts.prev).bind(opts.prevNextEvent,function(){return advance(opts,0);});
-       if (opts.pager || opts.pagerAnchorBuilder)
-               buildPager(els,opts);
-
-       exposeAddSlide(opts, els);
-
-       return opts;
-}
-
-// save off original opts so we can restore after clearing state
-function saveOriginalOpts(opts) {
-       opts.original = { before: [], after: [] };
-       opts.original.cssBefore = $.extend({}, opts.cssBefore);
-       opts.original.cssAfter  = $.extend({}, opts.cssAfter);
-       opts.original.animIn    = $.extend({}, opts.animIn);
-       opts.original.animOut   = $.extend({}, opts.animOut);
-       $.each(opts.before, function() { opts.original.before.push(this); });
-       $.each(opts.after,  function() { opts.original.after.push(this); });
-}
-
-function supportMultiTransitions(opts) {
-       var i, tx, txs = $.fn.cycle.transitions;
-       // look for multiple effects
-       if (opts.fx.indexOf(',') > 0) {
-               opts.multiFx = true;
-               opts.fxs = opts.fx.replace(/\s*/g,'').split(',');
-               // discard any bogus effect names
-               for (i=0; i < opts.fxs.length; i++) {
-                       var fx = opts.fxs[i];
-                       tx = txs[fx];
-                       if (!tx || !txs.hasOwnProperty(fx) || !$.isFunction(tx)) {
-                               log('discarding unknown transition: ',fx);
-                               opts.fxs.splice(i,1);
-                               i--;
-                       }
-               }
-               // if we have an empty list then we threw everything away!
-               if (!opts.fxs.length) {
-                       log('No valid transitions named; slideshow terminating.');
-                       return false;
-               }
-       }
-       else if (opts.fx == 'all') {  // auto-gen the list of transitions
-               opts.multiFx = true;
-               opts.fxs = [];
-               for (var p in txs) {
-                       if (txs.hasOwnProperty(p)) {
-                               tx = txs[p];
-                               if (txs.hasOwnProperty(p) && $.isFunction(tx))
-                                       opts.fxs.push(p);
-                       }
-               }
-       }
-       if (opts.multiFx && opts.randomizeEffects) {
-               // munge the fxs array to make effect selection random
-               var r1 = Math.floor(Math.random() * 20) + 30;
-               for (i = 0; i < r1; i++) {
-                       var r2 = Math.floor(Math.random() * opts.fxs.length);
-                       opts.fxs.push(opts.fxs.splice(r2,1)[0]);
-               }
-               debug('randomized fx sequence: ',opts.fxs);
-       }
-       return true;
-}
-
-// provide a mechanism for adding slides after the slideshow has started
-function exposeAddSlide(opts, els) {
-       opts.addSlide = function(newSlide, prepend) {
-               var $s = $(newSlide), s = $s[0];
-               if (!opts.autostopCount)
-                       opts.countdown++;
-               els[prepend?'unshift':'push'](s);
-               if (opts.els)
-                       opts.els[prepend?'unshift':'push'](s); // shuffle needs this
-               opts.slideCount = els.length;
-
-               // add the slide to the random map and resort
-               if (opts.random) {
-                       opts.randomMap.push(opts.slideCount-1);
-                       opts.randomMap.sort(function(a,b) {return Math.random() - 0.5;});
-               }
-
-               $s.css('position','absolute');
-               $s[prepend?'prependTo':'appendTo'](opts.$cont);
-
-               if (prepend) {
-                       opts.currSlide++;
-                       opts.nextSlide++;
-               }
-
-               if (!$.support.opacity && opts.cleartype && !opts.cleartypeNoBg)
-                       clearTypeFix($s);
-
-               if (opts.fit && opts.width)
-                       $s.width(opts.width);
-               if (opts.fit && opts.height && opts.height != 'auto')
-                       $s.height(opts.height);
-               s.cycleH = (opts.fit && opts.height) ? opts.height : $s.height();
-               s.cycleW = (opts.fit && opts.width) ? opts.width : $s.width();
-
-               $s.css(opts.cssBefore);
-
-               if (opts.pager || opts.pagerAnchorBuilder)
-                       $.fn.cycle.createPagerAnchor(els.length-1, s, $(opts.pager), els, opts);
-
-               if ($.isFunction(opts.onAddSlide))
-                       opts.onAddSlide($s);
-               else
-                       $s.hide(); // default behavior
-       };
-}
-
-// reset internal state; we do this on every pass in order to support multiple effects
-$.fn.cycle.resetState = function(opts, fx) {
-       fx = fx || opts.fx;
-       opts.before = []; opts.after = [];
-       opts.cssBefore = $.extend({}, opts.original.cssBefore);
-       opts.cssAfter  = $.extend({}, opts.original.cssAfter);
-       opts.animIn     = $.extend({}, opts.original.animIn);
-       opts.animOut   = $.extend({}, opts.original.animOut);
-       opts.fxFn = null;
-       $.each(opts.original.before, function() { opts.before.push(this); });
-       $.each(opts.original.after,  function() { opts.after.push(this); });
-
-       // re-init
-       var init = $.fn.cycle.transitions[fx];
-       if ($.isFunction(init))
-               init(opts.$cont, $(opts.elements), opts);
-};
-
-// this is the main engine fn, it handles the timeouts, callbacks and slide index mgmt
-function go(els, opts, manual, fwd) {
-       var p = opts.$cont[0], curr = els[opts.currSlide], next = els[opts.nextSlide];
-
-       // opts.busy is true if we're in the middle of an animation
-       if (manual && opts.busy && opts.manualTrump) {
-               // let manual transitions requests trump active ones
-               debug('manualTrump in go(), stopping active transition');
-               $(els).stop(true,true);
-               opts.busy = 0;
-               clearTimeout(p.cycleTimeout);
-       }
-
-       // don't begin another timeout-based transition if there is one active
-       if (opts.busy) {
-               debug('transition active, ignoring new tx request');
-               return;
-       }
-
-
-       // stop cycling if we have an outstanding stop request
-       if (p.cycleStop != opts.stopCount || p.cycleTimeout === 0 && !manual)
-               return;
-
-       // check to see if we should stop cycling based on autostop options
-       if (!manual && !p.cyclePause && !opts.bounce &&
-               ((opts.autostop && (--opts.countdown <= 0)) ||
-               (opts.nowrap && !opts.random && opts.nextSlide < opts.currSlide))) {
-               if (opts.end)
-                       opts.end(opts);
-               return;
-       }
-
-       // if slideshow is paused, only transition on a manual trigger
-       var changed = false;
-       if ((manual || !p.cyclePause) && (opts.nextSlide != opts.currSlide)) {
-               changed = true;
-               var fx = opts.fx;
-               // keep trying to get the slide size if we don't have it yet
-               curr.cycleH = curr.cycleH || $(curr).height();
-               curr.cycleW = curr.cycleW || $(curr).width();
-               next.cycleH = next.cycleH || $(next).height();
-               next.cycleW = next.cycleW || $(next).width();
-
-               // support multiple transition types
-               if (opts.multiFx) {
-                       if (fwd && (opts.lastFx === undefined || ++opts.lastFx >= opts.fxs.length))
-                               opts.lastFx = 0;
-                       else if (!fwd && (opts.lastFx === undefined || --opts.lastFx < 0))
-                               opts.lastFx = opts.fxs.length - 1;
-                       fx = opts.fxs[opts.lastFx];
-               }
-
-               // one-time fx overrides apply to:  $('div').cycle(3,'zoom');
-               if (opts.oneTimeFx) {
-                       fx = opts.oneTimeFx;
-                       opts.oneTimeFx = null;
-               }
-
-               $.fn.cycle.resetState(opts, fx);
-
-               // run the before callbacks
-               if (opts.before.length)
-                       $.each(opts.before, function(i,o) {
-                               if (p.cycleStop != opts.stopCount) return;
-                               o.apply(next, [curr, next, opts, fwd]);
-                       });
-
-               // stage the after callacks
-               var after = function() {
-                       opts.busy = 0;
-                       $.each(opts.after, function(i,o) {
-                               if (p.cycleStop != opts.stopCount) return;
-                               o.apply(next, [curr, next, opts, fwd]);
-                       });
-                       if (!p.cycleStop) {
-                               // queue next transition
-                               queueNext();
-                       }
-               };
-
-               debug('tx firing('+fx+'); currSlide: ' + opts.currSlide + '; nextSlide: ' + opts.nextSlide);
-               
-               // get ready to perform the transition
-               opts.busy = 1;
-               if (opts.fxFn) // fx function provided?
-                       opts.fxFn(curr, next, opts, after, fwd, manual && opts.fastOnEvent);
-               else if ($.isFunction($.fn.cycle[opts.fx])) // fx plugin ?
-                       $.fn.cycle[opts.fx](curr, next, opts, after, fwd, manual && opts.fastOnEvent);
-               else
-                       $.fn.cycle.custom(curr, next, opts, after, fwd, manual && opts.fastOnEvent);
-       }
-       else {
-               queueNext();
-       }
-
-       if (changed || opts.nextSlide == opts.currSlide) {
-               // calculate the next slide
-               var roll;
-               opts.lastSlide = opts.currSlide;
-               if (opts.random) {
-                       opts.currSlide = opts.nextSlide;
-                       if (++opts.randomIndex == els.length) {
-                               opts.randomIndex = 0;
-                               opts.randomMap.sort(function(a,b) {return Math.random() - 0.5;});
-                       }
-                       opts.nextSlide = opts.randomMap[opts.randomIndex];
-                       if (opts.nextSlide == opts.currSlide)
-                               opts.nextSlide = (opts.currSlide == opts.slideCount - 1) ? 0 : opts.currSlide + 1;
-               }
-               else if (opts.backwards) {
-                       roll = (opts.nextSlide - 1) < 0;
-                       if (roll && opts.bounce) {
-                               opts.backwards = !opts.backwards;
-                               opts.nextSlide = 1;
-                               opts.currSlide = 0;
-                       }
-                       else {
-                               opts.nextSlide = roll ? (els.length-1) : opts.nextSlide-1;
-                               opts.currSlide = roll ? 0 : opts.nextSlide+1;
-                       }
-               }
-               else { // sequence
-                       roll = (opts.nextSlide + 1) == els.length;
-                       if (roll && opts.bounce) {
-                               opts.backwards = !opts.backwards;
-                               opts.nextSlide = els.length-2;
-                               opts.currSlide = els.length-1;
-                       }
-                       else {
-                               opts.nextSlide = roll ? 0 : opts.nextSlide+1;
-                               opts.currSlide = roll ? els.length-1 : opts.nextSlide-1;
-                       }
-               }
-       }
-       if (changed && opts.pager)
-               opts.updateActivePagerLink(opts.pager, opts.currSlide, opts.activePagerClass);
-       
-       function queueNext() {
-               // stage the next transition
-               var ms = 0, timeout = opts.timeout;
-               if (opts.timeout && !opts.continuous) {
-                       ms = getTimeout(els[opts.currSlide], els[opts.nextSlide], opts, fwd);
-         if (opts.fx == 'shuffle')
-            ms -= opts.speedOut;
-      }
-               else if (opts.continuous && p.cyclePause) // continuous shows work off an after callback, not this timer logic
-                       ms = 10;
-               if (ms > 0)
-                       p.cycleTimeout = setTimeout(function(){ go(els, opts, 0, !opts.backwards); }, ms);
-       }
-}
-
-// invoked after transition
-$.fn.cycle.updateActivePagerLink = function(pager, currSlide, clsName) {
-   $(pager).each(function() {
-       $(this).children().removeClass(clsName).eq(currSlide).addClass(clsName);
-   });
-};
-
-// calculate timeout value for current transition
-function getTimeout(curr, next, opts, fwd) {
-       if (opts.timeoutFn) {
-               // call user provided calc fn
-               var t = opts.timeoutFn.call(curr,curr,next,opts,fwd);
-               while (opts.fx != 'none' && (t - opts.speed) < 250) // sanitize timeout
-                       t += opts.speed;
-               debug('calculated timeout: ' + t + '; speed: ' + opts.speed);
-               if (t !== false)
-                       return t;
-       }
-       return opts.timeout;
-}
-
-// expose next/prev function, caller must pass in state
-$.fn.cycle.next = function(opts) { advance(opts,1); };
-$.fn.cycle.prev = function(opts) { advance(opts,0);};
-
-// advance slide forward or back
-function advance(opts, moveForward) {
-       var val = moveForward ? 1 : -1;
-       var els = opts.elements;
-       var p = opts.$cont[0], timeout = p.cycleTimeout;
-       if (timeout) {
-               clearTimeout(timeout);
-               p.cycleTimeout = 0;
-       }
-       if (opts.random && val < 0) {
-               // move back to the previously display slide
-               opts.randomIndex--;
-               if (--opts.randomIndex == -2)
-                       opts.randomIndex = els.length-2;
-               else if (opts.randomIndex == -1)
-                       opts.randomIndex = els.length-1;
-               opts.nextSlide = opts.randomMap[opts.randomIndex];
-       }
-       else if (opts.random) {
-               opts.nextSlide = opts.randomMap[opts.randomIndex];
-       }
-       else {
-               opts.nextSlide = opts.currSlide + val;
-               if (opts.nextSlide < 0) {
-                       if (opts.nowrap) return false;
-                       opts.nextSlide = els.length - 1;
-               }
-               else if (opts.nextSlide >= els.length) {
-                       if (opts.nowrap) return false;
-                       opts.nextSlide = 0;
-               }
-       }
-
-       var cb = opts.onPrevNextEvent || opts.prevNextClick; // prevNextClick is deprecated
-       if ($.isFunction(cb))
-               cb(val > 0, opts.nextSlide, els[opts.nextSlide]);
-       go(els, opts, 1, moveForward);
-       return false;
-}
-
-function buildPager(els, opts) {
-       var $p = $(opts.pager);
-       $.each(els, function(i,o) {
-               $.fn.cycle.createPagerAnchor(i,o,$p,els,opts);
-       });
-       opts.updateActivePagerLink(opts.pager, opts.startingSlide, opts.activePagerClass);
-}
-
-$.fn.cycle.createPagerAnchor = function(i, el, $p, els, opts) {
-       var a;
-       if ($.isFunction(opts.pagerAnchorBuilder)) {
-               a = opts.pagerAnchorBuilder(i,el);
-               debug('pagerAnchorBuilder('+i+', el) returned: ' + a);
-       }
-       else
-               a = '<a href="#">'+(i+1)+'</a>';
-               
-       if (!a)
-               return;
-       var $a = $(a);
-       // don't reparent if anchor is in the dom
-       if ($a.parents('body').length === 0) {
-               var arr = [];
-               if ($p.length > 1) {
-                       $p.each(function() {
-                               var $clone = $a.clone(true);
-                               $(this).append($clone);
-                               arr.push($clone[0]);
-                       });
-                       $a = $(arr);
-               }
-               else {
-                       $a.appendTo($p);
-               }
-       }
-
-       opts.pagerAnchors =  opts.pagerAnchors || [];
-       opts.pagerAnchors.push($a);
-       
-       var pagerFn = function(e) {
-               e.preventDefault();
-               opts.nextSlide = i;
-               var p = opts.$cont[0], timeout = p.cycleTimeout;
-               if (timeout) {
-                       clearTimeout(timeout);
-                       p.cycleTimeout = 0;
-               }
-               var cb = opts.onPagerEvent || opts.pagerClick; // pagerClick is deprecated
-               if ($.isFunction(cb))
-                       cb(opts.nextSlide, els[opts.nextSlide]);
-               go(els,opts,1,opts.currSlide < i); // trigger the trans
-//             return false; // <== allow bubble
-       };
-       
-       if ( /mouseenter|mouseover/i.test(opts.pagerEvent) ) {
-               $a.hover(pagerFn, function(){/* no-op */} );
-       }
-       else {
-               $a.bind(opts.pagerEvent, pagerFn);
-       }
-       
-       if ( ! /^click/.test(opts.pagerEvent) && !opts.allowPagerClickBubble)
-               $a.bind('click.cycle', function(){return false;}); // suppress click
-       
-       var cont = opts.$cont[0];
-       var pauseFlag = false; // https://github.com/malsup/cycle/issues/44
-       if (opts.pauseOnPagerHover) {
-               $a.hover(
-                       function() { 
-                               pauseFlag = true;
-                               cont.cyclePause++; 
-                               triggerPause(cont,true,true);
-                       }, function() { 
-                               if (pauseFlag)
-                                       cont.cyclePause--; 
-                               triggerPause(cont,true,true);
-                       } 
-               );
-       }
-};
-
-// helper fn to calculate the number of slides between the current and the next
-$.fn.cycle.hopsFromLast = function(opts, fwd) {
-       var hops, l = opts.lastSlide, c = opts.currSlide;
-       if (fwd)
-               hops = c > l ? c - l : opts.slideCount - l;
-       else
-               hops = c < l ? l - c : l + opts.slideCount - c;
-       return hops;
-};
-
-// fix clearType problems in ie6 by setting an explicit bg color
-// (otherwise text slides look horrible during a fade transition)
-function clearTypeFix($slides) {
-       debug('applying clearType background-color hack');
-       function hex(s) {
-               s = parseInt(s,10).toString(16);
-               return s.length < 2 ? '0'+s : s;
-       }
-       function getBg(e) {
-               for ( ; e && e.nodeName.toLowerCase() != 'html'; e = e.parentNode) {
-                       var v = $.css(e,'background-color');
-                       if (v && v.indexOf('rgb') >= 0 ) {
-                               var rgb = v.match(/\d+/g);
-                               return '#'+ hex(rgb[0]) + hex(rgb[1]) + hex(rgb[2]);
-                       }
-                       if (v && v != 'transparent')
-                               return v;
-               }
-               return '#ffffff';
-       }
-       $slides.each(function() { $(this).css('background-color', getBg(this)); });
-}
-
-// reset common props before the next transition
-$.fn.cycle.commonReset = function(curr,next,opts,w,h,rev) {
-       $(opts.elements).not(curr).hide();
-       if (typeof opts.cssBefore.opacity == 'undefined')
-               opts.cssBefore.opacity = 1;
-       opts.cssBefore.display = 'block';
-       if (opts.slideResize && w !== false && next.cycleW > 0)
-               opts.cssBefore.width = next.cycleW;
-       if (opts.slideResize && h !== false && next.cycleH > 0)
-               opts.cssBefore.height = next.cycleH;
-       opts.cssAfter = opts.cssAfter || {};
-       opts.cssAfter.display = 'none';
-       $(curr).css('zIndex',opts.slideCount + (rev === true ? 1 : 0));
-       $(next).css('zIndex',opts.slideCount + (rev === true ? 0 : 1));
-};
-
-// the actual fn for effecting a transition
-$.fn.cycle.custom = function(curr, next, opts, cb, fwd, speedOverride) {
-       var $l = $(curr), $n = $(next);
-       var speedIn = opts.speedIn, speedOut = opts.speedOut, easeIn = opts.easeIn, easeOut = opts.easeOut;
-       $n.css(opts.cssBefore);
-       if (speedOverride) {
-               if (typeof speedOverride == 'number')
-                       speedIn = speedOut = speedOverride;
-               else
-                       speedIn = speedOut = 1;
-               easeIn = easeOut = null;
-       }
-       var fn = function() {
-               $n.animate(opts.animIn, speedIn, easeIn, function() {
-                       cb();
-               });
-       };
-       $l.animate(opts.animOut, speedOut, easeOut, function() {
-               $l.css(opts.cssAfter);
-               if (!opts.sync) 
-                       fn();
-       });
-       if (opts.sync) fn();
-};
-
-// transition definitions - only fade is defined here, transition pack defines the rest
-$.fn.cycle.transitions = {
-       fade: function($cont, $slides, opts) {
-               $slides.not(':eq('+opts.currSlide+')').css('opacity',0);
-               opts.before.push(function(curr,next,opts) {
-                       $.fn.cycle.commonReset(curr,next,opts);
-                       opts.cssBefore.opacity = 0;
-               });
-               opts.animIn        = { opacity: 1 };
-               opts.animOut   = { opacity: 0 };
-               opts.cssBefore = { top: 0, left: 0 };
-       }
-};
-
-$.fn.cycle.ver = function() { return ver; };
-
-// override these globally if you like (they are all optional)
-$.fn.cycle.defaults = {
-    activePagerClass: 'activeSlide', // class name used for the active pager link
-    after:            null,     // transition callback (scope set to element that was shown):  function(currSlideElement, nextSlideElement, options, forwardFlag)
-    allowPagerClickBubble: false, // allows or prevents click event on pager anchors from bubbling
-    animIn:           null,     // properties that define how the slide animates in
-    animOut:          null,     // properties that define how the slide animates out
-    aspect:           false,    // preserve aspect ratio during fit resizing, cropping if necessary (must be used with fit option)
-    autostop:         0,        // true to end slideshow after X transitions (where X == slide count)
-    autostopCount:    0,        // number of transitions (optionally used with autostop to define X)
-    backwards:        false,    // true to start slideshow at last slide and move backwards through the stack
-    before:           null,     // transition callback (scope set to element to be shown):     function(currSlideElement, nextSlideElement, options, forwardFlag)
-    center:           null,     // set to true to have cycle add top/left margin to each slide (use with width and height options)
-    cleartype:        !$.support.opacity,  // true if clearType corrections should be applied (for IE)
-    cleartypeNoBg:    false,    // set to true to disable extra cleartype fixing (leave false to force background color setting on slides)
-    containerResize:  1,        // resize container to fit largest slide
-    containerResizeHeight:  0,  // resize containers height to fit the largest slide but leave the width dynamic
-    continuous:       0,        // true to start next transition immediately after current one completes
-    cssAfter:         null,     // properties that defined the state of the slide after transitioning out
-    cssBefore:        null,     // properties that define the initial state of the slide before transitioning in
-    delay:            0,        // additional delay (in ms) for first transition (hint: can be negative)
-    easeIn:           null,     // easing for "in" transition
-    easeOut:          null,     // easing for "out" transition
-    easing:           null,     // easing method for both in and out transitions
-    end:              null,     // callback invoked when the slideshow terminates (use with autostop or nowrap options): function(options)
-    fastOnEvent:      0,        // force fast transitions when triggered manually (via pager or prev/next); value == time in ms
-    fit:              0,        // force slides to fit container
-    fx:               'fade',   // name of transition effect (or comma separated names, ex: 'fade,scrollUp,shuffle')
-    fxFn:             null,     // function used to control the transition: function(currSlideElement, nextSlideElement, options, afterCalback, forwardFlag)
-    height:           'auto',   // container height (if the 'fit' option is true, the slides will be set to this height as well)
-    manualTrump:      true,     // causes manual transition to stop an active transition instead of being ignored
-    metaAttr:         'cycle',  // data- attribute that holds the option data for the slideshow
-    next:             null,     // element, jQuery object, or jQuery selector string for the element to use as event trigger for next slide
-    nowrap:           0,        // true to prevent slideshow from wrapping
-    onPagerEvent:     null,     // callback fn for pager events: function(zeroBasedSlideIndex, slideElement)
-    onPrevNextEvent:  null,     // callback fn for prev/next events: function(isNext, zeroBasedSlideIndex, slideElement)
-    pager:            null,     // element, jQuery object, or jQuery selector string for the element to use as pager container
-    pagerAnchorBuilder: null,   // callback fn for building anchor links:  function(index, DOMelement)
-    pagerEvent:       'click.cycle', // name of event which drives the pager navigation
-    pause:            0,        // true to enable "pause on hover"
-    pauseOnPagerHover: 0,       // true to pause when hovering over pager link
-    prev:             null,     // element, jQuery object, or jQuery selector string for the element to use as event trigger for previous slide
-    prevNextEvent:    'click.cycle',// event which drives the manual transition to the previous or next slide
-    random:           0,        // true for random, false for sequence (not applicable to shuffle fx)
-    randomizeEffects: 1,        // valid when multiple effects are used; true to make the effect sequence random
-    requeueOnImageNotLoaded: true, // requeue the slideshow if any image slides are not yet loaded
-    requeueTimeout:   250,      // ms delay for requeue
-    rev:              0,        // causes animations to transition in reverse (for effects that support it such as scrollHorz/scrollVert/shuffle)
-    shuffle:          null,     // coords for shuffle animation, ex: { top:15, left: 200 }
-    skipInitializationCallbacks: false, // set to true to disable the first before/after callback that occurs prior to any transition
-    slideExpr:        null,     // expression for selecting slides (if something other than all children is required)
-    slideResize:      1,        // force slide width/height to fixed size before every transition
-    speed:            1000,     // speed of the transition (any valid fx speed value)
-    speedIn:          null,     // speed of the 'in' transition
-    speedOut:         null,     // speed of the 'out' transition
-    startingSlide:    undefined,// zero-based index of the first slide to be displayed
-    sync:             1,        // true if in/out transitions should occur simultaneously
-    timeout:          4000,     // milliseconds between slide transitions (0 to disable auto advance)
-    timeoutFn:        null,     // callback for determining per-slide timeout value:  function(currSlideElement, nextSlideElement, options, forwardFlag)
-    updateActivePagerLink: null,// callback fn invoked to update the active pager link (adds/removes activePagerClass style)
-    width:            null      // container width (if the 'fit' option is true, the slides will be set to this width as well)
-};
-
-})(jQuery);
-
-
-/*!
- * jQuery Cycle Plugin Transition Definitions
- * This script is a plugin for the jQuery Cycle Plugin
- * Examples and documentation at: http://malsup.com/jquery/cycle/
- * Copyright (c) 2007-2010 M. Alsup
- * Version:     2.73
- * Dual licensed under the MIT and GPL licenses:
- * http://www.opensource.org/licenses/mit-license.php
- * http://www.gnu.org/licenses/gpl.html
- */
-(function($) {
-"use strict";
-
-//
-// These functions define slide initialization and properties for the named
-// transitions. To save file size feel free to remove any of these that you
-// don't need.
-//
-$.fn.cycle.transitions.none = function($cont, $slides, opts) {
-       opts.fxFn = function(curr,next,opts,after){
-               $(next).show();
-               $(curr).hide();
-               after();
-       };
-};
-
-// not a cross-fade, fadeout only fades out the top slide
-$.fn.cycle.transitions.fadeout = function($cont, $slides, opts) {
-       $slides.not(':eq('+opts.currSlide+')').css({ display: 'block', 'opacity': 1 });
-       opts.before.push(function(curr,next,opts,w,h,rev) {
-               $(curr).css('zIndex',opts.slideCount + (rev !== true ? 1 : 0));
-               $(next).css('zIndex',opts.slideCount + (rev !== true ? 0 : 1));
-       });
-       opts.animIn.opacity = 1;
-       opts.animOut.opacity = 0;
-       opts.cssBefore.opacity = 1;
-       opts.cssBefore.display = 'block';
-       opts.cssAfter.zIndex = 0;
-};
-
-// scrollUp/Down/Left/Right
-$.fn.cycle.transitions.scrollUp = function($cont, $slides, opts) {
-       $cont.css('overflow','hidden');
-       opts.before.push($.fn.cycle.commonReset);
-       var h = $cont.height();
-       opts.cssBefore.top = h;
-       opts.cssBefore.left = 0;
-       opts.cssFirst.top = 0;
-       opts.animIn.top = 0;
-       opts.animOut.top = -h;
-};
-$.fn.cycle.transitions.scrollDown = function($cont, $slides, opts) {
-       $cont.css('overflow','hidden');
-       opts.before.push($.fn.cycle.commonReset);
-       var h = $cont.height();
-       opts.cssFirst.top = 0;
-       opts.cssBefore.top = -h;
-       opts.cssBefore.left = 0;
-       opts.animIn.top = 0;
-       opts.animOut.top = h;
-};
-$.fn.cycle.transitions.scrollLeft = function($cont, $slides, opts) {
-       $cont.css('overflow','hidden');
-       opts.before.push($.fn.cycle.commonReset);
-       var w = $cont.width();
-       opts.cssFirst.left = 0;
-       opts.cssBefore.left = w;
-       opts.cssBefore.top = 0;
-       opts.animIn.left = 0;
-       opts.animOut.left = 0-w;
-};
-$.fn.cycle.transitions.scrollRight = function($cont, $slides, opts) {
-       $cont.css('overflow','hidden');
-       opts.before.push($.fn.cycle.commonReset);
-       var w = $cont.width();
-       opts.cssFirst.left = 0;
-       opts.cssBefore.left = -w;
-       opts.cssBefore.top = 0;
-       opts.animIn.left = 0;
-       opts.animOut.left = w;
-};
-$.fn.cycle.transitions.scrollHorz = function($cont, $slides, opts) {
-       $cont.css('overflow','hidden').width();
-       opts.before.push(function(curr, next, opts, fwd) {
-               if (opts.rev)
-                       fwd = !fwd;
-               $.fn.cycle.commonReset(curr,next,opts);
-               opts.cssBefore.left = fwd ? (next.cycleW-1) : (1-next.cycleW);
-               opts.animOut.left = fwd ? -curr.cycleW : curr.cycleW;
-       });
-       opts.cssFirst.left = 0;
-       opts.cssBefore.top = 0;
-       opts.animIn.left = 0;
-       opts.animOut.top = 0;
-};
-$.fn.cycle.transitions.scrollVert = function($cont, $slides, opts) {
-       $cont.css('overflow','hidden');
-       opts.before.push(function(curr, next, opts, fwd) {
-               if (opts.rev)
-                       fwd = !fwd;
-               $.fn.cycle.commonReset(curr,next,opts);
-               opts.cssBefore.top = fwd ? (1-next.cycleH) : (next.cycleH-1);
-               opts.animOut.top = fwd ? curr.cycleH : -curr.cycleH;
-       });
-       opts.cssFirst.top = 0;
-       opts.cssBefore.left = 0;
-       opts.animIn.top = 0;
-       opts.animOut.left = 0;
-};
-
-// slideX/slideY
-$.fn.cycle.transitions.slideX = function($cont, $slides, opts) {
-       opts.before.push(function(curr, next, opts) {
-               $(opts.elements).not(curr).hide();
-               $.fn.cycle.commonReset(curr,next,opts,false,true);
-               opts.animIn.width = next.cycleW;
-       });
-       opts.cssBefore.left = 0;
-       opts.cssBefore.top = 0;
-       opts.cssBefore.width = 0;
-       opts.animIn.width = 'show';
-       opts.animOut.width = 0;
-};
-$.fn.cycle.transitions.slideY = function($cont, $slides, opts) {
-       opts.before.push(function(curr, next, opts) {
-               $(opts.elements).not(curr).hide();
-               $.fn.cycle.commonReset(curr,next,opts,true,false);
-               opts.animIn.height = next.cycleH;
-       });
-       opts.cssBefore.left = 0;
-       opts.cssBefore.top = 0;
-       opts.cssBefore.height = 0;
-       opts.animIn.height = 'show';
-       opts.animOut.height = 0;
-};
-
-// shuffle
-$.fn.cycle.transitions.shuffle = function($cont, $slides, opts) {
-       var i, w = $cont.css('overflow', 'visible').width();
-       $slides.css({left: 0, top: 0});
-       opts.before.push(function(curr,next,opts) {
-               $.fn.cycle.commonReset(curr,next,opts,true,true,true);
-       });
-       // only adjust speed once!
-       if (!opts.speedAdjusted) {
-               opts.speed = opts.speed / 2; // shuffle has 2 transitions
-               opts.speedAdjusted = true;
-       }
-       opts.random = 0;
-       opts.shuffle = opts.shuffle || {left:-w, top:15};
-       opts.els = [];
-       for (i=0; i < $slides.length; i++)
-               opts.els.push($slides[i]);
-
-       for (i=0; i < opts.currSlide; i++)
-               opts.els.push(opts.els.shift());
-
-       // custom transition fn (hat tip to Benjamin Sterling for this bit of sweetness!)
-       opts.fxFn = function(curr, next, opts, cb, fwd) {
-               if (opts.rev)
-                       fwd = !fwd;
-               var $el = fwd ? $(curr) : $(next);
-               $(next).css(opts.cssBefore);
-               var count = opts.slideCount;
-               $el.animate(opts.shuffle, opts.speedIn, opts.easeIn, function() {
-                       var hops = $.fn.cycle.hopsFromLast(opts, fwd);
-                       for (var k=0; k < hops; k++) {
-                               if (fwd)
-                                       opts.els.push(opts.els.shift());
-                               else
-                                       opts.els.unshift(opts.els.pop());
-                       }
-                       if (fwd) {
-                               for (var i=0, len=opts.els.length; i < len; i++)
-                                       $(opts.els[i]).css('z-index', len-i+count);
-                       }
-                       else {
-                               var z = $(curr).css('z-index');
-                               $el.css('z-index', parseInt(z,10)+1+count);
-                       }
-                       $el.animate({left:0, top:0}, opts.speedOut, opts.easeOut, function() {
-                               $(fwd ? this : curr).hide();
-                               if (cb) cb();
-                       });
-               });
-       };
-       $.extend(opts.cssBefore, { display: 'block', opacity: 1, top: 0, left: 0 });
-};
-
-// turnUp/Down/Left/Right
-$.fn.cycle.transitions.turnUp = function($cont, $slides, opts) {
-       opts.before.push(function(curr, next, opts) {
-               $.fn.cycle.commonReset(curr,next,opts,true,false);
-               opts.cssBefore.top = next.cycleH;
-               opts.animIn.height = next.cycleH;
-               opts.animOut.width = next.cycleW;
-       });
-       opts.cssFirst.top = 0;
-       opts.cssBefore.left = 0;
-       opts.cssBefore.height = 0;
-       opts.animIn.top = 0;
-       opts.animOut.height = 0;
-};
-$.fn.cycle.transitions.turnDown = function($cont, $slides, opts) {
-       opts.before.push(function(curr, next, opts) {
-               $.fn.cycle.commonReset(curr,next,opts,true,false);
-               opts.animIn.height = next.cycleH;
-               opts.animOut.top   = curr.cycleH;
-       });
-       opts.cssFirst.top = 0;
-       opts.cssBefore.left = 0;
-       opts.cssBefore.top = 0;
-       opts.cssBefore.height = 0;
-       opts.animOut.height = 0;
-};
-$.fn.cycle.transitions.turnLeft = function($cont, $slides, opts) {
-       opts.before.push(function(curr, next, opts) {
-               $.fn.cycle.commonReset(curr,next,opts,false,true);
-               opts.cssBefore.left = next.cycleW;
-               opts.animIn.width = next.cycleW;
-       });
-       opts.cssBefore.top = 0;
-       opts.cssBefore.width = 0;
-       opts.animIn.left = 0;
-       opts.animOut.width = 0;
-};
-$.fn.cycle.transitions.turnRight = function($cont, $slides, opts) {
-       opts.before.push(function(curr, next, opts) {
-               $.fn.cycle.commonReset(curr,next,opts,false,true);
-               opts.animIn.width = next.cycleW;
-               opts.animOut.left = curr.cycleW;
-       });
-       $.extend(opts.cssBefore, { top: 0, left: 0, width: 0 });
-       opts.animIn.left = 0;
-       opts.animOut.width = 0;
-};
-
-// zoom
-$.fn.cycle.transitions.zoom = function($cont, $slides, opts) {
-       opts.before.push(function(curr, next, opts) {
-               $.fn.cycle.commonReset(curr,next,opts,false,false,true);
-               opts.cssBefore.top = next.cycleH/2;
-               opts.cssBefore.left = next.cycleW/2;
-               $.extend(opts.animIn, { top: 0, left: 0, width: next.cycleW, height: next.cycleH });
-               $.extend(opts.animOut, { width: 0, height: 0, top: curr.cycleH/2, left: curr.cycleW/2 });
-       });
-       opts.cssFirst.top = 0;
-       opts.cssFirst.left = 0;
-       opts.cssBefore.width = 0;
-       opts.cssBefore.height = 0;
-};
-
-// fadeZoom
-$.fn.cycle.transitions.fadeZoom = function($cont, $slides, opts) {
-       opts.before.push(function(curr, next, opts) {
-               $.fn.cycle.commonReset(curr,next,opts,false,false);
-               opts.cssBefore.left = next.cycleW/2;
-               opts.cssBefore.top = next.cycleH/2;
-               $.extend(opts.animIn, { top: 0, left: 0, width: next.cycleW, height: next.cycleH });
-       });
-       opts.cssBefore.width = 0;
-       opts.cssBefore.height = 0;
-       opts.animOut.opacity = 0;
-};
-
-// blindX
-$.fn.cycle.transitions.blindX = function($cont, $slides, opts) {
-       var w = $cont.css('overflow','hidden').width();
-       opts.before.push(function(curr, next, opts) {
-               $.fn.cycle.commonReset(curr,next,opts);
-               opts.animIn.width = next.cycleW;
-               opts.animOut.left   = curr.cycleW;
-       });
-       opts.cssBefore.left = w;
-       opts.cssBefore.top = 0;
-       opts.animIn.left = 0;
-       opts.animOut.left = w;
-};
-// blindY
-$.fn.cycle.transitions.blindY = function($cont, $slides, opts) {
-       var h = $cont.css('overflow','hidden').height();
-       opts.before.push(function(curr, next, opts) {
-               $.fn.cycle.commonReset(curr,next,opts);
-               opts.animIn.height = next.cycleH;
-               opts.animOut.top   = curr.cycleH;
-       });
-       opts.cssBefore.top = h;
-       opts.cssBefore.left = 0;
-       opts.animIn.top = 0;
-       opts.animOut.top = h;
-};
-// blindZ
-$.fn.cycle.transitions.blindZ = function($cont, $slides, opts) {
-       var h = $cont.css('overflow','hidden').height();
-       var w = $cont.width();
-       opts.before.push(function(curr, next, opts) {
-               $.fn.cycle.commonReset(curr,next,opts);
-               opts.animIn.height = next.cycleH;
-               opts.animOut.top   = curr.cycleH;
-       });
-       opts.cssBefore.top = h;
-       opts.cssBefore.left = w;
-       opts.animIn.top = 0;
-       opts.animIn.left = 0;
-       opts.animOut.top = h;
-       opts.animOut.left = w;
-};
-
-// growX - grow horizontally from centered 0 width
-$.fn.cycle.transitions.growX = function($cont, $slides, opts) {
-       opts.before.push(function(curr, next, opts) {
-               $.fn.cycle.commonReset(curr,next,opts,false,true);
-               opts.cssBefore.left = this.cycleW/2;
-               opts.animIn.left = 0;
-               opts.animIn.width = this.cycleW;
-               opts.animOut.left = 0;
-       });
-       opts.cssBefore.top = 0;
-       opts.cssBefore.width = 0;
-};
-// growY - grow vertically from centered 0 height
-$.fn.cycle.transitions.growY = function($cont, $slides, opts) {
-       opts.before.push(function(curr, next, opts) {
-               $.fn.cycle.commonReset(curr,next,opts,true,false);
-               opts.cssBefore.top = this.cycleH/2;
-               opts.animIn.top = 0;
-               opts.animIn.height = this.cycleH;
-               opts.animOut.top = 0;
-       });
-       opts.cssBefore.height = 0;
-       opts.cssBefore.left = 0;
-};
-
-// curtainX - squeeze in both edges horizontally
-$.fn.cycle.transitions.curtainX = function($cont, $slides, opts) {
-       opts.before.push(function(curr, next, opts) {
-               $.fn.cycle.commonReset(curr,next,opts,false,true,true);
-               opts.cssBefore.left = next.cycleW/2;
-               opts.animIn.left = 0;
-               opts.animIn.width = this.cycleW;
-               opts.animOut.left = curr.cycleW/2;
-               opts.animOut.width = 0;
-       });
-       opts.cssBefore.top = 0;
-       opts.cssBefore.width = 0;
-};
-// curtainY - squeeze in both edges vertically
-$.fn.cycle.transitions.curtainY = function($cont, $slides, opts) {
-       opts.before.push(function(curr, next, opts) {
-               $.fn.cycle.commonReset(curr,next,opts,true,false,true);
-               opts.cssBefore.top = next.cycleH/2;
-               opts.animIn.top = 0;
-               opts.animIn.height = next.cycleH;
-               opts.animOut.top = curr.cycleH/2;
-               opts.animOut.height = 0;
-       });
-       opts.cssBefore.height = 0;
-       opts.cssBefore.left = 0;
-};
-
-// cover - curr slide covered by next slide
-$.fn.cycle.transitions.cover = function($cont, $slides, opts) {
-       var d = opts.direction || 'left';
-       var w = $cont.css('overflow','hidden').width();
-       var h = $cont.height();
-       opts.before.push(function(curr, next, opts) {
-               $.fn.cycle.commonReset(curr,next,opts);
-               opts.cssAfter.display = '';
-               if (d == 'right')
-                       opts.cssBefore.left = -w;
-               else if (d == 'up')
-                       opts.cssBefore.top = h;
-               else if (d == 'down')
-                       opts.cssBefore.top = -h;
-               else
-                       opts.cssBefore.left = w;
-       });
-       opts.animIn.left = 0;
-       opts.animIn.top = 0;
-       opts.cssBefore.top = 0;
-       opts.cssBefore.left = 0;
-};
-
-// uncover - curr slide moves off next slide
-$.fn.cycle.transitions.uncover = function($cont, $slides, opts) {
-       var d = opts.direction || 'left';
-       var w = $cont.css('overflow','hidden').width();
-       var h = $cont.height();
-       opts.before.push(function(curr, next, opts) {
-               $.fn.cycle.commonReset(curr,next,opts,true,true,true);
-               if (d == 'right')
-                       opts.animOut.left = w;
-               else if (d == 'up')
-                       opts.animOut.top = -h;
-               else if (d == 'down')
-                       opts.animOut.top = h;
-               else
-                       opts.animOut.left = -w;
-       });
-       opts.animIn.left = 0;
-       opts.animIn.top = 0;
-       opts.cssBefore.top = 0;
-       opts.cssBefore.left = 0;
-};
-
-// toss - move top slide and fade away
-$.fn.cycle.transitions.toss = function($cont, $slides, opts) {
-       var w = $cont.css('overflow','visible').width();
-       var h = $cont.height();
-       opts.before.push(function(curr, next, opts) {
-               $.fn.cycle.commonReset(curr,next,opts,true,true,true);
-               // provide default toss settings if animOut not provided
-               if (!opts.animOut.left && !opts.animOut.top)
-                       $.extend(opts.animOut, { left: w*2, top: -h/2, opacity: 0 });
-               else
-                       opts.animOut.opacity = 0;
-       });
-       opts.cssBefore.left = 0;
-       opts.cssBefore.top = 0;
-       opts.animIn.left = 0;
-};
-
-// wipe - clip animation
-$.fn.cycle.transitions.wipe = function($cont, $slides, opts) {
-       var w = $cont.css('overflow','hidden').width();
-       var h = $cont.height();
-       opts.cssBefore = opts.cssBefore || {};
-       var clip;
-       if (opts.clip) {
-               if (/l2r/.test(opts.clip))
-                       clip = 'rect(0px 0px '+h+'px 0px)';
-               else if (/r2l/.test(opts.clip))
-                       clip = 'rect(0px '+w+'px '+h+'px '+w+'px)';
-               else if (/t2b/.test(opts.clip))
-                       clip = 'rect(0px '+w+'px 0px 0px)';
-               else if (/b2t/.test(opts.clip))
-                       clip = 'rect('+h+'px '+w+'px '+h+'px 0px)';
-               else if (/zoom/.test(opts.clip)) {
-                       var top = parseInt(h/2,10);
-                       var left = parseInt(w/2,10);
-                       clip = 'rect('+top+'px '+left+'px '+top+'px '+left+'px)';
-               }
-       }
-
-       opts.cssBefore.clip = opts.cssBefore.clip || clip || 'rect(0px 0px 0px 0px)';
-
-       var d = opts.cssBefore.clip.match(/(\d+)/g);
-       var t = parseInt(d[0],10), r = parseInt(d[1],10), b = parseInt(d[2],10), l = parseInt(d[3],10);
-
-       opts.before.push(function(curr, next, opts) {
-               if (curr == next) return;
-               var $curr = $(curr), $next = $(next);
-               $.fn.cycle.commonReset(curr,next,opts,true,true,false);
-               opts.cssAfter.display = 'block';
-
-               var step = 1, count = parseInt((opts.speedIn / 13),10) - 1;
-               (function f() {
-                       var tt = t ? t - parseInt(step * (t/count),10) : 0;
-                       var ll = l ? l - parseInt(step * (l/count),10) : 0;
-                       var bb = b < h ? b + parseInt(step * ((h-b)/count || 1),10) : h;
-                       var rr = r < w ? r + parseInt(step * ((w-r)/count || 1),10) : w;
-                       $next.css({ clip: 'rect('+tt+'px '+rr+'px '+bb+'px '+ll+'px)' });
-                       (step++ <= count) ? setTimeout(f, 13) : $curr.css('display', 'none');
-               })();
-       });
-       $.extend(opts.cssBefore, { display: 'block', opacity: 1, top: 0, left: 0 });
-       opts.animIn        = { left: 0 };
-       opts.animOut   = { left: 0 };
-};
-
-})(jQuery);
diff --git a/catalogue/static/catalogue/js/lesson-list.js b/catalogue/static/catalogue/js/lesson-list.js
deleted file mode 100644 (file)
index 62bbb65..0000000
+++ /dev/null
@@ -1,60 +0,0 @@
-(function($){
-$(function() {
-
-
-function scrollTo(thing) {
-    $('html, body').scrollTop($(thing).offset().top - $('#level-chooser').outerHeight());
-}
-
-function updateView() {
-    var scrolltop = $(window).scrollTop();
-
-    $('#level-chooser-place').each(function(i, el){
-        if (scrolltop > $(el).offset().top) {
-            $("#level-chooser").addClass("fixed");
-        }
-        else {
-            $("#level-chooser").removeClass("fixed");
-        }
-    });
-
-    $('.level-toc').each(function(i, el) {
-        var $sect = $($(el).parent());
-        var menu_top = $('#level-chooser').outerHeight();
-        var menu_scrolltop = scrolltop + menu_top;
-
-        if (menu_scrolltop + 2 >= $sect.offset().top && 
-                menu_scrolltop < $sect.offset().top + $sect.outerHeight()) {
-            $(el).addClass("fixed").css("top", Math.min(
-                menu_top, 
-                - scrolltop + $sect.offset().top + $sect.outerHeight() - $(el).outerHeight()
-            ));
-            $("#level-chooser a[href='#" + $sect.attr('id') + "']").addClass('active');
-        }
-        else {
-            $(el).removeClass("fixed");
-            $("#level-chooser a[href='#" + $sect.attr('id') + "']").removeClass('active');
-        }
-    });
-}
-
-
-
-$("#level-chooser a, .level-toc a").click(function(ev) {
-    ev.preventDefault();
-    scrollTo($(this).attr('href'));
-});
-
-
-
-
-
-updateView();
-$(document).scroll(updateView);
-if (window.location.hash) {
-    scrollTo(window.location.hash);
-}
-
-
-});
-})(jQuery);
diff --git a/catalogue/static/catalogue/js/lesson.js b/catalogue/static/catalogue/js/lesson.js
deleted file mode 100755 (executable)
index 080eb45..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-(function($){
-$(function() {
-
-
-$('a.image').colorbox({
-    maxWidth: '100%',
-    maxHeight: '100%',
-});
-
-
-});
-})($);
diff --git a/catalogue/templates/catalogue/latest_blog_posts.html b/catalogue/templates/catalogue/latest_blog_posts.html
deleted file mode 100755 (executable)
index e9eb109..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-<ol class="link-list">
-{% for post in posts %}
-    <li><a href="{{ post.link }}">{{ post.title }}</a></li>
-{% endfor %}
-</ol>
diff --git a/catalogue/templates/catalogue/lesson/added-var/lesson_detail.html b/catalogue/templates/catalogue/lesson/added-var/lesson_detail.html
deleted file mode 100644 (file)
index a40c999..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-{% extends "catalogue/lesson/lesson_detail.html" %}
-{% load static from staticfiles %}
-
-{% block lesson-info %}
-<section class="box">
-    <div class="box-icon"><img src="/static/img/icons/activity-time.png"><br>45m</div>
-
-    {% include "catalogue/lesson/box-icons.html" %}
-
-    <p>Ta lekcja jest częścią tematu
-    <a href="{% url 'catalogue_lessons' %}#{{ object.level.slug }}_varsaviana"><strong>Edukacja varsavianistyczna</strong></a>
-    na poziomie {{ object.level|lower }}.
-    </p>
-    <div style="clear: right"></div>
-</section>
-
-{% endblock %}
-
-
-{% block sidebar-top %}
-<div class="buttons" style="padding-bottom: 1em; border-bottom: 1px solid red;">
-
-{% if object.package %}
-    <section class="box-button"><a href="{{ object.package.url }}" class="dl-button">Pobierz całą lekcję</a></section>
-{% endif %}
-{% if object.student_package %}
-    <section><a href="{{ object.student_package.url }}" class="dl-button">Pobierz lekcję w wersji dla ucznia</a></section>
-{% endif %}
-
-</div>
-{% endblock %}
diff --git a/catalogue/templates/catalogue/lesson/added/lesson_detail.html b/catalogue/templates/catalogue/lesson/added/lesson_detail.html
deleted file mode 100644 (file)
index 62ec0a4..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-{% extends "catalogue/lesson/lesson_detail.html" %}
-{% load static from staticfiles %}
-
-{% block lesson-info %}
-<section class="box">
-    <div class="box-icon"><img src="/static/img/icons/activity-time.png"><br>45m</div>
-
-    {% include "catalogue/lesson/box-icons.html" %}
-
-    <p>Ta lekcja jest częścią tematu
-    <a href="{% url 'catalogue_lessons' %}#{{ object.level.slug }}_filmowa"><strong>Edukacja filmowa</strong></a>
-    na poziomie {{ object.level|lower }}.
-    </p>
-    <div style="clear: right"></div>
-</section>
-
-{% endblock %}
-
-
-{% block sidebar-top %}
-<div class="buttons" style="padding-bottom: 1em; border-bottom: 1px solid red;">
-
-{% if object.package %}
-    <section class="box-button"><a href="{{ object.package.url }}" class="dl-button">Pobierz całą lekcję</a></section>
-{% endif %}
-{% if object.student_package %}
-    <section><a href="{{ object.student_package.url }}" class="dl-button">Pobierz lekcję w wersji dla ucznia</a></section>
-{% endif %}
-
-</div>
-{% endblock %}
diff --git a/catalogue/templates/catalogue/lesson/appendix/lesson_detail.html b/catalogue/templates/catalogue/lesson/appendix/lesson_detail.html
deleted file mode 100755 (executable)
index 98b6e3b..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-{% extends "catalogue/lesson/lesson_detail.html" %}
-
-{% block lesson-info %}
-{% endblock %}
-
-
-{% block suggest-link %}
-<a href="{% url 'contact_form' 'sugestie' %}?temat={{ object.title|urlencode }}">
-    Zgłoś swoją uwagę na temat tej strony.
-</a>
-{% endblock %}
diff --git a/catalogue/templates/catalogue/lesson/box-icons.html b/catalogue/templates/catalogue/lesson/box-icons.html
deleted file mode 100644 (file)
index 2963698..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-{% load static from staticfiles %}
-{% if object.requires_internet %}
-<div class="box-icon"><img src="{% static 'img/icons/internet_black.png' %}"
-        title="Wymaga dostępu do Internetu"
-        alt="Wymaga dostępu do Internetu"
-    ><br>Internet</div>
-{% else %}
-<div class="box-icon"><img src="{% static 'img/icons/nointernet_black.png' %}"
-        title="Nie wymaga dostępu do Internetu"
-        alt="Nie wymaga dostępu do Internetu"
-        ><br>Bez Internetu</div>
-{% endif %}
-{% if publisher %}
-<div class="box-icon"><img src="{{ publisher.logo.url }}"
-        title="{{ publisher.name }}"
-        alt="{{ publisher.name }}"
-    ></div>
-{% endif %}
diff --git a/catalogue/templates/catalogue/lesson/course/lesson_detail.html b/catalogue/templates/catalogue/lesson/course/lesson_detail.html
deleted file mode 100755 (executable)
index 38ef906..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-{% extends "catalogue/lesson/lesson_detail.html" %}
-{% load static from staticfiles %}
-
-{% block lesson-info %}
-<section class="box">
-    <div class="box-icon"><img src="/static/img/icons/activity-time.png"><br>45m</div>
-
-    {% include "catalogue/lesson/box-icons.html" %}
-
-    <p>Ta lekcja jest częścią tematu
-    <a href="{% url 'catalogue_lessons' %}#{{ object.level.slug }}_{{ object.section.slug }}"><strong>{{ object.section }}</strong></a>
-    na poziomie {{ object.level|lower }}.
-    </p>
-    <div style="clear: right"></div>
-</section>
-
-{% endblock %}
-
-
-{% block sidebar-top %}
-<div class="buttons" style="padding-bottom: 1em; border-bottom: 1px solid red;">
-
-{% if object.package %}
-    <section class="box-button"><a href="{{ object.package.url }}" class="dl-button">Pobierz całą lekcję</a></section>
-{% endif %}
-{% if object.student_package %}
-    <section><a href="{{ object.student_package.url }}" class="dl-button">Pobierz lekcję w wersji dla ucznia</a></section>
-{% endif %}
-
-</div>
-{% endblock %}
diff --git a/catalogue/templates/catalogue/lesson/lesson_detail.html b/catalogue/templates/catalogue/lesson/lesson_detail.html
deleted file mode 100755 (executable)
index 2493a77..0000000
+++ /dev/null
@@ -1,143 +0,0 @@
-{% extends "base.html" %}
-{% load lesson_link lesson_nav person_list from catalogue_tags %}
-{% load competence curriculum url_for_level from curriculum_tags %}
-
-
-{% block title %}{{ object }}{% endblock %}
-
-{% block body %}
-    <!--h1>{{ object }}</h1-->
-
-<aside id="sidebar">
-    {% block sidebar-top %}{% endblock %}
-
-    <section class="section">
-        {% lesson_nav object %}
-    </section>
-
-    {% if object.dc.relations %}
-    <section class="section-minor">
-        <h1>Powiązane lekcje</h1>
-        <ul class="link-list link-list-colored">
-        {% for uri in object.dc.relations %}
-            <li>{% lesson_link uri %}</li>
-        {% endfor %}
-        </ul>
-    </section>
-    {% endif %}
-
-    {% if object.dc.competences %}
-    <section class="section-minor">
-        <h1>Kompetencje:</h1>
-        <ul class="plain">
-        {% competence object.dc.competences object.level %}
-        </ul>
-    </section>
-    {% endif %}
-
-    {% if object.dc.curriculum %}
-    <section class="section-minor">
-        <h1>Podstawa programowa:</h1>
-        <ul class="plain">
-        {% curriculum object.dc.curriculum %}
-        </ul>
-    </section>
-    {% endif %}
-
-    {% if object.dc.curriculum_new %}
-    <section class="section-minor">
-        <h1>Nowa podstawa programowa:</h1>
-        <ul class="plain">
-        {% curriculum object.dc.curriculum_new new=True %}
-        </ul>
-    </section>
-    {% endif %}
-
-    <section class="section-micro">
-        <h1>Informacje:</h1>
-        <p>
-        {% if object.dc.authors_textbook %}
-        Tekst: {{ object.dc.authors_textbook|person_list }}<br/>
-        {% endif %}
-        {% if object.dc.authors_scenario %}
-        Scenariusz: {{ object.dc.authors_scenario|person_list }}<br/>
-        {% endif %}
-        {% if object.dc.authors_expert %}
-        Konsultacja merytoryczna: {{ object.dc.authors_expert|person_list }}<br/>
-        {% endif %}
-        {% if object.dc.authors_methodologist %}
-        Konsultacja metodyczna: {{ object.dc.authors_methodologist|person_list }}<br/>
-        {% endif %}
-        Licencja: <a href="{{ object.dc.license }}">{{ object.dc.license_description }}</a>.</p>
-    </section>
-
-    <section class="section-micro">
-        <h1>Narzędzia:</h1>
-        <ul class="link-list">
-            <li><a href="{{ object.xml_file.url }}">źródłowy plik XML</a></li>
-            <!--li><a href="{{ object.dc.about }}">lekcja na Platformie Redakcyjnej</a></li-->
-        </ul>
-    </section>
-
-    <section class="section-micro">
-        <p>{{ object.dc.description }}</p>
-    </section>
-
-</aside>
-
-<div id="main-bar">
-
-{% block lesson-info %}
-{% endblock %}
-
-{{ object.html_file.read|safe }}
-
-
-<a class="top-link" href="#">wróć na górę</a>
-<footer class="lesson-footer">
-
-{% if object.section %}
-
-<p class="section-info"><a href="{{ object.section.get_absolute_url }}">Temat: {{ object.section }}</a>
-<br/>(<a href="{% url 'catalogue_lessons' %}">spis wszystkich lekcji</a>)</p>
-
-<p>
-{% with object.get_previous as previous %}
-    {% if previous %}
-        <a class="previous-lesson" href="{{ previous.get_absolute_url }}">&larr; {{ previous }}</a>
-    {% endif %}
-{% endwith %}
-
-{% with object.get_next as next %}
-    {% if next %}
-        <a class="next-lesson" href="{{ next.get_absolute_url }}">{{ next }} &rarr;</a>
-    {% endif %}
-{% endwith %}
-</p>
-{% endif %}
-
-<div class="clr"></div>
-
-<p class="section-info">
-    {% block suggest-link %}
-    <a href="{% url 'contact_form' 'sugestie' %}?temat={{ 'Lekcja: '|add:object.title|urlencode }}">
-        Zgłoś swoją uwagę na temat tej lekcji.
-    </a>
-    {% endblock %}
-</p>
-
-</footer>
-
-
-{% if request.user.is_authenticated and object.forum_topics.all.count %}
-    <h2>Na forum</h2>
-    <ul>
-    {% for forum_topic in object.forum_topics.all %}
-        <li><a href="{{forum_topic.pybb_topic.get_absolute_url}}">{{forum_topic.pybb_topic.name}}</a></li>
-    {% endfor %}
-    </ul>
-{% endif %}
-
-</div>
-
-{% endblock %}
diff --git a/catalogue/templates/catalogue/lesson/project/lesson_detail.html b/catalogue/templates/catalogue/lesson/project/lesson_detail.html
deleted file mode 100755 (executable)
index 7a17251..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-{% extends "catalogue/lesson/lesson_detail.html" %}
-
-{% block lesson-info %}
-<section class="box">
-    {% if publisher %}
-    <div class="box-icon"><img src="{{ publisher.logo.url }}"
-            title="{{ publisher.name }}"
-            alt="{{ publisher.name }}"
-        ></div>
-    {% endif %}
-
-    <p>To jest <a href="{% url 'info' 'metoda-projektowa' %}">projekt</a> 
-    na poziomie
-    <a href="{% url 'catalogue_lessons' %}#{{ object.level.slug }}">{{ object.level|lower }}</a>.
-    </p>
-</section>
-{% endblock %}
-
-
-
-{% block sidebar-top %}
-
-
-{% if object.package %}
-    <section class="box-button"><a href="{{ object.package.url }}" class="dl-button">Pobierz cały projekt</a></section>
-{% endif %}
-
-{% endblock %}
diff --git a/catalogue/templates/catalogue/lesson/synthetic/lesson_detail.html b/catalogue/templates/catalogue/lesson/synthetic/lesson_detail.html
deleted file mode 100755 (executable)
index df60c9f..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-{% extends "catalogue/lesson/lesson_detail.html" %}
-
-{% block lesson-info %}
-<section class="box">
-    <div class="box-icon"><img src="/static/img/icons/activity-time.png"><br>45m</div>
-
-    {% include "catalogue/lesson/box-icons.html" %}
-
-    <p>Ta lekcja jest częścią skróconego kursu na poziomie {{ object.level|lower }}.
-        Zobacz też <a href="{% url 'catalogue_lessons' %}#{{ object.level.slug }}_pelny">pełny kurs</a>.
-    </p>
-    <div style="clear: right"></div>
-</section>
-{% endblock %}
-
-{% block sidebar-top %}
-
-{% if object.package %}
-    <section class="box-button"><a href="{{ object.package.url }}" class="dl-button">Pobierz całą lekcję</a></section>
-{% endif %}
-{% if object.student_package %}
-    <section><a href="{{ object.student_package.url }}" class="dl-button">Pobierz lekcję w wersji dla ucznia</a></section>
-{% endif %}
-
-{% endblock %}
diff --git a/catalogue/templates/catalogue/lesson_list.html b/catalogue/templates/catalogue/lesson_list.html
deleted file mode 100755 (executable)
index d89b547..0000000
+++ /dev/null
@@ -1,47 +0,0 @@
-{% extends "base.html" %}
-{% load catalogue_tags %}
-{% load static from staticfiles %}
-{% load course_boxes course_boxes_toc from curriculum_tags %}
-{% load chunk from chunks %}
-
-{% block title %}Lekcje{% endblock %}
-
-{% block body %}
-    <h1>Lekcje</h1>
-
-<aside id="sidebar">
-    <section class="section-minor">
-        <h1>Zebrane dla wszystkich tematów</h1>
-        <ul class="link-list">
-            {% for lesson in appendix %}
-                <li><a href="{{ lesson.get_absolute_url }}">{{ lesson }}</a></li>
-            {% endfor %}
-            <li><a href="{% url 'info' 'infografiki' %}">Infografiki</a></li>
-        </ul>
-    </section>
-    {% chunk 'lesson_list_sidebar' %}
-</aside>
-
-<div id="main-bar">
-    <div class="box">
-    {% chunk 'levels_disclaimer' %}
-    </div>
-
-    <div id="level-chooser-place">
-        <ul id="level-chooser">
-            <li class="home"><a href="#body"><img src="{% static 'img/logo.png' %}" /></a></li>
-            {% for object in object_list %}
-                <li><a href="#{{ object.slug }}">{{ object }}</a></li>
-            {% endfor %}
-        </ul>
-    </div>
-
-
-
-    {% for level in object_list %}
-        {% level_box level %}
-    {% endfor %}
-</div>
-
-
-{% endblock %}
diff --git a/catalogue/templates/catalogue/section_detail.html b/catalogue/templates/catalogue/section_detail.html
deleted file mode 100755 (executable)
index 01889ee..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-{% extends "base.html" %}
-{% load catalogue_tags %}
-
-{% block title %}{{ object }}{% endblock %}
-
-{% block body %}
-    <h1>{{ object }}</h1>
-    {% section_box object %}
-    
-
-{% endblock %}
diff --git a/catalogue/templates/catalogue/snippets/carousel.html b/catalogue/templates/catalogue/snippets/carousel.html
deleted file mode 100755 (executable)
index bb31eae..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-{% load thumbnail %}
-{% url 'catalogue_lessons' as lessons %}
-<section id="catalogue-carousel">
-    <ul id="catalogue-carousel-links">
-        {% for section in object_list %}
-        <li style="{% if section.pic %}{% thumbnail section.pic '460x235' crop='center' as th %}background-image: url('{{ th.url }}');{% endthumbnail %}{% endif %}">
-            <a href="{{ lessons }}#gimnazjum_{{ section.slug }}" class="catalogue-carousel-link">
-                <div class="catalogue-carousel-note">
-                    <div>
-                        <p>
-                        <strong>{{ section }}</strong>
-                        {{ section.summary }}
-                        <span class="more">zobacz &rarr;</span>
-                        </p>
-                    </div>
-                </div>
-            </a>
-            <a class="attribution" href="{{ section.pic_src }}">fot. {{ section.pic_attribution }}</a>
-        </li>    
-        {% endfor %}
-    </ul>
-    <ul id="catalogue-carousel-switcher">
-        {% for section in object_list %}
-            <li><a href="{{ section.get_absolute_url }}">{{ section }}</a></li>
-        {% endfor %}
-    </ul>
-</section>
diff --git a/catalogue/templates/catalogue/snippets/lesson_link.html b/catalogue/templates/catalogue/snippets/lesson_link.html
deleted file mode 100755 (executable)
index 749b4e1..0000000
+++ /dev/null
@@ -1 +0,0 @@
-{% if lesson %}<a href="{{ lesson.get_absolute_url }}">{{ lesson }}</a>{% endif %}
diff --git a/catalogue/templates/catalogue/snippets/lesson_nav.html b/catalogue/templates/catalogue/snippets/lesson_nav.html
deleted file mode 100755 (executable)
index 0e64225..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-<h1>
-{% if root %}
-    <a href="{{ root.get_absolute_url }}">{{ root }}, <br>{{ lesson.level }}</a>
-{% elif lesson.type == 'synthetic' %}
-    <a href="{% url 'catalogue_lessons' %}">Kurs skrócony, <br>{{ lesson.level }}</a>
-{% elif lesson.type == 'project' %}
-    <a href="{% url 'catalogue_lessons' %}">Projekty, <br>{{ lesson.level }}</a>
-{% elif lesson.type == 'added' %}
-    <a href="{% url 'catalogue_lessons' %}#liceum_filmowa">Edukacja filmowa</a>
-{% elif lesson.type == 'added-var' %}
-    <a href="{% url 'catalogue_lessons' %}#liceum_varsaviana">Edukacja varsavianistyczna</a>
-{% else %}
-    <a href="{% url 'catalogue_lessons' %}">Inne</a>
-{% endif %}
-</h1>
-
-<ul>
-{% for item in siblings %}
-    <li>
-    {% if item == lesson %}
-        <strong>{{ item }}</strong>
-    {% else %}
-        <a href="{{ item.get_absolute_url }}">{{ item }}</a>
-    {% endif %}
-    </li>
-{% endfor %}
-</ul>
diff --git a/catalogue/templates/catalogue/snippets/lesson_or_stub.html b/catalogue/templates/catalogue/snippets/lesson_or_stub.html
deleted file mode 100644 (file)
index 5bb2614..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-{% if lesson.slug %}
-    <a href="{{ lesson.get_absolute_url }}" title="{{ lesson.description }}">
-{% endif %}
-{{ lesson }}
-{% if lesson.slug %}
-    </a>
-{% else %}
-(w przygotowaniu)
-{% endif %}
diff --git a/catalogue/templates/catalogue/snippets/level_box.html b/catalogue/templates/catalogue/snippets/level_box.html
deleted file mode 100755 (executable)
index 3155cce..0000000
+++ /dev/null
@@ -1,176 +0,0 @@
-<section id="{{ level.slug }}" class="level" style="margin-left: 20em">
-
-    <section class="box level-toc" style="float: left; margin-left: -20em; width: 15em;">
-        <strong><a href="#{{ level.slug }}">{{ level }}</a></strong>
-        <ul  class="link-list"  style="list-style: none; padding: 0; margin: 0;">
-            {% if lessons.synthetic %}
-            <li><a href="#{{ level.slug }}_skrocony">Skrócony kurs</a></li>
-            {% endif %}
-            {% if lessons.course %}
-            <li><a href="#{{ level.slug }}_pelny">Pełny kurs</a>
-                <ul style="list-style: none; padding: 0 0 0 1em; margin: 0;">
-                {% for section in lessons.course %}
-                        <li><a href="#{{ level.slug }}_{{ section.slug}}">{{ section }}</a></li>
-                {% endfor %}
-                </ul>
-            </li>
-            {% endif %}
-            {% if lessons.project %}
-            <li><a href="#{{ level.slug }}_projekty">Projekty</a></li>
-            {% endif %}
-            {% if lessons.appendix %}
-            <li><a href="#{{ level.slug }}_pozostale">Pozostałe materiały</a></li>
-            {% endif %}
-
-            {% if courses %}
-            <li class="curriculumcourses"><a href="#{{ level.slug }}_podstawa">Według postawy programowej</a>
-                <ul style="list-style: none; padding: 0 0 0 1em; margin: 0;">
-                {% for course, lessons in courses %}
-                        <li><a href="#{{ level.slug }}_{{ course.slug}}">{{ course }}</a></li>
-                {% endfor %}
-                </ul>
-            </li>
-            {% endif %}
-
-            {% if added %}
-            <li class="curriculumcourses"><a href="#{{ level.slug }}_inne">Inne</a>
-                <ul style="list-style: none; padding: 0 0 0 1em; margin: 0;">
-                {% for item in added %}
-                    <li><a href="#{{ level.slug }}_{{ item.slug }}">{{ item.title }}</a></li>
-                {% endfor %}
-                </ul>
-            </li>
-            {% endif %}
-
-        </ul>
-
-
-    </section>
-
-
-
-    <h1>{{ level }}</h1>
-
-    <section class="box-button button"><a href="{{ level.package.url }}" class="dl-button">Pobierz wszystkie lekcje</a></section>
-    <section class="button"><a href="{{ level.student_package.url }}" class="dl-button">Pobierz wszystkie lekcje w&nbsp;wersji dla ucznia</a></section>
-
-    {% if lessons.synthetic %}
-    <section id="{{ level.slug }}_skrocony">
-        <h1>Skrócony kurs</h1>
-
-        <p>Masz kilka godzin? Przeprowadź po jednej lekcji przeglądowej z każdego tematu.</p>
-
-        <ul class="link-list">
-            {% for lesson in lessons.synthetic %}
-                <li>{% include "catalogue/snippets/lesson_or_stub.html" %}</li>
-            {% endfor %}
-        </ul>
-    </section>
-    {% endif %}
-
-
-    {% if lessons.course %}
-    <section id="{{ level.slug }}_pelny">
-        <h1>Pełny kurs</h1>
-
-        <p>Masz więcej czasu? Zrealizuj kompletny program edukacji medialnej.</p>
-
-        {% for section, s_lessons in lessons.course.items %}
-            <section id="{{ level.slug }}_{{ section.slug}}">
-                <h1>{{ section }}</h1>
-
-                <ul class="link-list">
-                    {% for lesson in s_lessons %}
-                        <li>{% include "catalogue/snippets/lesson_or_stub.html" %}</li>
-                    {% endfor %}
-                </ul>
-            </section>
-        {% endfor %}
-
-    </section>
-    {% endif %}
-
-
-    {% if lessons.project %}
-    <section id="{{ level.slug }}_projekty">
-        <h1>Projekty</h1>
-
-        <p>Masz 4-6 tygodni? Zrealizuj jeden z projektów ze swoimi uczniami.</p>
-
-        <ul class="link-list">
-            {% for lesson in lessons.project %}
-                <li>{% include "catalogue/snippets/lesson_or_stub.html" %}</li>
-            {% endfor %}
-        </ul>
-    </section>
-    {% endif %}
-
-
-    {% if courses %}
-    <section id="{{ level.slug }}_podstawa">
-        <h1>Według podstawy programowej</h1>
-
-        {% for course, lessons in courses %}
-        <section id="{{ level.slug}}_{{ course.slug }}">
-            <h1>{{ course }}</h1>
-
-            {% if lessons.synthetic %}
-            <section>
-                <h1>Z kursu skróconego</h1>
-                <ul class="link-list">
-                    {% for lesson in lessons.synthetic %}
-                        <li>{% include "catalogue/snippets/lesson_or_stub.html" %}</li>
-                    {% endfor %}
-                </ul>
-            </section>
-            {% endif %}
-
-            {% if lessons.course %}
-            <section>
-                <h1>Z kursu pełnego</h1>
-                <ul class="link-list">
-                    {% for lesson in lessons.course %}
-                        <li>{% include "catalogue/snippets/lesson_or_stub.html" %}</li>
-                    {% endfor %}
-                </ul>
-            </section>
-            {% endif %}
-
-            {% if lessons.project %}
-            <section>
-                <h1>Projekty</h1>
-                <ul class="link-list">
-                    {% for lesson in lessons.project %}
-                        <li>{% include "catalogue/snippets/lesson_or_stub.html" %}</li>
-                    {% endfor %}
-                </ul>
-            </section>
-            {% endif %}
-
-        </section>
-        {% endfor %}
-        
-    </section>
-    {% endif %}
-
-
-    {% if added %}
-    <section id="{{ level.slug }}_inne">
-        <h1>Inne</h1>
-
-        {% for item in added %}
-        <section id="{{ level.slug }}_{{ item.slug }}">
-            <h1>{{ item.title }}</h1>
-
-            <ul class="link-list">
-                {% for lesson in item.lessons %}
-                    <li><a href="{{ lesson.get_absolute_url }}" title="{{ lesson.description }}">{{ lesson }}</a></li>
-                {% endfor %}
-            </ul>
-        </section>
-        {% endfor %}
-    </section>
-    {% endif %}
-
-
-</section>
diff --git a/catalogue/templates/catalogue/snippets/levels_main.html b/catalogue/templates/catalogue/snippets/levels_main.html
deleted file mode 100644 (file)
index 54ceed9..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-{% load i18n %}
-<style type="text/css">
-#main-sections ul li {width: {{ section_width }}px;}
-#main-sections ul li a {width: {{ section_width|add:"-10" }}px;}
-.levelth {width: {{ section_width }}px;}
-</style>
-{% url 'catalogue_lessons' as les %}
-<ul class="section-buttons">
-{% for level in object_list %}
-<li class="box{{ level.pk }}">
-    <a href="{{ les }}#{{ level.slug }}">
-    <span class="in-box">
-    <span class="name">{{ level }}</span>
-    {% if level.length_synthetic %}{{ level.length_synthetic }} lub {% endif %}{{ level.length_course }} godzin
-    </span>
-    </a>
-</li>
-{% endfor %}
-<li class="box6">
-    <a href="{{ les }}#liceum_filmowa">
-    <span class="in-box">
-    <span class="name">Edukacja filmowa</span>
-    8 godzin
-    </span>
-    </a>
-</li>
-<li class="box7">
-    <a href="{{ les }}#liceum_varsaviana">
-    <span class="in-box">
-    <span class="name">Edukacja varsavianistyczna</span>
-    10 godzin
-    </span>
-    </a>
-</li>
-
-</ul>
diff --git a/catalogue/templates/search/indexes/catalogue/lesson_text.txt b/catalogue/templates/search/indexes/catalogue/lesson_text.txt
deleted file mode 100755 (executable)
index ab6feff..0000000
+++ /dev/null
@@ -1 +0,0 @@
-{{ object.html_file.read|striptags }}
diff --git a/catalogue/templatetags/__init__.py b/catalogue/templatetags/__init__.py
deleted file mode 100755 (executable)
index e69de29..0000000
diff --git a/catalogue/templatetags/catalogue_tags.py b/catalogue/templatetags/catalogue_tags.py
deleted file mode 100755 (executable)
index b74224d..0000000
+++ /dev/null
@@ -1,173 +0,0 @@
-# -*- coding: utf-8 -*-
-from collections import defaultdict
-from django import template
-from django.utils.datastructures import SortedDict
-from ..models import Lesson, Section
-from curriculum.models import Level, CurriculumCourse
-from librarian.dcparser import WLURI, Person
-
-register = template.Library()
-
-
-@register.inclusion_tag("catalogue/snippets/carousel.html")
-def catalogue_carousel():
-    return {
-        "object_list": Section.objects.all()
-    }
-
-
-@register.inclusion_tag("catalogue/snippets/levels_main.html")
-def catalogue_levels_main():
-    object_list = Level.objects.exclude(lesson=None)
-    c = object_list.count()
-    return {
-        'object_list': object_list,
-        # 'section_width': (700 - 20 * (c - 1)) / c,
-        'section_width': (700 - 20 * 2) / 3
-    }
-
-
-@register.inclusion_tag("catalogue/snippets/level_box.html")
-def level_box(level):
-    lessons = {'synthetic': [], 'course': SortedDict(), 'project': []}
-    by_course = defaultdict(lambda: defaultdict(list))
-
-    lesson_lists = [alist for alist in [
-        list(level.lesson_set.exclude(type='appendix').order_by('section__order', 'order')),
-        list(level.lessonstub_set.all())
-    ] if alist]
-
-    while lesson_lists:
-        min_index, min_list = min(enumerate(lesson_lists), key=lambda x: x[1][0].order)
-        lesson = min_list.pop(0)
-        if not min_list:
-            lesson_lists.pop(min_index)
-
-        if lesson.type == 'course':
-            if lesson.section not in lessons['course']:
-                lessons['course'][lesson.section] = []
-            lessons['course'][lesson.section].append(lesson)
-        elif lesson.type.startswith('added'):
-            continue
-        else:
-            lessons[lesson.type].append(lesson)
-
-        if hasattr(lesson, 'curriculum_courses'):
-            for course in lesson.curriculum_courses.all():
-                by_course[course][lesson.type].append(lesson)
-
-    courses = [(course, by_course[course])
-               for course in CurriculumCourse.objects.filter(lesson__level=level).distinct()]
-
-    added = []
-    if level.slug == 'liceum':
-        added.append({
-            'slug': 'filmowa',
-            'title': u'Edukacja filmowa',
-            'lessons': [
-                Lesson.objects.get(slug=s) for s in [
-                    'film-co-to-wlasciwie-jest',
-                    'scenariusz-scenopis-i-srodki-realizacyjne',
-                    'kompozycja-obrazu-filmowego',
-                    'praca-kamery-kadr-kat',
-                    'montaz-materialu-filmowego',
-                    'swiatlo-i-dzwiek-w-filmie',
-                    'scenografia-charakteryzacja-kostiumy-i-aktorzy',
-                    'narracja-w-filmie-tekst-i-fabula',
-                ]
-            ],
-        })
-        added.append({
-            'slug': 'varsaviana',
-            'title': u'Edukacja varsavianistyczna',
-            'lessons': [
-                Lesson.objects.get(slug=s) for s in [
-                    'czego-prus-w-lalce-o-zydach-nie-powiedzial',
-                    'jak-zmienila-sie-warszawa-o-dworcu-dawniej-i-dzis',
-                    'o-gwarze-praskiej',
-                    'poznaj-i-pokaz-prage',
-                    'praga-trzech-religii',
-                    'sladami-zydow-w-warszawie',
-                    'tajemnice-palacu-saskiego',
-                    'warszawa-przedwojenne-miasto-neonow',
-                    'warszawski-barok',
-                    'ziemianska-jako-soczewka-swiata-lat-miedzywojennych',
-                ]
-            ],
-        })
-
-    return {
-        "level": level,
-        "lessons": lessons,
-        "courses": courses,
-        "added": added,
-    }
-
-
-@register.inclusion_tag("catalogue/snippets/lesson_nav.html")
-def lesson_nav(lesson):
-    if lesson.type == 'course':
-        root = lesson.section
-        siblings = Lesson.objects.filter(type='course', level=lesson.level, section=root)
-    elif lesson.type == 'appendix':
-        root = None
-        siblings = Lesson.objects.filter(type=lesson.type)
-    elif lesson.type == 'added':
-        root = None
-        siblings = [
-                Lesson.objects.get(slug=s) for s in [
-                    'film-co-to-wlasciwie-jest',
-                    'scenariusz-scenopis-i-srodki-realizacyjne',
-                    'kompozycja-obrazu-filmowego',
-                    'praca-kamery-kadr-kat',
-                    'montaz-materialu-filmowego',
-                    'swiatlo-i-dzwiek-w-filmie',
-                    'scenografia-charakteryzacja-kostiumy-i-aktorzy',
-                    'narracja-w-filmie-tekst-i-fabula',
-                ]
-            ]
-    else:
-        root = None
-        siblings = Lesson.objects.filter(type=lesson.type, level=lesson.level)
-    return {
-        "lesson": lesson,
-        "root": root,
-        "siblings": siblings,
-    }
-
-
-@register.inclusion_tag("catalogue/snippets/lesson_link.html")
-def lesson_link(uri):
-    try:
-        return {'lesson': Lesson.objects.get(slug=WLURI(uri).slug)}
-    except Lesson.DoesNotExist:
-        return {}
-
-
-@register.filter
-def person_list(persons):
-    return u", ".join(Person.from_text(p).readable() for p in persons)
-
-
-# FIXME: Move to fnpdjango
-import feedparser
-import datetime
-
-
-@register.inclusion_tag('catalogue/latest_blog_posts.html')
-def latest_blog_posts(feed_url, posts_to_show=5):
-    try:
-        feed = feedparser.parse(str(feed_url))
-        posts = []
-        for i in range(posts_to_show):
-            pub_date = feed['entries'][i].updated_parsed
-            published = datetime.date(pub_date[0], pub_date[1], pub_date[2])
-            posts.append({
-                'title': feed['entries'][i].title,
-                'summary': feed['entries'][i].summary,
-                'link': feed['entries'][i].link,
-                'date': published,
-                })
-        return {'posts': posts}
-    except:
-        return {'posts': []}
diff --git a/catalogue/tests.py b/catalogue/tests.py
deleted file mode 100644 (file)
index b967c44..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-# -*- coding: utf-8 -*-
-"""
-This file demonstrates writing tests using the unittest module. These will pass
-when you run "manage.py test".
-
-Replace this with more appropriate tests for your application.
-"""
-
-from django.test import TestCase
-
-
-class SimpleTest(TestCase):
-    def test_basic_addition(self):
-        """
-        Tests that 1 + 1 always equals 2.
-        """
-        self.assertEqual(1 + 1, 2)
diff --git a/catalogue/urls.py b/catalogue/urls.py
deleted file mode 100755 (executable)
index f2a8b08..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-# -*- coding: utf-8 -*-
-from django.conf.urls import patterns, url
-from .views import LessonListView, LessonView
-
-urlpatterns = patterns(
-    '',
-    url(r'^$',
-        LessonListView.as_view(),
-        name="catalogue_lessons"),
-    url(r'^(?P<slug>[^/]+)/$',
-        LessonView.as_view(),
-        name="catalogue_lesson"),
-)
diff --git a/catalogue/views.py b/catalogue/views.py
deleted file mode 100644 (file)
index 4f9d78c..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-# -*- coding: utf-8 -*-
-from django.views.generic import DetailView, ListView
-
-from curriculum.models import Level
-from publishers.models import Publisher
-from .models import Lesson
-
-
-class LessonListView(ListView):
-    queryset = Level.objects.exclude(lesson=None)
-    template_name = "catalogue/lesson_list.html"
-
-    def get_context_data(self, **kwargs):
-        context = super(LessonListView, self).get_context_data(**kwargs)
-        context['appendix'] = Lesson.objects.filter(type='appendix')
-        return context
-
-
-class LessonView(DetailView):
-    model = Lesson
-
-    def get_template_names(self):
-        return [
-            'catalogue/lesson/%s/lesson_detail.html' % self.object.type,
-            'catalogue/lesson/lesson_detail.html',
-        ]
-
-    def get_context_data(self, **kwargs):
-        context = super(LessonView, self).get_context_data(**kwargs)
-        try:
-            context['publisher'] = Publisher.objects.get(
-                name=context['object'].dc.get('publisher', '').strip())
-        except (Publisher.DoesNotExist, Publisher.MultipleObjectsReturned):
-            pass
-        return context
diff --git a/chunks/__init__.py b/chunks/__init__.py
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/chunks/admin.py b/chunks/admin.py
deleted file mode 100644 (file)
index 5bdbddc..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-# -*- coding: utf-8 -*-
-from django.contrib import admin
-
-from chunks.models import Chunk, Attachment
-
-
-class ChunkAdmin(admin.ModelAdmin):
-    list_display = ('key', 'description',)
-    search_fields = ('key', 'content',)
-
-admin.site.register(Chunk, ChunkAdmin)
-
-
-class AttachmentAdmin(admin.ModelAdmin):
-    list_display = ('key',)
-    search_fields = ('key',)
-
-admin.site.register(Attachment, AttachmentAdmin)
diff --git a/chunks/fixtures/chunks.json b/chunks/fixtures/chunks.json
deleted file mode 100644 (file)
index 0d26270..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-[
-    {
-        "pk": "document-list", 
-        "model": "chunks.chunk", 
-        "fields": {
-            "content": "        <p>Zasoby szkolnej biblioteki internetowej Wolne Lektury oraz jej funkcjonalno\u015bci wykorzystywane s\u0105 przez nauczycieli i nauczycielki podczas pracy w szkole. Poni\u017cej znajduj\u0105 si\u0119 materia\u0142y edukacyjne \u2013 scenariusze lekcji, tematy wypracowa\u0144 i inne \u2013 stworzone przez pedagog\u00f3w, kt\u00f3rzy w swojej codziennej pracy w szkole wykorzystuj\u0105 przygotowane przez nas narz\u0119dzia i opracowane merytorycznie teksty.</p>\r\n\r\n<ol>\r\n<li><strong>Scenariusze lekcji</strong>\r\n\r\n <ul>\r\n  <li><a href=\"/materialy/kot-w-literaturze-scenariusz-lekcji/\" data-hash=\"#kot-w-literaturze-scenariusz-lekcji\">Scenariusz lekcji. Kot w literaturze.</a> <a class='download-doc' href=\"/media/lessons/document/wolnelektury-kot-scenariusz.doc\">Pobierz dokument</a></li>\r\n  <li><a href=\"/materialy/lekcja-multimedialna-danse-macabre/\" data-hash=\"#lekcja-multimedialna-danse-macabre\">Lekcja multimedialna - Motyw danse macabre wyst\u0119puj\u0105cy w tekstach kultury. </a><a class='download-doc' href=\"/media/lessons/document/wolnelektury-lekcja.multimedialna-danse.macabre_.ppt\">Pobierz prezentacj\u0119</a></li>\r\n  <li><a href=\"/materialy/lekcja-multimedialna-sonet/\" data-hash=\"#lekcja-multimedialna-sonet\">R\u00f3\u017cnorodno\u015b\u0107 tematyczna  sonetu.</a><a class='download-doc' href=\"/media/lessons/document/wolnelektury-lekcja.multimedialna-sonet.ppt\">Pobierz dokument</a></li>\r\n  <li><a href=\"/materialy/slowacki-czesc-i/\" data-hash=\"#slowacki-czesc-i\">\u201eBo to jest wieszcza najja\u015bniejsza chwa\u0142a\u2026\u201d Juliusz S\u0142owacki - cz\u0142owiek i poeta</a> <a class='download-doc' href=\"/media/lessons/document/wolnelektury-slowacki01.ppt\">Pobierz prezentacj\u0119</a></li>\r\n  <li><a href=\"/materialy/usmiech-i-lzy-wieszcza/\" data-hash=\"#usmiech-i-lzy-wieszcza\">U\u015bmiech  i \u0142zy wieszcza czyli S\u0142owacki p\u00f3\u0142 \u017cartem,  p\u00f3\u0142 serio.</a> <a class='download-doc' href=\"/media/lessons/document/wolnelektury-usmiech.i.lzy.wieszcza.ppt\">Pobierz prezentacj\u0119</a></li>\r\n\r\n</ul>\r\n</li>\r\n\r\n<li><a href=\"/materialy/przyklady-zadan/\" data-hash=\"#przyklady-zadan\">Przyk\u0142ady zada\u0144 do opracowania przez zespo\u0142y uczni\u00f3w</a> <a class='download-doc' href=\"/media/lessons/document/wolnelektury-przyklady.zadan.doc\">Pobierz dokument</a></li>\r\n<li><a href=\"/materialy/tematy-wypracowan/\" data-hash=\"#tematy-wypracowan\">Tematy wypracowa\u0144</a> <a class='download-doc' href=\"/media/lessons/document/wolne.lektury-tematy.wypracowan.doc\">Pobierz dokument</a></li>\r\n<li><a href=\"/materialy/repetytorium-maturalne/\" data-hash=\"#repetytorium-maturalne\">Repetytorium maturalne.</a> <a class='download-doc' href=\"/media/lessons/document/wolnelektury-repetytorium.maturalne.ppt\">Pobierz prezentacj\u0119</a></li>\r\n\r\n</ol>\r\n</p>\r\n\r\n<p>Zach\u0119camy wszystkich nauczycieli i wszystkie nauczycielki do tworzenia materia\u0142\u00f3w edukacyjnych i publikowania ich na naszej stronie! Warto zapozna\u0107 si\u0119 z <a href=\"/materialy/tworzenie-scenariuszy-lekcji/\" data-hash=\"#tworzenie-scenariuszy-lekcji\">instrukcj\u0105 dotycz\u0105c\u0105 pisania scenariuszy lekcji</a> i <a href=\"/materialy/schemat-scenariusza-lekcji/\" data-hash=\"#schemat-scenariusza-lekcji\">schematem przyk\u0142adowego scenariusza lekcji</a>, a gotowe materia\u0142y przes\u0142a\u0107 na adres <a href=\"mailto:fundacja@nowoczesnapolska.org.pl\">fundacja@nowoczesnapolska.org.pl</a>.</p>", 
-            "description": ""
-        }
-    }, 
-    {
-        "pk": "footer-map", 
-        "model": "chunks.chunk", 
-        "fields": {
-            "content": "<AREA SHAPE=\"rect\" COORDS=\"104,83,261,101\" HREF=\"http://edukacja.gazeta.pl\" ALT=\"GazetaEdukacja.pl - matura, testy, egzaminy, studia\" TITLE=\"GazetaEdukacja.pl - matura, testy, egzaminy, studia\"><AREA SHAPE=\"rect\" COORDS=\"539,38,656,73\" ALT=\"Kurier Wile\u0144ski\" HREF=\"http://www.kurierwilenski.lt/\"><AREA SHAPE=\"rect\" COORDS=\"687,81,789,116\" ALT=\"Radio znad Wilii\" HREF=\"http://www.znadwilii.lt\"><AREA SHAPE=\"rect\" COORDS=\"376,34,520,75\" ALT=\"Ministerstwo Edukacji Narodowej\" HREF=\"http://www.men.gov.pl/\"><AREA SHAPE=\"rect\" COORDS=\"761,59,822,77\" ALT=\"Biblioteka Analiz\" HREF=\"http://www.rynek-ksiazki.pl/\"><AREA SHAPE=\"rect\" COORDS=\"734,55,759,76\" ALT=\"Przekr\u00f3j\" HREF=\"http://www.przekroj.pl/\"><AREA SHAPE=\"rect\" COORDS=\"695,55,732,76\" ALT=\"TVP Kultura\" HREF=\"http://www.tvp.pl/tvpkultura/\"><AREA SHAPE=\"rect\" COORDS=\"762,35,821,59\" ALT=\"Elle\" HREF=\"http://elle.interia.pl/\"><AREA SHAPE=\"rect\" COORDS=\"659,55,693,77\" ALT=\"Radio TOK.FM\" HREF=\"http://www.tok.fm/\"><AREA SHAPE=\"rect\" COORDS=\"658,35,760,53\" ALT=\"Tygodnik Powszechny\" HREF=\"http://tygodnik.onet.pl/\"><AREA SHAPE=\"rect\" COORDS=\"265,35,366,74\" ALT=\"Ministerstwo Kultury i Dziedzictwa Narodowego\" HREF=\"http://www.mkidn.gov.pl/\"><AREA SHAPE=\"rect\" COORDS=\"222,29,261,83\" ALT=\"Biblioteka Narodowa\" HREF=\"http://www.bn.org.pl/\"><AREA SHAPE=\"rect\" COORDS=\"188,58,217,81\" ALT=\"PZL\" HREF=\"http://www.pzl.pl/\"><AREA SHAPE=\"rect\" COORDS=\"162,32,218,56\" ALT=\"eo Networks - administracja, zarz\u0105dzanie serwerami, technologie Sun,\r\nlinux, bsd, unix, solaris\" HREF=\"http://eo.pl/\"><AREA SHAPE=\"rect\" COORDS=\"104,61,184,76\" ALT=\"Kancelaria Prawna Grynhoff Wo\u017any Mali\u0144ski Sp\u00f3\u0142ka komandytowa\" HREF=\"http://www.gww.pl/\"><AREA SHAPE=\"rect\" COORDS=\"104,35,160,60\" ALT=\"Information is art\" HREF=\"http://www.informationisart.com/\"><AREA SHAPE=\"rect\" COORDS=\"15,39,98,75\" ALT=\"Fundacja Nowoczesna Polska\" HREF=\"http://nowoczesnapolska.org.pl/\"><AREA SHAPE=\"default\" COORDS=\"0,0,860,120\" NOHREF>", 
-            "description": ""
-        }
-    }, 
-    {
-        "pk": "site-description", 
-        "model": "chunks.chunk", 
-        "fields": {
-            "content": "", 
-            "description": ""
-        }
-    }, 
-    {
-        "pk": "top-message", 
-        "model": "chunks.chunk", 
-        "fields": {
-            "content": "", 
-            "description": ""
-        }
-    }, 
-    {
-        "pk": "footer-img", 
-        "model": "chunks.attachment", 
-        "fields": {
-            "attachment": "chunks/attachment/footer.png"
-        }
-    }
-]
diff --git a/chunks/locale/de/LC_MESSAGES/django.mo b/chunks/locale/de/LC_MESSAGES/django.mo
deleted file mode 100644 (file)
index be5f8ae..0000000
Binary files a/chunks/locale/de/LC_MESSAGES/django.mo and /dev/null differ
diff --git a/chunks/locale/de/LC_MESSAGES/django.po b/chunks/locale/de/LC_MESSAGES/django.po
deleted file mode 100644 (file)
index 7fbf84e..0000000
+++ /dev/null
@@ -1,74 +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: 2012-07-19 11:39+0200\n"
-"PO-Revision-Date: 2012-04-11 22:56+0100\n"
-"Last-Translator: Kamil <kjaklukowski@gmail.com>\n"
-"Language-Team: \n"
-"Language: \n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-
-#: models.py:11 models.py:33
-msgid "key"
-msgstr "Schlüssel"
-
-#: models.py:11
-msgid "A unique name for this chunk of content"
-msgstr "Die einzigartige Bezeichnung für dieses Chunk von Inhalten"
-
-#: models.py:12
-msgid "description"
-msgstr "Beschreibung"
-
-#: models.py:13
-msgid "content"
-msgstr "Inhalt"
-
-#: models.py:17
-msgid "chunk"
-msgstr "Chunk"
-
-#: models.py:18
-msgid "chunks"
-msgstr "Chunks"
-
-#: models.py:33
-msgid "A unique name for this attachment"
-msgstr "Die einzigartige Bezeichnung für diese Beilage"
-
-#: models.py:38
-msgid "attachment"
-msgstr "Beilage"
-
-#: models.py:38
-msgid "attachments"
-msgstr "Beilagen"
-
-#~ msgid "title"
-#~ msgstr "Titel"
-
-#~ msgid "slug"
-#~ msgstr "Slug"
-
-#~ msgid "file"
-#~ msgstr "Datei"
-
-#~ msgid "author"
-#~ msgstr "Autor"
-
-#~ msgid "slideshare ID"
-#~ msgstr "Dia-ID"
-
-#~ msgid "HTML"
-#~ msgstr "HTML"
-
-#~ msgid "document"
-#~ msgstr "Dokument"
diff --git a/chunks/locale/en/LC_MESSAGES/django.mo b/chunks/locale/en/LC_MESSAGES/django.mo
deleted file mode 100644 (file)
index a81e430..0000000
Binary files a/chunks/locale/en/LC_MESSAGES/django.mo and /dev/null differ
diff --git a/chunks/locale/en/LC_MESSAGES/django.po b/chunks/locale/en/LC_MESSAGES/django.po
deleted file mode 100644 (file)
index e81d48a..0000000
+++ /dev/null
@@ -1,53 +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: 2012-07-19 11:39+0200\n"
-"PO-Revision-Date: 2012-03-04 20:05+0100\n"
-"Last-Translator: xxx <xxx>\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"
-
-#: models.py:11 models.py:33
-msgid "key"
-msgstr "key"
-
-#: models.py:11
-msgid "A unique name for this chunk of content"
-msgstr "A unique name for this piece of content"
-
-#: models.py:12
-msgid "description"
-msgstr "description"
-
-#: models.py:13
-msgid "content"
-msgstr "content"
-
-#: models.py:17
-msgid "chunk"
-msgstr "piece"
-
-#: models.py:18
-msgid "chunks"
-msgstr "pieces"
-
-#: models.py:33
-msgid "A unique name for this attachment"
-msgstr "A unique name for this attachment"
-
-#: models.py:38
-msgid "attachment"
-msgstr "attachment"
-
-#: models.py:38
-msgid "attachments"
-msgstr "attachments"
diff --git a/chunks/locale/es/LC_MESSAGES/django.mo b/chunks/locale/es/LC_MESSAGES/django.mo
deleted file mode 100644 (file)
index 83f03fb..0000000
Binary files a/chunks/locale/es/LC_MESSAGES/django.mo and /dev/null differ
diff --git a/chunks/locale/es/LC_MESSAGES/django.po b/chunks/locale/es/LC_MESSAGES/django.po
deleted file mode 100644 (file)
index 4130ea1..0000000
+++ /dev/null
@@ -1,53 +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: 2012-07-19 11:39+0200\n"
-"PO-Revision-Date: 2012-02-18 13:02+0100\n"
-"Last-Translator: Anna Jopp <aniajopp@gmail.com>\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"
-
-#: models.py:11 models.py:33
-msgid "key"
-msgstr "clave"
-
-#: models.py:11
-msgid "A unique name for this chunk of content"
-msgstr "El nombre único para este elemento del contenido"
-
-#: models.py:12
-msgid "description"
-msgstr "descripción"
-
-#: models.py:13
-msgid "content"
-msgstr "contenido"
-
-#: models.py:17
-msgid "chunk"
-msgstr "elemento"
-
-#: models.py:18
-msgid "chunks"
-msgstr "elementos"
-
-#: models.py:33
-msgid "A unique name for this attachment"
-msgstr "El nombre único para este archivo adjunto"
-
-#: models.py:38
-msgid "attachment"
-msgstr "archivo adjunto"
-
-#: models.py:38
-msgid "attachments"
-msgstr "archivos adjuntos"
diff --git a/chunks/locale/fr/LC_MESSAGES/django.mo b/chunks/locale/fr/LC_MESSAGES/django.mo
deleted file mode 100644 (file)
index 1ef6af2..0000000
Binary files a/chunks/locale/fr/LC_MESSAGES/django.mo and /dev/null differ
diff --git a/chunks/locale/fr/LC_MESSAGES/django.po b/chunks/locale/fr/LC_MESSAGES/django.po
deleted file mode 100644 (file)
index 150a92c..0000000
+++ /dev/null
@@ -1,53 +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: 2012-07-19 11:39+0200\n"
-"PO-Revision-Date: 2012-02-22 20:52+0100\n"
-"Last-Translator: Ela Janota <amarillis5@wp.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"
-
-#: models.py:11 models.py:33
-msgid "key"
-msgstr "clé"
-
-#: models.py:11
-msgid "A unique name for this chunk of content"
-msgstr "Un nom unique pour ce fragment du contenu"
-
-#: models.py:12
-msgid "description"
-msgstr "description"
-
-#: models.py:13
-msgid "content"
-msgstr "contenu"
-
-#: models.py:17
-msgid "chunk"
-msgstr "fragment"
-
-#: models.py:18
-msgid "chunks"
-msgstr "fragments"
-
-#: models.py:33
-msgid "A unique name for this attachment"
-msgstr "Un nom unique pour cette pièce jointe"
-
-#: models.py:38
-msgid "attachment"
-msgstr "pièce jointe"
-
-#: models.py:38
-msgid "attachments"
-msgstr "pièces jointes"
diff --git a/chunks/locale/it/LC_MESSAGES/django.mo b/chunks/locale/it/LC_MESSAGES/django.mo
deleted file mode 100644 (file)
index a07410f..0000000
Binary files a/chunks/locale/it/LC_MESSAGES/django.mo and /dev/null differ
diff --git a/chunks/locale/it/LC_MESSAGES/django.po b/chunks/locale/it/LC_MESSAGES/django.po
deleted file mode 100644 (file)
index 4598d53..0000000
+++ /dev/null
@@ -1,54 +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: 2012-07-19 11:39+0200\n"
-"PO-Revision-Date: 2012-02-21 16:52+0100\n"
-"Last-Translator: xxx\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=2; plural=(n != 1)\n"
-
-#: models.py:11 models.py:33
-msgid "key"
-msgstr "Chiave"
-
-#: models.py:11
-msgid "A unique name for this chunk of content"
-msgstr "un nome unico per questo allegato"
-
-#: models.py:12
-msgid "description"
-msgstr "descrizione"
-
-#: models.py:13
-msgid "content"
-msgstr "contenuto"
-
-#: models.py:17
-msgid "chunk"
-msgstr "blocco"
-
-#: models.py:18
-msgid "chunks"
-msgstr "blocchi"
-
-#: models.py:33
-msgid "A unique name for this attachment"
-msgstr "Un nome unico per questo allegato"
-
-#: models.py:38
-msgid "attachment"
-msgstr "allegato"
-
-#: models.py:38
-msgid "attachments"
-msgstr "allegati"
diff --git a/chunks/locale/jp/LC_MESSAGES/django.mo b/chunks/locale/jp/LC_MESSAGES/django.mo
deleted file mode 100644 (file)
index ad2faa7..0000000
Binary files a/chunks/locale/jp/LC_MESSAGES/django.mo and /dev/null differ
diff --git a/chunks/locale/jp/LC_MESSAGES/django.po b/chunks/locale/jp/LC_MESSAGES/django.po
deleted file mode 100644 (file)
index dcc303c..0000000
+++ /dev/null
@@ -1,54 +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.
-#
-#, fuzzy
-msgid ""
-msgstr ""
-"Project-Id-Version: PACKAGE VERSION\n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2012-07-19 11:39+0200\n"
-"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
-"Last-Translator: FULL NAME <EMAIL@ADDRESS>\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"
-
-#: models.py:11 models.py:33
-msgid "key"
-msgstr ""
-
-#: models.py:11
-msgid "A unique name for this chunk of content"
-msgstr ""
-
-#: models.py:12
-msgid "description"
-msgstr ""
-
-#: models.py:13
-msgid "content"
-msgstr ""
-
-#: models.py:17
-msgid "chunk"
-msgstr ""
-
-#: models.py:18
-msgid "chunks"
-msgstr ""
-
-#: models.py:33
-msgid "A unique name for this attachment"
-msgstr ""
-
-#: models.py:38
-msgid "attachment"
-msgstr ""
-
-#: models.py:38
-msgid "attachments"
-msgstr ""
diff --git a/chunks/locale/lt/LC_MESSAGES/django.mo b/chunks/locale/lt/LC_MESSAGES/django.mo
deleted file mode 100644 (file)
index 6131fd5..0000000
Binary files a/chunks/locale/lt/LC_MESSAGES/django.mo and /dev/null differ
diff --git a/chunks/locale/lt/LC_MESSAGES/django.po b/chunks/locale/lt/LC_MESSAGES/django.po
deleted file mode 100644 (file)
index a78804a..0000000
+++ /dev/null
@@ -1,54 +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: 2012-07-19 11:39+0200\n"
-"PO-Revision-Date: 2012-03-01 16:13+0100\n"
-"Last-Translator: Aneta\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"
-"X-Translated-Using: django-rosetta 0.5.3\n"
-
-#: models.py:11 models.py:33
-msgid "key"
-msgstr "raktas"
-
-#: models.py:11
-msgid "A unique name for this chunk of content"
-msgstr "Unikalus šio turinio gabalo pavadnimas"
-
-#: models.py:12
-msgid "description"
-msgstr "aprašymas"
-
-#: models.py:13
-msgid "content"
-msgstr "turinys"
-
-#: models.py:17
-msgid "chunk"
-msgstr "gabalas"
-
-#: models.py:18
-msgid "chunks"
-msgstr "gabalai"
-
-#: models.py:33
-msgid "A unique name for this attachment"
-msgstr "Unikalus šio priedo pavadnimas"
-
-#: models.py:38
-msgid "attachment"
-msgstr "priedas"
-
-#: models.py:38
-msgid "attachments"
-msgstr "priedai"
diff --git a/chunks/locale/pl/LC_MESSAGES/django.mo b/chunks/locale/pl/LC_MESSAGES/django.mo
deleted file mode 100644 (file)
index a26b41c..0000000
Binary files a/chunks/locale/pl/LC_MESSAGES/django.mo and /dev/null differ
diff --git a/chunks/locale/pl/LC_MESSAGES/django.po b/chunks/locale/pl/LC_MESSAGES/django.po
deleted file mode 100644 (file)
index c562232..0000000
+++ /dev/null
@@ -1,54 +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: 2012-07-19 11:39+0200\n"
-"PO-Revision-Date: 2010-05-19 16:19\n"
-"Last-Translator: <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"
-"X-Translated-Using: django-rosetta 0.5.3\n"
-
-#: models.py:11 models.py:33
-msgid "key"
-msgstr "klucz"
-
-#: models.py:11
-msgid "A unique name for this chunk of content"
-msgstr "Unikalna nazwa dla tego kawałka treści"
-
-#: models.py:12
-msgid "description"
-msgstr "opis"
-
-#: models.py:13
-msgid "content"
-msgstr "zawartość"
-
-#: models.py:17
-msgid "chunk"
-msgstr "kawałek"
-
-#: models.py:18
-msgid "chunks"
-msgstr "kawałki"
-
-#: models.py:33
-msgid "A unique name for this attachment"
-msgstr "Unikalna nazwa dla tego załącznika"
-
-#: models.py:38
-msgid "attachment"
-msgstr "załącznik"
-
-#: models.py:38
-msgid "attachments"
-msgstr "załączniki"
diff --git a/chunks/locale/ru/LC_MESSAGES/django.mo b/chunks/locale/ru/LC_MESSAGES/django.mo
deleted file mode 100644 (file)
index e1d650c..0000000
Binary files a/chunks/locale/ru/LC_MESSAGES/django.mo and /dev/null differ
diff --git a/chunks/locale/ru/LC_MESSAGES/django.po b/chunks/locale/ru/LC_MESSAGES/django.po
deleted file mode 100644 (file)
index 593521f..0000000
+++ /dev/null
@@ -1,53 +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: 2012-07-19 11:39+0200\n"
-"PO-Revision-Date: 2012-03-04 22:10+0100\n"
-"Last-Translator: xxx <xxx>\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"
-
-#: models.py:11 models.py:33
-msgid "key"
-msgstr "ключ"
-
-#: models.py:11
-msgid "A unique name for this chunk of content"
-msgstr "Уникальное имя для этого фрагмента содержания"
-
-#: models.py:12
-msgid "description"
-msgstr "описание"
-
-#: models.py:13
-msgid "content"
-msgstr "содержание"
-
-#: models.py:17
-msgid "chunk"
-msgstr "фрагмент"
-
-#: models.py:18
-msgid "chunks"
-msgstr "фрагменты"
-
-#: models.py:33
-msgid "A unique name for this attachment"
-msgstr "Уникальное имя для этого приложения"
-
-#: models.py:38
-msgid "attachment"
-msgstr "приложение"
-
-#: models.py:38
-msgid "attachments"
-msgstr "приложения"
diff --git a/chunks/locale/uk/LC_MESSAGES/django.mo b/chunks/locale/uk/LC_MESSAGES/django.mo
deleted file mode 100644 (file)
index 7c5388e..0000000
Binary files a/chunks/locale/uk/LC_MESSAGES/django.mo and /dev/null differ
diff --git a/chunks/locale/uk/LC_MESSAGES/django.po b/chunks/locale/uk/LC_MESSAGES/django.po
deleted file mode 100644 (file)
index edb9b06..0000000
+++ /dev/null
@@ -1,53 +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: 2012-07-19 11:39+0200\n"
-"PO-Revision-Date: 2012-03-04 17:29+0100\n"
-"Last-Translator: xxx <xxx>\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"
-
-#: models.py:11 models.py:33
-msgid "key"
-msgstr "ключ"
-
-#: models.py:11
-msgid "A unique name for this chunk of content"
-msgstr "Унікальна назва для цієї частини змісту"
-
-#: models.py:12
-msgid "description"
-msgstr "опис"
-
-#: models.py:13
-msgid "content"
-msgstr "зміст"
-
-#: models.py:17
-msgid "chunk"
-msgstr "частина"
-
-#: models.py:18
-msgid "chunks"
-msgstr "частини"
-
-#: models.py:33
-msgid "A unique name for this attachment"
-msgstr "Унікальна назва для цього додатку"
-
-#: models.py:38
-msgid "attachment"
-msgstr "додаток"
-
-#: models.py:38
-msgid "attachments"
-msgstr "додатки"
diff --git a/chunks/models.py b/chunks/models.py
deleted file mode 100644 (file)
index 5cd007d..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-# -*- coding: utf-8 -*-
-from django.core.cache import cache
-from django.db import models
-from django.utils.translation import ugettext_lazy as _
-
-
-class Chunk(models.Model):
-    """
-    A Chunk is a piece of content associated with a unique key that can be inserted into
-    any template with the use of a special template tag.
-    """
-    key = models.CharField(
-        _('key'), help_text=_('A unique name for this chunk of content'), primary_key=True, max_length=255)
-    description = models.CharField(_('description'), blank=True, max_length=255)
-    content = models.TextField(_('content'), blank=True)
-
-    class Meta:
-        ordering = ('key',)
-        verbose_name = _('chunk')
-        verbose_name_plural = _('chunks')
-
-    def __unicode__(self):
-        return self.key
-
-    def cache_key(self):
-        return 'chunk_' + self.key
-
-    def save(self, *args, **kwargs):
-        ret = super(Chunk, self).save(*args, **kwargs)
-        cache.delete(self.cache_key())
-        return ret
-
-
-class Attachment(models.Model):
-    key = models.CharField(_('key'), help_text=_('A unique name for this attachment'), primary_key=True, max_length=255)
-    attachment = models.FileField(upload_to='chunks/attachment')
-
-    class Meta:
-        ordering = ('key',)
-        verbose_name, verbose_name_plural = _('attachment'), _('attachments')
-
-    def __unicode__(self):
-        return self.key
diff --git a/chunks/templatetags/__init__.py b/chunks/templatetags/__init__.py
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/chunks/templatetags/chunks.py b/chunks/templatetags/chunks.py
deleted file mode 100644 (file)
index 968d284..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-# -*- coding: utf-8 -*-
-from django import template
-from django.core.cache import cache
-from ..models import Chunk, Attachment
-
-
-register = template.Library()
-
-
-@register.simple_tag
-def chunk(key, cache_time=0):
-    try:
-        cache_key = 'chunk_' + key
-        c = cache.get(cache_key)
-        if c is None:
-            c = Chunk.objects.get(key=key)
-            cache.set(cache_key, c, int(cache_time))
-        content = c.content
-    except Chunk.DoesNotExist:
-        n = Chunk(key=key)
-        n.save()
-        return ''
-    return content
-
-
-@register.simple_tag
-def attachment(key, cache_time=0):
-    try:
-        cache_key = 'attachment_' + key
-        c = cache.get(cache_key)
-        if c is None:
-            c = Attachment.objects.get(key=key)
-            cache.set(cache_key, c, int(cache_time))
-        return c.attachment.url
-    except Attachment.DoesNotExist:
-        return ''
diff --git a/comment/__init__.py b/comment/__init__.py
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/comment/admin.py b/comment/admin.py
deleted file mode 100644 (file)
index 7c9ce9a..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-# -*- coding: utf-8 -*-
-from django.contrib import admin
-
-from .models import CommentDocument
-
-
-class CommentDocumentAdmin(admin.ModelAdmin):
-    prepopulated_fields = {"slug": ("name",)}
-
-admin.site.register(CommentDocument, CommentDocumentAdmin)
diff --git a/comment/locale/pl/LC_MESSAGES/django.mo b/comment/locale/pl/LC_MESSAGES/django.mo
deleted file mode 100644 (file)
index b3595bd..0000000
Binary files a/comment/locale/pl/LC_MESSAGES/django.mo and /dev/null differ
diff --git a/comment/locale/pl/LC_MESSAGES/django.po b/comment/locale/pl/LC_MESSAGES/django.po
deleted file mode 100644 (file)
index 94594a8..0000000
+++ /dev/null
@@ -1,84 +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.
-#
-#, fuzzy
-msgid ""
-msgstr ""
-"Project-Id-Version: PACKAGE VERSION\n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2013-12-05 09:48+0100\n"
-"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
-"Last-Translator: FULL NAME <EMAIL@ADDRESS>\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"
-
-#: templates/comment/commentdocument_list.html:7
-#, python-format
-msgid ""
-"\n"
-"    Take part in the consultation by filling in <a href=\"%(form_href)s"
-"\">the form</a> or comment on specific competencies in different thematic "
-"fields\n"
-"    "
-msgstr ""
-"\n"
-" Weź udział w konsultacjach wypełniając <a href=\"%(form_href)s\">ten "
-"formularz</a> lub skomentuj szczegółowo kompetencje w poszczególnych "
-"obszarach tematycznych\n"
-"    "
-
-#: templates/comment/commentdocument_list.html:17
-msgid ""
-"\n"
-"        <p>To insert comments in a selected thematic field you need to "
-"register.</p>\n"
-"\n"
-"        <p>How to do it?</p>\n"
-"        <ol>\n"
-"            <li>Click on a selected link from the list of the thematic "
-"fields.</li>\n"
-"            <li>Choose \"Register\" option.</li>\n"
-"            <li>Enter your data.</li>\n"
-"            <li>Check your email for the message confirming the registration "
-"and click on the link included.</li>\n"
-"            <li>Enter your username and password.</li>\n"
-"            <li>Go back to the consultation page. Choose one of the fields, "
-"log in and share your comments.</li>\n"
-"        </ol>\n"
-"\n"
-"        <p>How to add a comment?</p>\n"
-"        <ol>\n"
-"            <li>Highlight a fragment of the text.</li>\n"
-"            <li>Click on a yellow \"comment\" button on the left.</li>\n"
-"            <li>Type in a subject and content of your comment.</li>\n"
-"            <li>Save your comment.</li>\n"
-"        </ol>\n"
-"    "
-msgstr ""
-"\n"
-"        <p>Aby wprowadzić szczegółowe komentarze w poszczególnych obszarach tematycznych konieczna jest rejestracja.</p>"
-"        <p>Jak to zrobić?</p>"
-"        <ol>"
-"            <li>Kliknij w dowolny link z listy obszarów tematycznych.</li>"
-"            <li>Wybierz opcję \"Register\" (Zarejestruj się).</li>"
-"            <li>Wprowadź swoje dane (adres e-mail, imię, nazwisko). Kliknij zielony przycisk \"Register\".</li>"
-"            <li>Na Twoje konto e-mail zostanie wysłana wiadomość potwierdzająca rejestrację. Kliknij w podany w niej link, aby aktywować swoje konto.</li>"
-"            <li>Wprowadź nazwę użytkownika i hasło. Potwierdź zielonym przyciskiem.</li>"
-"            <li>Wejdź ponownie na stronę http://katalog.edukacjamedialna.edu.pl/wez-udzial/. Wybierz interesujący Cię obszar tematyczny, zaloguj się i podziel się swoimi uwagami.</li>"
-"        </ol>"
-"        "
-"        <p>Jak dodać komentarz?</p>"
-"        <ol>"
-"            <li>Zaznacz dowolny fragment tekstu.</li>"
-"            <li>Wciśnij żółty przycisk \"comment\" po lewej stronie.</li>"
-"            <li>W polu \"subject\" wpisz temat uwagi, a w polu \"content\" jej treść.</li>"
-"            <li>Zapisz swój komentarz przyciskiem \"save\".</li>"
-"        </ol>"
-"    "
\ No newline at end of file
diff --git a/comment/migrations/0001_initial.py b/comment/migrations/0001_initial.py
deleted file mode 100644 (file)
index 9bf33a5..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-# -*- coding: utf-8 -*-
-import datetime
-from south.db import db
-from south.v2 import SchemaMigration
-from django.db import models
-
-
-class Migration(SchemaMigration):
-
-    def forwards(self, orm):
-        # Adding model 'CommentDocument'
-        db.create_table(u'comment_commentdocument', (
-            (u'id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
-            ('name', self.gf('django.db.models.fields.CharField')(unique=True, max_length=255)),
-            ('slug', self.gf('django.db.models.fields.SlugField')(unique=True, max_length=255)),
-            ('comment_id', self.gf('django.db.models.fields.CharField')(unique=True, max_length=255)),
-            ('order', self.gf('django.db.models.fields.IntegerField')()),
-        ))
-        db.send_create_signal(u'comment', ['CommentDocument'])
-
-
-    def backwards(self, orm):
-        # Deleting model 'CommentDocument'
-        db.delete_table(u'comment_commentdocument')
-
-
-    models = {
-        u'comment.commentdocument': {
-            'Meta': {'ordering': "['order']", 'object_name': 'CommentDocument'},
-            'comment_id': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'}),
-            'order': ('django.db.models.fields.IntegerField', [], {}),
-            'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '255'})
-        }
-    }
-
-    complete_apps = ['comment']
\ No newline at end of file
diff --git a/comment/migrations/0002_auto__add_field_commentdocument_language_code.py b/comment/migrations/0002_auto__add_field_commentdocument_language_code.py
deleted file mode 100644 (file)
index 686f568..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-# -*- coding: utf-8 -*-
-import datetime
-from south.db import db
-from south.v2 import SchemaMigration
-from django.db import models
-
-
-class Migration(SchemaMigration):
-
-    def forwards(self, orm):
-        # Adding field 'CommentDocument.language_code'
-        db.add_column(u'comment_commentdocument', 'language_code',
-                      self.gf('django.db.models.fields.CharField')(default='pl', max_length=2),
-                      keep_default=False)
-
-
-    def backwards(self, orm):
-        # Deleting field 'CommentDocument.language_code'
-        db.delete_column(u'comment_commentdocument', 'language_code')
-
-
-    models = {
-        u'comment.commentdocument': {
-            'Meta': {'ordering': "['order']", 'object_name': 'CommentDocument'},
-            'comment_id': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'language_code': ('django.db.models.fields.CharField', [], {'default': "'pl'", 'max_length': '2'}),
-            'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'}),
-            'order': ('django.db.models.fields.IntegerField', [], {}),
-            'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '255'})
-        }
-    }
-
-    complete_apps = ['comment']
\ No newline at end of file
diff --git a/comment/migrations/__init__.py b/comment/migrations/__init__.py
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/comment/models.py b/comment/models.py
deleted file mode 100644 (file)
index 38c43d1..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-# -*- coding: utf-8 -*-
-from django.db import models
-from django.core.urlresolvers import reverse
-
-
-class CommentDocument(models.Model):
-    name = models.CharField(max_length=255, unique=True)
-    slug = models.SlugField(max_length=255, unique=True)
-    comment_id = models.CharField(max_length=255, unique=True)
-    order = models.IntegerField()
-    language_code = models.CharField(max_length=2, default='pl')
-
-    class Meta:
-        ordering = ['order']
-
-    def __unicode__(self):
-        return self.name
-
-    def get_absolute_url(self):
-        return reverse('comment_document', kwargs={'slug': self.slug})
diff --git a/comment/templates/comment/commentdocument_detail.html b/comment/templates/comment/commentdocument_detail.html
deleted file mode 100644 (file)
index 2ab214b..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-{% extends "base_mil.html" %}
-
-{% block body %}
-
-    <h1>{{object.name}}</h1>
-
-    <iframe  frameborder="0" src="{{comment_url}}/text/{{object.comment_id}}/comments_frame/?" style="height: 600px; width: 99.9%; position: relative; top: 0px;"></iframe>
-
-{% endblock %}
\ No newline at end of file
diff --git a/comment/templates/comment/commentdocument_list.html b/comment/templates/comment/commentdocument_list.html
deleted file mode 100644 (file)
index 0a13f63..0000000
+++ /dev/null
@@ -1,39 +0,0 @@
-{% extends "base_mil.html" %}
-{% load i18n %}
-
-
-{% block body %}
-
-    <p>{% blocktrans with href=form_href %}
-    Take part in the consultation by filling in <a href="{{form_href}}">the form</a> or comment on specific competencies in different thematic fields
-    {% endblocktrans %}:</p>
-
-    <ol>
-    {% for document in object_list %}
-        <li><a href="{{document.get_absolute_url}}">{{document.name}}</a></li>
-    {% endfor %}
-    </ol>
-
-    {% blocktrans %}
-        <p>To insert comments in a selected thematic field you need to register.</p>
-
-        <p>How to do it?</p>
-        <ol>
-            <li>Click on a selected link from the list of the thematic fields.</li>
-            <li>Choose "Register" option.</li>
-            <li>Enter your data.</li>
-            <li>Check your email for the message confirming the registration and click on the link included.</li>
-            <li>Enter your username and password.</li>
-            <li>Go back to the consultation page. Choose one of the fields, log in and share your comments.</li>
-        </ol>
-
-        <p>How to add a comment?</p>
-        <ol>
-            <li>Highlight a fragment of the text.</li>
-            <li>Click on a yellow "comment" button on the left.</li>
-            <li>Type in a subject and content of your comment.</li>
-            <li>Save your comment.</li>
-        </ol>
-    {% endblocktrans %}
-
-{% endblock %}
\ No newline at end of file
diff --git a/comment/urls.py b/comment/urls.py
deleted file mode 100644 (file)
index ef48089..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-# -*- coding: utf-8 -*-
-from django.conf.urls import patterns, url
-
-from .views import CommentDocumentList, CommentDocument
-
-
-urlpatterns = patterns(
-    '',
-    url('^$', CommentDocumentList.as_view(), name='comment_document_index'),
-    url('^(?P<slug>[^/]+)/$', CommentDocument.as_view(), name='comment_document')
-)
diff --git a/comment/views.py b/comment/views.py
deleted file mode 100644 (file)
index 40db4b0..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-# -*- coding: utf-8 -*-
-from django.views.generic import ListView, DetailView
-from django.conf import settings
-from django.utils.translation import get_language
-
-from django.core.urlresolvers import reverse
-
-from .models import CommentDocument as CommentDocumentModel
-
-
-class CommentDocumentList(ListView):
-    model = CommentDocumentModel
-
-    def get_queryset(self):
-        return super(CommentDocumentList, self).get_queryset().filter(language_code=get_language())
-
-    def get_context_data(self, **kwargs):
-        context = super(CommentDocumentList, self).get_context_data(**kwargs)
-        context['form_href'] = reverse('contact_form', kwargs={'form_tag': 'mil'})
-        return context
-
-
-class CommentDocument(DetailView):
-    model = CommentDocumentModel
-
-    def get_context_data(self, **kwargs):
-        context = super(CommentDocument, self).get_context_data(**kwargs)
-        context['comment_url'] = settings.COMMENT_URL
-        return context
\ No newline at end of file
diff --git a/contact/__init__.py b/contact/__init__.py
deleted file mode 100644 (file)
index 3bce2e3..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-# -*- coding: utf-8 -*-
-"""
-Generic app for creating contact forms.
-
-0. Add 'contact' to your INSTALLED_APPS and include 'contact.urls' somewhere
-in your urls.py, like: 
-    url(r'^contact/', 
-        include('contact.urls'))
-
-1. Migrate.
-
-2. Create somewhere in your project a module with some subclasses of
-contact.forms.ContactForm, specyfing form_tag and some fields in each.
-
-3. Set CONTACT_FORMS_MODULE in your settings to point to the module.
-
-4. Link to the form with {% url 'contact_form' form_tag %}.
-
-5. Optionally override some templates in form-specific template directories
-(/contact/<form_tag>/...).
-
-6. Receive submitted forms by email and read them in admin.
-
-
-Example:
-========
-
-settings.py:
-    CONTACT_FORMS_MODULE = 'myproject.contact_forms'
-
-myproject/contact_forms.py:
-    from django import forms
-    from contact.forms import ContactForm
-    from django.utils.translation import ugettext_lazy as _
-
-    class RegistrationForm(ContactForm):
-        form_tag = 'register'
-        name = forms.CharField(label=_('Name'), max_length=128)
-        presentation = forms.FileField(label=_('Presentation'))
-
-some_template.html:
-    {% url 'contact:form' 'register' %}
-
-"""
-
-from fnpdjango.utils.app import AppSettings
-
-
-class Settings(AppSettings):
-    FORMS_MODULE = "contact_forms"
-
-
-app_settings = Settings('CONTACT')
diff --git a/contact/admin.py b/contact/admin.py
deleted file mode 100644 (file)
index 22d3593..0000000
+++ /dev/null
@@ -1,177 +0,0 @@
-# -*- coding: utf-8 -*-
-import csv
-import json
-
-from django.contrib import admin
-from django.utils.translation import ugettext as _
-from django.utils.safestring import mark_safe
-from django.conf.urls import patterns, url
-from django.http import HttpResponse, Http404
-
-from edumed.utils import UnicodeCSVWriter
-from .forms import contact_forms, admin_list_width
-from .models import Contact
-
-
-class ContactAdminMeta(admin.ModelAdmin.__class__):
-    def __getattr__(cls, name):
-        if name.startswith('admin_list_'):
-            return lambda self: ""
-        raise AttributeError(name)
-
-
-class ContactAdmin(admin.ModelAdmin):
-    __metaclass__ = ContactAdminMeta
-    date_hierarchy = 'created_at'
-    list_display = ['created_at', 'contact', 'form_tag'] + \
-        ["admin_list_%d" % i for i in range(admin_list_width)]
-    fields = ['form_tag', 'created_at', 'contact', 'ip']
-    readonly_fields = ['form_tag', 'created_at', 'contact', 'ip']
-    list_filter = ['form_tag']
-
-    @staticmethod
-    def admin_list(obj, nr):
-        try:
-            field_name = contact_forms[obj.form_tag].admin_list[nr]
-        except BaseException:
-            return ''
-        else:
-            return Contact.pretty_print(obj.body.get(field_name, ''), for_html=True)
-
-    def __getattr__(self, name):
-        if name.startswith('admin_list_'):
-            nr = int(name[len('admin_list_'):])
-            return lambda obj: self.admin_list(obj, nr)
-        raise AttributeError(name)
-
-    def change_view(self, request, object_id, form_url='', extra_context=None):
-        if object_id:
-            try:
-                instance = Contact.objects.get(pk=object_id)
-                assert isinstance(instance.body, dict)
-            except (Contact.DoesNotExist, AssertionError):
-                pass
-            else:
-                # Create readonly fields from the body JSON.
-                attachments = list(instance.attachment_set.all())
-                body_keys = instance.body.keys() + [a.tag for a in attachments]
-
-                # Find the original form.
-                try:
-                    orig_fields = contact_forms[instance.form_tag]().fields
-                except KeyError:
-                    orig_fields = {}
-
-                # Try to preserve the original order.
-                orig_keys = list(orig_fields.keys())
-                admin_keys = [key for key in orig_keys if key in body_keys] + \
-                             [key for key in body_keys if key not in orig_keys]
-                admin_fields = ['body__%s' % key for key in admin_keys]
-
-                self.readonly_fields.extend(admin_fields)
-
-                self.fieldsets = [
-                    (None, {'fields': self.fields}),
-                    (_('Body'), {'fields': admin_fields}),
-                ]
-
-                # Create field getters for fields and attachments.
-                def attach_getter(key, value):
-                    def f(self):
-                        return value
-                    f.short_description = orig_fields[key].label if key in orig_fields else _(key)
-                    setattr(self, "body__%s" % key, f)
-
-                for k, v in instance.body.items():
-                    attach_getter(k, Contact.pretty_print(v, for_html=True))
-
-                download_link = "<a href='%(url)s'>%(url)s</a>"
-                for attachment in attachments:
-                    link = mark_safe(download_link % {
-                            'url': attachment.get_absolute_url()})
-                    attach_getter(attachment.tag, link)
-        return super(ContactAdmin, self).change_view(
-            request, object_id, form_url=form_url, extra_context=extra_context)
-
-    def changelist_view(self, request, extra_context=None):
-        context = dict()
-        if 'form_tag' in request.GET:
-            form = contact_forms.get(request.GET['form_tag'])
-            context['extract_types'] = [
-                {'slug': 'all', 'label': _('all')},
-                {'slug': 'contacts', 'label': _('contacts')}]
-            context['extract_types'] += [type for type in getattr(form, 'extract_types', [])]
-        return super(ContactAdmin, self).changelist_view(request, extra_context=context)
-
-    def get_urls(self):
-        # urls = super(ContactAdmin, self).get_urls()
-        return patterns(
-            '',
-            url(r'^extract/(?P<form_tag>[\w-]+)/(?P<extract_type_slug>[\w-]+)/$',
-                self.admin_site.admin_view(extract_view), name='contact_extract')
-        ) + super(ContactAdmin, self).get_urls()
-
-
-def extract_view(request, form_tag, extract_type_slug):
-    contacts_by_spec = dict()
-    form = contact_forms.get(form_tag)
-    if form is None and extract_type_slug not in ('contacts', 'all'):
-        raise Http404
-
-    q = Contact.objects.filter(form_tag=form_tag)
-    at_year = request.GET.get('created_at__year')
-    at_month = request.GET.get('created_at__month')
-    if at_year:
-        q = q.filter(created_at__year=at_year)
-        if at_month:
-            q = q.filter(created_at__month=at_month)
-
-    # Segregate contacts by body key sets
-    if form:
-        orig_keys = list(form().fields.keys())
-    else:
-        orig_keys = []
-    for contact in q.all():
-        if extract_type_slug == 'contacts':
-            keys = ['contact']
-        elif extract_type_slug == 'all':
-            keys = contact.body.keys() + ['contact']
-            keys = [key for key in orig_keys if key in keys] + [key for key in keys if key not in orig_keys]
-        else:
-            keys = form.get_extract_fields(contact, extract_type_slug)
-        contacts_by_spec.setdefault(tuple(keys), []).append(contact)
-
-    response = HttpResponse(content_type='text/csv')
-    csv_writer = UnicodeCSVWriter(response)
-
-    # Generate list for each body key set
-    for keys, contacts in contacts_by_spec.items():
-        csv_writer.writerow(keys)
-        for contact in contacts:
-            if extract_type_slug == 'contacts':
-                records = [dict(contact=contact.contact)]
-            elif extract_type_slug == 'all':
-                records = [dict(contact=contact.contact, **contact.body)]
-            else:
-                records = form.get_extract_records(keys, contact, extract_type_slug)
-
-            for record in records:
-                for key in keys:
-                    if key not in record:
-                        record[key] = ''
-                    if isinstance(record[key], basestring):
-                        pass
-                    elif isinstance(record[key], bool):
-                        record[key] = 'tak' if record[key] else 'nie'
-                    elif isinstance(record[key], (list, tuple)) and all(isinstance(v, basestring) for v in record[key]):
-                        record[key] = ', '.join(record[key])
-                    else:
-                        record[key] = json.dumps(record[key])
-
-                csv_writer.writerow([record[key] for key in keys])
-        csv_writer.writerow([])
-
-    response['Content-Disposition'] = 'attachment; filename="kontakt.csv"'
-    return response
-
-admin.site.register(Contact, ContactAdmin)
diff --git a/contact/fields.py b/contact/fields.py
deleted file mode 100644 (file)
index 67fc71b..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-# -*- coding: utf-8 -*-
-from django import forms
-from .widgets import HeaderWidget
-
-
-class HeaderField(forms.CharField):
-    def __init__(self, required=False, widget=None, *args, **kwargs):
-        if widget is None:
-            widget = HeaderWidget
-        super(HeaderField, self).__init__(required=required, widget=widget, *args, **kwargs)
diff --git a/contact/forms.py b/contact/forms.py
deleted file mode 100644 (file)
index 059f9e8..0000000
+++ /dev/null
@@ -1,192 +0,0 @@
-# -*- coding: utf-8 -*-
-import os
-
-from django.contrib.sites.models import Site
-from django.core.exceptions import ValidationError
-from django.core.files.uploadedfile import UploadedFile
-from django.core.mail import send_mail, mail_managers
-from django.core.validators import validate_email
-from django import forms
-from django.db.models.fields.files import FieldFile
-from django.template.loader import render_to_string
-from django.template import RequestContext
-from django.utils.translation import ugettext_lazy as _
-
-from . import mailing
-
-
-contact_forms = {}
-update_forms = {}
-admin_list_width = 0
-
-
-class ContactFormMeta(forms.Form.__class__):
-    def __new__(cls, name, bases, attrs):
-        global admin_list_width
-        model = super(ContactFormMeta, cls).__new__(cls, name, bases, attrs)
-        if model.form_tag:
-            if model.form_type == 'create':
-                assert model.form_tag not in contact_forms, 'Duplicate form_tag.'
-                if model.admin_list:
-                    admin_list_width = max(admin_list_width, len(model.admin_list))
-                contact_forms[model.form_tag] = model
-            elif model.form_type == 'update':
-                assert model.form_tag not in update_forms, 'Duplicate form_tag.'
-                update_forms[model.form_tag] = model
-        return model
-
-
-class ContactForm(forms.Form):
-    """Subclass and define some fields."""
-    __metaclass__ = ContactFormMeta
-
-    form_tag = None
-    form_type = 'create'
-    updatable = False
-    old_form_tags = []
-    form_title = _('Contact form')
-    submit_label = _('Submit')
-    admin_list = None
-    result_page = False
-    mailing_field = None
-    mailing = False
-    data_processing = None
-    form_formsets = {}
-
-    disabled = False
-    disabled_template = None
-
-    required_css_class = 'required'
-    contact = NotImplemented
-
-    def __init__(self, data=None, files=None, *args, **kwargs):
-        self.instance = kwargs.pop('instance', None)
-        if self.instance and (data is not None or files is not None):
-            for attachment in self.instance.attachment_set.all():
-                if attachment.tag not in files:
-                    files[attachment.tag] = attachment.file
-        super(ContactForm, self).__init__(data, files, *args, **kwargs)
-        if not self.is_bound and self.instance:
-            self.fields['contact'].initial = self.instance.contact
-            self.fields['contact'].widget = forms.HiddenInput()
-            body = self.instance.body
-            for field, value in body.iteritems():
-                if field in self.fields:
-                    self.fields[field].initial = value
-            for attachment in self.instance.attachment_set.all():
-                self.fields[attachment.tag].initial = attachment
-
-    def get_dictionary(self, contact):
-        site = Site.objects.get_current()
-        return {
-            'form_tag': self.form_tag,
-            'site_name': getattr(self, 'site_name', site.name),
-            'site_domain': getattr(self, 'site_domain', site.domain),
-            'contact': contact,
-        }
-
-    @classmethod
-    def is_disabled(cls):
-        # end_time = localtime_to_utc(datetime(*cls.ends_on)) if cls.ends_on else None
-        # expired = end_time and end_time < timezone.now()
-        return cls.disabled  # or expired
-
-    def formset_initial(self, prefix):
-        if not self.instance:
-            return None
-        return self.instance.body.get(prefix)
-
-    def get_formsets(self, request=None):
-        request_data = {'data': request.POST, 'files': request.FILES} if request else {}
-        kwargs_instance = dict(request_data)
-        kwargs_instance['instance'] = self.instance
-        formsets = {}
-        for prefix, formset_class in self.form_formsets.iteritems():
-            if getattr(formset_class, 'takes_instance', False):
-                kwargs = kwargs_instance
-            else:
-                kwargs = request_data
-            formsets[prefix] = formset_class(
-                prefix=prefix, initial=self.formset_initial(prefix), **kwargs)
-        return formsets
-
-    def save(self, request, formsets=None):
-        from .models import Attachment, Contact
-        body = {}
-        for name, value in self.cleaned_data.items():
-            if not isinstance(value, UploadedFile) and not isinstance(value, FieldFile) and name != 'contact':
-                body[name] = value
-
-        for formset in formsets or []:
-            for f in formset.forms:
-                sub_body = {}
-                for name, value in f.cleaned_data.items():
-                    if not isinstance(value, UploadedFile):
-                        sub_body[name] = value
-                if sub_body:
-                    body.setdefault(f.form_tag, []).append(sub_body)
-
-        if self.instance:
-            contact = self.instance
-            contact.body = body
-            email_changed = contact.contact != self.cleaned_data['contact']
-            contact.contact = self.cleaned_data['contact']
-            assert contact.form_tag == self.form_tag
-            contact.save()
-        else:
-            contact = Contact.objects.create(
-                body=body,
-                ip=request.META['REMOTE_ADDR'],
-                contact=self.cleaned_data['contact'],
-                form_tag=self.form_tag)
-            contact.generate_key()
-            email_changed = True
-        for name, value in self.cleaned_data.items():
-            if isinstance(value, UploadedFile):
-                for attachment in Attachment.objects.filter(contact=contact, tag=name):
-                    os.remove(attachment.file.path)
-                    attachment.delete()
-                attachment = Attachment(contact=contact, tag=name)
-                attachment.file.save(value.name, value)
-                attachment.save()
-
-        site = Site.objects.get_current()
-        dictionary = self.get_dictionary(contact)
-        context = RequestContext(request)
-        mail_managers_subject = render_to_string([
-                'contact/%s/mail_managers_subject.txt' % self.form_tag,
-                'contact/mail_managers_subject.txt', 
-            ], dictionary, context).strip()
-        mail_managers_body = render_to_string([
-                'contact/%s/mail_managers_body.txt' % self.form_tag,
-                'contact/mail_managers_body.txt', 
-            ], dictionary, context)
-        mail_managers(mail_managers_subject, mail_managers_body, fail_silently=True)
-
-        try:
-            validate_email(contact.contact)
-        except ValidationError:
-            pass
-        else:
-            if not self.instance:
-                mail_subject = render_to_string([
-                        'contact/%s/mail_subject.txt' % self.form_tag,
-                        'contact/mail_subject.txt',
-                    ], dictionary, context).strip()
-                if self.result_page:
-                    mail_body = render_to_string(
-                        'contact/%s/results_email.txt' % contact.form_tag,
-                        {
-                            'contact': contact,
-                            'results': self.results(contact),
-                        }, context)
-                else:
-                    mail_body = render_to_string([
-                            'contact/%s/mail_body.txt' % self.form_tag,
-                            'contact/mail_body.txt',
-                        ], dictionary, context)
-                send_mail(mail_subject, mail_body, 'no-reply@%s' % site.domain, [contact.contact], fail_silently=True)
-            if email_changed and (self.mailing or (self.mailing_field and self.cleaned_data[self.mailing_field])):
-                mailing.subscribe(contact.contact)
-
-        return contact
diff --git a/contact/locale/pl/LC_MESSAGES/django.mo b/contact/locale/pl/LC_MESSAGES/django.mo
deleted file mode 100644 (file)
index ef06814..0000000
Binary files a/contact/locale/pl/LC_MESSAGES/django.mo and /dev/null differ
diff --git a/contact/locale/pl/LC_MESSAGES/django.po b/contact/locale/pl/LC_MESSAGES/django.po
deleted file mode 100644 (file)
index cabbe00..0000000
+++ /dev/null
@@ -1,92 +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: 2013-11-05 10:16+0100\n"
-"PO-Revision-Date: 2012-10-10 13:12+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"
-
-#: admin.py:77
-msgid "Body"
-msgstr "Treść"
-
-#: admin.py:101
-msgid "all"
-msgstr "wszystko"
-
-#: admin.py:101
-msgid "contacts"
-msgstr "kontakty"
-
-#: forms.py:29
-msgid "Contact form"
-msgstr "Formularz kontaktowy"
-
-#: forms.py:30
-msgid "Submit"
-msgstr "Wyślij"
-
-#: models.py:11
-msgid "submission date"
-msgstr "data wysłania"
-
-#: models.py:12
-msgid "IP address"
-msgstr "adres IP"
-
-#: models.py:13
-msgid "contact"
-msgstr "kontakt"
-
-#: models.py:14
-msgid "form"
-msgstr "formularz"
-
-#: models.py:15
-msgid "body"
-msgstr "treść"
-
-#: models.py:29
-msgid "submitted form"
-msgstr "przysłany formularz"
-
-#: models.py:30
-msgid "submitted forms"
-msgstr "przysłane formularze"
-
-#: templates/admin/contact/contact/change_list.html:12
-msgid "Extract"
-msgstr "Ekstrakt"
-
-#: templates/contact/mail_body.txt:2 templates/contact/mail_subject.txt:1
-#, python-format
-msgid "Thank you for contacting us at %(site_name)s."
-msgstr "Dziękujemy za skontaktowanie się z nami na stronie %(site_name)s."
-
-#: templates/contact/mail_body.txt:3
-msgid "Your submission has been referred to the project coordinator."
-msgstr "Twoje zgłoszenie zostało przekazane osobie koordynującej projekt."
-
-#: templates/contact/mail_body.txt:6
-msgid "Message sent automatically. Please do not reply to it."
-msgstr "Wiadomość wysłana automatycznie, prosimy nie odpowiadać."
-
-#: templates/contact/thanks.html:4 templates/contact/thanks.html.py:8
-msgid "Thank you"
-msgstr "Dziękujemy"
-
-#: templates/contact/thanks.html:11
-msgid "Thank you for submitting the form."
-msgstr "Dziękujemy za wypełnienie formularza."
diff --git a/contact/mailing.py b/contact/mailing.py
deleted file mode 100644 (file)
index bfd4209..0000000
+++ /dev/null
@@ -1,52 +0,0 @@
-# -*- coding: utf-8 -*-
-
-from hashlib import md5
-
-import requests
-from django.conf import settings
-from mailchimp3 import MailChimp
-from mailchimp3.mailchimpclient import MailChimpError
-
-INTERESTS = {settings.MAILCHIMP_GROUP_ID: True}
-
-
-def get_client():
-    headers = requests.utils.default_headers()
-    headers['User-Agent'] = '%s (%s)' % settings.MANAGERS[0]
-
-
-def subscriber_hash(email):
-    return md5(email).hexdigest()
-
-
-def remove_from_groups(email, client):
-    group_ids = []
-    categories = client.lists.interest_categories.all(list_id=settings.MAILCHIMP_LIST_ID)['categories']
-    for category in categories:
-        groups = client.lists.interest_categories.interests.all(
-            list_id=settings.MAILCHIMP_LIST_ID, category_id=category['id'])['interests']
-        group_ids += [group['id'] for group in groups]
-    interests = {group_id: False for group_id in group_ids}
-    client.lists.members.update(
-         settings.MAILCHIMP_LIST_ID, subscriber_hash(email),
-         data={'interests': interests})
-
-
-def subscribe(email):
-    client = MailChimp(mc_api=settings.MAILCHIMP_API_KEY, timeout=10.0)
-    try:
-        member = client.lists.members.get(settings.MAILCHIMP_LIST_ID, subscriber_hash(email))
-    except MailChimpError:
-        pass
-    else:
-        if member['status'] != 'subscribed':
-            remove_from_groups(email, client)
-    client.lists.members.create_or_update(
-        settings.MAILCHIMP_LIST_ID, subscriber_hash(email),
-        data={
-            'email_address': email,
-            'status_if_new': 'subscribed',
-            'status': 'subscribed',
-            'interests': INTERESTS,
-        }
-    )
diff --git a/contact/management/__init__.py b/contact/management/__init__.py
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/contact/management/commands/__init__.py b/contact/management/commands/__init__.py
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/contact/management/commands/export_newsletter.py b/contact/management/commands/export_newsletter.py
deleted file mode 100644 (file)
index 70ef2b4..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-# -*- coding: utf-8 -*-
-# This file is part of EduMed, licensed under GNU Affero GPLv3 or later.
-# Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
-#
-from django.core.management.base import BaseCommand
-
-from contact.models import Contact
-from edumed import contact_forms
-
-FORMS = (
-    contact_forms.CooperateForm,
-    contact_forms.ContestForm,
-    contact_forms.WTEMForm,
-    contact_forms.TEMForm,
-    contact_forms.CybernauciForm,
-    contact_forms.WLEMForm,
-)
-
-
-class Command(BaseCommand):
-    help = 'Export contacts for newsletter.'
-
-    def handle(self, **options):
-        addresses = set(self.get_addresses())
-        for address in addresses:
-            print address
-
-    def get_addresses(self):
-        for form in FORMS:
-            tags = [form.form_tag] + form.old_form_tags
-            contacts = Contact.objects.filter(form_tag__in=tags)
-            for contact in contacts:
-                if contact.body.get(form.mailing_field):
-                    yield contact.contact
diff --git a/contact/migrations/0001_initial.py b/contact/migrations/0001_initial.py
deleted file mode 100644 (file)
index d16bf4c..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-# -*- coding: utf-8 -*-
-import datetime
-from south.db import db
-from south.v2 import SchemaMigration
-from django.db import models
-
-
-class Migration(SchemaMigration):
-
-    def forwards(self, orm):
-        # Adding model 'Contact'
-        db.create_table('contact_contact', (
-            ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
-            ('created_at', self.gf('django.db.models.fields.DateTimeField')(auto_now_add=True, blank=True)),
-            ('ip', self.gf('django.db.models.fields.IPAddressField')(max_length=15)),
-            ('contact', self.gf('django.db.models.fields.CharField')(max_length=128)),
-            ('form_tag', self.gf('django.db.models.fields.CharField')(max_length=32)),
-            ('body', self.gf('jsonfield.fields.JSONField')()),
-        ))
-        db.send_create_signal('contact', ['Contact'])
-
-
-    def backwards(self, orm):
-        # Deleting model 'Contact'
-        db.delete_table('contact_contact')
-
-
-    models = {
-        'contact.contact': {
-            'Meta': {'ordering': "('-created_at',)", 'object_name': 'Contact'},
-            'body': ('jsonfield.fields.JSONField', [], {}),
-            'contact': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
-            'created_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
-            'form_tag': ('django.db.models.fields.CharField', [], {'max_length': '32'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'ip': ('django.db.models.fields.IPAddressField', [], {'max_length': '15'})
-        }
-    }
-
-    complete_apps = ['contact']
\ No newline at end of file
diff --git a/contact/migrations/0002_auto__add_attachment.py b/contact/migrations/0002_auto__add_attachment.py
deleted file mode 100644 (file)
index 8dc031d..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
-# -*- coding: utf-8 -*-
-import datetime
-from south.db import db
-from south.v2 import SchemaMigration
-from django.db import models
-
-
-class Migration(SchemaMigration):
-
-    def forwards(self, orm):
-        # Adding model 'Attachment'
-        db.create_table('contact_attachment', (
-            ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
-            ('contact', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['contact.Contact'])),
-            ('tag', self.gf('django.db.models.fields.CharField')(max_length=64)),
-            ('file', self.gf('django.db.models.fields.files.FileField')(max_length=100)),
-        ))
-        db.send_create_signal('contact', ['Attachment'])
-
-        # Adding index on 'Contact', fields ['form_tag']
-        db.create_index('contact_contact', ['form_tag'])
-
-
-    def backwards(self, orm):
-        # Removing index on 'Contact', fields ['form_tag']
-        db.delete_index('contact_contact', ['form_tag'])
-
-        # Deleting model 'Attachment'
-        db.delete_table('contact_attachment')
-
-
-    models = {
-        'contact.attachment': {
-            'Meta': {'object_name': 'Attachment'},
-            'contact': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contact.Contact']"}),
-            'file': ('django.db.models.fields.files.FileField', [], {'max_length': '100'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'tag': ('django.db.models.fields.CharField', [], {'max_length': '64'})
-        },
-        'contact.contact': {
-            'Meta': {'ordering': "('-created_at',)", 'object_name': 'Contact'},
-            'body': ('jsonfield.fields.JSONField', [], {}),
-            'contact': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
-            'created_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
-            'form_tag': ('django.db.models.fields.CharField', [], {'max_length': '32', 'db_index': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'ip': ('django.db.models.fields.IPAddressField', [], {'max_length': '15'})
-        }
-    }
-
-    complete_apps = ['contact']
\ No newline at end of file
diff --git a/contact/migrations/0003_auto__add_field_contact_key.py b/contact/migrations/0003_auto__add_field_contact_key.py
deleted file mode 100644 (file)
index d9347a4..0000000
+++ /dev/null
@@ -1,42 +0,0 @@
-# -*- coding: utf-8 -*-
-from south.utils import datetime_utils as datetime
-from south.db import db
-from south.v2 import SchemaMigration
-from django.db import models
-
-
-class Migration(SchemaMigration):
-
-    def forwards(self, orm):
-        # Adding field 'Contact.key'
-        db.add_column(u'contact_contact', 'key',
-                      self.gf('django.db.models.fields.CharField')(default='#', max_length=30),
-                      keep_default=False)
-
-
-    def backwards(self, orm):
-        # Deleting field 'Contact.key'
-        db.delete_column(u'contact_contact', 'key')
-
-
-    models = {
-        u'contact.attachment': {
-            'Meta': {'object_name': 'Attachment'},
-            'contact': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['contact.Contact']"}),
-            'file': ('django.db.models.fields.files.FileField', [], {'max_length': '100'}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'tag': ('django.db.models.fields.CharField', [], {'max_length': '64'})
-        },
-        u'contact.contact': {
-            'Meta': {'ordering': "('-created_at',)", 'object_name': 'Contact'},
-            'body': ('jsonfield.fields.JSONField', [], {}),
-            'contact': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
-            'created_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
-            'form_tag': ('django.db.models.fields.CharField', [], {'max_length': '32', 'db_index': 'True'}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'ip': ('django.db.models.fields.IPAddressField', [], {'max_length': '15'}),
-            'key': ('django.db.models.fields.CharField', [], {'max_length': '30'})
-        }
-    }
-
-    complete_apps = ['contact']
\ No newline at end of file
diff --git a/contact/migrations/__init__.py b/contact/migrations/__init__.py
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/contact/models.py b/contact/models.py
deleted file mode 100644 (file)
index fac089a..0000000
+++ /dev/null
@@ -1,83 +0,0 @@
-# -*- coding: utf-8 -*-
-import yaml
-from hashlib import sha1
-import random
-import string
-from django.db import models
-from django.utils.encoding import smart_unicode, force_str
-from django.db.models import permalink
-from django.utils.translation import ugettext_lazy as _
-from jsonfield import JSONField
-from . import app_settings
-
-
-KEY_SIZE = 30
-
-
-def make_key(length):
-    return ''.join(
-        random.choice(string.ascii_uppercase + string.ascii_lowercase + string.digits)
-        for i in range(length))
-
-
-class Contact(models.Model):
-    created_at = models.DateTimeField(_('submission date'), auto_now_add=True)
-    ip = models.IPAddressField(_('IP address'))
-    contact = models.CharField(_('contact'), max_length=128)
-    form_tag = models.CharField(_('form'), max_length=32, db_index=True)
-    body = JSONField(_('body'))
-    key = models.CharField(max_length=KEY_SIZE)
-
-    def generate_key(self):
-        key = ''
-        while not key or Contact.objects.filter(key=key).exists():
-            key = make_key(KEY_SIZE)
-        self.key = key
-        self.save()
-
-    @staticmethod
-    def pretty_print(value, for_html=False):
-        if type(value) in (tuple, list, dict):
-            value = yaml.safe_dump(value, allow_unicode=True, default_flow_style=False)
-            if for_html:
-                value = smart_unicode(value).replace(u" ", unichr(160))
-        return value
-
-    class Meta:
-        ordering = ('-created_at',)
-        verbose_name = _('submitted form')
-        verbose_name_plural = _('submitted forms')
-
-    def __unicode__(self):
-        return unicode(self.created_at)
-
-    def digest(self):
-        serialized_body = ';'.join(sorted('%s:%s' % item for item in self.body.iteritems()))
-        data = '%s%s%s%s%s' % (self.id, self.contact, serialized_body, self.ip, self.form_tag)
-        data = force_str(data)
-        return sha1(data).hexdigest()
-
-    @permalink
-    def update_url(self):
-        return 'edit_form', [], {'form_tag': self.form_tag, 'contact_id': self.id, 'key': self.key}
-
-
-class Attachment(models.Model):
-    contact = models.ForeignKey(Contact)
-    tag = models.CharField(max_length=64)
-    file = models.FileField(upload_to='contact/attachment')
-
-    @models.permalink
-    def get_absolute_url(self):
-        return 'contact_attachment', [self.contact_id, self.tag]
-
-    @property
-    @models.permalink
-    def url(self):
-        return 'contact_attachment_key', [self.contact_id, self.tag, self.contact.key]
-
-    def __unicode__(self):
-        return self.file.name.rsplit('/', 1)[-1]
-
-
-__import__(app_settings.FORMS_MODULE)
diff --git a/contact/templates/admin/contact/contact/change_list.html b/contact/templates/admin/contact/contact/change_list.html
deleted file mode 100644 (file)
index 3b47c97..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-{% extends "admin/change_list.html" %}
-{% load i18n %}
-{% load admin_urls %}
-
-
-{% block object-tools-items %}
-    {{block.super}}
-    {% if request.GET.form_tag %}
-        {% for extract_type in extract_types %}
-            <li>
-                <a href="{% url 'admin:contact_extract' form_tag=request.GET.form_tag extract_type_slug=extract_type.slug %}?created_at__month={{request.GET.created_at__month}}&created_at__year={{request.GET.created_at__year}}">
-                    {% trans 'Extract' %}: {{extract_type.label}}
-                </a>
-            </li>
-        {% endfor %}
-    {% endif %}
-{% endblock %}
-
diff --git a/contact/templates/contact/disabled_contact_form.html b/contact/templates/contact/disabled_contact_form.html
deleted file mode 100644 (file)
index a3ccfc8..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-{% extends "base.html" %}
-
-{% block title %}{{ title }}{% endblock %}
-
-{% block body %}
-
-    <h1>{{ title }}</h1>
-
-    {% block contact_form_description %}
-        <p class="notice">Rejestracja została zamknięta.</p>
-    {% endblock %}
-
-{% endblock %}
diff --git a/contact/templates/contact/form.html b/contact/templates/contact/form.html
deleted file mode 100644 (file)
index ce837ae..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-{% extends form.base_template|default:"base.html" %}
-{% load chunks %}
-{% load honeypot %}
-
-{% block title %}{{ form.form_title }}{% endblock %}
-
-{% block body %}
-
-    <h1>{% block contact_form_title %}{{ form.form_title }}{% endblock %}</h1>
-
-    <div class="form-info">
-    {% block contact_form_description %}
-        {% chunk "contact_form__"|add:form.form_tag %}
-    {% endblock %}
-    </div>
-
-    <form method="POST" action="." enctype="multipart/form-data" class="submit-form">
-    {% csrf_token %}
-    {% render_honeypot_field %}
-    {% block form %}
-        <table>
-            {{ form.as_table }}
-            {% if form.data_processing %}<tr><td></td><td><div class="helptext">{{ form.data_processing }}</div></td></tr>{% endif %}
-            {% block form_extra %}{% endblock %}
-            <tr><td></td><td><button>{% block contact_form_submit %}{{ form.submit_label }}{% endblock %}</button></td></tr>
-        </table>
-    {% endblock %}
-    <div class="form-footer">{% chunk "contact_form_footer__"|add:form.form_tag %}</div>
-    </form>
-
-{% endblock %}
diff --git a/contact/templates/contact/mail_body.txt b/contact/templates/contact/mail_body.txt
deleted file mode 100644 (file)
index 5015757..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-{% load i18n %}
-{% blocktrans %}Thank you for contacting us at {{ site_name }}.{% endblocktrans %}
-{% trans "Your submission has been referred to the project coordinator." %}
-
--- 
-{% trans "Message sent automatically. Please do not reply to it." %}
diff --git a/contact/templates/contact/mail_managers_body.txt b/contact/templates/contact/mail_managers_body.txt
deleted file mode 100644 (file)
index b7f97cf..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-{% load pretty_print from contact_tags %}{% load subdomainurls %}Wypełniono formularz {{ form_tag }} na stronie {{ site_name }}.
-
-{% url 'admin:contact_contact_change' None contact.pk %}
-
-{% for k, v in contact.body.items %}
-{{ k }}:
-{{ v|pretty_print }}
-{% endfor %}
-{% for attachment in contact.attachment_set.all %}
-{{ attachment.tag }}:
-http://{{ site_domain }}{{ attachment.get_absolute_url }}
-{% endfor %}
diff --git a/contact/templates/contact/mail_managers_subject.txt b/contact/templates/contact/mail_managers_subject.txt
deleted file mode 100644 (file)
index 12d2c8e..0000000
+++ /dev/null
@@ -1 +0,0 @@
-Wypełniono formularz {{ form_tag }} na stronie {{ site_name }}.
\ No newline at end of file
diff --git a/contact/templates/contact/mail_subject.txt b/contact/templates/contact/mail_subject.txt
deleted file mode 100644 (file)
index b8f586e..0000000
+++ /dev/null
@@ -1 +0,0 @@
-{% load i18n %}{% blocktrans %}Thank you for contacting us at {{ site_name }}.{% endblocktrans %}
\ No newline at end of file
diff --git a/contact/templates/contact/thanks.html b/contact/templates/contact/thanks.html
deleted file mode 100644 (file)
index 00dc0fe..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-{% extends base_template|default:"base.html" %}
-{% load i18n %}
-
-{% block title %}{% trans "Thank you" %}{% endblock %}
-
-{% block body %}
-
-    <h1>{% block contact_form_title %}{% trans "Thank you" %}{% endblock %}</h1>
-
-    {% block contact_form_description %}
-    <p class="notice">{% trans "Thank you for submitting the form." %}</p>
-    {% endblock %}
-
-{% endblock %}
diff --git a/contact/templatetags/__init__.py b/contact/templatetags/__init__.py
deleted file mode 100755 (executable)
index e69de29..0000000
diff --git a/contact/templatetags/contact_tags.py b/contact/templatetags/contact_tags.py
deleted file mode 100755 (executable)
index d8b18cb..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-# -*- coding: utf-8 -*-
-from django.template import Library
-
-from contact.forms import contact_forms
-from contact.models import Contact
-
-register = Library()
-
-
-@register.filter
-def pretty_print(value):
-    return Contact.pretty_print(value)
-
-
-@register.filter
-def is_enabled(form_tag):
-    form_class = contact_forms.get(form_tag)
-    if form_class:
-        return not getattr(form_class, 'disabled', False)
-    else:
-        return False
diff --git a/contact/urls.py b/contact/urls.py
deleted file mode 100644 (file)
index ed6f49c..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-# -*- coding: utf-8 -*-
-from django.conf.urls import patterns, url
-from . import views
-
-urlpatterns = patterns(
-    'contact.views',
-    url(r'^(?P<form_tag>[^/]+)/$', views.form, name='contact_form'),
-    url(r'^(?P<form_tag>[^/]+)/edit/(?P<contact_id>[0-9]+)/(?P<key>[0-9a-zA-Z]+)/$', views.form, name='edit_form'),
-    url(r'^(?P<form_tag>[^/]+)/thanks/$', views.thanks, name='contact_thanks'),
-    url(r'^attachment/(?P<contact_id>\d+)/(?P<tag>[^/]+)/$', views.attachment, name='contact_attachment'),
-    url(r'^attachment/(?P<contact_id>\d+)/(?P<tag>[^/]+)/(?P<key>[0-9a-zA-Z]+)/$', views.attachment_key,
-        name='contact_attachment_key'),
-    url(r'^results/(?P<contact_id>\d+)/(?P<digest>[0-9a-f]+)/', views.results, name='contact_results'),
-)
diff --git a/contact/views.py b/contact/views.py
deleted file mode 100644 (file)
index 580a65d..0000000
+++ /dev/null
@@ -1,103 +0,0 @@
-# -*- coding: utf-8 -*-
-from urllib import unquote
-
-from django.contrib.auth.decorators import permission_required
-from django.http import Http404
-from django.shortcuts import get_object_or_404, redirect, render
-from django.views.decorators.cache import never_cache
-from fnpdjango.utils.views import serve_file
-from honeypot.decorators import check_honeypot
-
-from .forms import contact_forms, update_forms
-from .models import Attachment, Contact
-
-
-@check_honeypot
-@never_cache
-def form(request, form_tag, force_enabled=False, contact_id=None, key=None):
-    update = bool(contact_id and key)
-    try:
-        if update and form_tag in update_forms:
-            form_class = update_forms[form_tag]
-        else:
-            form_class = contact_forms[form_tag]
-    except KeyError:
-        raise Http404
-    if not (force_enabled and request.user.is_superuser):
-        if form_class.is_disabled():
-            template = form_class.disabled_template
-            if template:
-                return render(request, template, {'title': form_class.form_title})
-            raise Http404
-    if contact_id:
-        contact = get_object_or_404(Contact, id=contact_id, form_tag=form_tag)
-        if not form_class.updatable:
-            raise Http404
-        if key != contact.key:
-            raise Http404
-    else:
-        contact = None
-    if request.method == 'POST':
-        form = form_class(request.POST, request.FILES, instance=contact)
-    else:
-        form = form_class(initial=request.GET, instance=contact)
-    if request.method == 'POST':
-        formsets = form.get_formsets(request)
-        if form.is_valid() and all(formset.is_valid() for formset in formsets.itervalues()):
-            contact = form.save(request, formsets.values())
-            if form.result_page:
-                return redirect('contact_results', contact.id, contact.digest())
-            else:
-                return redirect('contact_thanks', form_tag)
-    else:
-        formsets = form.get_formsets()
-
-    return render(
-        request, ['contact/%s/form.html' % form_tag, 'contact/form.html'],
-        {'form': form, 'formsets': formsets, 'formset_errors': any(formset.errors for formset in formsets.values())}
-    )
-
-
-def thanks(request, form_tag):
-    try:
-        form_class = contact_forms[form_tag]
-    except KeyError:
-        raise Http404
-
-    return render(
-        request, ['contact/%s/thanks.html' % form_tag, 'contact/thanks.html'],
-        {'base_template': getattr(form_class, 'base_template', None)})
-
-
-def results(request, contact_id, digest):
-    contact = get_object_or_404(Contact, id=contact_id)
-    if digest != contact.digest():
-        raise Http404
-    try:
-        form_class = contact_forms[contact.form_tag]
-    except KeyError:
-        raise Http404
-
-    return render(
-        request, 'contact/%s/results.html' % contact.form_tag,
-        {
-            'results': form_class.results(contact),
-            'base_template': getattr(form_class, 'base_template', None),
-        }
-    )
-
-
-@permission_required('contact.change_attachment')
-def attachment(request, contact_id, tag):
-    attachment = get_object_or_404(Attachment, contact_id=contact_id, tag=tag)
-    attachment_url = unquote(attachment.file.url)
-    return serve_file(attachment_url)
-
-
-def attachment_key(request, contact_id, tag, key):
-    contact = Contact.objects.get(id=contact_id)
-    if key != contact.key:
-        raise Http404
-    attachment = get_object_or_404(Attachment, contact_id=contact_id, tag=tag)
-    attachment_url = unquote(attachment.file.url)
-    return serve_file(attachment_url)
diff --git a/contact/widgets.py b/contact/widgets.py
deleted file mode 100644 (file)
index ddcf3cf..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-# -*- coding: utf-8 -*-
-from django import forms
-from django.forms.util import flatatt
-from django.utils.html import format_html
-
-
-class HeaderWidget(forms.widgets.Widget):
-    def render(self, name, value, attrs=None):
-        attrs.update(self.attrs)
-        return format_html('<a{0}></a>', flatatt(attrs))
diff --git a/curriculum/__init__.py b/curriculum/__init__.py
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/curriculum/admin.py b/curriculum/admin.py
deleted file mode 100755 (executable)
index 0f378bc..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-# -*- coding: utf-8 -*-
-from django.contrib import admin
-from .models import Competence, CompetenceLevel, Level, Section, CurriculumCourse, CurriculumLevel, Curriculum
-
-
-class CompetenceLevelInline(admin.TabularInline):
-    model = CompetenceLevel
-
-
-class CompetenceAdmin(admin.ModelAdmin):
-    model = Competence
-    list_display = ['name_pl', 'name_en', 'section', 'slug', 'order']
-    inlines = [CompetenceLevelInline]
-
-
-class LevelAdmin(admin.ModelAdmin):
-    model = Level
-    list_display = ['name_pl', 'name_en', 'group_pl', 'group_en', 'slug', 'order']
-
-
-class SectionAdmin(admin.ModelAdmin):
-    model = Section
-    list_display = ['name_pl', 'name_en', 'slug', 'order']
-
-
-admin.site.register(Level, LevelAdmin)
-admin.site.register(Section, SectionAdmin)
-admin.site.register(Competence, CompetenceAdmin)
-
-admin.site.register(CurriculumCourse)
-admin.site.register(CurriculumLevel)
-admin.site.register(Curriculum)
diff --git a/curriculum/fixtures/competences.json b/curriculum/fixtures/competences.json
deleted file mode 100644 (file)
index 3d6731d..0000000
+++ /dev/null
@@ -1,2951 +0,0 @@
-[
-    {
-        "pk": 1,
-        "model": "curriculum.section",
-        "fields": {
-            "order": 1,
-            "name": "Korzystanie z informacji",
-            "slug": "korzystanie-z-informacji"
-        }
-    },
-    {
-        "pk": 2,
-        "model": "curriculum.section",
-        "fields": {
-            "order": 2,
-            "name": "Relacje w \u015brodowisku medialnym",
-            "slug": "relacje-w-srodowisku-medialnym"
-        }
-    },
-    {
-        "pk": 3,
-        "model": "curriculum.section",
-        "fields": {
-            "order": 3,
-            "name": "J\u0119zyk medi\u00f3w",
-            "slug": "jezyk-mediow"
-        }
-    },
-    {
-        "pk": 4,
-        "model": "curriculum.section",
-        "fields": {
-            "order": 4,
-            "name": "Kreatywne korzystanie z medi\u00f3w",
-            "slug": "kreatywne-korzystanie-z-mediow"
-        }
-    },
-    {
-        "pk": 5,
-        "model": "curriculum.section",
-        "fields": {
-            "order": 5,
-            "name": "Etyka i warto\u015bci w komunikacji i mediach",
-            "slug": "etyka-i-wartosci-w-komunikacji-i-mediach"
-        }
-    },
-    {
-        "pk": 6,
-        "model": "curriculum.section",
-        "fields": {
-            "order": 6,
-            "name": "Bezpiecze\u0144stwo w komunikacji i mediach",
-            "slug": "bezpieczenstwo-w-komunikacji-i-mediach"
-        }
-    },
-    {
-        "pk": 7,
-        "model": "curriculum.section",
-        "fields": {
-            "order": 7,
-            "name": "Prawo w komunikacji i mediach",
-            "slug": "prawo-w-mediach-i-komunikacji"
-        }
-    },
-    {
-        "pk": 8,
-        "model": "curriculum.section",
-        "fields": {
-            "order": 8,
-            "name": "Ekonomiczne aspekty dzia\u0142ania medi\u00f3w",
-            "slug": "ekonomiczne-aspekty-dzialania-mediow"
-        }
-    },
-    {
-        "pk": 1,
-        "model": "curriculum.competence",
-        "fields": {
-            "section": 1,
-            "order": 1,
-            "name": "\u0179r\u00f3d\u0142a informacji",
-            "slug": "zrodla-informacji"
-        }
-    },
-    {
-        "pk": 2,
-        "model": "curriculum.competence",
-        "fields": {
-            "section": 1,
-            "order": 2,
-            "name": "Wyszukiwanie informacji",
-            "slug": "wyszukiwanie-informacji"
-        }
-    },
-    {
-        "pk": 3,
-        "model": "curriculum.competence",
-        "fields": {
-            "section": 1,
-            "order": 3,
-            "name": "Podej\u015bcie krytyczne do informacji",
-            "slug": "podejscie-krytyczne-do-informacji"
-        }
-    },
-    {
-        "pk": 4,
-        "model": "curriculum.competence",
-        "fields": {
-            "section": 1,
-            "order": 4,
-            "name": "Wykorzystanie informacji",
-            "slug": "wykorzystanie-informacji"
-        }
-    },
-    {
-        "pk": 7,
-        "model": "curriculum.competence",
-        "fields": {
-            "section": 2,
-            "order": 1,
-            "name": "Wizerunek",
-            "slug": "wizerunek"
-        }
-    },
-    {
-        "pk": 5,
-        "model": "curriculum.competence",
-        "fields": {
-            "section": 2,
-            "order": 2,
-            "name": "Komunikacja",
-            "slug": "komunikacja"
-        }
-    },
-    {
-        "pk": 6,
-        "model": "curriculum.competence",
-        "fields": {
-            "section": 2,
-            "order": 3,
-            "name": "Otoczenie",
-            "slug": "otoczenie"
-        }
-    },
-    {
-        "pk": 10,
-        "model": "curriculum.competence",
-        "fields": {
-            "section": 3,
-            "order": 1,
-            "name": "J\u0119zykowa natura medi\u00f3w",
-            "slug": "jezykowa-natura-mediow"
-        }
-    },
-    {
-        "pk": 9,
-        "model": "curriculum.competence",
-        "fields": {
-            "section": 3,
-            "order": 2,
-            "name": "Funkcje komunikat\u00f3w medialnych",
-            "slug": "funkcje-komunikatow-medialnych"
-        }
-    },
-    {
-        "pk": 8,
-        "model": "curriculum.competence",
-        "fields": {
-            "section": 3,
-            "order": 3,
-            "name": "Kultura komunikacji medialnej",
-            "slug": "kultura-komunikacji-medialnej"
-        }
-    },
-    {
-        "pk": 11,
-        "model": "curriculum.competence",
-        "fields": {
-            "section": 4,
-            "order": 1,
-            "name": "Tworzenie",
-            "slug": "tworzenie"
-        }
-    },
-    {
-        "pk": 12,
-        "model": "curriculum.competence",
-        "fields": {
-            "section": 4,
-            "order": 2,
-            "name": "Przetwarzanie",
-            "slug": "przetwarzanie"
-        }
-    },
-    {
-        "pk": 13,
-        "model": "curriculum.competence",
-        "fields": {
-            "section": 4,
-            "order": 3,
-            "name": "Prezentowanie",
-            "slug": "prezentowanie"
-        }
-    },
-    {
-        "pk": 16,
-        "model": "curriculum.competence",
-        "fields": {
-            "section": 5,
-            "order": 1,
-            "name": "Komunikacja i media jako przedmiot refleksji etycznej",
-            "slug": "komunikacja-i-media-jako-przedmiot-refleksji-etycz"
-        }
-    },
-    {
-        "pk": 15,
-        "model": "curriculum.competence",
-        "fields": {
-            "section": 5,
-            "order": 2,
-            "name": "Wyzwania etyczne a tre\u015bci medi\u00f3w i komunikacji",
-            "slug": "wyzwania-etyczne-a-tresci-mediow-i-komunikacji"
-        }
-    },
-    {
-        "pk": 17,
-        "model": "curriculum.competence",
-        "fields": {
-            "section": 5,
-            "order": 3,
-            "name": "Wyzwania etyczne w relacjach przez media",
-            "slug": "wyzwania-etyczne-w-relacjach-przez-media"
-        }
-    },
-    {
-        "pk": 14,
-        "model": "curriculum.competence",
-        "fields": {
-            "section": 5,
-            "order": 4,
-            "name": "Wyzwania etyczne a normy prawa w mediach i komunikacji",
-            "slug": "wyzwania-etyczne-a-normy-prawa"
-        }
-    },
-    {
-        "pk": 21,
-        "model": "curriculum.competence",
-        "fields": {
-            "section": 6,
-            "order": 1,
-            "name": "Ochrona prywatno\u015bci i wizerunku",
-            "slug": "ochrona-prywatnosci-i-wizerunku"
-        }
-    },
-    {
-        "pk": 20,
-        "model": "curriculum.competence",
-        "fields": {
-            "section": 6,
-            "order": 2,
-            "name": "Anonimowo\u015b\u0107",
-            "slug": "anonimowosc"
-        }
-    },
-    {
-        "pk": 18,
-        "model": "curriculum.competence",
-        "fields": {
-            "section": 6,
-            "order": 3,
-            "name": "Bezpiecze\u0144stwo komunikacji, pracy i transakcji",
-            "slug": "bezpieczenstwo-komunikacji-pracy-i-transakcji"
-        }
-    },
-    {
-        "pk": 22,
-        "model": "curriculum.competence",
-        "fields": {
-            "section": 6,
-            "order": 4,
-            "name": "Nadz\u00f3r nad sieci\u0105",
-            "slug": "nadzor-nad-siecia"
-        }
-    },
-    {
-        "pk": 19,
-        "model": "curriculum.competence",
-        "fields": {
-            "section": 6,
-            "order": 5,
-            "name": "Uzale\u017cnienia i higiena korzystania z medi\u00f3w",
-            "slug": "uzaleznienia-i-higiena-korzystania-z-mediow"
-        }
-    },
-    {
-        "pk": 23,
-        "model": "curriculum.competence",
-        "fields": {
-            "section": 7,
-            "order": 1,
-            "name": "Rodzaje, \u017ar\u00f3d\u0142a i praktyka stosowania prawa w kontek\u015bcie medi\u00f3w",
-            "slug": "rodzaje-zrodla-i-praktyka-stosowania-prawa"
-        }
-    },
-    {
-        "pk": 28,
-        "model": "curriculum.competence",
-        "fields": {
-            "section": 7,
-            "order": 2,
-            "name": "Media a prawa cz\u0142owieka, obywatela i dziecka",
-            "slug": "media-a-prawa-czlowieka-obywatela-i-dziecka"
-        }
-    },
-    {
-        "pk": 27,
-        "model": "curriculum.competence",
-        "fields": {
-            "section": 7,
-            "order": 3,
-            "name": "Prawa wy\u0142\u0105czne i monopole intelektualne",
-            "slug": "prawa-wylaczne-i-monopole-intelektualne"
-        }
-    },
-    {
-        "pk": 29,
-        "model": "curriculum.competence",
-        "fields": {
-            "section": 7,
-            "order": 4,
-            "name": "Prawo telekomunikacyjne",
-            "slug": "prawo-telekomunikacyjne"
-        }
-    },
-    {
-        "pk": 25,
-        "model": "curriculum.competence",
-        "fields": {
-            "section": 7,
-            "order": 5,
-            "name": "Prawo medi\u00f3w i media publiczne",
-            "slug": "prawo-mediow-i-media-publiczne"
-        }
-    },
-    {
-        "pk": 24,
-        "model": "curriculum.competence",
-        "fields": {
-            "section": 7,
-            "order": 6,
-            "name": "Prawa os\u00f3b niepe\u0142nosprawnych",
-            "slug": "prawa-osob-niepelnosprawnych"
-        }
-    },
-    {
-        "pk": 26,
-        "model": "curriculum.competence",
-        "fields": {
-            "section": 7,
-            "order": 7,
-            "name": "Ochrona danych osobowych",
-            "slug": "ochrona-danych-osobowych"
-        }
-    },
-    {
-        "pk": 30,
-        "model": "curriculum.competence",
-        "fields": {
-            "section": 8,
-            "order": 1,
-            "name": "Rynek medi\u00f3w",
-            "slug": "rynek-mediow"
-        }
-    },
-    {
-        "pk": 31,
-        "model": "curriculum.competence",
-        "fields": {
-            "section": 8,
-            "order": 2,
-            "name": "Informacja jako dobro ekonomiczne",
-            "slug": "informacja-jako-dobro-ekonomiczne"
-        }
-    },
-    {
-        "pk": 32,
-        "model": "curriculum.competence",
-        "fields": {
-            "section": 8,
-            "order": 3,
-            "name": "Finansowanie medi\u00f3w i wybrane sposoby zarabiania w nowych mediach",
-            "slug": "finansowanie-mediow-i-wybrane-sposoby-zarabiania"
-        }
-    },
-    {
-        "pk": 33,
-        "model": "curriculum.competence",
-        "fields": {
-            "section": 8,
-            "order": 4,
-            "name": "Polityka medialna",
-            "slug": "polityka-medialna"
-        }
-    },
-    {
-        "pk": 1,
-        "model": "curriculum.level",
-        "fields": {
-            "order": 1,
-            "group": "edukacja formalna",
-            "name": "Wych. przedszkolne",
-            "slug": "przedszkole"
-        }
-    },
-    {
-        "pk": 2,
-        "model": "curriculum.level",
-        "fields": {
-            "order": 2,
-            "group": "edukacja formalna",
-            "name": "SP 1-3",
-            "slug": "sp1-3"
-        }
-    },
-    {
-        "pk": 3,
-        "model": "curriculum.level",
-        "fields": {
-            "order": 3,
-            "group": "edukacja formalna",
-            "name": "SP 4-6",
-            "slug": "sp4-6"
-        }
-    },
-    {
-        "pk": 4,
-        "model": "curriculum.level",
-        "fields": {
-            "order": 4,
-            "group": "edukacja formalna",
-            "name": "Gimnazjum",
-            "slug": "gimnazjum"
-        }
-    },
-    {
-        "pk": 5,
-        "model": "curriculum.level",
-        "fields": {
-            "order": 5,
-            "group": "edukacja formalna",
-            "name": "Szk. ponadgimnazjalna",
-            "slug": "liceum"
-        }
-    },
-    {
-        "pk": 6,
-        "model": "curriculum.level",
-        "fields": {
-            "order": 6,
-            "group": "edukacja formalna",
-            "name": "Szk. wy\u017csze",
-            "slug": "studia"
-        }
-    },
-    {
-        "pk": 7,
-        "model": "curriculum.level",
-        "fields": {
-            "order": 101,
-            "group": "edukacja ustawiczna",
-            "name": "Poziom minimum",
-            "slug": "minimum"
-        }
-    },
-    {
-        "pk": 8,
-        "model": "curriculum.level",
-        "fields": {
-            "order": 102,
-            "group": "edukacja ustawiczna",
-            "name": "Poziom optimum",
-            "slug": "optimum"
-        }
-    },
-    {
-        "pk": 9,
-        "model": "curriculum.level",
-        "fields": {
-            "order": 103,
-            "group": "edukacja ustawiczna",
-            "name": "Poziom mistrzowski",
-            "slug": "master"
-        }
-    },
-    {
-        "pk": 1,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- wie, \u017ce informacja wyst\u0119puje w r\u00f3\u017cnych formach; \u00a0np. rozumie, jakie s\u0105 podstawowe r\u00f3\u017cnice pomi\u0119dzy obrazem, tekstem, filmem, stron\u0105 internetow\u0105.\n- wie, \u017ce istniej\u0105 r\u00f3\u017cne \u017ar\u00f3d\u0142a informacji (TV, internet, radio, ksi\u0105\u017cki, gazety, inni ludzie).\n- umie skorzysta\u0107 z wybranych \u017ar\u00f3de\u0142 informacji; np. wyszukuje potrzebne informacje na temat ulubionego zwierz\u0119cia korzystaj\u0105c ze s\u0142ownika obrazkowego, rozmawiaj\u0105c z rodzicem / nauczycielem.",
-            "competence": 1,
-            "level": 1
-        }
-    },
-    {
-        "pk": 2,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- wie, jakie s\u0105 najwa\u017cniejsze \u017ar\u00f3d\u0142a informacji dostosowane do jego wieku i poziomu edukacji i umie z nich skorzysta\u0107;\nnp. korzysta z drukowanych i elektronicznych encyklopedii i s\u0142ownik\u00f3w dla dzieci.\n- umie skorzysta\u0107 z biblioteki szkolnej, kieruj\u0105c si\u0119 wskaz\u00f3wkami nauczyciela;\nnp. wybiera lektury, korzystaj\u0105c z rad nauczyciela.\n- wie, \u017ce informacje pochodz\u0105ce z r\u00f3\u017cnych \u017ar\u00f3de\u0142 mog\u0105 si\u0119 r\u00f3\u017cni\u0107.",
-            "competence": 1,
-            "level": 2
-        }
-    },
-    {
-        "pk": 3,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- wie, jakie s\u0105 podstawowe kryteria oceny \u017ar\u00f3de\u0142 informacji; np. wie, czym jest wiarygodno\u015b\u0107, \u0142atwo\u015b\u0107 i efektywno\u015b\u0107 korzystania, szybko\u015b\u0107 dost\u0119pu w odniesieniu do \u017ar\u00f3de\u0142 informacji.\n- umie dokona\u0107 wyboru \u017ar\u00f3de\u0142 informacji, kieruj\u0105c si\u0119 przede wszystkim kryterium wiarygodno\u015bci;\nnp. umie skorzysta\u0107 z wiarygodnych \u017ar\u00f3de\u0142 takich jak encyklopedie, s\u0142owniki drukowane lub elektroniczne.\n- umie skorzysta\u0107 z zasob\u00f3w biblioteki szkolnej, samodzielnie wybieraj\u0105c lektury oraz dobieraj\u0105c odpowiednie \u017ar\u00f3d\u0142a informacji do konkretnych zada\u0144.\n- wie, \u017ce jako\u015b\u0107 \u017ar\u00f3de\u0142 informacji ma zasadnicze znaczenie dla wynik\u00f3w pracy.",
-            "competence": 1,
-            "level": 3
-        }
-    },
-    {
-        "pk": 4,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- wie, \u017ce \u017ar\u00f3d\u0142a informacji nale\u017cy wybiera\u0107 \u015bwiadomie, maj\u0105c na uwadze potrzeby informacyjne oraz cel wykorzystania informacji.\n- umie biegle wybiera\u0107 \u017ar\u00f3d\u0142a informacji wykorzystywanych w procesie kszta\u0142cenia, kieruj\u0105c si\u0119 poszczeg\u00f3lnymi kryteriami wyboru;\nnp. zale\u017cnie od sytuacji korzysta z Wikipedii lub innych \u017ar\u00f3de\u0142.\n- rozumie konsekwencje korzystania z niew\u0142a\u015bciwych \u017ar\u00f3de\u0142 informacji w odniesieniu do edukacji szkolnej.\n- rozumie, jakie s\u0105 r\u00f3\u017cnice pomi\u0119dzy kana\u0142em a \u017ar\u00f3d\u0142em informacji.",
-            "competence": 1,
-            "level": 4
-        }
-    },
-    {
-        "pk": 5,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- wie, jakie s\u0105 najwa\u017cniejsze \u017ar\u00f3d\u0142a informacji naukowej i umie z nich skorzysta\u0107 w podstawowym zakresie;\nnp. korzysta z katalog\u00f3w elektronicznych bibliotek akademickich.\n- umie dokona\u0107 wyboru \u017ar\u00f3de\u0142 informacji, bior\u0105c pod uwag\u0119 dodatkowe kryteria takie jak relewancja, \u0142atwo\u015b\u0107 i efektywno\u015b\u0107 korzystania.\n- rozumie znaczenie doboru w\u0142a\u015bciwych \u017ar\u00f3de\u0142 informacji dla efekt\u00f3w wykonywanej pracy.\n- rozumie przyczyny ogranicze\u0144 system\u00f3w organizacji informacji;\nnp. rozumie, jakie nast\u0119pstwa ma fakt, \u017ce j\u0119zyki informacyjno-wyszukiwawcze s\u0105 j\u0119zykami sztucznymi.",
-            "competence": 1,
-            "level": 5
-        }
-    },
-    {
-        "pk": 6,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- wie, jaka jest r\u00f3\u017cnica pomi\u0119dzy \u017ar\u00f3d\u0142ami informacji wykorzystywanymi w pracy naukowej i \u017cyciu codziennym.\n- umie dokona\u0107 wyboru optymalnych \u017ar\u00f3de\u0142 informacji naukowej.\n- umie dokona\u0107 wyboru system\u00f3w informacyjnych zgodnie z zapotrzebowaniem wynikaj\u0105cym z jego pracy.\n- rozumie, jakie s\u0105 konsekwencje wykorzystania niew\u0142a\u015bciwych \u017ar\u00f3de\u0142 w pracy naukowej.\n- rozumie konieczno\u015b\u0107 odwo\u0142ywania si\u0119 do wykorzystanych \u017ar\u00f3de\u0142;\nnp. wie, jak i dlaczego nale\u017cy stosowa\u0107 przypisy i zamieszcza\u0107 bibliografi\u0119.",
-            "competence": 1,
-            "level": 6
-        }
-    },
-    {
-        "pk": 7,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- wie, jakie s\u0105 najwa\u017cniejsze \u017ar\u00f3d\u0142a informacji we wsp\u00f3\u0142czesnym \u015bwiecie.\n- wie, \u017ce \u017ar\u00f3d\u0142a informacji nale\u017cy wybiera\u0107 \u015bwiadomie, maj\u0105c na uwadze potrzeby informacyjne oraz cel wykorzystania informacji.\n- umie wykorzysta\u0107 g\u0142\u00f3wne \u017ar\u00f3d\u0142a informacji w procesie zaspokajania swoich potrzeb informacyjnych.\n- umie w spos\u00f3b intuicyjny oceni\u0107 wiarygodno\u015b\u0107 \u017ar\u00f3de\u0142 informacji.\n- umie dokona\u0107 wyboru \u017ar\u00f3de\u0142 informacji, bior\u0105c pod uwag\u0119 takie kryteria jak wiarygodno\u015b\u0107, relewancja, \u0142atwo\u015b\u0107 i efektywno\u015b\u0107 korzystania.\n- rozumie, jakie jest znaczenie informacji w spo\u0142ecze\u0144stwie XXI wieku.\n- rozumie, \u017ce informacje r\u00f3\u017cni\u0105 si\u0119 w zale\u017cno\u015bci od \u017ar\u00f3d\u0142a, z kt\u00f3rego pochodz\u0105, oraz intencji nadawcy.",
-            "competence": 1,
-            "level": 7
-        }
-    },
-    {
-        "pk": 8,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- wie, \u017ce relewantna i wiarygodna informacja powinna zawsze by\u0107 podstaw\u0105 podejmowanych decyzji.\n- wie, jakie s\u0105 najwa\u017cniejsze modele zachowa\u0144 informacyjnych.\n- umie biegle wybiera\u0107 \u017ar\u00f3d\u0142a informacji wykorzystywanych w procesie kszta\u0142cenia, kieruj\u0105c si\u0119 odpowiednimi kryteriami.\n- rozumie, jakie jest znaczenie doboru w\u0142a\u015bciwych \u017ar\u00f3de\u0142 informacji dla efekt\u00f3w wykonywanej pracy.",
-            "competence": 1,
-            "level": 8
-        }
-    },
-    {
-        "pk": 9,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- wie, jaka jest organizacja \u017ar\u00f3de\u0142 informacji oraz przep\u0142ywu informacji w spo\u0142ecze\u0144stwie.\n- umie sprawnie wybiera\u0107 \u017ar\u00f3d\u0142a informacji w zale\u017cno\u015bci od celu dzia\u0142ania i specyfiki realizowanego zadania.\n- rozumie, jakie s\u0105 konsekwencje korzystania z niew\u0142a\u015bciwych \u017ar\u00f3de\u0142 informacji w odniesieniu do efekt\u00f3w wykonywanej pracy i realizacji konkretnego zadania.",
-            "competence": 1,
-            "level": 9
-        }
-    },
-    {
-        "pk": 10,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- umie skorzysta\u0107 z pomocy doros\u0142ego w procesie pozyskiwania informacji; np. prosi rodzica o znalezienie jakiej\u015b informacji.",
-            "competence": 2,
-            "level": 1
-        }
-    },
-    {
-        "pk": 11,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- wie, \u017ce \u201ej\u0119zyk komputera\u201d r\u00f3\u017cni si\u0119 od j\u0119zyka m\u00f3wionego;\nnp. wie, \u017ce komputer zawsze \u201erobi\u201d to, co mu si\u0119 ka\u017ce, dlatego trzeba si\u0119 nauczy\u0107, jak wydawa\u0107 polecenia.\n- umie skorzysta\u0107 z podstawowych technik wyszukiwania w \u017ar\u00f3d\u0142ach tradycyjnych oraz elektronicznych.\n- wie, \u017ce dzia\u0142ania na zbiorach mog\u0105 by\u0107 wykorzystywane przy szukaniu informacji;\nnp. poznaje mo\u017cliwo\u015bci prostych zastosowa\u0144 operator\u00f3w logicznych (kot AND/ORAZ pies itd.)\n- umie zastosowa\u0107 proste has\u0142a osobowe, przedmiotowe, wpisuje proste zapytania informacyjno-wyszukiwawcze w wyszukiwarkach, encyklopediach;\nnp. wyszukuje informacje nt. ulubionego zwierz\u0119cia w s\u0142owniku obrazkowym, encyklopedii elektronicznej dla dzieci i internecie.\n- rozumie, \u017ce umiej\u0119tno\u015b\u0107 wyszukiwania informacji przyda mu si\u0119 w \u017cyciu;\nnp. rozumie, \u017ce na podstawie wyszukanych informacji b\u0119dzie podejmowa\u0142 r\u00f3\u017cne decyzje.",
-            "competence": 2,
-            "level": 2
-        }
-    },
-    {
-        "pk": 12,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- wie, jakie s\u0105 podstawowe r\u00f3\u017cnice w budowie hase\u0142 w j\u0119zyku naturalnym i j\u0119zyku systemu informacyjnego;\nnp. poznaje na przyk\u0142adzie hase\u0142 przedmiotowych r\u00f3\u017cnice w okre\u015blaniu zwierz\u0105t.\n- wie, \u017ce s\u0105 r\u00f3\u017cne modele zachowa\u0144 informacyjnych - umie wyszuka\u0107 informacje w wybranych tradycyjnych i elektronicznych \u017ar\u00f3d\u0142ach.\n- umie budowa\u0107 proste zapytania informacyjno-wyszukiwawcze;\nnp. rozk\u0142ad jazdy pkp warszawa.\n- wie, \u017ce trzeba dok\u0142adnie formu\u0142owa\u0107 zapytania informacyjno-wyszukiwawcze.\n- wie, \u017ce wynik wyszukiwania zale\u017cy od tego, jak b\u0119dzie sformu\u0142owane zapytanie informacyjno-wyszukiwawcze.",
-            "competence": 2,
-            "level": 3
-        }
-    },
-    {
-        "pk": 13,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- wie, jakie s\u0105 podstawowe techniki i strategie wyszukiwania informacji;\nnp. stosuje strategi\u0119 zaw\u0119\u017cania wynik\u00f3w poszukiwa\u0144.\n- umie wyszukiwa\u0107 informacje w \u017ar\u00f3d\u0142ach tradycyjnych i elektronicznych;\nnp. wyszukuje informacje, korzystaj\u0105c ze stron, blog\u00f3w, portali, wortali oraz materia\u0142\u00f3w drukowanych.\n- umie zastosowa\u0107 z\u0142o\u017cone strategie wyszukiwania w oparciu o znane modele zachowa\u0144 informacyjnych w odpowiednich adaptacjach.\n\n- umie wykorzysta\u0107 wybrane techniki wyszukiwania;\nnp. korzysta z operator\u00f3w logicznych.\n- umie budowa\u0107 zapytania informacyjno-wyszukiwawcze w j\u0119zyku systemu informacyjnego.",
-            "competence": 2,
-            "level": 4
-        }
-    },
-    {
-        "pk": 14,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- wie, jakie s\u0105 z\u0142o\u017cone strategie wyszukiwania.\n- umie sprawnie wyszukiwa\u0107 informacje, buduj\u0105c strategie wyszukiwania w oparciu o najwa\u017cniejsze modele zachowa\u0144 informacyjnych.\n- umie przek\u0142ada\u0107 zapytania informacyjno-wyszukiwawcze wyra\u017cone w j\u0119zyku naturalnym na j\u0119zyk systemu informacyjnego.",
-            "competence": 2,
-            "level": 5
-        }
-    },
-    {
-        "pk": 15,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- wie, jak wyszukiwa\u0107 informacj\u0119 naukow\u0105 w r\u00f3\u017cnych \u017ar\u00f3d\u0142ach.\n- umie biegle korzysta\u0107 z najwa\u017cniejszych \u017ar\u00f3de\u0142 informacji naukowej;\nnp. biegle korzysta z katalog\u00f3w bibliotecznych, stosuj\u0105c opcje wyszukiwania zaawansowanego, sprawnie korzysta z dziedzinowych baz danych literatury naukowej.\n- umie zaprojektowa\u0107 efektywn\u0105 strategi\u0119 wyszukiwania informacji.",
-            "competence": 2,
-            "level": 6
-        }
-    },
-    {
-        "pk": 16,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- wie, \u017ce wyszukiwanie informacji wymaga odpowiednich umiej\u0119tno\u015bci.\n- wie, \u017ce trzeba dok\u0142adnie formu\u0142owa\u0107 zapytania informacyjno-wyszukiwawcze.\n- umie skorzysta\u0107 z podstawowych technik wyszukiwania w \u017ar\u00f3d\u0142ach tradycyjnych oraz elektronicznych.\n- umie zastosowa\u0107 proste has\u0142a osobowe, przedmiotowe, wpisuje zapytania informacyjno-wyszukiwawcze w wyszukiwarkach, encyklopediach.\n- rozumie, \u017ce wynik wyszukiwania zale\u017cy od tego, jak b\u0119dzie sformu\u0142owane zapytanie informacyjno-wyszukiwawcze.\n- rozumie konsekwencje, jakie mo\u017ce mie\u0107 opieranie swoich decyzji na niepe\u0142nych lub nieaktualnych informacjach.",
-            "competence": 2,
-            "level": 7
-        }
-    },
-    {
-        "pk": 17,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- wie, jakie s\u0105 podstawowe techniki i strategie wyszukiwania informacji.\n- wie, jakie s\u0105 najwa\u017cniejsze modele zachowa\u0144 informacyjnych.\n- wie, jakie s\u0105 podstawowe r\u00f3\u017cnice w budowie hase\u0142 w j\u0119zyku naturalnym i j\u0119zyku systemu informacyjnego.\n- umie sprawnie wyszukiwa\u0107 informacje, buduj\u0105c strategie wyszukiwania w oparciu o najwa\u017cniejsze modele zachowa\u0144 informacyjnych.\n- umie stosowa\u0107 zaawansowane techniki wyszukiwania informacji.\n- umie dodawa\u0107, ulepsza\u0107 i \u0142\u0105czy\u0107 informacje w r\u00f3\u017cnych formach, zaczerpni\u0119te z r\u00f3\u017cnych \u017ar\u00f3de\u0142.",
-            "competence": 2,
-            "level": 8
-        }
-    },
-    {
-        "pk": 18,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- wie, jakie s\u0105 z\u0142o\u017cone strategie wyszukiwania.\n- umie sprawnie wyszukiwa\u0107 informacje, buduj\u0105c strategie wyszukiwania w oparciu o najwa\u017cniejsze modele zachowa\u0144 informacyjnych.\n- umie zaprojektowa\u0107 efektywn\u0105 strategi\u0119 wyszukiwania informacji.",
-            "competence": 2,
-            "level": 9
-        }
-    },
-    {
-        "pk": 19,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- wie, \u017ce je\u015bli informacja budzi w\u0105tpliwo\u015bci, powinien j\u0105 om\u00f3wi\u0107 z rodzicami lub nauczycielem przedszkolnym.\n- umie zada\u0107 pytanie dotycz\u0105ce wiarygodno\u015bci informacji;\nnp. zadaje pytania \u201emamo, czy to prawda, \u017ce\u201d...",
-            "competence": 3,
-            "level": 1
-        }
-    },
-    {
-        "pk": 20,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- wie, \u017ce informacje mog\u0105 by\u0107 nieprawdziwe, niepe\u0142ne, niedok\u0142adne.\n- wie, \u017ce nale\u017cy zastanawia\u0107 si\u0119 i rozmawia\u0107 na temat sposob\u00f3w korzystania z informacji.\n- wie, \u017ce nadawcy informacji mog\u0105 chcie\u0107 wywrze\u0107 na niego wp\u0142yw i sk\u0142oni\u0107 do okre\u015blonych zachowa\u0144.\n- umie dostrzec r\u00f3\u017cnic\u0119 pomi\u0119dzy informacj\u0105 prawdziw\u0105 i nieprawdziw\u0105, kieruj\u0105c si\u0119 swoj\u0105 intuicj\u0105.",
-            "competence": 3,
-            "level": 2
-        }
-    },
-    {
-        "pk": 21,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- wie, \u017ce przekazywane informacje r\u00f3\u017cni\u0105 si\u0119 w zale\u017cno\u015bci od intencji nadawcy;\nnp. por\u00f3wnuje, jak przekazywana jest ta sama informacja w r\u00f3\u017cnych mediach.\n- wie, \u017ce informacje niskiej jako\u015bci prowadz\u0105 do b\u0142\u0119dnych wniosk\u00f3w.\n- umie kwestionowa\u0107 wiarygodno\u015b\u0107 informacji.\n- umie weryfikowa\u0107 informacje poprzez por\u00f3wnywanie ich w r\u00f3\u017cnych \u017ar\u00f3d\u0142ach.\n- wie, \u017ce jest r\u00f3\u017cnica pomi\u0119dzy informacj\u0105 a plotk\u0105.\n- rozumie, czym jest manipulacja informacj\u0105.",
-            "competence": 3,
-            "level": 3
-        }
-    },
-    {
-        "pk": 22,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- wie, \u017ce zawsze nale\u017cy by\u0107 krytycznym wobec \u017ar\u00f3d\u0142a.\n- wie, z jakich \u017ar\u00f3de\u0142 skorzysta\u0107, by jednoznacznie zweryfikowa\u0107 informacje;\nnp. korzysta z encyklopedii PWN, by potwierdzi\u0107 informacje znalezione na blogu.\n- umie selekcjonowa\u0107 potrzebne informacje, sprawdzaj\u0105c ich dok\u0142adno\u015b\u0107.\n- umie oceni\u0107 wykorzystanie TIK w swojej pracy.\n- umie dostrzec i okre\u015bli\u0107 r\u00f3\u017cnice pomi\u0119dzy informacj\u0105 a innym przekazem, w tym opini\u0105, ocen\u0105, krytyk\u0105;\nnp. por\u00f3wnuje artyku\u0142y z r\u00f3\u017cnych gazet, okre\u015blaj\u0105c ich cechy.\n- umie rozr\u00f3\u017cni\u0107 cechy i funkcje informacji i plotki; np. por\u00f3wnuje teksty z \u201eGazety Wyborczej\u201d, \u201eFaktu\u201d i \u201ePudelka\u201d.",
-            "competence": 3,
-            "level": 4
-        }
-    },
-    {
-        "pk": 23,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- wie, \u017ce umiej\u0119tno\u015b\u0107 krytycznej oceny informacji jest kluczowa w procesie realizacji zada\u0144.\n- wie, \u017ce \u017ar\u00f3d\u0142a informacji i narz\u0119dzia TIK wykorzystywane w pracy maj\u0105 swoje wady, zalety i ograniczenia.\n- umie przedstawi\u0107 argumenty dotycz\u0105ce wad, zalet i ogranicze\u0144 \u017ar\u00f3de\u0142 informacji i narz\u0119dzi TIK.\n- rozumie konsekwencje wynikaj\u0105ce z braku podej\u015bcia krytycznego w zakresie korzystania ze \u017ar\u00f3de\u0142 informacji i narz\u0119dzi TIK.\n- rozumie konsekwencje przyjmowania okre\u015blonego stanowiska w pracy z informacj\u0105; np. np.rozumie, \u017ce wyniki bada\u0144 dotycz\u0105cych preferencji politycznych mog\u0105 by\u0107 r\u00f3\u017cnie interpretowane w zale\u017cno\u015bci od przekona\u0144 i sympatii politycznych autora lub linii programowej stacji oraz zdaje sobie spraw\u0119, \u017ce mo\u017ce to prowadzi\u0107 do b\u0142\u0119dnych wniosk\u00f3w.",
-            "competence": 3,
-            "level": 5
-        }
-    },
-    {
-        "pk": 24,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- umie wykorzysta\u0107 wyniki rozm\u00f3w na temat wad, zalet i ogranicze\u0144 \u017ar\u00f3de\u0142 informacji i narz\u0119dzi TIK do formu\u0142owania ocen dotycz\u0105cych jako\u015bci swojej pracy.\n- rozumie, jaki wp\u0142yw na rozw\u00f3j sektora TIK maj\u0105 czynniki takie jak prawo,etyka, ekonomia i wykorzystuje t\u0119 wiedz\u0119 w procesie realizacji zada\u0144 informacyjnych.",
-            "competence": 3,
-            "level": 6
-        }
-    },
-    {
-        "pk": 25,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- wie, \u017ce nadawcy informacji mog\u0105 chcie\u0107 wywrze\u0107 na niego wp\u0142yw i sk\u0142oni\u0107 do okre\u015blonych zachowa\u0144.\n- wie, \u017ce intencje nadawcy oraz specyfika danego medium ma decyduj\u0105cy wp\u0142yw na tre\u015b\u0107 i form\u0119 informacji.\n- wie, jakie s\u0105 podstawowe kryteria oceny \u017ar\u00f3de\u0142 informacji.\n- umie dostrzec r\u00f3\u017cnic\u0119 pomi\u0119dzy informacj\u0105 prawdziw\u0105 i nieprawdziw\u0105, kieruj\u0105c si\u0119 swoj\u0105 intuicj\u0105.\n- umie kwestionowa\u0107 wiarygodno\u015b\u0107 informacji.\n- umie weryfikowa\u0107 informacje poprzez por\u00f3wnywanie ich w r\u00f3\u017cnych \u017ar\u00f3d\u0142ach.\n- umie dostrzec i okre\u015bli\u0107 r\u00f3\u017cnice pomi\u0119dzy informacj\u0105 a innym przekazem, w tym opini\u0105, ocen\u0105, krytyk\u0105.\n- rozumie, czym jest manipulacja informacj\u0105.",
-            "competence": 3,
-            "level": 7
-        }
-    },
-    {
-        "pk": 26,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- wie, \u017ce umiej\u0119tno\u015b\u0107 krytycznej oceny informacji jest kluczowa w procesie realizacji zada\u0144.\n- rozumie konsekwencje przyjmowania okre\u015blonego stanowiska w pracy z informacj\u0105.",
-            "competence": 3,
-            "level": 8
-        }
-    },
-    {
-        "pk": 27,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- rozumie, jaki wp\u0142yw na rozw\u00f3j sektora TIK maj\u0105 czynniki takie jak prawo,etyka, ekonomia i wykorzystuje t\u0119 wiedz\u0119 w procesie realizacji zada\u0144 informacyjnych.",
-            "competence": 3,
-            "level": 9
-        }
-    },
-    {
-        "pk": 29,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- wie, \u017ce zasoby informacyjne trzeba porz\u0105dkowa\u0107 w celu \u0142atwego ich wykorzystania i odnalezienia.\n- umie wprowadza\u0107, zachowywa\u0107 i odzyskiwa\u0107 wyniki swojej pracy;\nnp. zapisuje wyniki swojej pracy w edytorze tekst\u00f3w.\n- umie zastosowa\u0107 proste schematy organizacji informacji, \u0142\u0105czy\u0107 i organizowa\u0107 materia\u0142;\nnp. szereguje, klasyfikuje, tworzy katalogi i foldery, opisuje je w zrozumia\u0142y dla siebie spos\u00f3b.",
-            "competence": 4,
-            "level": 2
-        }
-    },
-    {
-        "pk": 30,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- wie, \u017ce prezentuj\u0105c wyniki swojej pracy, powinien bra\u0107 pod uwag\u0119 potrzeby odbiorc\u00f3w.\n- umie wykorzystywa\u0107 TIK podczas tworzenia, ulepszania i zapisywania wynik\u00f3w pracy;\nnp. umie skorzysta\u0107 z poczty e-mail, by przes\u0142a\u0107 wyniki pracy kolegom.\n- umie wykorzystywa\u0107 TIK do dzielenia si\u0119 swoimi pomys\u0142ami z innymi, wykorzystuj\u0105c w tym celu r\u00f3\u017cne formy prezentacji informacji;\nnp. tworzy wsp\u00f3lnie z kolegami projekt, wykorzystuj\u0105c tekst, tabele, ilustracje.\n- umie sprawnie organizowa\u0107 w\u0142asne zasoby informacyjne w celu \u0142atwego ich wykorzystania.\n- rozumie, jakie s\u0105 konsekwencje braku opracowania i organizacji informacji.\n- rozumie, jakie s\u0105 potrzeby poszczeg\u00f3lnych grup odbiorc\u00f3w w zakresie prezentowania informacji;\nnp. rozumie, \u017ce komunikat podobnej tre\u015bci nale\u017cy zbudowa\u0107 inaczej, gdy jest adresowany do r\u00f3wie\u015bnik\u00f3w, rodzic\u00f3w, nauczycieli.",
-            "competence": 4,
-            "level": 3
-        }
-    },
-    {
-        "pk": 31,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- wie, jak odpowiednio prezentowa\u0107 wyniki swojej pracy;\nnp. wie, \u017ce prezentacja musi by\u0107 przejrzysta, zawiera\u0107 niezbyt du\u017co tekstu oraz rozmaite ilustracje.\n- umie dodawa\u0107, ulepsza\u0107 i \u0142\u0105czy\u0107 informacje w r\u00f3\u017cnych formach, zaczerpni\u0119te z r\u00f3\u017cnych \u017ar\u00f3de\u0142.\n- umie wykorzystywa\u0107 TIK w procesie prezentowania wynik\u00f3w swojej pracy;\nnp. umie przygotowa\u0107 prezentacje multimedialne i prowadzi\u0107 wyst\u0105pienia publiczne.\n- umie organizowa\u0107 informacje w spos\u00f3b najbardziej odpowiedni do wykorzystania.",
-            "competence": 4,
-            "level": 4
-        }
-    },
-    {
-        "pk": 32,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- umie rozwija\u0107 i ulepsza\u0107 wyniki swojej pracy z wykorzystaniem TIK, by podnie\u015b\u0107 jej jako\u015b\u0107.\n- umie \u0142\u0105czy\u0107 informacje pochodz\u0105ce z r\u00f3\u017cnych \u017ar\u00f3de\u0142, by w odpowiedni spos\u00f3b przedstawi\u0107 je odbiorcom.\n- umie samodzielnie wybra\u0107 narz\u0119dzia TIK odpowiadaj\u0105ce realizacji okre\u015blonych zada\u0144.\n- rozumie, jakie s\u0105 przyczyny ogranicze\u0144 zastosowania TIK w wykonywaniu okre\u015blonych prac;\nnp. rozumie ograniczenia wynikaj\u0105ce z konieczno\u015bci algorytmizacji wszelkich prac, by mog\u0142y by\u0107 wykonywane przez TIK.",
-            "competence": 4,
-            "level": 5
-        }
-    },
-    {
-        "pk": 34,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- wie, \u017ce prezentuj\u0105c wyniki swojej pracy, powinien bra\u0107 pod uwag\u0119 potrzeby odbiorc\u00f3w.\n- umie wprowadza\u0107, zachowywa\u0107 i odzyskiwa\u0107 wyniki swojej pracy.\n- umie wykorzystywa\u0107 TIK podczas tworzenia, ulepszania i zapisywania wynik\u00f3w pracy.\n- umie selekcjonowa\u0107 potrzebne informacje, sprawdzaj\u0105c ich dok\u0142adno\u015b\u0107.",
-            "competence": 4,
-            "level": 7
-        }
-    },
-    {
-        "pk": 35,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- wie, \u017ce \u017ar\u00f3d\u0142a informacji i narz\u0119dzia TIK wykorzystywane w pracy maj\u0105 swoje wady, zalety i ograniczenia.\n- umie wykorzystywa\u0107 TIK w procesie prezentowania wynik\u00f3w swojej pracy.\n- umie oceni\u0107 wykorzystanie TIK w swojej pracy.\n- umie wykorzysta\u0107 wyniki rozm\u00f3w na temat wad, zalet i ogranicze\u0144 \u017ar\u00f3de\u0142 informacji i narz\u0119dzi TIK do formu\u0142owania ocen dotycz\u0105cych jako\u015bci jego pracy.\n- rozumie, jakie s\u0105 przyczyny ogranicze\u0144 zastosowania TIK w wykonywaniu okre\u015blonych prac.",
-            "competence": 4,
-            "level": 8
-        }
-    },
-    {
-        "pk": 36,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- umie \u0142\u0105czy\u0107 informacje pochodz\u0105ce z r\u00f3\u017cnych \u017ar\u00f3de\u0142, by w odpowiedni spos\u00f3b przedstawi\u0107 je odbiorcom.\n- umie wybra\u0107 narz\u0119dzia TIK odpowiadaj\u0105ce realizacji okre\u015blonych zada\u0144.\n- rozumie konsekwencje wynikaj\u0105ce z braku podej\u015bcia krytycznego w zakresie korzystania ze \u017ar\u00f3de\u0142 informacji i narz\u0119dzi TIK.",
-            "competence": 4,
-            "level": 9
-        }
-    },
-    {
-        "pk": 55,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- wie, jakie s\u0105 specyficzne cechy jego samego i najbli\u017cszego otoczenia;\r\nnp. w przekazach medialnych rozpoznaje og\u00f3lne podobie\u0144stwa miejsc i przedmiot\u00f3w, zauwa\u017ca taki sam rower lub plac zabaw.\r\n- umie rozr\u00f3\u017cni\u0107 siebie na tle innych (poczucie indywiduum);\r\nnp. dostrzega na zdj\u0119ciach lub materia\u0142ach filmowych swoje cechy indywidualne w por\u00f3wnaniu z innymi (wzrost, kolor w\u0142os\u00f3w).",
-            "competence": 7,
-            "level": 1
-        }
-    },
-    {
-        "pk": 56,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- wie, \u017ce nie zawsze i wsz\u0119dzie nale\u017cy ujawnia\u0107 informacje o sobie;\r\nnp. rozmawiaj\u0105c z nowo poznan\u0105 osob\u0105 na czacie, nie podaje swojego numeru telefonu ani maila.\r\n- umie dostrzec r\u00f3\u017cnice mi\u0119dzy swoim wizerunkiem, zdolno\u015bciami i umiej\u0119tno\u015bciami a cechami postaci w grze; np. graj\u0105c w gr\u0119 komputerow\u0105, ma \u015bwiadomo\u015b\u0107, \u017ce po wyj\u015bciu z niej nie b\u0119dzie mia\u0142 nadal trzech \u201e\u017cy\u0107\u201d jak jego awatar.",
-            "competence": 7,
-            "level": 2
-        }
-    },
-    {
-        "pk": 57,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- wie, \u017ce wizerunek mo\u017cna budowa\u0107 i prezentowa\u0107 na r\u00f3\u017cne sposoby;\r\nnp. ma \u015bwiadomo\u015b\u0107, \u017ce osoba siedz\u0105ca po drugiej stronie monitora podczas czatu, mo\u017ce by\u0107 zupe\u0142nie kim\u015b innym ni\u017c ta, za kt\u00f3r\u0105 si\u0119 podaje.\r\n- wie, jakie dzia\u0142ania przez media mog\u0105 mie\u0107 negatywne konsekwencje dla niego lub innych;\r\nnp. wie, \u017ce np. \u015bmieszny filmik z jego udzia\u0142em, wrzucony spontanicznie do sieci, mo\u017ce kiedy\u015b zosta\u0107 wykorzystany przeciwko niemu lub sprawi\u0107 komu\u015b przykro\u015b\u0107.\r\n- umie \u015bwiadomie kreowa\u0107 sw\u00f3j wizerunek w podstawowym zakresie;\r\nnp. rejestruj\u0105c si\u0119 na nowym portalu, umie wybra\u0107, kieruj\u0105c si\u0119 wzgl\u0119dami bezpiecze\u0144stwa, kt\u00f3re informacje o sobie podaje, a kt\u00f3rych nie.",
-            "competence": 7,
-            "level": 3
-        }
-    },
-    {
-        "pk": 58,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- umie, w zale\u017cno\u015bci od potrzeb, tworzy\u0107 i modyfikowa\u0107 sw\u00f3j wizerunek;\r\nnp. do\u0142\u0105czaj\u0105c do jakiej\u015b grupy w sieci, podaje tylko wybrane informacje o sobie.\r\n- rozumie szanse i zagro\u017cenia wynikaj\u0105ce z budowania w\u0142asnego wizerunku;\r\nnp. zwraca du\u017c\u0105 uwag\u0119 na to, co i gdzie na jego temat pojawia si\u0119 w internecie. Ma \u015bwiadomo\u015b\u0107, \u017ce nawet po skasowaniu jakiej\u015b tre\u015bci, w sieci i tak pozostaje po niej \u015blad.",
-            "competence": 7,
-            "level": 4
-        }
-    },
-    {
-        "pk": 59,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- wie, jakie s\u0105 elementy sk\u0142adowe wizerunku i umie je interpretowa\u0107;\r\nnp. zdaje sobie spraw\u0119, \u017ce wizerunek medialny os\u00f3b publicznych wykorzystuje j\u0119zyk i mow\u0119 cia\u0142a do realizacji zak\u0142adnych cel\u00f3w (np. pozyskania poparcia wyborc\u00f3w)\r\n- umie \u015bwiadomie tworzy\u0107 sw\u00f3j wizerunek w zale\u017cno\u015bci od kontekstu;\r\nnp. wpisuj\u0105c komentarze na portalach spo\u0142eczno\u015bciowych, zdaje sobie spraw\u0119, \u017ce s\u0105 one elementem jego to\u017csamo\u015bci w oczach innych, w tym r\u00f3wnie\u017c przysz\u0142ych pracodawc\u00f3w.\r\n- rozumie konsekwencje i potrzeb\u0119 \u015bwiadomego budowania w\u0142asnego wizerunku;\r\nnp. nie pozwala przypadkowo fotografowa\u0107 swojej osoby podczas imprez.",
-            "competence": 7,
-            "level": 5
-        }
-    },
-    {
-        "pk": 61,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- umie wskaza\u0107 elementy wizerunku on-line, zar\u00f3wno swojego, jak i innych os\u00f3b.\r\n- umie do\u0142\u0105czy\u0107 do wybranej spo\u0142eczno\u015bci i uczestniczy\u0107 w jej \u017cyciu, odpowiednio kreuj\u0105c sw\u00f3j wizerunek;\r\nnp. aktywnie uczestniczy w r\u00f3\u017cnych grupach hobbystycznych, edukacyjnych, terapeutycznych, \u015bwiatopogl\u0105dowych, politycznych itd.\r\n- rozumie r\u00f3\u017cnice pomi\u0119dzy \u015bwiatem do\u015bwiadczanym bezpo\u015brednio i przez media, zdaje sobie spraw\u0119 z powi\u0105za\u0144 mi\u0119dzy nimi;\r\nnp. tworz\u0105c profil na portalu spo\u0142eczno\u015bciowym dba przy tym o w\u0142asny wizerunek, gdy\u017c ma \u015bwiadomo\u015b\u0107 mo\u017cliwych konsekwencji, m.in. wp\u0142ywu na swoj\u0105 \u015bcie\u017ck\u0119 kariery.",
-            "competence": 7,
-            "level": 7
-        }
-    },
-    {
-        "pk": 62,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- umie budowa\u0107 sieci kontakt\u00f3w \u2013 trwa\u0142e i zadaniowe;\r\nnp. w zale\u017cno\u015bci od kontekstu kreuje sw\u00f3j wizerunek w sieci na potrzeby danych \u015brodowisk, przyjmuj\u0105c w nich r\u00f3\u017cne role spo\u0142eczne.\r\n- umie w spos\u00f3b \u015bwiadomy i odpowiedzialny budowa\u0107 sw\u00f3j wizerunek sieciowy i wykorzysta\u0107 go do realizacji okre\u015blonych cel\u00f3w;\r\nnp. wykorzystuje swojego bloga do budowania pozycji w \u015brodowisku zawodowym.\r\n- rozumie r\u00f3\u017cnice pomi\u0119dzy wizerunkami trwa\u0142ymi a ulotnymi;\r\nnp. inaczej buduje sw\u00f3j wizerunek w procesie tworzenia profilu na portalu spo\u0142eczno\u015bciowym czy forum specjalistycznym, a inaczej na czacie.\r\n- rozumie szanse i korzy\u015bci p\u0142yn\u0105ce z przynale\u017cno\u015bci do danej grupy;\r\n\r\nnp. potrafi je wykorzystywa\u0107 w planowaniu kariery zawodowej, do\u0142\u0105czaj\u0105c do grup specjalist\u00f3w w danej dziedzinie oraz tworz\u0105c profile w spo\u0142eczno\u015bciowych serwisach specjalistycznych.",
-            "competence": 7,
-            "level": 8
-        }
-    },
-    {
-        "pk": 63,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- umie budowa\u0107 spo\u0142eczno\u015bci i wsp\u00f3\u0142tworzy\u0107 \u015brodowisko cyfrowe oraz kreowa\u0107 to\u017csamo\u015bci zbiorowe, takie jak grupy hobbystyczne czy polityczne;\r\nnp. samodzielnie prowadzi forum, administruje stron\u0105 internetow\u0105 lub tworzy potrzebne mu narz\u0119dzia cyfrowe.\r\n- umie kszta\u0142towa\u0107 w\u0142asny wizerunek w sieci stosownie do r\u00f3\u017cnych kontekst\u00f3w;\r\nnp. na tym samym profilu spo\u0142eczno\u015bciowym potrafi wykreowa\u0107 kilka, cz\u0119sto zupe\u0142nie r\u00f3\u017cnych wizerunk\u00f3w w zale\u017cno\u015bci od kontekstu i potrzeb.",
-            "competence": 7,
-            "level": 9
-        }
-    },
-    {
-        "pk": 37,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- wie, jak wyra\u017ca\u0107 swoje elementarne potrzeby i emocje dotycz\u0105ce medi\u00f3w;\r\nnp. w kontakcie z medium (ksi\u0105\u017ck\u0105 czy gr\u0105 w sieci) wskazuje na to, co lubi; wybiera, kt\u00f3r\u0105 ksi\u0105\u017ck\u0119 chce przeczyta\u0107.\r\n- umie korzysta\u0107 ze znanych mu kana\u0142\u00f3w komunikacji;\r\nnp. w podstawowym zakresie rozr\u00f3\u017cnia zasady korzystania z poszczeg\u00f3lnych medi\u00f3w, wie, \u017ce radia (muzyki) si\u0119 s\u0142ucha, a telewizj\u0119 (film) ogl\u0105da.",
-            "competence": 5,
-            "level": 1
-        }
-    },
-    {
-        "pk": 38,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- wie, jak zastosowa\u0107 r\u00f3\u017cne rodzaje komunikat\u00f3w (formalne i nieformalne);\r\nnp. dostrzega, \u017ce innymi kana\u0142ami i w inny spos\u00f3b komunikuje si\u0119 z kolegami z klasy i nauczycielem.\r\n- umie korzysta\u0107 z podstawowych narz\u0119dzi komunikacyjnych;\r\nnp. porozumiewa si\u0119 za pomoc\u0105 telefonu kom\u00f3rkowego i komunikator\u00f3w internetowych.\r\n- wie, jakie s\u0105 podstawowe rodzaje komunikat\u00f3w i zna ich funkcje (obraz, d\u017awi\u0119k, s\u0142owo);\r\nnp. potrafi dopasowa\u0107 element muzyczny do odpowiadaj\u0105cej mu ilustracji.",
-            "competence": 5,
-            "level": 2
-        }
-    },
-    {
-        "pk": 39,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- wie, w jaki spos\u00f3b tworzy\u0107 komunikaty w zale\u017cno\u015bci od kontekstu;\r\nnp. inaczej napisze fragment bloga, a inaczej maila do nauczyciela.\r\n- wie, jak znale\u017a\u0107 w sieci osoby, kt\u00f3re podzielaj\u0105 jego zainteresowania, i umie si\u0119 z nimi komunikowa\u0107;\r\nnp. potrafi za\u0142o\u017cy\u0107 nowy w\u0105tek na forum lub do\u0142\u0105czy\u0107 si\u0119 do istniej\u0105cej ju\u017c grupy dyskusyjnej.\r\n- umie wybra\u0107 narz\u0119dzia / technologie w zale\u017cno\u015bci od potrzeb komunikacyjnych;\r\nnp. \u015bwiadomie w\u0142\u0105cza lub wy\u0142\u0105cza kamer\u0119 internetow\u0105 podczas rozmowy przez komunikator.\r\n- rozumie przebieg procesu komunikacji bezpo\u015bredniej i przez media;\r\nnp. potrafi wyja\u015bni\u0107 r\u00f3\u017cnice i podobie\u0144stwa mi\u0119dzy nadawc\u0105 i odbiorc\u0105 komunikatu, a tak\u017ce bierze odpowiedzialno\u015b\u0107 za komunikowane przez siebie tre\u015bci.",
-            "competence": 5,
-            "level": 3
-        }
-    },
-    {
-        "pk": 40,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- wie, jakie s\u0105 zasady komunikowania si\u0119 z innymi u\u017cytkownikami medi\u00f3w;\r\nnp. zna i potrafi stosowa\u0107 w praktyce zasady netykiety.\r\n- wie, jak u\u017cywa\u0107 r\u00f3\u017cnych rodzaj\u00f3w komunikat\u00f3w do przekazywania okre\u015blonych tre\u015bci w zale\u017cno\u015bci od celu i potrzeb;\r\nnp. ma \u015bwiadomo\u015b\u0107 tego, \u017ce czasami jedno zdj\u0119cie mo\u017ce wyrazi\u0107 wi\u0119cej ni\u017c wiele s\u0142\u00f3w.\r\n- wie, czym s\u0105 spo\u0142eczno\u015bci fanowskie oraz zjawisko fanfiction;\r\nnp. umie tworzy\u0107 sieci kontakt\u00f3w spo\u0142ecznych w internecie, w tym r\u00f3wnie\u017c grupy skupiaj\u0105ce cz\u0142onk\u00f3w subkultur fanowskich.",
-            "competence": 5,
-            "level": 4
-        }
-    },
-    {
-        "pk": 41,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- wie, jakie czynniki mog\u0105 mie\u0107 wp\u0142yw na przebieg komunikacji;\r\nnp. zdaje sobie spraw\u0119, \u017ce to, czy jego wiadomo\u015b\u0107 w rozmowie telefonicznej lub kontakcie mailowym zostanie odebrana zgodnie z jego intencj\u0105, zale\u017cy od sytuacji i mo\u017cliwo\u015bci odbiorcy.\r\n- umie skutecznie i precyzyjnie porozumiewa\u0107 si\u0119 z innymi, wykorzystuj\u0105c do tego r\u00f3\u017cnego rodzaju kana\u0142y komunikacji.",
-            "competence": 5,
-            "level": 5
-        }
-    },
-    {
-        "pk": 43,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- wie, \u017ce anonimowo\u015b\u0107 w sieci jest cz\u0119sto pozorna;\r\nzdaje sobie spraw\u0119, \u017ce ka\u017cdy jego ruch w internecie pozostawia \u015blad mo\u017cliwy potem do odtworzenia.\r\n- wie, \u017ce swoim zachowaniem nie wolno rani\u0107 innych i w procesie komunikacji nie dopuszcza si\u0119 zachowa\u0144 nieakceptowanych spo\u0142ecznie;\r\nnp. prowokowanie k\u0142\u00f3tni, u\u017cywanie obelg, trollowanie itp.\r\n- umie zachowywa\u0107 si\u0119 w spos\u00f3b asertywny i skutecznie komunikowa\u0107 si\u0119 w \u015brodowisku medialnym;\r\nnp. umie w spos\u00f3b jasny, konkretny, otwarty i szczery wyra\u017ca\u0107 swoje opinie, ch\u0119ci, potrzeby i uczucia, a tak\u017ce odrzuca\u0107 propozycje mog\u0105ce stanowi\u0107 zagro\u017cenie.\r\n- umie wyr\u00f3\u017cnia\u0107 komunikaty k\u0142amliwe, propagandowe, maj\u0105ce na celu manipulacj\u0119;\r\nnp. ogl\u0105daj\u0105c reklam\u0119 telewizyjn\u0105 dostrzega w niej elementy r\u00f3\u017cnych socjotechnik.\r\n- rozumie r\u00f3\u017cnice pomi\u0119dzy komunikacj\u0105 formaln\u0105 a nieformaln\u0105;\r\nnp. tworz\u0105c komunikat, uwzgl\u0119dnia specyfik\u0119 jego odbiorcy oraz kontekstu wypowiedzi (np. inaczej napisze maila do prze\u0142o\u017conego, a inaczej do kolegi z pracy).\r\n- wie, jak znale\u017a\u0107 w sieci osoby, kt\u00f3re podzielaj\u0105 jego zainteresowania, i umie si\u0119 z nimi komunikowa\u0107;\r\nnp. potrafi za\u0142o\u017cy\u0107 nowy w\u0105tek na forum lub do\u0142\u0105czy\u0107 si\u0119 do istniej\u0105cej ju\u017c grupy dyskusyjnej.",
-            "competence": 5,
-            "level": 7
-        }
-    },
-    {
-        "pk": 44,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- wie, jakie s\u0105 zasady komunikowania si\u0119 z innymi u\u017cytkownikami medi\u00f3w;\r\nnp. zna i potrafi stosowa\u0107 w praktyce zasady netykiety.\r\n- wie, jakie czynniki mog\u0105 mie\u0107 wp\u0142yw na przebieg komunikacji;\r\nnp. zdaje sobie spraw\u0119, \u017ce to, czy jego wiadomo\u015b\u0107 w rozmowie telefonicznej lub kontakcie mailowym zostanie odebrana zgodnie z jego intencj\u0105, zale\u017cy od sytuacji i mo\u017cliwo\u015bci odbiorcy.\r\n- umie nawi\u0105zywa\u0107 kontakty z osobami mieszkaj\u0105cymi w r\u00f3\u017cnych cz\u0119\u015bciach \u015bwiata, wie, jak r\u00f3\u017cnice kulturowe mog\u0105 wp\u0142ywa\u0107 na proces komunikacji;\r\nnp. potrafi aktywnie uczestniczy\u0107 w spo\u0142eczno\u015bciach ponadlokalnych, mi\u0119dzynarodowych.",
-            "competence": 5,
-            "level": 8
-        }
-    },
-    {
-        "pk": 45,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- umie wychwytywa\u0107 dzia\u0142ania niezgodne z prawem lub spo\u0142ecznie nieakceptowane pope\u0142niane przez lub wobec innych cz\u0142onk\u00f3w spo\u0142eczno\u015bci oraz reaguje na nie;\r\nnp. b\u0119d\u0105c administratorem forum moderuje i weryfikuje proces przep\u0142ywu informacji.\r\n- umie przeciwdzia\u0142a\u0107 barierom informacyjnym, wykluczeniu cyfrowemu, asymetrii informacji oraz prowadzi\u0107 dzia\u0142alno\u015b\u0107 informacyjn\u0105;\r\nnp. samodzielnie tworzy materia\u0142y edukacyjne oraz odpowiednie narz\u0119dzia medialne dla os\u00f3b maj\u0105cych trudno\u015bci z poruszaniem si\u0119 w \u015brodowisku medialnym.",
-            "competence": 5,
-            "level": 9
-        }
-    },
-    {
-        "pk": 46,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- umie dostrzec w przekazie medialnym elementy znanego mu otoczenia;\r\nnp. wyr\u00f3\u017cnia z t\u0142a medialnego znane mu miejsca.\r\n- umie intuicyjnie pos\u0142ugiwa\u0107 si\u0119 na poziomie elementarnym dost\u0119pnymi w jego otoczeniu mediami;\r\nnp. samodzielnie w\u0142\u0105czy telewizor na kana\u0142 z kresk\u00f3wkami lub uruchomi w telefonie aplikacj\u0119 z ulubion\u0105 gr\u0105.",
-            "competence": 6,
-            "level": 1
-        }
-    },
-    {
-        "pk": 47,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- wie, \u017ce \u015bwiat przedstawiany w mediach nie jest tym samym, co \u015bwiat do\u015bwiadczany bezpo\u015brednio;\r\nnp. zdaje sobie spraw\u0119, \u017ce nie wszystko to, co jest mo\u017cliwe w grach, jest mo\u017cliwe r\u00f3wnie\u017c w rzeczywisto\u015bci.\r\n- wie, jakie s\u0105 zasady bezpiecze\u0144stwa i higieny korzystania z medi\u00f3w;\r\nnp. ma \u015bwiadomo\u015b\u0107, \u017ce nie nale\u017cy zbyt d\u0142ugo siedzie\u0107 przed telewizorem lub monitorem komputera.\r\n- wie, \u017ce dzi\u0119ki mediom mo\u017cemy poznawa\u0107 \u015bwiat\r\nnp. zdaje sobie spraw\u0119, \u017ce na wybranym kanale telewizyjnym lub w internecie mo\u017ce \u00a0ogl\u0105da\u0107 rzeczy odleg\u0142e i nieznane mu z najbli\u017cszego otoczenia, np. filmy przyrodnicze.\r\n- umie korzysta\u0107 z r\u00f3\u017cnych \u017ar\u00f3de\u0142 i kana\u0142\u00f3w informacji;\r\nnp. potrafi wyszukiwa\u0107 informacje w internecie.",
-            "competence": 6,
-            "level": 2
-        }
-    },
-    {
-        "pk": 48,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- wie, jakie s\u0105 mo\u017cliwo\u015bci i zagro\u017cenia w korzystaniu z r\u00f3\u017cnych medi\u00f3w;\r\nnp. ma \u015bwiadomo\u015b\u0107, \u017ce nale\u017cy by\u0107 ostro\u017cnym w kontaktach z nieznajomymi poznanymi np. poprzez komunikator internetowy.\r\n- umie aktywnie korzysta\u0107 z nowych medi\u00f3w;\r\nnp. potrafi zapisa\u0107 si\u0119 do grupy dyskusyjnej i bra\u0107 w niej aktywny udzia\u0142 lub przy\u0142\u0105czy\u0107 si\u0119 do czatu.\r\n- umie w spos\u00f3b \u015bwiadomy korzysta\u0107 z r\u00f3\u017cnych kana\u0142\u00f3w informacji;\r\nnp. znajduje kilka r\u00f3\u017cnych \u017ar\u00f3de\u0142 odnosz\u0105cych si\u0119 do tej samej informacji i dokonuje ich weryfikacji.\r\n- rozumie podstawowe zasady bezpiecze\u0144stwa w przestrzeni cyfrowej;\r\nnp. nie pobiera z internetu tre\u015bci nieznanych lub pochodz\u0105cych z niepewnych \u017ar\u00f3de\u0142.",
-            "competence": 6,
-            "level": 3
-        }
-    },
-    {
-        "pk": 49,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- wie, jakie s\u0105 og\u00f3lne zasady dzia\u0142ania i umie wykorzystywa\u0107 r\u00f3\u017cne narz\u0119dzia medialne w zale\u017cno\u015bci od specyfiki otoczenia;\r\nnp. w miar\u0119 potrzeby komunikuje si\u0119 za pomoc\u0105 telefonu kom\u00f3rkowego,\r\nkomunikatora internetowego lub pisz\u0105c na forum.\r\n- wie, jak grupa i otoczenie wp\u0142ywaj\u0105 na jego \u017cycie;\r\nnp. umie dostrzec wp\u0142yw komentarzy pod swoim wpisem na portalu spo\u0142eczno\u015bciowym na w\u0142asne wybory, decyzje i upodobania.\r\n- umie aktywnie uczestniczy\u0107 w wybranych spo\u0142eczno\u015bciach on-line;\r\nnp. wymienia si\u0119 informacjami, wyra\u017ca opinie i prowadzi dyskusje w r\u00f3\u017cnych sieciach spo\u0142ecznych w internecie.",
-            "competence": 6,
-            "level": 4
-        }
-    },
-    {
-        "pk": 50,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- wie, \u017ce r\u00f3\u017cne grupy istniej\u0105ce w otoczeniu medialnym maj\u0105 sw\u00f3j specyficzny charakter, zasady funkcjonowania oraz dynamik\u0119;\r\nnp. wskazuje r\u00f3\u017cnice pomi\u0119dzy spo\u0142eczno\u015bciami on-line os\u00f3b, kt\u00f3re si\u0119 nigdy nie spotka\u0142y, a tymi, kt\u00f3re znaj\u0105 si\u0119 np. ze szko\u0142y.\r\n- umie wykorzystywa\u0107 spo\u0142eczno\u015bciowy potencja\u0142 sieci dla realizacji w\u0142asnych cel\u00f3w;\r\nnp. potrafi w zale\u017cno\u015bci od potrzeby znale\u017a\u0107 po\u017c\u0105dany produkt lub us\u0142ug\u0119 i pozna\u0107 opinie innych u\u017cytkownik\u00f3w na jej temat.\r\n- rozumie procesy powstawania grup i budowania sieci spo\u0142ecznych;\r\nnp. dostrzega r\u00f3\u017cnice w sposobie uczestnictwa w spontanicznie zebranej grupie os\u00f3b w internecie, a r\u00f3wnolegle dzia\u0142aj\u0105cej grupie graczy spotykaj\u0105cych si\u0119 regularnie on-line.",
-            "competence": 6,
-            "level": 5
-        }
-    },
-    {
-        "pk": 52,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- umie pos\u0142ugiwa\u0107 si\u0119 nowymi technologiami w zakresie umo\u017cliwiaj\u0105cym uczestnictwo w spo\u0142e\r\n- umie aktywnie uczestniczy\u0107 w wybranych spo\u0142eczno\u015bciach on-line;\r\nnp. wymienia si\u0119 informacjami, wyra\u017ca opinie i prowadzi dyskusje w r\u00f3\u017cnych sieciach spo\u0142ecznych w internecie.\r\n- zna zasady bezpiecze\u0144stwa i higieny korzystania z medi\u00f3w.\r\n- umie kszta\u0142towa\u0107 swoje relacje przez media tak, by nie zaburza\u0142y one relacji bezpo\u015brednich;\r\nnp. bezpo\u015brednie kontakty z najbli\u017cszymi osobami uzupe\u0142nia o mo\u017cliwo\u015bci komunikacji przez media, a nie zast\u0119puje ich nimi.",
-            "competence": 6,
-            "level": 7
-        }
-    },
-    {
-        "pk": 53,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- wie, \u017ce internet to wi\u0119cej ni\u017c tylko medium;\r\nma \u015bwiadomo\u015b\u0107, \u017ce jest to nowy rodzaj rzeczywisto\u015bci, w kt\u00f3rym toczy si\u0119 r\u00f3wnoleg\u0142e, cz\u0119sto tak samo prawdziwe \u017cycie, za\u015b komunikacja przez media jest tylko innym, r\u00f3wnorz\u0119dnym i r\u00f3wnoprawnym sposobem komunikacji z lud\u017ami.\r\n- rozumie zagro\u017cenia mog\u0105ce p\u0142yn\u0105\u0107 z uzale\u017cnienia od internetu.\r\n- wie, \u017ce r\u00f3\u017cne grupy istniej\u0105ce w otoczeniu medialnym maj\u0105 sw\u00f3j specyficzny charakter, zasady funkcjonowania oraz dynamik\u0119;\r\nnp. wskazuje r\u00f3\u017cnice pomi\u0119dzy spo\u0142eczno\u015bciami on-line os\u00f3b, kt\u00f3re si\u0119 nigdy nie spotka\u0142y, a tymi, kt\u00f3re znaj\u0105 si\u0119 np. z pracy.\r\n- umie wykorzystywa\u0107 spo\u0142eczno\u015bciowy potencja\u0142 sieci dla realizacji w\u0142asnych cel\u00f3w;\r\nnp. potrafi w zale\u017cno\u015bci od potrzeby znale\u017a\u0107 po\u017c\u0105dany produkt lub us\u0142ug\u0119 i pozna\u0107 opinie innych u\u017cytkownik\u00f3w na jej temat.",
-            "competence": 6,
-            "level": 8
-        }
-    },
-    {
-        "pk": 54,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- umie zarz\u0105dza\u0107 infrastruktur\u0105 informatyczn\u0105. Posiada odpowiednie umiej\u0119tno\u015bci techniczne pozwalaj\u0105ce na dob\u00f3r specyficznych narz\u0119dzi i technologii do realizacji okre\u015blonych zada\u0144;\r\nnp. potrafi od podstaw stworzy\u0107 i skutecznie pozycjonowa\u0107 stron\u0119 internetow\u0105 lub portal.\r\n- rozumie procesy powstawania grup i budowania sieci spo\u0142ecznych, umie nimi zarz\u0105dza\u0107.",
-            "competence": 6,
-            "level": 9
-        }
-    },
-    {
-        "pk": 82,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- wie, \u017ce postacie obserwowane w mediach, ukazywane na ekranie telewizyjnym mog\u0105 by\u0107 fikcyjne;\r\nnp. wie, \u017ce postacie z bajek telewizyjnych tj. Gumisie, Kaczor Donald nie istniej\u0105 w rzeczywisto\u015bci, a s\u0105 jedynie wymys\u0142em cz\u0142owieka.\r\n- rozumie r\u00f3\u017cnic\u0119 pomi\u0119dzy bezpo\u015bredni\u0105 rozmow\u0105 a komunikacj\u0105 przez media;\r\nnp. wie, \u017ce podczas rozmowy telefonicznej s\u0142yszymy jedynie g\u0142os rozm\u00f3wcy, ale mo\u017ce on pozostawa\u0107 daleko od nas.\r\n- wie, \u017ce s\u0105 r\u00f3\u017cne sposoby zapisywania i przekazywania s\u0142\u00f3w, obraz\u00f3w i d\u017awi\u0119k\u00f3w, \u017ce mo\u017cna przekazywa\u0107 t\u0119 sam\u0105 tre\u015b\u0107 za pomoc\u0105 r\u00f3\u017cnych urz\u0105dze\u0144;\r\nnp. wie, \u017ce mo\u017cna nagra\u0107 i odtwarza\u0107 odg\u0142osy przyrody i w\u0142asnej mowy, rysowa\u0107, a potem zeskanowa\u0107 rysunek i ogl\u0105da\u0107 go na ekranie komputera, telewizora lub telefonu.\r\n- znai rozr\u00f3\u017cnia r\u00f3\u017cnorakie urz\u0105dzenia s\u0142u\u017c\u0105ce do przekazywania informacji;\r\nnp. umie wskazywa\u0107, podawa\u0107 nazwy oraz opisywa\u0107 w\u0142asnymi s\u0142owami, do czego s\u0142u\u017c\u0105 radio, telewizja, komputer przy\u0142\u0105czony do internetu, telefon kom\u00f3rkowy.",
-            "competence": 10,
-            "level": 1
-        }
-    },
-    {
-        "pk": 83,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- wie, \u017ce same przekazy audiowizualne, nawet prezentuj\u0105ce realnie istniej\u0105ce postacie, r\u00f3\u017cni\u0105 si\u0119 od spotkania w rzeczywistym \u015bwiecie;\r\nnp. postacie obserwowane w telewizji, na ekranie kinowym lub komputera mog\u0105 wygl\u0105da\u0107 odmiennie, kiedy spotkamy je osobi\u015bcie.\r\n- umie rozr\u00f3\u017cnia\u0107 pomi\u0119dzy potocznym j\u0119zykiem, kt\u00f3rym m\u00f3wimy do rodzic\u00f3w i r\u00f3wie\u015bnik\u00f3w, a s\u0142owami p\u0142yn\u0105cymi z telewizji;\r\nnp. wie, czym r\u00f3\u017cni si\u0119 j\u0119zyk ogl\u0105danej bajki czy transmisji sportowej od codziennej rozmowy.\r\n- zna r\u00f3\u017cne formy przekaz\u00f3w audialnych i audiowizualnych, potrafi wskazywa\u0107 na r\u00f3\u017cnice mi\u0119dzy nimi oraz sposobem ich odbioru;\r\nnp. potrafi wskaza\u0107, czym r\u00f3\u017cni si\u0119 bajka na DVD, emitowana w telewizji, nagrana w formie s\u0142uchowiska na audiobooku, drukowana w formie ksi\u0105\u017cki lub wydana jako e-book.\r\n- zna r\u00f3\u017cnic\u0119 pomi\u0119dzy przekazem tekstowym, d\u017awi\u0119kowym i wideo, potrafi wskaza\u0107 na korzy\u015bci i ograniczenia w odbiorze tych przekaz\u00f3w;\r\nnp. wie, \u017ce lektura s\u0142owa drukowanego wymaga wi\u0119kszego zaanga\u017cowania uwagi ni\u017c telewizja, \u017ce druk bardziej oddzia\u0142uje na nasze my\u015bli, a telewizja na emocje; \u017ce radio pozwala wykonywa\u0107 inne czynno\u015bci i najmniej anga\u017cuje nasz\u0105 uwag\u0119 po\u015br\u00f3d wy\u017cej wymienionych.",
-            "competence": 10,
-            "level": 2
-        }
-    },
-    {
-        "pk": 84,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- zna poj\u0119cie technologii analogowej i cyfrowej;\r\nnp. wie, \u017ce media cyfrowe opieraj\u0105 si\u0119 na kodowaniu przekaz\u00f3w w formie zapisu binarnego (zerojedynkowego).\r\n- umie w\u0142asnymi s\u0142owami wskaza\u0107 najprostsze r\u00f3\u017cnice mi\u0119dzy zapisami analogowymi i cyfrowymi oraz wskaza\u0107 przyk\u0142ady urz\u0105dze\u0144 do zapisu i odtwarzania w obu technologiach;\r\nnp. wie, czym r\u00f3\u017cni si\u0119 fotografia cyfrowa od wykonanej na kliszy, jaki jest proces jej powstawania, czym si\u0119 r\u00f3\u017cni\u0105 te procesy.\r\n- zna podstawowe poj\u0119cia zwi\u0105zane z j\u0119zykiem filmu oraz fotografii zar\u00f3wno w odniesieniu do medi\u00f3w analogowych, jak i cyfrowych;\r\nnp. wie, czym jest kadr, uj\u0119cie, monta\u017c, zna proces powstawania fotografii i filmu w technologii analogowej i cyfrowej.\r\n- rozumie poj\u0119cie multimedi\u00f3w jako technologii integruj\u0105cych r\u00f3\u017cne techniki przekazu;\r\nnp. wie, \u017ce \u0142\u0105cz\u0105 one d\u017awi\u0119ki, teksty drukowane, fotografie i filmy, \u017ce dzi\u0119ki technologii cyfrowej mamy wi\u0119ksz\u0105 mo\u017cliwo\u015b\u0107 nie tylko modyfikowania, ale i \u0142\u0105czenia zapisywanych dot\u0105d w odmienny spos\u00f3b przekaz\u00f3w.",
-            "competence": 10,
-            "level": 3
-        }
-    },
-    {
-        "pk": 85,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- rozumie poj\u0119cie hipertekstu oraz umie wyja\u015bni\u0107 r\u00f3\u017cnic\u0119 mi\u0119dzy hipertekstem a tekstem linearnym;\r\nnp. wie, \u017ce s\u0105 to powi\u0105zane ze sob\u0105 odsy\u0142aczami teksty elektroniczne, co u\u0142atwia tworzenie skojarze\u0144 i poznawanie wiedzy, wie, \u017ce spos\u00f3b lektury hipertekst\u00f3w jest r\u00f3\u017cny od lektury drukowanych ksi\u0105\u017cek.\r\n- umie rozr\u00f3\u017cnia\u0107 podstawowe gatunki filmowe i telewizyjne;\r\nnp. potrafi opisa\u0107 w\u0142asnymi s\u0142owami, czym charakteryzuj\u0105 si\u0119 thriller, komedia romantyczna, telenowela dokumentalna, talk show.\r\n- rozumie zjawisko konwergencji gatunk\u00f3w medialnych;\r\nnp. zdaje sobie spraw\u0119, jak tradycyjne audycje i programy telewizyjne mo\u017cna odbiera\u0107 poprzez internet w formie podcast\u00f3w i wideocast\u00f3w, transmisji strumieniowych, jakie zmiany to powoduje dla tre\u015bci przekaz\u00f3w.\r\n- dostrzega, w jaki spos\u00f3b ten sam tekst kultury medialnej mo\u017ce by\u0107 przedstawiany za pomoc\u0105 r\u00f3\u017cnych no\u015bnik\u00f3w przekazu i reklamy;\r\nnp. strony internetowe, film kinowy i DVD, gad\u017cety zwi\u0105zane z seri\u0105 wydawnicz\u0105 o Harrym Potterze.",
-            "competence": 10,
-            "level": 4
-        }
-    },
-    {
-        "pk": 86,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- zna cechy r\u00f3\u017cnicuj\u0105ce przekazu tekstowego dostosowanego do r\u00f3\u017cnych medi\u00f3w i potrafi dostosowywa\u0107 form\u0119 przekazu do medium;\r\nnp. wie, czym r\u00f3\u017cni si\u0119 dany tekst zapisany w formie linearnej, strony internetowej, e-maila, czatu, SMS-a, postu w serwisie spo\u0142eczno\u015bciowym, wsp\u00f3lnie pisanego dokumentu w sieci \u00a0(booksprint).\r\n- rozumie poj\u0119cie interfejsu w relacjach u\u017cytkownik-medium;\r\nnp. potrafi scharakteryzowa\u0107 r\u00f3\u017cnice w sposobie korzystania z tabletu i z gazety, z interfejsu graficznego (GUI) i z interfejsu tekstowego aplikacji komputerowych.\r\n- rozumie poj\u0119cie ekranu, umie opisa\u0107 jego rol\u0119 i przemiany w kulturze audiowizualnej;\r\nnp. umie rozr\u00f3\u017cni\u0107 pomi\u0119dzy odbiorem filmu w kinie, na ekranie telewizora, komputera, tabletu.",
-            "competence": 10,
-            "level": 5
-        }
-    },
-    {
-        "pk": 87,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- rozumie poj\u0119cie medialnej reprezentacji rzeczywisto\u015bci i umie wskaza\u0107 na jej rol\u0119 i ograniczenia w poznaniu;\r\nnp. potrafi scharakteryzowa\u0107 spos\u00f3b, w jaki tw\u00f3rcy medi\u00f3w konstruuj\u0105 przekazy, opisa\u0107, czym gatunkowo przekazy audiowizualne r\u00f3\u017cni\u0105 si\u0119 od rzeczywisto\u015bci poznawanej bezpo\u015brednio, dlaczego m\u00f3wimy, \u017ce s\u0105 \u201eobrazami\u201d rzeczywisto\u015bci, potrafi wyja\u015bni\u0107 zjawisko teleobecno\u015bci podmiotu poznania w kategoriach filozoficznych.\r\n- rozumie poj\u0119cie tekstu w szerokim kulturowym znaczeniu, poj\u0119cia kodowania i dekodowania, znaku, semiotyki;\r\nnp. wie, w jaki spos\u00f3b mo\u017cemy postrzega\u0107 film, rze\u017ab\u0119, architektur\u0119 jako teksty kultury z\u0142o\u017cone z okre\u015blonych znak\u00f3w i kod\u00f3w j\u0119zykowych.\r\n- rozumie poj\u0119cie new media literacies;\r\nnp. potrafi opisa\u0107 w kategoriach gatunku medialnego nie tylko przekazy audiowizualne, ale tak\u017ce sieci spo\u0142eczno\u015bciowe, gry wideo, potrafi analizowa\u0107 i scharakteryzowa\u0107 obraz \u015bwiata, kt\u00f3ry tworz\u0105 te przekazy.",
-            "competence": 10,
-            "level": 6
-        }
-    },
-    {
-        "pk": 88,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- rozumie r\u00f3\u017cnice mi\u0119dzy gatunkami medialnymi;\r\nnp. potrafi odr\u00f3\u017cni\u0107 program informacyjny, debat\u0119 w studio telewizyjnym, serial, thriller, talent show i scharakteryzowa\u0107 ich g\u0142\u00f3wne cechy.\r\n- potrafi formu\u0142owa\u0107 komunikaty informacyjne w r\u00f3\u017cnych formach, tak\u017ce za po\u015brednictwem wybranych \u015brodk\u00f3w komunikacji internetowej, takich jak np. poczta elektroniczna, czat, komunikator g\u0142osowy, Skype.",
-            "competence": 10,
-            "level": 7
-        }
-    },
-    {
-        "pk": 89,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- rozumie specyfik\u0119 poszczeg\u00f3lnych gatunk\u00f3w medialnych i innych zagadnie\u0144;\r\nnp. zwi\u0105zanych z kadrowaniem w filmie, znajomo\u015bci\u0105 form i zasad komunikowania si\u0119 w internecie, w spo\u0142eczno\u015bciach sieciowych.",
-            "competence": 10,
-            "level": 8
-        }
-    },
-    {
-        "pk": 90,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- umie tworzy\u0107 przekazy medialne (audiowizualne, multimedialne), pos\u0142uguj\u0105c si\u0119 r\u00f3\u017cnymi gatunkami dziennikarskimi i medialnymi w swobodny spos\u00f3b;\r\nnp. potrafi za\u0142o\u017cy\u0107 stron\u0119 internetow\u0105 lub bloga, przygotowa\u0107 film amatorski, zredagowa\u0107 gazet\u0119 \u015brodowiskow\u0105, biuletyn elektroniczny, pos\u0142uguj\u0105c si\u0119 swobodnie aplikacjami umo\u017cliwiaj\u0105cymi wykonanie tych zada\u0144.",
-            "competence": 10,
-            "level": 9
-        }
-    },
-    {
-        "pk": 73,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- wie, \u017ce pewne przekazy medialne mog\u0105 zach\u0119ca\u0107 nas do czego\u015b;\r\nnp. do zakupu okre\u015blonego produktu, zabawki, czy te\u017c wykonania jakiej\u015b czynno\u015bci, obejrzenia bajki w telewizji.\r\n- wie, kt\u00f3re przekazy s\u0142u\u017c\u0105 zabawie, a kt\u00f3re dotycz\u0105 powa\u017cnych spraw, informuj\u0105 o pewnych wydarzeniach;\r\nnp. umie rozr\u00f3\u017cni\u0107 pomi\u0119dzy bajk\u0105 a programem dla dzieci, w kt\u00f3rym podawane s\u0105 wiadomo\u015bci dotycz\u0105ce naszego \u017cycia.",
-            "competence": 9,
-            "level": 1
-        }
-    },
-    {
-        "pk": 74,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- znapoj\u0119cie reklamy i umie zidentyfikowa\u0107 przekazy reklamowe, kt\u00f3re go otaczaj\u0105;\r\nnp. potrafi rozpoznawa\u0107 i por\u00f3wnywa\u0107 reklamy na ulicy, w prasie, telewizji, internecie.\r\n\r\n- umie rozr\u00f3\u017cni\u0107 pomi\u0119dzy przekazami medialnymi, kt\u00f3re wywo\u0142uj\u0105 r\u00f3\u017cne emocje;\r\nnp. strach, smutek, rado\u015b\u0107.",
-            "competence": 9,
-            "level": 2
-        }
-    },
-    {
-        "pk": 75,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- wie, jakie podstawowe elementy powinna zawiera\u0107 ka\u017cda informacja, tak\u017ce medialna;\r\nnp. umie analizowa\u0107 dany przekaz wiadomo\u015bci telewizyjnych pod k\u0105tem kategorii dlaczego, kto, co, kiedy, gdzie.\r\n- rozumie r\u00f3\u017cnic\u0119 pomi\u0119dzy informacj\u0105 a opini\u0105 i umie formu\u0142owa\u0107 komunikaty zr\u00f3\u017cnicowane pod wzgl\u0119dem funkcji w mediach, tak\u017ce spo\u0142eczno\u015bciowych;\r\nnp. umie poda\u0107 informacj\u0119 o danym przedsi\u0119wzi\u0119ciu spo\u0142ecznym czy kulturalnym oraz wyrazi\u0107 swoj\u0105 opini\u0119; widzi r\u00f3\u017cnic\u0119 pomi\u0119dzy tymi dwoma rodzajami wypowiedzi medialnych.",
-            "competence": 9,
-            "level": 3
-        }
-    },
-    {
-        "pk": 76,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- umie dyskutowa\u0107, formu\u0142uj\u0105c w\u0142asne opinie w mediach spo\u0142eczno\u015bciowych przy poszanowaniu godno\u015bci dyskutant\u00f3w i koncentrowaniu si\u0119 na merytorycznej stronie przekazu;\r\nnp. zna podstawy etykiety j\u0119zykowej w komunikacji internetowej.\r\n- umie przekonywa\u0107 do swoich racji innych, uzasadniaj\u0105c i obrazuj\u0105c swoje przekonania tak\u017ce przy u\u017cyciu \u015brodk\u00f3w audiowizualnych;\r\nnp. potrafi zaprezentowa\u0107 swoje stanowisko, przedstawi\u0107 je w punktach, zilustrowa\u0107 przyk\u0142adami, pos\u0142u\u017cy\u0107 si\u0119 obrazami, statystykami przestawionymi w formie wizualnej.",
-            "competence": 9,
-            "level": 4
-        }
-    },
-    {
-        "pk": 77,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- umie tworzy\u0107 przekazy informacyjne\r\ni reklamowe;\r\nnp. inicjatyw spo\u0142ecznych, kulturalnych, w kt\u00f3rych bierze udzia\u0142.\r\n- wie, \u017ce pewne przekazy informacyjne mog\u0105 zawiera\u0107 elementy rozrywki, potrafi wskaza\u0107 przyk\u0142ady takiego po\u0142\u0105czenia w r\u00f3\u017cnych gatunkach medialnych;\r\nnp. umie wskaza\u0107, co w danym przekazie audiowizualnym jest elementem telewizyjnego show, a co ma warto\u015b\u0107 poznawcz\u0105.",
-            "competence": 9,
-            "level": 5
-        }
-    },
-    {
-        "pk": 78,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- zna zagadnienia wsp\u00f3\u0142czesnej teorii wywierania wp\u0142ywu na spo\u0142ecze\u0144stwo, obejmuj\u0105cej zar\u00f3wno reklam\u0119, jak i elementy marketingu;\r\nnp. umie wskaza\u0107 przyk\u0142ady technik stosowanych przez polityk\u00f3w, sprzedawc\u00f3w w przekazach audiowizualnych dobieranych w celu przekonania nas do swojej racji lub produktu.\r\n- rozumie poj\u0119cia infotainment i edutaintment, potrafi \u0142\u0105czy\u0107 elementy edukacji opartej na przekazach werbalnych z reprezentacjami wizualnymi, d\u017awi\u0119kowymi;\r\nnp. umie tworzy\u0107 notatki, prezentacje, kt\u00f3re zawieraj\u0105 nie tylko informacje, ale r\u00f3wnie\u017c przekazy wizualne wyra\u017caj\u0105ce okre\u015blone emocje, potrafi pos\u0142ugiwa\u0107 si\u0119 j\u0119zykiem anegdoty, humoru w prezentowaniu informacji.",
-            "competence": 9,
-            "level": 6
-        }
-    },
-    {
-        "pk": 79,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- dostrzega r\u00f3\u017cnic\u0119 pomi\u0119dzy przekazami informacyjnymi, opiniami a perswazj\u0105;\r\nnp. w reklamie, w wypowiedziach polityk\u00f3w.\r\n- rozr\u00f3\u017cnia przekaz informacyjny od rozrywkowego;\r\nnp. umie okre\u015bli\u0107, co ma warto\u015b\u0107 poznawcz\u0105 w danym przekazie, a co jest elementem, kt\u00f3ry ma budzi\u0107 emocje odbiorcy.",
-            "competence": 9,
-            "level": 7
-        }
-    },
-    {
-        "pk": 80,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- potrafi formu\u0142owa\u0107 poprawne, jasne i logiczne komunikaty informacyjne w mowie i pi\u015bmie, tak\u017ce za po\u015brednictwem\r\n- potrafi wykorzysta\u0107 r\u00f3\u017cne media do formu\u0142owania komunikat\u00f3w perswazyjnych;\r\nnp. forum internetowe.\r\n- sprawnie pos\u0142uguje si\u0119 r\u00f3\u017cnymi \u015brodkami retorycznymi w formu\u0142owanych przez siebie komunikatach. Umie odwo\u0142ywa\u0107 si\u0119 do emocji w swoim przekazie stosownie do potrzeb, wywo\u0142ywa\u0107 wzruszenie;\r\nnp. potrafi przygotowa\u0107 i wyg\u0142osi\u0107 przem\u00f3wienie.",
-            "competence": 9,
-            "level": 8
-        }
-    },
-    {
-        "pk": 81,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- potrafi formu\u0142owa\u0107 skuteczne komunikaty informacyjne w mowie i pi\u015bmie, dostosowane do specyfiki r\u00f3\u017cnych medi\u00f3w komunikacyjnych;\r\nnp. mo\u017ce swobodnie operowa\u0107 j\u0119zykiem publicystycznym, informacyjnym, urz\u0119dowym, naukowym.",
-            "competence": 9,
-            "level": 9
-        }
-    },
-    {
-        "pk": 64,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- umie wyra\u017ca\u0107 swoj\u0105 opini\u0119 o danym przekazie i uzasadni\u0107 j\u0105 swoimi s\u0142owami;\r\nnp. m\u00f3wi: \u201epodoba mi si\u0119 ta bajka, bo te postacie s\u0105 bardzo zabawne\u201d.\r\n- wie, \u017ce zar\u00f3wno s\u0142owa, jak i obrazy maj\u0105 swoje specyficzne znaczenie;\r\nnp. wie, \u017ce mo\u017cna poinformowa\u0107 kogo\u015b zar\u00f3wno za pomoc\u0105 s\u0142owa, jak i rysunku.",
-            "competence": 8,
-            "level": 1
-        }
-    },
-    {
-        "pk": 65,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- umieoceni\u0107 dany przekaz medialny w kategoriach estetycznych, uzasadniaj\u0105c swoj\u0105 opini\u0119;\r\nnp. umie powiedzie\u0107, \u017ce w tym filmie s\u0105 interesuj\u0105ce efekty specjalne, ale niezbyt interesuj\u0105ca fabu\u0142a, a bohater grany przez aktora jest osob\u0105 godn\u0105 na\u015bladowania, poniewa\u017c...\r\n- umie pos\u0142ugiwa\u0107 si\u0119 emotikonami w komunikacji SMS-owej i internetowej;\r\nnp. zna znaczenie symbolu :) czy :(\r\n- zna i rozumie r\u00f3\u017cnice pomi\u0119dzy komunikowaniem za pomoc\u0105 s\u0142\u00f3w i gest\u00f3w;\r\nnp. wie, co oznacza gest OK (uniesionego kciuka) lub V, kt\u00f3re gesty s\u0105 uznawane za obra\u017aliwe w danym kr\u0119gu kulturowym.",
-            "competence": 8,
-            "level": 2
-        }
-    },
-    {
-        "pk": 66,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- rozumie zjawisko wulgaryzacji kultury medialnej, umie ocenia\u0107 i wybiera\u0107 przekazy, kt\u00f3re temu przeciwdzia\u0142aj\u0105;\r\nnp. potrafi skrytykowa\u0107 film lub gr\u0119 komputerow\u0105 wskazuj\u0105c jej niski poziom, s\u0142u\u017c\u0105cy jedynie prostej rozrywce, brak przes\u0142ania, ub\u00f3stwo \u015brodk\u00f3w obrazowania czy warstwy d\u017awi\u0119kowej, agresywny j\u0119zyk przekazu.\r\n- umie przet\u0142umaczy\u0107 emocje wyra\u017cane emotikonami na zdania opisuj\u0105ce i uzasadniaj\u0105ce te emocje w komunikacji internetowej. Np. u\u017cywa stwierdze\u0144 takich jak: \u201eJestem smutny i rozczarowany, poniewa\u017c...\u201d zamiast skr\u00f3tu :(",
-            "competence": 8,
-            "level": 3
-        }
-    },
-    {
-        "pk": 67,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- zna podstawowe poj\u0119cia z zakresu estetyki, krytyki kulturalnej;\r\nnp. potrafi tworzy\u0107 recenzje przekaz\u00f3w medialnych, swobodnie operuj\u0105c przyk\u0142adami i por\u00f3wnaniami dzie\u0142 audiowizualnych.\r\n- wie, jakie znaczenie w komunikacji maj\u0105 poszczeg\u00f3lne gesty, mimika, postawy cia\u0142a czy odleg\u0142o\u015b\u0107 pomi\u0119dzy osobami i umie wskazywa\u0107 przyk\u0142ady w przekazach audiowizualnych;\r\nnp. potrafi okre\u015bli\u0107 na podstawie zachowa\u0144 polityk\u00f3w w studio telewizyjnym ich stosunek do omawianych kwestii.",
-            "competence": 8,
-            "level": 4
-        }
-    },
-    {
-        "pk": 68,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- rozumie i potrafi opisa\u0107 zasady zwi\u0105zane z savoir vivre w zakresie komunikowania si\u0119 z innymi osobami za po\u015brednictwem medi\u00f3w;\r\nnp. wie, o jakiej porze mo\u017cna zadzwoni\u0107 do danej osoby ze wzgl\u0119du na pe\u0142nion\u0105 funkcj\u0119, w jaki spos\u00f3b powinno si\u0119 odnosi\u0107 do go\u015bci w studio telewizyjnym itp.\r\n- umie stosowa\u0107 odpowiedni\u0105 dykcj\u0119, intonacj\u0119 g\u0142osu i mow\u0119 cia\u0142a podczas komunikacji bezpo\u015bredniej oraz pos\u0142ugiwa\u0107 si\u0119 symbolami w komunikacji wizualnej;\r\nnp. umie dobra\u0107 ilustracje do prezentacji wyra\u017caj\u0105cej r\u00f3\u017cne emocje, przekonania.",
-            "competence": 8,
-            "level": 5
-        }
-    },
-    {
-        "pk": 69,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- umiewykorzysta\u0107 podstawowe poj\u0119cia z zakresu retoryki, umie przygotowa\u0107 i wyg\u0142osi\u0107 publiczne przem\u00f3wienie na zaj\u0119ciach akademickich;\r\nnp. potrafi wyst\u0105pi\u0107 publicznie w studio radiowym i telewizyjnym.\r\n- rozumie zagadnienia z zakresu komunikowania i kultury medialnej;\r\nnp. potrafi poda\u0107 podstawowe modele komunikowania, opisa\u0107 charakter przemian kulturowych (np. j\u0119zykowych) wywo\u0142anych przez zmiany technologiczne.",
-            "competence": 8,
-            "level": 6
-        }
-    },
-    {
-        "pk": 70,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- rozumie potrzeb\u0119 i specyfik\u0119 dostosowania j\u0119zyka do komunikacji z r\u00f3\u017cnymi grupami odbiorc\u00f3w za po\u015brednictwem medi\u00f3w;\r\nnp. wie, jakie s\u0105 psychologiczne i spo\u0142eczne uwarunkowania j\u0119zyka kierowanego do dzieci, podw\u0142adnych, prze\u0142o\u017conych, urz\u0119dnik\u00f3w, dziennikarzy.\r\n- zna znaczenie mowy cia\u0142a, rozpoznaje podstawowe gesty, pozycje cia\u0142a, mimik\u0119, rozumie znaczenie odleg\u0142o\u015bci od innych os\u00f3b w komunikacji, dostosowywania intonacji g\u0142osu;\r\nnp. potrafi wskazywa\u0107 je w \u017cyciu publicznym.",
-            "competence": 8,
-            "level": 7
-        }
-    },
-    {
-        "pk": 71,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- umie tworzy\u0107 przekazy medialne w pracy i \u017cyciu osobistym.\r\n- dba o logiczny, jasny i czytelny przekaz swoich komunikat\u00f3w.\r\n- potrafi wypowiada\u0107 si\u0119 podczas audycji radiowej i telewizyjnej, dyskusji internetowej z poszanowaniem zasad dyskusji i godno\u015bci jej uczestnik\u00f3w.",
-            "competence": 8,
-            "level": 8
-        }
-    },
-    {
-        "pk": 72,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- swobodnie dostosowuje sw\u00f3j przekaz do konkretnej osoby i sytuacji komunikacyjnej.\r\n- biegle zna j\u0119zyk cia\u0142a, umie si\u0119 nim pos\u0142ugiwa\u0107 w komunikacji publicznej, w kontaktach z mediami instytucjonalnymi. Potrafi dostosowa\u0107 sw\u00f3j przekaz do sytuacji medialnej, gatunku, formatu.\r\n- swobodnie wyst\u0119puje przed kamer\u0105, ma i stosuje wiedz\u0119 z zakresu wywierania wp\u0142ywu na inne osoby za pomoc\u0105 mowy cia\u0142a i intonacji g\u0142osu.\r\n- potrafiprzekazywa\u0107 swoj\u0105 wiedz\u0119 i umiej\u0119tno\u015bci w zakresie komunikacji innym;\r\nnp. mo\u017ce prowadzi\u0107 szkolenia i warsztaty z zakresu edukacji medialnej, etykiety komunikacyjnej.",
-            "competence": 8,
-            "level": 9
-        }
-    },
-    {
-        "pk": 91,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- wie, za pomoc\u0105 jakich narz\u0119dzi medialnych mo\u017cna przygotowa\u0107 zdj\u0119cie, nagranie d\u017awi\u0119kowe, kr\u00f3tki film wideo, rysunek.\r\n- zna podstawowe poj\u0119cia zwi\u0105zane z korzystaniem z medi\u00f3w;\r\nnp. klikanie, ikona.\r\n- pr\u00f3buje samodzielnie korzysta\u0107 z medialnych narz\u0119dzi;\r\nnp. umie korzysta\u0107 z ekranu dotykowego lub pos\u0142ugiwa\u0107 si\u0119 myszk\u0105.\r\n- umie utrwala\u0107 subiektywny obraz \u015bwiata za pomoc\u0105 narz\u0119dzi medialnych;\r\n\r\nnp. fotografuje swoje zabawki.",
-            "competence": 11,
-            "level": 1
-        }
-    },
-    {
-        "pk": 92,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- umie przygotowa\u0107 z zastosowaniem prostego sprz\u0119tu: zdj\u0119cie, nagranie w\u0142asnego g\u0142osu lub d\u017awi\u0119k\u00f3w otoczenia, nagranie kr\u00f3tkiego filmu wideo, narysowa\u0107 prosty obraz przy u\u017cyciu odpowiedniego oprogramowania, napisa\u0107 kr\u00f3tki tekst w edytorze tekstu.\r\n- umie, wsp\u00f3lnie z innymi uczniami, przygotowa\u0107 prost\u0105 opowie\u015b\u0107 z wykorzystaniem komunikat\u00f3w medialnych jednego typu;\r\nnp. serii zdj\u0119\u0107, wykonanych przez r\u00f3\u017cnych uczni\u00f3w lub serii rysunk\u00f3w lub serii uj\u0119\u0107 wideo.",
-            "competence": 11,
-            "level": 2
-        }
-    },
-    {
-        "pk": 93,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- umie przygotowa\u0107 prost\u0105 fotografi\u0119 otoczenia lub obiekt\u00f3w, potrafi samodzielnie nagrywa\u0107 d\u017awi\u0119ki, umie przygotowa\u0107 kr\u00f3tki film wideo, przygotowa\u0107 prosty rysunek w odpowiednim programie, przygotowa\u0107 prost\u0105 form\u0119 graficzn\u0105 przy u\u017cyciu oprogramowania, przygotowa\u0107 kr\u00f3tki tekst w edytorze tekstu.\r\n- umie przygotowa\u0107 (przy wsparciu nauczyciela, animatora) w trakcie pracy grupowej prost\u0105 opowie\u015b\u0107 medialn\u0105 z wykorzystaniem medi\u00f3w jednego typu (elementy sk\u0142adowe przygotowuj\u0105 poszczeg\u00f3lni cz\u0142onkowie grupy), z dodaniem kr\u00f3tkich element\u00f3w tekstowych opisuj\u0105cych scen\u0119, zwiastuj\u0105cych kolejne wydarzenia.\r\n- pr\u00f3buje tworzy\u0107 w grupie proste narracje medialne z wykorzystaniem r\u00f3\u017cnorodnych komunikat\u00f3w sk\u0142adowych (<em>digital storytelling</em>).",
-            "competence": 11,
-            "level": 3
-        }
-    },
-    {
-        "pk": 94,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- umie samodzielnie przygotowa\u0107 zestaw fotografii, scen filmowych, rysunk\u00f3w, nagra\u0144, element\u00f3w graficznych na wybrany temat.- umie swobodnie \u0142\u0105czy\u0107 ze sob\u0105 r\u00f3\u017cnorodne zgromadzone tre\u015bci i tworzy\u0107 rozbudowane narracje cyfrowe na wybrany temat.\r\n- umie przygotowa\u0107 w grupie narracj\u0119 z\u0142o\u017con\u0105 z r\u00f3\u017cnorodnych medi\u00f3w na wybrany temat, planuj\u0105c wcze\u015bniej zespo\u0142owo dzia\u0142ania grupy on-line w edytorze rozszerzonych medi\u00f3w lub wymieniaj\u0105c si\u0119 informacjami na temat przygotowa\u0144 i planowania projektu na blogu lub w grupie w serwisie spo\u0142eczno\u015bciowym.\r\n- umie wsp\u00f3\u0142tworzy\u0107 w grupie proste teksty i prezentacje multimedialne przy u\u017cyciu narz\u0119dzi umo\u017cliwiaj\u0105cych sieciow\u0105 wsp\u00f3\u0142prac\u0119.",
-            "competence": 11,
-            "level": 4
-        }
-    },
-    {
-        "pk": 95,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- umie samodzielnie przygotowa\u0107 obszerny zestaw r\u00f3\u017cnorodnych tre\u015bci medialnych na wybrany temat.\r\n- umie swobodnie \u0142\u0105czy\u0107 ze sob\u0105 r\u00f3\u017cnorodne zgromadzone tre\u015bci i tworzy\u0107 na ich bazie rozbudowane narracje cyfrowe;\r\n\r\nnp. kolekcje i archiwa cyfrowe, blogi, wiki, opowiadanie hipertekstowe, serwis internetowy, gazeta on-line lub inne formy oparte na hipertekstowej architekturze.\r\n- umie zrealizowa\u0107 w grupie projekt medialny z podzia\u0142em zada\u0144 dotycz\u0105cych przygotowywania sk\u0142adowych cz\u0119\u015bci medialnych oraz montowania w ca\u0142o\u015b\u0107 zgromadzonych element\u00f3w lub ich kolekcji;\r\n\r\nnp. umie organizowa\u0107 prac\u0119 zwi\u0105zan\u0105 z przygotowaniem dzia\u0142a\u0144 grupy, w\u0142\u0105cza\u0107 si\u0119 za pomoc\u0105 narz\u0119dzi medialnych do grupowej pracy, nadzorowa\u0107 przebieg prac grupy, realizacj\u0119 kolejnych krok\u00f3w i tworzenie efekt\u00f3w projektu przy u\u017cyciu sieciowych technologii wsp\u00f3\u0142pracy, takich jak portal edukacyjny, wiki, blog, edytory tekstu lub prezentacje multimedialne wsp\u00f3\u0142tworzone on-line, serwisy spo\u0142eczno\u015bciowe.\r\n- umie wsp\u00f3\u0142tworzy\u0107 w grupie teksty i prezentacje multimedialne przy u\u017cyciu sieciowych narz\u0119dzi wsp\u00f3\u0142pracy.\r\n- umie dokumentowa\u0107 i komentowa\u0107 otoczenie i zachodz\u0105ce w nim procesy;\r\n\r\nnp. tworzy reporta\u017c tekstowy, zdj\u0119ciowy, wideo, reporta\u017c radiowy i inne formy radiowe publikowane w formie podcastu, wywiady, digitalizuje artefakty.",
-            "competence": 11,
-            "level": 5
-        }
-    },
-    {
-        "pk": 97,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- umie samodzielnie przygotowa\u0107 zestaw fotografii, scen filmowych, rysunk\u00f3w, nagra\u0144, element\u00f3w graficznych na wybrany temat.\r\n- umie swobodnie \u0142\u0105czy\u0107 ze sob\u0105 r\u00f3\u017cnorodne zgromadzone tre\u015bci i tworzy\u0107 proste narracje cyfrowe na wybrany temat.\r\n- umie przygotowa\u0107 w grupie narracj\u0119 z\u0142o\u017con\u0105 z r\u00f3\u017cnorodnych medi\u00f3w na wybrany temat, planuj\u0105c wcze\u015bniej zespo\u0142owo dzia\u0142ania grupy on-line w edytorze rozszerzonych medi\u00f3w lub wymieniaj\u0105c si\u0119 informacjami na temat przygotowa\u0144 i planowania projektu na blogu lub w grupie w serwisie spo\u0142eczno\u015bciowym.\r\n- umie wsp\u00f3\u0142tworzy\u0107 w grupie proste teksty i prezentacje multimedialne przy u\u017cyciu narz\u0119dzi umo\u017cliwiaj\u0105cych sieciow\u0105 wsp\u00f3\u0142prac\u0119.",
-            "competence": 11,
-            "level": 7
-        }
-    },
-    {
-        "pk": 98,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- umie samodzielnie przygotowa\u0107 obszerny zestaw r\u00f3\u017cnorodnych tre\u015bci medialnych na wybrany temat.\r\n- umie swobodnie \u0142\u0105czy\u0107 ze sob\u0105 r\u00f3\u017cnorodne zgromadzone tre\u015bci i tworzy\u0107 na ich bazie rozbudowane narracje cyfrowe (np. kolekcje i archiwa cyfrowe, blogi, wiki, opowiadanie hipertekstowe, serwis internetowy, gazeta on-line lub inne formy oparte na hipertekstowej architekturze).\r\n- umie zrealizowa\u0107 w grupie projekt medialny z podzia\u0142em zada\u0144 dotycz\u0105cych przygotowywania sk\u0142adowych cz\u0119\u015bci medialnych oraz montowania w ca\u0142o\u015b\u0107 zgromadzonych element\u00f3w lub ich kolekcji;\r\n\r\nnp. umie organizowa\u0107 prac\u0119 zwi\u0105zan\u0105 z przygotowaniem dzia\u0142a\u0144 grupy, w\u0142\u0105cza\u0107 si\u0119 za pomoc\u0105 narz\u0119dzi medialnych do grupowej pracy, nadzorowa\u0107 przebieg prac grupy, realizacj\u0119 kolejnych krok\u00f3w i tworzenie efekt\u00f3w projektu przy u\u017cyciu sieciowych technologii wsp\u00f3\u0142pracy, takich jak portal edukacyjny, wiki, blog, edytory tekstu lub prezentacje multimedialne wsp\u00f3\u0142tworzone on-line, serwisy spo\u0142eczno\u015bciowe.\r\n- umie wsp\u00f3\u0142tworzy\u0107 w grupie teksty i prezentacje multimedialne przy u\u017cyciu sieciowych narz\u0119dzi wsp\u00f3\u0142pracy.\r\n- umie dokumentowa\u0107 i komentowa\u0107 otoczenie i zachodz\u0105ce w nim procesy;\r\n\r\nnp. tworzy reporta\u017c tekstowy, zdj\u0119ciowy, wideo, reporta\u017c radiowy i inne formy radiowe publikowane w formie podcastu, wywiady, digitalizuje artefakty.",
-            "competence": 11,
-            "level": 8
-        }
-    },
-    {
-        "pk": 99,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- umie koordynowa\u0107 dzia\u0142anie zespo\u0142u przygotowuj\u0105cego tre\u015bci do realizowanego projektu medialnego.\r\n- umie uczy\u0107 innych, jak gromadzi\u0107 tre\u015bci i tworzy\u0107 na ich podstawie rozbudowane narracje cyfrowe.\r\n- umie nadzorowa\u0107 realizacj\u0119 projektu medialnego, dzieli\u0107 zadania dotycz\u0105ce przygotowywania sk\u0142adowych cz\u0119\u015bci medialnych oraz montowania w ca\u0142o\u015b\u0107 zgromadzonych element\u00f3w lub ich kolekcji, potrafi organizowa\u0107 prac\u0119 kilku zespo\u0142\u00f3w realizuj\u0105cych wsp\u00f3lny projekt medialny.\r\n- umie uczy\u0107 innych, jak przygotowywa\u0107 prezentacje medialne, umie tworzy\u0107 prezentacje medialne na profesjonalnym poziomie.\r\n- umie przeprowadzi\u0107 szkolenie w zakresie dokumentowania i komentowania otoczenia i zachodz\u0105cych w nim proces\u00f3w;\r\n\r\nnp. tworzenia reporta\u017cy tekstowych, zdj\u0119ciowych, wideo, reporta\u017cy radiowych i innych form radiowych publikowanych w formie podcastu, wywiad\u00f3w, digitalizowania artefakt\u00f3w.",
-            "competence": 11,
-            "level": 9
-        }
-    },
-    {
-        "pk": 100,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- wie, \u017ce proste tre\u015bci medialne mo\u017cna przetwarza\u0107.\r\n- pr\u00f3buje przy u\u017cyciu prostego oprogramowania modyfikowa\u0107 zdj\u0119cie lub grafik\u0119;\r\n\r\nnp. bawi si\u0119 programami do modyfikacji zdj\u0119\u0107 lub narz\u0119dziem do rysowania.",
-            "competence": 12,
-            "level": 1
-        }
-    },
-    {
-        "pk": 101,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- umie przetwarza\u0107 w podstawowym zakresie dost\u0119pne tre\u015bci medialne \u00a0 (zdj\u0119cia, grafik\u0119, filmy wideo, d\u017awi\u0119k) przy u\u017cyciu prostego oprogramowania do obr\u00f3bki tre\u015bci.\r\n- wie, \u017ce tre\u015bci analogowe mo\u017cna przekszta\u0142ci\u0107 na form\u0119 cyfrow\u0105, odtwarzan\u0105 za pomoc\u0105 cyfrowych urz\u0105dze\u0144.",
-            "competence": 12,
-            "level": 2
-        }
-    },
-    {
-        "pk": 102,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- umie przetwarza\u0107 dost\u0119pne i samodzielnie przygotowane tre\u015bci medialne (zdj\u0119cia, grafik\u0119, filmy wideo, d\u017awi\u0119k).\r\n- umie w grupie tworzy\u0107 cyfrowe narracje na bazie zmodyfikowanych wcze\u015bniej znalezionych lub przygotowanych przez zesp\u00f3\u0142 tre\u015bci medialnych.\r\n- potrafi skanowa\u0107 dokumenty, zdj\u0119cia i przeprowadza\u0107 ich podstawow\u0105 edycj\u0119 za pomoc\u0105 program\u00f3w do skanowania.",
-            "competence": 12,
-            "level": 3
-        }
-    },
-    {
-        "pk": 103,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- umie przetwarza\u0107 znalezione i przygotowane wcze\u015bniej rozbudowane kolekcje tre\u015bci medialnych z\u0142o\u017cone ze zdj\u0119\u0107, grafiki, film\u00f3w wideo, d\u017awi\u0119ku.\r\n- umie w grupie tworzy\u0107 rozbudowane cyfrowe narracje, filmy, hipermedialne projekty oparte na zmodyfikowanych przez cz\u0142onk\u00f3w grupy tre\u015bciach lub znalezionych, przetworzonych materia\u0142ach.\r\n- umie samodzielnie digitalizowa\u0107 tre\u015bci analogowe;\r\n\r\nnp. umie skanowa\u0107 ksi\u0105\u017cki, gazety, dokumenty, zdj\u0119cia.",
-            "competence": 12,
-            "level": 4
-        }
-    },
-    {
-        "pk": 104,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- umie na zaawansowanym poziomie modyfikowa\u0107 przygotowane i znalezione rozbudowane zasoby tre\u015bci multimedialnych i hipermedialnych.\r\n- umie w grupie tworzy\u0107 zaawansowane cyfrowe narracje, filmy, hipermedialne projekty oparte na zmodyfikowanych przez uczestnik\u00f3w grupy tre\u015bciach lub znalezionych, z\u0142o\u017conych komunikatach medialnych.\r\n- umie, dzia\u0142aj\u0105c w grupie, digitalizowa\u0107 analogowe tre\u015bci;\r\n\r\nnp. wsp\u00f3lnie z innymi realizuje projekt digitalizacyjny.",
-            "competence": 12,
-            "level": 5
-        }
-    },
-    {
-        "pk": 106,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- umie przetwarza\u0107 znalezione i przygotowane wcze\u015bniej rozbudowane kolekcje tre\u015bci medialnych z\u0142o\u017cone ze zdj\u0119\u0107, grafiki, film\u00f3w wideo, d\u017awi\u0119ku.\r\n- umie w grupie tworzy\u0107 proste cyfrowe narracje, filmy, hipermedialne projekty oparte na zmodyfikowanych przez uczestnik\u00f3w grupy tre\u015bciach lub znalezionych, przetworzonych materia\u0142ach.\r\n- umie samodzielnie digitalizowa\u0107 tre\u015bci analogowe: skanowa\u0107 ksi\u0105\u017cki, gazety, dokumenty, zdj\u0119cia.",
-            "competence": 12,
-            "level": 7
-        }
-    },
-    {
-        "pk": 107,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- umie na zaawansowanym poziomie modyfikowa\u0107 przygotowane i znalezione rozbudowane zasoby tre\u015bci multimedialnych i hipermedialnych.\r\n- umie w grupie tworzy\u0107 zaawansowane cyfrowe narracje, filmy, hipermedialne projekty oparte na zmodyfikowanych przez cz\u0142onk\u00f3w grupy tre\u015bciach lub znalezionych, z\u0142o\u017conych komunikatach medialnych.\r\n- umie, dzia\u0142aj\u0105c w grupie, digitalizowa\u0107 analogowe tre\u015bci.",
-            "competence": 12,
-            "level": 8
-        }
-    },
-    {
-        "pk": 108,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- umie rozwi\u0105zywa\u0107 problemy pojawiaj\u0105ce si\u0119 w trakcie zaawansowanego modyfikowania tre\u015bci multimedialnych i hipermedialnych.\r\n- umie przeprowadzi\u0107 warsztatowe szkolenie w zakresie modyfikacji tre\u015bci dla u\u017cytkownik\u00f3w od poziomu pocz\u0105tkuj\u0105cego do zaawansowanego.\r\n- umie koordynowa\u0107 dzia\u0142anie zespo\u0142u lub zespo\u0142\u00f3w tworz\u0105cych zaawansowane cyfrowe narracje, filmy, hipermedialne projekty oparte na zmodyfikowanych tre\u015bciach.\r\n- umie koordynowa\u0107 zaawansowane dzia\u0142ania w zakresie digitalizacji.",
-            "competence": 12,
-            "level": 9
-        }
-    },
-    {
-        "pk": 109,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- przy wsparciu osoby doros\u0142ej pokazuje grupie efekty pr\u00f3b samodzielnego tworzenia i przetwarzania komunikat\u00f3w.",
-            "competence": 13,
-            "level": 1
-        }
-    },
-    {
-        "pk": 110,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- umie zaprezentowa\u0107, z wykorzystaniem sprz\u0119tu multimedialnego (np. komputer z rzutnikiem multimedialnym), przygotowane indywidualnie lub w grupie tre\u015bci medialne.",
-            "competence": 13,
-            "level": 2
-        }
-    },
-    {
-        "pk": 111,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- umie obs\u0142ugiwa\u0107 rzutnik multimedialny lub inne narz\u0119dzie o podobnym zastosowaniu;\r\n\r\nnp. umie za jego pomoc\u0105 wy\u015bwietli\u0107 pojedyncze komunikaty \u2013 zdj\u0119cia, teksty, slajdy prezentacji multimedialnej, filmy, strony internetowe.\r\n- wie o istnieniu serwis\u00f3w internetowych, blog\u00f3w, narz\u0119dzi do kolektywnego tworzenia tre\u015bci on-line.",
-            "competence": 13,
-            "level": 3
-        }
-    },
-    {
-        "pk": 112,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- umie obs\u0142ugiwa\u0107 narz\u0119dzia do synchronicznego prezentowania tre\u015bci (prezentacje on-line w czasie rzeczywistym).\r\n- umie obs\u0142ugiwa\u0107 narz\u0119dzia do asynchronicznego prezentowania tre\u015bci (prezentacje multimedialne on-line i off-line).\r\n- umie obs\u0142ugiwa\u0107 narz\u0119dzia do prowadzenia zbiorowej komunikacji on-line z wykorzystaniem d\u017awi\u0119ku i wideo.\r\n- umie prezentowa\u0107 tre\u015bci na blogu, publikowa\u0107 za pomoc\u0105 narz\u0119dzi do kolektywnego tworzenia tre\u015bci, umie w grupie przygotowa\u0107 prezentacj\u0119 tre\u015bci za pomoc\u0105 systemu typu wiki oraz zak\u0142ada\u0107 i moderowa\u0107 dyskusje sieciowe za pomoc\u0105 listy dyskusyjnej, forum oraz serwis\u00f3w spo\u0142eczno\u015bciowych.\r\n- wie, jakie s\u0105 podstawy pracy dziennikarskiej w internecie i potrafi po wcze\u015bniejszym przygotowaniu publikowa\u0107 tre\u015bci na temat \u017cycia w spo\u0142eczno\u015bci lokalnej;\r\n\r\nnp. wie, czym jest \u201edziennikarstwo obywatelskie\u201d i pr\u00f3buje dzia\u0142a\u0107 jako dziennikarz obywatelski.\r\n- umie tworzy\u0107 proste archiwa cyfrowe z\u0142o\u017cone ze zdigitalizowanych materia\u0142\u00f3w.",
-            "competence": 13,
-            "level": 4
-        }
-    },
-    {
-        "pk": 113,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- umie obs\u0142ugiwa\u0107 systemy zarz\u0105dzania tre\u015bci\u0105, zarz\u0105dza\u0107 list\u0105 autor\u00f3w i publikowanymi tre\u015bciami, dodawa\u0107, edytowa\u0107 i usuwa\u0107 tre\u015bci przy u\u017cyciu narz\u0119dzi typu blog, sieciowy pakiet biurowy.\r\n- umie rozpowszechnia\u0107 informacje na temat w\u0142asnej lub grupowej tw\u00f3rczo\u015bci;\r\n\r\nnp. umie wykorzystywa\u0107 serwisy spo\u0142eczno\u015bciowe do tworzenia przestrzeni publikacji na okre\u015blony temat.\r\n- wie, jak funkcjonuje redakcja internetowa, potrafi wykorzysta\u0107 podstawy umiej\u0119tno\u015bci dziennikarskich do publikowania (wcze\u015bniej przygotowanych samodzielnie i/lub w grupie) bie\u017c\u0105cych informacji na temat \u017cycia spo\u0142eczno\u015bci lokalnej.\r\n- umie tworzy\u0107 rozbudowane archiwa cyfrowe z\u0142o\u017cone ze zdigitalizowanych materia\u0142\u00f3w.",
-            "competence": 13,
-            "level": 5
-        }
-    },
-    {
-        "pk": 115,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- umie obs\u0142ugiwa\u0107 narz\u0119dzia do synchronicznego prezentowania tre\u015bci (prezentacje on-line w czasie rzeczywistym).\r\n- umie obs\u0142ugiwa\u0107 narz\u0119dzia do asynchronicznego prezentowania tre\u015bci (prezentacje multimedialne on-line i off-line).\r\n- umie obs\u0142ugiwa\u0107 narz\u0119dzia do prowadzenia zbiorowej komunikacji on-line z wykorzystaniem d\u017awi\u0119ku i wideo.\r\n- umie prezentowa\u0107 tre\u015bci na blogu, publikowa\u0107 za pomoc\u0105 narz\u0119dzi do kolektywnego tworzenia tre\u015bci;\r\n\r\nnp. umie w grupie przygotowa\u0107 prezentacj\u0119 tre\u015bci za pomoc\u0105 systemu typu wiki oraz zak\u0142ada\u0107 i moderowa\u0107 dyskusje sieciowe za pomoc\u0105 listy dyskusyjnej, forum oraz serwis\u00f3w spo\u0142eczno\u015bciowych.\r\n- wie, jakie s\u0105 podstawy pracy dziennikarskiej w internecie i potrafi po wcze\u015bniejszym przygotowaniu publikowa\u0107 tre\u015bci na temat \u017cycia w spo\u0142eczno\u015bci lokalnej;\r\n\r\nnp. wie, czym jest \u201edziennikarstwo obywatelskie\u201d i pr\u00f3buje dzia\u0142a\u0107 jako dziennikarz obywatelski.\r\n- umie tworzy\u0107 proste archiwa cyfrowe z\u0142o\u017cone ze zdigitalizowanych materia\u0142\u00f3w.",
-            "competence": 13,
-            "level": 7
-        }
-    },
-    {
-        "pk": 116,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- umie obs\u0142ugiwa\u0107 systemy zarz\u0105dzania tre\u015bci\u0105, zarz\u0105dza\u0107 list\u0105 autor\u00f3w i publikowanymi tre\u015bciami, dodawa\u0107, edytowa\u0107 i usuwa\u0107 tre\u015bci przy u\u017cyciu narz\u0119dzi typu blog, sieciowy pakiet biurowy.\r\n- umie wykorzystywa\u0107 serwisy spo\u0142eczno\u015bciowe do tworzenia przestrzeni publikacji na okre\u015blony temat, umie rozpowszechnia\u0107 informacje na temat w\u0142asnej lub grupowej tw\u00f3rczo\u015bci.\r\n- wie, jak funkcjonuje redakcja internetowa, potrafi wykorzysta\u0107 podstawy umiej\u0119tno\u015bci dziennikarskich do publikowania (wcze\u015bniej przygotowanych samodzielnie i/lub w grupie) bie\u017c\u0105cych informacji na temat \u017cycia spo\u0142eczno\u015bci lokalnej.\r\n- umie tworzy\u0107 rozbudowane archiwa cyfrowe z\u0142o\u017cone ze zdigitalizowanych materia\u0142\u00f3w.",
-            "competence": 13,
-            "level": 8
-        }
-    },
-    {
-        "pk": 117,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- umie rozwi\u0105zywa\u0107 problemy zwi\u0105zane z obs\u0142ug\u0105 system\u00f3w zarz\u0105dzania tre\u015bci\u0105.\r\n- umie animowa\u0107 sieciowe spo\u0142eczno\u015bci i szkoli\u0107 na temat zarz\u0105dzania sieciowymi spo\u0142eczno\u015bciami inne osoby.\r\n- umie zorganizowa\u0107 internetow\u0105 redakcj\u0119, koordynowa\u0107 jej funkcjonowanie i aktywizowa\u0107 za jej pomoc\u0105 spo\u0142eczno\u015b\u0107 lokaln\u0105.\r\n- wie, jak stworzy\u0107 zaawansowane archiwa cyfrowe, umie przeprowadzi\u0107 szkolenie w zakresie tworzenia cyfrowych archiw\u00f3w od poziomu pocz\u0105tkuj\u0105cego do zaawansowanego.",
-            "competence": 13,
-            "level": 9
-        }
-    },
-    {
-        "pk": 136,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- umie na podstawowym poziomie rozr\u00f3\u017cni\u0107 dobro i z\u0142o w mediach i komunikacji;\r\nnp. potrafi wskaza\u0107 z\u0142e post\u0119powanie bohatera ogl\u0105danego filmu.",
-            "competence": 16,
-            "level": 1
-        }
-    },
-    {
-        "pk": 137,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- wie, \u017ce problem dobra i z\u0142a, k\u0142amstwa i prawdy dotyczy tak\u017ce medi\u00f3w i komunikacji;\r\nnp. wie, \u017ce w telewizji mo\u017cna us\u0142ysze\u0107 k\u0142amstwo albo \u017ce granie w okre\u015blone gry mo\u017ce by\u0107 z\u0142e.\r\n- wie, \u017ce zosta\u0142y ustalone okre\u015blone regu\u0142y komunikacji i korzystania z medi\u00f3w oraz \u017ce nale\u017cy si\u0119 do nich stosowa\u0107.\r\n- umie wskaza\u0107 zagro\u017cenia etyczne zwi\u0105zane z korzystaniem z medi\u00f3w;\r\nnp. umie opowiedzie\u0107 o problemie k\u0142amstwa w reklamie telewizyjnej.",
-            "competence": 16,
-            "level": 2
-        }
-    },
-    {
-        "pk": 138,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- rozumie, dlaczego normy moralne i warto\u015bci odnosz\u0105 si\u0119 tak\u017ce do medi\u00f3w i komunikacji przez media;\r\nnp. rozumie, dlaczego obra\u017canie kogo\u015b w internecie ma takie samo znaczenie jak obra\u017canie kogo\u015b twarz\u0105 w twarz.",
-            "competence": 16,
-            "level": 3
-        }
-    },
-    {
-        "pk": 139,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- umie stawia\u0107 pytania dotycz\u0105ce etycznych konsekwencji komunikacji i korzystania z medi\u00f3w w perspektywie w\u0142asnych zachowa\u0144 i do\u015bwiadcze\u0144;\r\nnp. potrafi zastanowi\u0107 si\u0119 nad konsekwencjami i moraln\u0105 ocen\u0105 propozycji radykalnych sposob\u00f3w odchudzania, kt\u00f3re publikuje na swoim blogu.\r\n- rozumie, \u017ce wyzwania etyczne w mediach i komunikacji istniej\u0105 tak\u017ce poza perspektyw\u0105 jego w\u0142asnych do\u015bwiadcze\u0144 i umie zadawa\u0107 pytania na ich temat;\r\nnp. potrafi opisa\u0107, na czym polega moralny problem kontroli aktywno\u015bci internetowych pracownika przez pracodawc\u0119 oraz zada\u0107 pytania dotycz\u0105ce natury tego problemu: granic prywatno\u015bci pracownika, wymog\u00f3w uczciwej i skutecznej pracy itp.",
-            "competence": 16,
-            "level": 4
-        }
-    },
-    {
-        "pk": 140,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- umie zdefiniowa\u0107 i zanalizowa\u0107 wyzwania etyczne w perspektywie medi\u00f3w i komunikacji niezale\u017cnie od w\u0142asnych do\u015bwiadcze\u0144 oraz potrafi znale\u017a\u0107 pomoc w ich krytycznej analizie i rozwi\u0105zywaniu;\r\nnp. potrafi krytycznie zanalizowa\u0107 etyczny problem zdrady on-line dzi\u0119ki znalezionym w internecie wypowiedziom psycholog\u00f3w, badaniom itp.\r\n- umie podj\u0105\u0107 refleksj\u0119 etyczn\u0105 nad komunikacj\u0105 i mediami z r\u00f3\u017cnych perspektyw, np. dzia\u0142alno\u015bci biznesowej, reklamy, polityki, edukacji, nauki, z punktu widzenia r\u00f3\u017cnych system\u00f3w moralnych.\r\n- rozumie problem j\u0119zyka w dyskusjach nad etyk\u0105 medi\u00f3w i komunikacji;\r\nnp. rozumie problem zdefiniowania poj\u0119cia piractwa komputerowego.\r\n- rozumie potrzeb\u0119 kszta\u0142towania swoich postaw w komunikacji i korzystaniu z medi\u00f3w w kierunku wykszta\u0142cenia w\u0142asnych zasad post\u0119powania opartych o sumienie.",
-            "competence": 16,
-            "level": 5
-        }
-    },
-    {
-        "pk": 141,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- umie wypracowa\u0107 subiektywne zasady etyczne dotycz\u0105ce komunikacji i korzystania z medi\u00f3w oraz stosowa\u0107 je na co dzie\u0144.",
-            "competence": 16,
-            "level": 6
-        }
-    },
-    {
-        "pk": 142,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- umie stawia\u0107 pytania dotycz\u0105ce etycznych konsekwencji komunikacji i korzystania z medi\u00f3w w perspektywie w\u0142asnych zachowa\u0144 i do\u015bwiadcze\u0144;\r\nnp. rozwa\u017ca: czy \u017ale zrobi\u0142em \u015bci\u0105gaj\u0105c ten plik?",
-            "competence": 16,
-            "level": 7
-        }
-    },
-    {
-        "pk": 143,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- umie zanalizowa\u0107 problemy etyczne w perspektywie medi\u00f3w i komunikacji niezale\u017cnie od w\u0142asnych do\u015bwiadcze\u0144 (na poziomie og\u00f3lnym, abstrakcyjnym) oraz potrafi znale\u017a\u0107 pomoc w ich krytycznej analizie i rozwi\u0105zywaniu;\r\nnp. zastanawia si\u0119: w jakich warunkach nielegalne \u015bci\u0105ganie plik\u00f3w z internetu mo\u017ce nie by\u0107 nieetyczne?\r\n\r\n- rozumie problem j\u0119zyka w dyskusjach nad etyk\u0105 medi\u00f3w.",
-            "competence": 16,
-            "level": 8
-        }
-    },
-    {
-        "pk": 144,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- umie zainicjowa\u0107 proces etycznej analizy medi\u00f3w i komunikacji w\u015br\u00f3d uczni\u00f3w, uczestnik\u00f3w warsztat\u00f3w itp.;\r\nnp. pyta: Czy kiedykolwiek ogl\u0105daj\u0105c \u201eWiadomo\u015bci, mieli\u015bcie poczucie, \u017ce jaki\u015b materia\u0142 nie powinien si\u0119 tam znale\u017a\u0107, poniewa\u017c by\u0142o to niestosowne albo krzywdz\u0105ce dla kogo\u015b?\r\n- umie wypracowa\u0107 subiektywne zasady etyczne dotycz\u0105ce komunikacji i korzystania z medi\u00f3w oraz stosowa\u0107 je na co dzie\u0144.",
-            "competence": 16,
-            "level": 9
-        }
-    },
-    {
-        "pk": 128,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- rozumie, \u017ce nale\u017cy stosowa\u0107 si\u0119 do ogranicze\u0144 w dost\u0119pie do tre\u015bci medi\u00f3w wprowadzonych dla jego dobra.\r\nnp. zakaz ogl\u0105dania niekt\u00f3rych program\u00f3w w telewizji",
-            "competence": 15,
-            "level": 2
-        }
-    },
-    {
-        "pk": 129,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- wie, \u017ce ma prawo dost\u0119pu do informacji i komunikacji.\r\n- rozumie, dlaczego korzystaj\u0105c z materia\u0142\u00f3w dost\u0119pnych w internecie, nale\u017cy szanowa\u0107 prac\u0119 innych;\r\nnp. rozumie, dlaczego wklejaj\u0105c do prezentacji multimedialnej obrazek \u015bci\u0105gni\u0119ty z internetu, nale\u017cy poda\u0107 jego \u017ar\u00f3d\u0142o.\r\n- umie wskaza\u0107 podstawowe warto\u015bci w przekazie medialnym;\r\nnp. wskaza\u0107, do jakich warto\u015bci odwo\u0142uje si\u0119 post\u0119powanie bohatera ogl\u0105danego filmu.\r\n- rozumie, \u017ce warto\u015bci promowane w tre\u015bci medi\u00f3w i komunikacji s\u0105 zale\u017cne od wielu czynnik\u00f3w;\r\nnp. rozumie, \u017ce reklama nie jest bezinteresownym informowaniem o produkcie, poniewa\u017c jej g\u0142\u00f3wn\u0105 funkcj\u0105 jest zach\u0119canie do kupna produktu, rozbudzanie potrzeb itp.\r\n- rozumie poj\u0119cie wolno\u015bci s\u0142owa w perspektywie medi\u00f3w i komunikacji.\r\n- rozumie potrzeb\u0119 krytycznej tolerancji i otwarto\u015bci (tak\u017ce na inne kultury) przy kontakcie z tre\u015bciami medi\u00f3w.",
-            "competence": 15,
-            "level": 3
-        }
-    },
-    {
-        "pk": 130,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- wie, jakie czynniki wp\u0142ywaj\u0105 na obecno\u015b\u0107 i kszta\u0142t okre\u015blonych warto\u015bci w mediach i komunikacji;\r\nnp. wie, \u017ce frakcja polityczna kontroluj\u0105ca media publiczne mo\u017ce mie\u0107 wp\u0142yw na warto\u015bci, jakie dominowa\u0107 b\u0119d\u0105 w przekazach tych medi\u00f3w.\r\n- umie krytycznie analizowa\u0107 warto\u015bci w tre\u015bci medi\u00f3w i komunikacji z uwzgl\u0119dnieniem tej wiedzy;\r\nnp. wiedz\u0105c o zasadach dzia\u0142ania tabloid\u00f3w, o modelu biznesowym tego gatunku medialnego, potrafi krytycznie opisa\u0107 warto\u015bci promowane na \u0142amach \u201eFaktu\u201d.\r\n- rozumie prawo do sprzeciwu lub czynnego oporu wobec tre\u015bci medialnych czy komunikacji;\r\nnp. rozumie, dlaczego mo\u017ce protestowa\u0107 przeciwko instalacji baner\u00f3w reklamowych w budynku szko\u0142y. Rozumie, \u017ce instalacja dodatku AdBlock w przegl\u0105darce wynika z jego prawa do kontrolowania tre\u015bci, kt\u00f3re odbiera.\r\n- wie o prawie dost\u0119pu do informacji, do d\u0105\u017cenia do jej uzyskania oraz ograniczeniach z tym zwi\u0105zanych;\r\nnp. zna warto\u015b\u0107 czyjej\u015b prywatno\u015bci i wie, \u017ce ogranicza ona jego prawo do dost\u0119pu do informacji. Zna poj\u0119cie informacji publicznej i wie o prawie dost\u0119pu do niej.\r\n- rozumie problem komunikowania tre\u015bci takich jak przemoc, nago\u015b\u0107, prywatno\u015b\u0107. Rozumie, \u017ce problem ten dotyczy\u0107 mo\u017ce tak\u017ce tre\u015bci o charakterze historycznym;\r\nnp. rozumie, \u017ce nale\u017cy zastanowi\u0107 si\u0119 nad form\u0105 i stylem fotografii dokumentuj\u0105cej wizyt\u0119 klasow\u0105 w Muzeum Auschwitz.\r\n- rozumie poj\u0119cie etyki dziennikarskiej i umie wskaza\u0107, jak odnosi si\u0119 ono do r\u00f3\u017cnych dostawc\u00f3w tre\u015bci.\r\n- umie przedstawi\u0107 pozytywn\u0105 interpretacj\u0119 poj\u0119cia hakowania jako dzia\u0142ania zmierzaj\u0105cego do dostosowania systemu (medium) do w\u0142asnych cel\u00f3w.",
-            "competence": 15,
-            "level": 4
-        }
-    },
-    {
-        "pk": 131,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- umie praktycznie rozpozna\u0107 wyzwania wobec etyki dziennikarskiej, obejmuj\u0105cej r\u00f3wnie\u017c innych nadawc\u00f3w tre\u015bci, z perspektywy r\u00f3\u017cnych system\u00f3w moralnych;\r\nnp. potrafi skonfrontowa\u0107 zasady etyki dziennikarskiej dotycz\u0105ce prezentowania scen przemocy z obejrzan\u0105 relacj\u0105 korespondenta wojennego.\r\n\r\n- umie odnie\u015b\u0107 problem wolno\u015bci s\u0142owa i pluralizmu medi\u00f3w do konkretnych zjawisk medialnych;\r\nnp. potrafi zanalizowa\u0107 funkcjonowanie Wikileaks w perspektywie wolno\u015bci s\u0142owa i polityki bezpiecze\u0144stwa pa\u0144stw.\r\n- umie odnie\u015b\u0107 problem dobra wsp\u00f3lnego do systemu medi\u00f3w i komunikacji z wykorzystaniem poj\u0119cia kultury (ekonomii) daru oraz poj\u0119\u0107 zwi\u0105zanych z ide\u0105 otwarto\u015bci tre\u015bci w internecie (Otwarta Nauka, Otwarte Zasoby Edukacyjne, wolne licencje itp.);\r\nnp. potrafi zanalizowa\u0107 model Wikipedii pod k\u0105tem dobra wsp\u00f3lnego, akcentuj\u0105c znaczenie licencji Creative Commons wykorzystywanej przez autor\u00f3w hase\u0142.\r\n\r\n- umie krytycznie zanalizowa\u0107 problem dobra wsp\u00f3lnego i otwarto\u015bci w perspektywie tre\u015bci medialnych;\r\nnp. potrafi wskaza\u0107 argumenty za udost\u0119pnianiem on-line wynik\u00f3w bada\u0144 naukowych. Potrafi krytycznie zanalizowa\u0107 problem abonamentu i funkcjonowania medi\u00f3w publicznych w perspektywie warto\u015bci dobra wsp\u00f3lnego.",
-            "competence": 15,
-            "level": 5
-        }
-    },
-    {
-        "pk": 133,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- wie o prawie dost\u0119pu do informacji oraz ograniczeniach z tym zwi\u0105zanych.\r\n- umie wskaza\u0107 podstawowe warto\u015bci w wybranym przekazie medialnym.\r\n- rozumie, \u017ce warto\u015bci obecne w tre\u015bci medi\u00f3w i komunikacji zale\u017c\u0105 od wielu czynnik\u00f3w.\r\n- wie, \u017ce korzystaj\u0105c z materia\u0142\u00f3w dost\u0119pnych w internecie nale\u017cy szanowa\u0107 prac\u0119 innych.\r\n- rozumie poj\u0119cie etyki dziennikarskiej.",
-            "competence": 15,
-            "level": 7
-        }
-    },
-    {
-        "pk": 134,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- wie, jakie czynniki wp\u0142ywaj\u0105 na obecno\u015b\u0107 i kszta\u0142t okre\u015blonych warto\u015bci w mediach i komunikacji.\r\n- umie krytycznie analizowa\u0107 warto\u015bci w tre\u015bci medi\u00f3w i komunikacji z uwzgl\u0119dnieniem tej wiedzy.\r\n- rozumie prawo do sprzeciwu lub czynnego oporu wobec tre\u015bci medialnych czy komunikacji.\r\n- rozumie problem komunikowania tre\u015bci takich jak przemoc, nago\u015b\u0107, prywatno\u015b\u0107 (tak\u017ce w odniesieniu do tre\u015bci o charakterze historycznym).\r\n- rozumie warto\u015b\u0107 r\u00f3wnego dost\u0119pu do informacji.\r\n- umie praktycznie rozpozna\u0107 wyzwania wobec etyki dziennikarskiej i odnie\u015b\u0107 je do innych dostawc\u00f3w tre\u015bci.",
-            "competence": 15,
-            "level": 8
-        }
-    },
-    {
-        "pk": 135,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- umie odnie\u015b\u0107 problem wolno\u015bci s\u0142owa i pluralizmu medi\u00f3w do konkretnych zjawisk medialnych.\r\n- umie odnie\u015b\u0107 problem dobra wsp\u00f3lnego do systemu medi\u00f3w i komunikacji z wykorzystaniem poj\u0119cia kultury (ekonomii) daru oraz poj\u0119\u0107 zwi\u0105zanych z ide\u0105 otwarto\u015bci tre\u015bci w internecie (Otwarta Nauka, Otwarte Zasoby Edukacyjne, wolne licencje itp.)\r\n- umie przedstawi\u0107 pozytywn\u0105 interpretacj\u0119 poj\u0119cia hakowania jako dzia\u0142ania zmierzaj\u0105cego do dostosowania systemu (medium) do w\u0142asnych cel\u00f3w.",
-            "competence": 15,
-            "level": 9
-        }
-    },
-    {
-        "pk": 146,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- wie, \u017ce ma prawo do zachowania anonimowo\u015bci i prywatno\u015bci;\r\nnp. wie, \u017ce nie musi si\u0119 zgadza\u0107 na to zrobienie sobie zdj\u0119cia przez kogo\u015b obcego. Wie, \u017ce nie musi podawa\u0107 swojego adresu domowego osobie spotkanej w internecie (i \u017ce to nie \u015bwiadczy o jej / jego z\u0142ym zachowaniu).\r\n- rozumie, \u017ce komunikacja w mediach to wci\u0105\u017c komunikacja mi\u0119dzy lud\u017ami;\r\nnp. rozumie, \u017ce po drugiej stronie ekranu siedzi inny cz\u0142owiek, kt\u00f3remu nale\u017cy si\u0119 szacunek.\r\n- rozumie, \u017ce komunikacja przez media nie mo\u017ce by\u0107 wystarczaj\u0105c\u0105 alternatyw\u0105 komunikacji interpersonalnej;\r\nnp. rozumie wady przyja\u017ani tylko przez internet.",
-            "competence": 17,
-            "level": 2
-        }
-    },
-    {
-        "pk": 147,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- wie, \u017ce prywatno\u015b\u0107 w\u0142asna i innych jest warto\u015bci\u0105;\r\nnp. wie, dlaczego nie nale\u017cy podawa\u0107 numeru telefonu znajomej osoby innym bez jej wyra\u017anej zgody.\r\n- umie stosowa\u0107 w komunikacji w internecie zasady netykiety.\r\n- rozumie postaw\u0119 krytycznej otwarto\u015bci i tolerancji w relacjach w mediach;\r\nnp. rozumie, \u017ce dyskutuj\u0105c on-line, nie zawsze ma si\u0119 racj\u0119 i czasem warto zaakceptowa\u0107 argument drugiej strony.",
-            "competence": 17,
-            "level": 3
-        }
-    },
-    {
-        "pk": 148,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- rozumie problem moralnej oceny zachowa\u0144 komunikacyjnych w mediach;\r\nnp. rozumie, \u017ce o\u015bmieszanie kogo\u015b w internecie ma tak\u0105 sam\u0105 warto\u015b\u0107 moraln\u0105 jak o\u015bmieszanie kogo\u015b w komunikacji bezpo\u015bredniej.\r\n- rozumie poj\u0119cie mowy nienawi\u015bci w internecie i potrafi je odnie\u015b\u0107 do wypowiedzi obserwowanych on-line oraz do idei wolno\u015bci s\u0142owa.\r\n- rozumie warto\u015b\u0107 wsp\u00f3\u0142pracy mi\u0119dzy u\u017cytkownikami internetu (w perspektywie zjawisk takich jak ruch open source, Wikipedia, crowdsourcing, peer-production itp.)",
-            "competence": 17,
-            "level": 4
-        }
-    },
-    {
-        "pk": 149,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- umie okre\u015bli\u0107 zasady ograniczania prawa do prywatno\u015bci w mediach;\r\nnp. umie poda\u0107 katalog warto\u015bci, wobec kt\u00f3rych prawo do prywatno\u015bci mo\u017ce by\u0107 zanegowane (np. wsp\u00f3lne bezpiecze\u0144stwo). Umie wskaza\u0107 i oceni\u0107 negatywne zjawiska ograniczania prawa do prywatno\u015bci (np. kontrola internaut\u00f3w w Chinach, problem ACTA).\r\n- potrafi krytycznie podej\u015b\u0107 do skodyfikowanych zasad netykiety.\r\n- potrafi wypracowa\u0107 w\u0142asne zasady kszta\u0142towania relacji w komunikacji przez media w oparciu o w\u0142asne do\u015bwiadczenia.",
-            "competence": 17,
-            "level": 5
-        }
-    },
-    {
-        "pk": 151,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- wie, \u017ce ma prawo do zachowania anonimowo\u015bci i prywatno\u015bci.\r\n- rozumie, \u017ce komunikacja w mediach to wci\u0105\u017c komunikacja mi\u0119dzy lud\u017ami.\r\n- wie, \u017ce nale\u017cy szanowa\u0107 prywatno\u015b\u0107 swoj\u0105 i innych.\r\n- umie stosowa\u0107 w komunikacji w internecie zasady netykiety.\r\n- rozumie postaw\u0119 krytycznej otwarto\u015bci i tolerancji w relacjach w mediach.",
-            "competence": 17,
-            "level": 7
-        }
-    },
-    {
-        "pk": 152,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- rozumie problem etycznej oceny zachowa\u0144 w komunikacji przez media.\r\n- rozumie poj\u0119cie mowy nienawi\u015bci w internecie i potrafi je odnie\u015b\u0107 do wypowiedzi obserwowanych on-line oraz do idei wolno\u015bci s\u0142owa.\r\n- rozumie warto\u015b\u0107 wsp\u00f3\u0142pracy mi\u0119dzy u\u017cytkownikami internetu (w perspektywie zjawisk takich jak ruch open source, Wikipedia, crowdsourcing, peer-production itp.)",
-            "competence": 17,
-            "level": 8
-        }
-    },
-    {
-        "pk": 153,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- potrafi krytycznie podej\u015b\u0107 do skodyfikowanych zasad netykiety.\r\n- potrafi wypracowa\u0107 w\u0142asne zasady kszta\u0142towania relacji w komunikacji przez media w oparciu o w\u0142asne do\u015bwiadczenia.",
-            "competence": 17,
-            "level": 9
-        }
-    },
-    {
-        "pk": 119,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- wie, \u017ce przepisy prawa stosuj\u0105 si\u0119 tak\u017ce do medi\u00f3w i komunikacji.\r\n- rozumie obowi\u0105zek przestrzegania prawa tak\u017ce w perspektywie medi\u00f3w i komunikacji;\r\nnp. potrafi wyja\u015bni\u0107, dlaczego kradzie\u017c w internecie ma taki sam status jak kradzie\u017c towaru ze sklepu.",
-            "competence": 14,
-            "level": 2
-        }
-    },
-    {
-        "pk": 121,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- wie, \u017ce system prawny nie zawsze odpowiednio szybko reaguje na nowe zjawiska w mediach;\r\nnp. zna poj\u0119cie stalkingu i wie, \u017ce jeszcze niedawno nie by\u0142o takiego przest\u0119pstwa w kodeksie karnym.\r\n- rozumie, \u017ce nie wszystkie zasady komunikacji i funkcjonowania w mediach musz\u0105 by\u0107 regulowane przez przepisy prawa;\r\nnp. umie wyja\u015bni\u0107 zasady i znaczenie kultury dyskusji na forach internetowych oraz pokaza\u0107, kt\u00f3re z tych zasad nie wynikaj\u0105 wprost z przepis\u00f3w prawa, a mimo to obowi\u0105zuj\u0105.",
-            "competence": 14,
-            "level": 4
-        }
-    },
-    {
-        "pk": 122,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- rozumie problem relacji mi\u0119dzy prawem stanowionym a moralno\u015bci\u0105 szczeg\u00f3lnie w odniesieniu do prawa autorskiego, prawa w\u0142asno\u015bci i prawa do prywatno\u015bci w mediach oraz rozumie problem j\u0119zyka w dyskusjach na ten temat;\r\nnp. rozumie z\u0142o\u017cono\u015b\u0107 moralnej oceny piractwa komputerowego, potrafi rozwa\u017ca\u0107, czy nielegalne korzystanie z program\u00f3w komputerowych do cel\u00f3w edukacyjnych jest etyczne, czy nie. Potrafi krytycznie zanalizowa\u0107 poj\u0119cie piractwa komputerowego.\r\n- rozumie, \u017ce normy funkcjonowania medi\u00f3w mog\u0105 by\u0107 r\u00f3\u017cne w r\u00f3\u017cnych systemach prawnych i normatywnych.\r\n- potrafi odnie\u015b\u0107 si\u0119 do tego problemu w pr\u00f3bie etycznej oceny zjawiska medialnego;\r\nnp. rozumie, \u017ce funkcjonowanie portalu Redwatch w kulturze prawnej USA jest dozwolone jako wyraz wolno\u015bci s\u0142owa, a w Polsce traktowane jako przest\u0119pstwo. Rozumie, jakie problemy rodzi zr\u00f3\u017cnicowanie system\u00f3w prawnych i normatywnych w pr\u00f3bie moralnej oceny tego zjawiska.",
-            "competence": 14,
-            "level": 5
-        }
-    },
-    {
-        "pk": 124,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- rozumie obowi\u0105zek przestrzegania prawa tak\u017ce w perspektywie medi\u00f3w i komunikacji.",
-            "competence": 14,
-            "level": 7
-        }
-    },
-    {
-        "pk": 125,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- wie, \u017ce system prawny nie zawsze odpowiednio szybko reaguje na nowe zjawiska w mediach.\r\n- rozumie, \u017ce nie wszystkie zasady komunikacji i funkcjonowania w mediach musz\u0105 by\u0107 regulowane przez przepisy prawa.\r\n- rozumie, \u017ce normy funkcjonowania medi\u00f3w mog\u0105 by\u0107 r\u00f3\u017cne w r\u00f3\u017cnych systemach prawnych i normatywnych.",
-            "competence": 14,
-            "level": 8
-        }
-    },
-    {
-        "pk": 126,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- rozumie problem relacji mi\u0119dzy prawem stanowionym a etyk\u0105, szczeg\u00f3lnie w odniesieniu do prawa autorskiego, prawa w\u0142asno\u015bci i prawa do prywatno\u015bci w mediach oraz rozumie problem j\u0119zyka w dyskusjach na ten temat.\r\n- potrafi odnie\u015b\u0107 problem r\u00f3\u017cnorodnych system\u00f3w prawnych i normatywnych do etycznej oceny zjawiska medialnego;\r\nnp. rozwa\u017ca: Czy skoro w USA nie jest zakazane propagowanie nazizmu (ze wzgl\u0119du na zasady wolno\u015bci s\u0142owa), oznacza to, \u017ce takie dzia\u0142anie w Polsce r\u00f3wnie\u017c powinno by\u0107 dozwolone?",
-            "competence": 14,
-            "level": 9
-        }
-    },
-    {
-        "pk": 181,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- umie zakomunikowa\u0107, \u017ce si\u0119 wstydzi i nie chce uczestniczy\u0107 w danej sytuacji komunikacyjnej;\r\nnp. nie chce by\u0107 nagrywane lub fotografowane, nie chce rozmawia\u0107 przez telefon.",
-            "competence": 21,
-            "level": 1
-        }
-    },
-    {
-        "pk": 182,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- wie, \u017ce pewnych informacji nie wolno udost\u0119pnia\u0107 obcym; w razie w\u0105tpliwo\u015bci pyta rodzic\u00f3w lub opiekun\u00f3w.\r\n- umie odr\u00f3\u017cni\u0107 uwiecznienie od upublicznienia.\r\n- umie sprzeciwi\u0107 si\u0119 innemu dziecku lub doros\u0142emu w kwestii publikacji swojego utworu lub zwi\u0105zanej z wizerunkiem;\r\nnp. pokazywanie filmu z jego udzia\u0142em.",
-            "competence": 21,
-            "level": 2
-        }
-    },
-    {
-        "pk": 183,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- umie wskaza\u0107 r\u00f3\u017cnice pomi\u0119dzy komunikacj\u0105 prywatn\u0105 i publiczn\u0105.",
-            "competence": 21,
-            "level": 3
-        }
-    },
-    {
-        "pk": 184,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- umie zdecydowa\u0107, czy w danej sytuacji komunikacja powinna by\u0107 prywatna czy publiczna.",
-            "competence": 21,
-            "level": 4
-        }
-    },
-    {
-        "pk": 185,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- umie poprawnie zidentyfikowa\u0107, czy dane narz\u0119dzia (np. czat na portalach spo\u0142eczno\u015bciowych) faktycznie oferuj\u0105 komunikacj\u0119 prywatn\u0105, czy tylko jej z\u0142udzenie.\r\n- umie pos\u0142u\u017cy\u0107 si\u0119 narz\u0119dziami zwi\u0119kszaj\u0105cymi prywatno\u015b\u0107,\r\nnp. rozszerzenia przegl\u0105darek, ustawienia prywatno\u015bci.\r\n- wie, do czego s\u0142u\u017c\u0105 regulaminy na stronach, z kt\u00f3rych korzysta.",
-            "competence": 21,
-            "level": 5
-        }
-    },
-    {
-        "pk": 186,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- umie p\u0142ynnie pos\u0142ugiwa\u0107 si\u0119 metodami i narz\u0119dziami ochrony prywatno\u015bci.\r\n- czyta ze zrozumieniem regulaminy stron, z kt\u00f3rych korzysta, i umie \u015bwiadomie podj\u0105\u0107 decyzje dotycz\u0105ce przyj\u0119cia lub odrzucenia ich postanowie\u0144.",
-            "competence": 21,
-            "level": 6
-        }
-    },
-    {
-        "pk": 187,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- wie, \u017ce prywatno\u015b\u0107 jest dobrem i \u017ce mamy do niej prawo.\r\n- wie, \u017ce ochrona wizerunku wymaga ochrony prywatno\u015bci.\r\n- wie, \u017ce dane prywatne mog\u0105 by\u0107 traktowane jak towar.\r\n- wie, \u017ce pewne komunikaty mog\u0105 by\u0107 przekazywane wy\u0142\u0105cznie prywatnie, a inne udost\u0119pniane publicznie.\r\n- rozumie, \u017ce bior\u0105c udzia\u0142 w komunikacji, potencjalnie odpowiada za wizerunek nie tylko sw\u00f3j, ale np. swojego pracodawcy, je\u015bli u\u017cywa np. firmowego adresu e-mail.",
-            "competence": 21,
-            "level": 7
-        }
-    },
-    {
-        "pk": 188,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- umie u\u017cywa\u0107 podstawowych narz\u0119dzi chroni\u0105cych prywatno\u015b\u0107, np. rozszerzenia do przegl\u0105darek, blokada ciasteczek.\r\n- umie precyzyjnie wskaza\u0107, kt\u00f3re, komunikaty mog\u0105 by\u0107 przekazywane wy\u0142\u0105cznie prywatnie, a kt\u00f3re udost\u0119pniane publicznie.\r\n- wie, \u017ce nawet dane anonimizowane zebrane w odpowiedniej ilo\u015bci mog\u0105 pozwoli\u0107 na naruszenie prywatno\u015bci.\r\n- wie, \u017ce jego decyzje dotycz\u0105ce prywatno\u015bci mog\u0105 r\u00f3\u017cni\u0107 si\u0119 od decyzji innych i umie to uszanowa\u0107.\r\n- umie dostosowa\u0107 sw\u00f3j wizerunek do sytuacji i roli.",
-            "competence": 21,
-            "level": 8
-        }
-    },
-    {
-        "pk": 189,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- \u015bwiadomie kreuje sw\u00f3j wizerunek on-line w r\u00f3\u017cnych kontekstach.\r\n- p\u0142ynnie pos\u0142uguje si\u0119 technikami i narz\u0119dziami ochrony prywatno\u015bci.\r\n- umie \u015bwiadomie podejmowa\u0107 decyzje dotycz\u0105ce udost\u0119pnienia b\u0105d\u017a nie danych swoich i swoich znajomych, uwzgl\u0119dniaj\u0105c ich preferencje w zakresie ochrony prywatno\u015bci i wizerunku.",
-            "competence": 21,
-            "level": 9
-        }
-    },
-    {
-        "pk": 173,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- wie, co to znaczy \u201eanonimowo\u015b\u0107\u201d.",
-            "competence": 20,
-            "level": 2
-        }
-    },
-    {
-        "pk": 174,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- wie, \u017ce z sieci mo\u017cemy korzysta\u0107 anonimowo.\r\n- umie poda\u0107 przyk\u0142ad sytuacji, w kt\u00f3rej anonimowo\u015b\u0107 jest wskazana.",
-            "competence": 20,
-            "level": 3
-        }
-    },
-    {
-        "pk": 175,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- wie, \u017ce s\u0105 specjalne narz\u0119dzia do zwi\u0119kszania anonimowo\u015bci w sieci i umie o nie spyta\u0107.\r\n- wie, \u017ce anonimowo\u015b\u0107 w sieci mo\u017ce by\u0107 pozorna i \u017ce cz\u0119sto mo\u017cliwe jest ustalenie autora danej informacji nawet je\u017celi u\u017cywa\u0142 pseudonimu.\r\n- wie, \u017ce je\u017celi ujawni w tre\u015bci komunikacji dane identyfikuj\u0105ce, sam fakt komunikowania si\u0119 anonimowo (np. przy u\u017cyciu odpowiednich narz\u0119dzi) nie wystarczy do zachowania anonimowo\u015bci.",
-            "competence": 20,
-            "level": 4
-        }
-    },
-    {
-        "pk": 176,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- umie pos\u0142u\u017cy\u0107 si\u0119 narz\u0119dziami zwi\u0119kszaj\u0105cymi anonimowo\u015b\u0107; np. TOR, anonimowe proxy, dystrybucja Linuksa TAILS.",
-            "competence": 20,
-            "level": 5
-        }
-    },
-    {
-        "pk": 177,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- \u015bwiadomie i trafnie podejmuje decyzje dotycz\u0105ce anonimowo\u015bci w r\u00f3\u017cnych sytuacjach komunikacyjnych;\r\nnp. \u015bwiadomie w pewnych sytuacjach wy\u0142\u0105cza us\u0142ugi lokalizacyjne dost\u0119pne w przegl\u0105darce.",
-            "competence": 20,
-            "level": 6
-        }
-    },
-    {
-        "pk": 178,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- wie, \u017ce z sieci mo\u017cemy korzysta\u0107 anonimowo\r\n- wie, \u017ce korzystanie anonimowe nie wyklucza mo\u017cliwo\u015bci ustalenia autora.\r\n- wie, \u017ce istniej\u0105 metody \u015bledzenia os\u00f3b w sieci bez ich wiedzy, np. ciasteczka.",
-            "competence": 20,
-            "level": 7
-        }
-    },
-    {
-        "pk": 179,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- wie, \u017ce istniej\u0105 narz\u0119dzia zwi\u0119kszaj\u0105ce anonimowo\u015b\u0107 (jak rozszerzenia do przegl\u0105darek, systemy TOR, I2P, proxy).\r\n- umie znale\u017a\u0107 i dostosowa\u0107 do swoich potrzeb ustawienia przegl\u0105darek zwi\u0119kszaj\u0105ce anonimowo\u015b\u0107.",
-            "competence": 20,
-            "level": 8
-        }
-    },
-    {
-        "pk": 180,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- biegle korzysta z narz\u0119dzi i technik zapewniaj\u0105cych anonimowo\u015b\u0107 w sieci.\r\n- umie kompleksowo zadba\u0107 o zachowanie anonimowo\u015bci, korzystaj\u0105c z kombinacji narz\u0119dzi, np. tryb prywatny, TOR, blokada ciasteczek.",
-            "competence": 20,
-            "level": 9
-        }
-    },
-    {
-        "pk": 154,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- umie zakomunikowa\u0107, \u017ce dana tre\u015b\u0107 budzi strach lub poczucie zagro\u017cenia, ale niekoniecznie umie temu zaradzi\u0107, np. celowo prze\u0142\u0105czy\u0107 kana\u0142.",
-            "competence": 18,
-            "level": 1
-        }
-    },
-    {
-        "pk": 155,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- rozumie, co to \u201esekret\u201d, \u201etajemnica\u201d i umie jej dochowa\u0107, r\u00f3wnie\u017c w sytuacji komunikacyjnej.\r\n- umie selekcjonowa\u0107 tre\u015bci, kt\u00f3re odbiera\r\nnp. poprzez wy\u0142\u0105czenie telewizora, zmian\u0119 filmu, zmian\u0119 strony.",
-            "competence": 18,
-            "level": 2
-        }
-    },
-    {
-        "pk": 156,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- wie, \u017ce pewne informacje i rodzaje komunikacji powinny by\u0107 \u201etajemnic\u0105\u201d (np. has\u0142o do poczty).\r\n- wie, \u017ce istniej\u0105 sposoby zapewnienia tej \u201etajemnicy\u201d i umie o nie spyta\u0107.\r\n- wie, \u017ce zakupy mo\u017cna zrobi\u0107 w fizycznym sklepie, jak i w sklepie internetowym czy portalu aukcyjnym; potrafi poda\u0107 przyk\u0142ady.\r\n- wie, co to spam i umie rozpozna\u0107 bardziej oczywiste jego przyk\u0142ady.",
-            "competence": 18,
-            "level": 3
-        }
-    },
-    {
-        "pk": 157,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- wie, \u017ce dane prywatne mog\u0105 by\u0107 traktowane jak towar.\r\n- umie skorzysta\u0107 z podstawowych narz\u0119dzi zapewniaj\u0105cych bezpiecze\u0144stwo komunikacji;\r\nnp. korzysta z https na stronach bank\u00f3w czy portalach spo\u0142eczno\u015bciowych.\r\n- wie, \u017ce nale\u017cy wylogowa\u0107 si\u0119 z portali po zako\u0144czeniu pracy.\r\n- wie, \u017ce s\u0105 r\u00f3\u017cne formy p\u0142atno\u015bci w internecie o r\u00f3\u017cnym poziomie bezpiecze\u0144stwa.\r\n- zna podstawowe zasady bezpiecze\u0144stwa przy zakupach on-line.",
-            "competence": 18,
-            "level": 4
-        }
-    },
-    {
-        "pk": 158,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- z du\u017c\u0105 doz\u0105 pewno\u015bci rozpoznaje spam i pr\u00f3by phishingu;\r\nnp. zwraca uwag\u0119 na to, \u017ce nie zgadza si\u0119 adres strony bankowej.\r\n- zwraca uwag\u0119 na certyfikaty;\r\nnp. nie akceptuje automatycznie ka\u017cdego napotkanego b\u0142\u0119dnego certyfikatu zg\u0142oszonego przez przegl\u0105dark\u0119.\r\n- wie, \u017ce istniej\u0105 narz\u0119dzia dodatkowo zwi\u0119kszaj\u0105ce bezpiecze\u0144stwo komunikacji i umie do nich dotrze\u0107;\r\nnp. szyfrowanie end-to-end, poczty, PGP/GPG, OTR.",
-            "competence": 18,
-            "level": 5
-        }
-    },
-    {
-        "pk": 159,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- p\u0142ynnie pos\u0142uguje si\u0119 narz\u0119dziami zwi\u0119kszaj\u0105cymi bezpiecze\u0144stwo komunikacji.\r\n- zna narz\u0119dzia szyfrowania end-to-end i umie ich u\u017cy\u0107 np. PGP/GPG, OTR.",
-            "competence": 18,
-            "level": 6
-        }
-    },
-    {
-        "pk": 160,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- umie skorzysta\u0107 z podstawowych narz\u0119dzi zapewniaj\u0105cych bezpiecze\u0144stwo transmisji (https).\r\n- wie, \u017ce nale\u017cy wylogowa\u0107 si\u0119 po zako\u0144czeniu pracy na publicznym terminalu lub w sytuacji, w kt\u00f3rej inni b\u0119d\u0105 korzysta\u0107 z tego samego komputera.\r\n- zwraca uwag\u0119 na ostrze\u017cenia o wygas\u0142ych/nieprawid\u0142owych certyfikatach, w razie w\u0105tpliwo\u015bci pyta (nie akceptuje automatycznie).\r\n- docenia wag\u0119 traktowania pewnych informacji jako tajnych, zdaje sobie spraw\u0119, \u017ce dzielenie si\u0119 has\u0142ami (nawet je\u015bli np. zwi\u0119ksza wygod\u0119) jest niedopuszczalne.\r\n- potrafi zachowa\u0107 \u201ehigien\u0119 informatyczn\u0105\u201d, np. zwraca uwag\u0119 na komunikaty pojawiaj\u0105ce si\u0119 na ekranie i nie akceptuje rzeczy, kt\u00f3rych nie rozumie \u2013 w takich sytuacjach pyta; zdaje sobie spraw\u0119 z zagro\u017ce\u0144 takich jak wirusy; potrafi korzysta\u0107 z tzw. \u201etrybu prywatnego\u201d przegl\u0105darek.",
-            "competence": 18,
-            "level": 7
-        }
-    },
-    {
-        "pk": 161,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- umie samodzielnie podj\u0105\u0107 decyzj\u0119 dotycz\u0105c\u0105 bezpiecze\u0144stwa komunikacji w danym przypadku, np. decyduje o zaakceptowaniu b\u0105d\u017a nie wygas\u0142ego/nieprawid\u0142owego certyfikatu.\r\n- zdaje sobie spraw\u0119 z zagro\u017ce\u0144 zwi\u0105zanych ze scentralizowanymi sieciami i us\u0142ugami; umie poda\u0107 przyk\u0142ady sieci scentralizowanych (np. Facebook, Google) oraz zagro\u017ce\u0144 z nimi zwi\u0105zanych (np. utrata kontroli nad komunikacj\u0105, pods\u0142uch).",
-            "competence": 18,
-            "level": 8
-        }
-    },
-    {
-        "pk": 162,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- p\u0142ynnie pos\u0142uguje si\u0119 systemami szyfrowania end-to-end (PGP/GPG, OTR).\r\n- \u015bledzi najwa\u017cniejsze doniesienia dotycz\u0105ce narusze\u0144 bezpiecze\u0144stwa i umie wdro\u017cy\u0107 rozwi\u0105zania problem\u00f3w oraz sugerowane praktyki.\r\n- podejmuje \u015bwiadome, oparte na rzetelnych przes\u0142ankach decyzje dotycz\u0105ce narz\u0119dzi, kt\u00f3rych u\u017cywa, bior\u0105c pod uwag\u0119 r\u00f3wnie\u017c przes\u0142anki pozatechniczne;\r\nnp. bierze pod uwag\u0119 to, czy wszystkie kana\u0142y komunikacji, z kt\u00f3rych korzysta, mog\u0105 by\u0107 \u0142atwo kontrolowane przez jedn\u0105 organizacj\u0119.\r\n- rozumie zalety decentralizacji i umie je uwzgl\u0119dni\u0107 w podejmowanych decyzjach.\r\n- potrafi przeprowadzi\u0107 prosty, nieformalny audyt bezpiecze\u0144stwa, wskazuj\u0105c na braki w danej sytuacji;\r\nnp. doradza szyfrowanie.",
-            "competence": 18,
-            "level": 9
-        }
-    },
-    {
-        "pk": 192,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- wie, co to znaczy \u201ecenzura\u201d.\r\n- wie, co to znaczy \u201epods\u0142uchiwa\u0107\u201d, r\u00f3wnie\u017c w kontek\u015bcie technologii i sieci;\r\nnp. wie, \u017ce kiedy pisze do kogo\u015b w internecie, czyta to te\u017c jeszcze kto\u015b inny.",
-            "competence": 22,
-            "level": 3
-        }
-    },
-    {
-        "pk": 193,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- wie, \u017ce sie\u0107 mo\u017ce by\u0107 nadzorowana.\r\n- wie, \u017ce nadz\u00f3r ten mo\u017ce mie\u0107 wiele form, w tym cenzury czy pods\u0142uchu.\r\n- wie, \u017ce nadz\u00f3r mo\u017ce nie by\u0107 zauwa\u017calny dla nadzorowanych;\r\nnp. zdaje sobie spraw\u0119, \u017ce skutkiem nadzoru mo\u017ce by\u0107 trudna do identyfikacji zmiana wynik\u00f3w wyszukiwania.",
-            "competence": 22,
-            "level": 4
-        }
-    },
-    {
-        "pk": 194,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- wie, \u017ce mog\u0105 by\u0107 r\u00f3\u017cne cele wprowadzania nadzoru i umie je wymieni\u0107;\r\nnp. ochrona dzieci w internecie; uzyskiwanie dodatkowych przychod\u00f3w przez dan\u0105 korporacj\u0119 ze sprzeda\u017cy prywatnych danych u\u017cytkownik\u00f3w.\r\n- wie, \u017ce nadz\u00f3r mo\u017ce by\u0107 legalny lub bezprawny; \u017ce mo\u017ce by\u0107 prowadzony przez organy pa\u0144stwowe (np. policj\u0119) i osoby prywatne czy korporacje;\r\n- wie, \u017ce istniej\u0105 metody obej\u015bcia / utrudnienia nadzoru, nie tylko techniczne;\r\nnp. potrafi wymieni\u0107 takie metody jak \u015bwiadome umieszczanie informacji fa\u0142szywych lub stosowanie szyfrowania nie tylko do tre\u015bci wra\u017cliwych, ale r\u00f3wnie\u017c banalnych, celem utrudnienia identyfikacji, kiedy zachodzi wa\u017cna / wra\u017cliwa komunikacja.",
-            "competence": 22,
-            "level": 5
-        }
-    },
-    {
-        "pk": 195,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- umie korzysta\u0107 z narz\u0119dzi obej\u015bcia / utrudnienia nadzoru.\r\n- \u015bwiadomie podejmuje decyzje o doborze narz\u0119dzi do konkretnych cel\u00f3w, bior\u0105c pod uwag\u0119 mo\u017cliwo\u015b\u0107 nadzoru os\u00f3b trzecich nad tymi narz\u0119dziami, oraz specyfik\u0119 tre\u015bci.",
-            "competence": 22,
-            "level": 6
-        }
-    },
-    {
-        "pk": 196,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- wie, \u017ce komunikacja w sieci mo\u017ce by\u0107 nadzorowana w spos\u00f3b niezauwa\u017calny dla korzystaj\u0105cego.\r\n- wie, \u017ce istniej\u0105 narz\u0119dzia obchodz\u0105ce nadz\u00f3r, umie znale\u017a\u0107 informacje na ich temat.\r\n- wie, \u017ce nadz\u00f3r mo\u017ce by\u0107 legalny lub bezprawny; prywatny i pa\u0144stwowy.\r\n- wie, \u017ce nadz\u00f3r mo\u017ce prowadzi\u0107 do cenzury.",
-            "competence": 22,
-            "level": 7
-        }
-    },
-    {
-        "pk": 197,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- umie skorzysta\u0107 samodzielnie z podstawowych narz\u0119dzi walki z potencjalnym nadzorem w sieci.\r\n- wie, \u017ce nadz\u00f3r nad komunikacj\u0105 w sieci jest wielopoziomowy.\r\n- umie rozpozna\u0107, kt\u00f3re kana\u0142y komunikacji s\u0105 bardziej podatne na nadz\u00f3r od innych.\r\n- umie poda\u0107 przyk\u0142ady sytuacji, w kt\u00f3rych nadz\u00f3r jest uzasadniony, i takich, w kt\u00f3rych nie jest.",
-            "competence": 22,
-            "level": 8
-        }
-    },
-    {
-        "pk": 198,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- umie aktywnie przeciwdzia\u0142a\u0107 nadzorowi w sieci, \u015bwiadomie stosuj\u0105c wiele technik w tym celu.\r\n- umie z du\u017c\u0105 doz\u0105 pewno\u015bci okre\u015bli\u0107, kt\u00f3re kana\u0142y komunikacji s\u0105 najprawdopodobniej nadzorowane i w jakich celach.",
-            "competence": 22,
-            "level": 9
-        }
-    },
-    {
-        "pk": 165,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- umie dostrzec sytuacje, w kt\u00f3rych przekroczone zostaj\u0105 granice higieny korzystania z medi\u00f3w;\r\nnp. mama za du\u017co gra w gry, kolega za du\u017co rozmawia przez telefon.\r\n- wie, \u017ce relacje przez media maj\u0105 wp\u0142yw na relacje bezpo\u015brednie, a czynno\u015bci dokonywane przez media mog\u0105 mie\u0107 bardzo realne konsekwencje (np. p\u0142atno\u015bci).",
-            "competence": 19,
-            "level": 3
-        }
-    },
-    {
-        "pk": 166,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- wie, \u017ce pewne wzorce zachowa\u0144 mog\u0105 prowadzi\u0107 do uzale\u017cnienia.\r\n- umie zidentyfikowa\u0107 niebezpieczne wzorce i ich unika\u0107.\r\n- wie, czym jest stalking (n\u0119kanie).",
-            "competence": 19,
-            "level": 4
-        }
-    },
-    {
-        "pk": 167,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- umie \u015bwiadomie kszta\u0142towa\u0107 swoje nawyki zwi\u0105zane z korzystaniem z technologii.\r\n- umie zaobserwowa\u0107 oznaki uzale\u017cnienia u siebie i u innych.\r\n- umie przewidzie\u0107 konsekwencje dzia\u0142a\u0144 w sieci, kt\u00f3re mog\u0105 spowodowa\u0107 gro\u017ane sytuacje tak\u017ce poza ni\u0105;\r\nnp. nie podaje publicznie informacji o planowanej d\u0142u\u017cszej nieobecno\u015bci w domu na portalu spo\u0142eczno\u015bciowym, na kt\u00f3rym podany jest r\u00f3wnie\u017c adres zamieszkania.\r\n- umie rozpozna\u0107 stalking (n\u0119kanie) i wie, jak si\u0119 przed nim broni\u0107.\r\n- umie zarz\u0105dza\u0107 wizerunkiem on-line; \u015bwiadomie podejmuje decyzj\u0119, na ile wizerunek on-line odzwierciedla jego prawdziw\u0105 to\u017csamo\u015b\u0107;\r\nnp. nie publikuje danych umo\u017cliwiaj\u0105cych odkrycie jego to\u017csamo\u015bci.",
-            "competence": 19,
-            "level": 5
-        }
-    },
-    {
-        "pk": 168,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- umie zareagowa\u0107 na negatywne wzorce zachowa\u0144 u innych, np. szukaj\u0105c pomocy specjalisty.\r\n- dostrzega powi\u0105zania pomi\u0119dzy swoimi dzia\u0142aniami w mediach a innymi sferami \u017cycia, umie tymi powi\u0105zaniami zarz\u0105dza\u0107.",
-            "competence": 19,
-            "level": 6
-        }
-    },
-    {
-        "pk": 169,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- wie, \u017ce pewne wzorce zachowa\u0144 mog\u0105 prowadzi\u0107 do uzale\u017cnienia.\r\n- wie, \u017ce relacje przez media maj\u0105 wp\u0142yw na relacje bezpo\u015brednie a czynno\u015bci dokonywane przez media maj\u0105 bardzo realne konsekwencje (np. p\u0142atno\u015bci).\r\n- umie przewidzie\u0107 konsekwencje dzia\u0142a\u0144 w sieci, kt\u00f3re mog\u0105 spowodowa\u0107 gro\u017ane sytuacje tak\u017ce poza ni\u0105.\r\n- wie,",
-            "competence": 19,
-            "level": 7
-        }
-    },
-    {
-        "pk": 170,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- umie zidentyfikowa\u0107 niebezpieczne wzorce zachowa\u0144 i unika\u0107 sytuacji, kt\u00f3re do nich prowadz\u0105.\r\n- umie \u015bwiadomie kszta\u0142towa\u0107 swoje nawyki zwi\u0105zane z korzystaniem z technologii.\r\n- umie zaobserwowa\u0107 oznaki uzale\u017cnienia u siebie i u innych.\r\n- zna podstawowe narz\u0119dzia i metody obrony przed zagro\u017ceniami zwi\u0105zanymi z komunikacj\u0105 przez media.",
-            "competence": 19,
-            "level": 8
-        }
-    },
-    {
-        "pk": 171,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- umie zareagowa\u0107 na negatywne wzorce zachowa\u0144, np. szukaj\u0105c pomocy specjalisty.\r\n- umie zidentyfikowa\u0107 pr\u00f3by aktywnych atak\u00f3w w \u015brodowisku medialnym (phishing targetowany) i si\u0119 przed nimi obroni\u0107.",
-            "competence": 19,
-            "level": 9
-        }
-    },
-    {
-        "pk": 199,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- wie, co znaczy da\u0107 komu\u015b s\u0142owo, um\u00f3wi\u0107 si\u0119 na co\u015b\r\nnp. gdy obieca mamie, \u017ce posprz\u0105ta zabawki w pokoju.",
-            "competence": 23,
-            "level": 1
-        }
-    },
-    {
-        "pk": 200,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- wie, czym s\u0105 zwyczajowe normy komunikacyjne i umie je zastosowa\u0107 w typowych sytuacjach;\r\nnp. wie, kiedy m\u00f3wi si\u0119 dzie\u0144 dobry, dobry wiecz\u00f3r, dzi\u0119kuj\u0119, przepraszam\r\n- wie, \u017ce prawo obowi\u0105zuje tak\u017ce w komunikacji z innymi, a naruszenie go jest karane.",
-            "competence": 23,
-            "level": 2
-        }
-    },
-    {
-        "pk": 201,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- rozumie poj\u0119cia wolno\u015bci s\u0142owa, prawa do prywatno\u015bci , ochrony dobrego imienia.\r\n- umie wskaza\u0107 przyk\u0142ady swoich praw i obowi\u0105zk\u00f3w w sferze komunikacji.\r\nnp. prawo do tajemnicy korespondencji\r\n- rozumie poj\u0119cie umowy.\r\n- wie, \u017ce korzystanie z us\u0142ug komunikacyjnych wi\u0105\u017ce si\u0119 z zawarciem umowy.",
-            "competence": 23,
-            "level": 3
-        }
-    },
-    {
-        "pk": 202,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- wie, \u017ce przed naruszeniem praw komunikacyjnych mo\u017cna si\u0119 broni\u0107 w s\u0105dzie.\r\n- wie, \u017ce istniej\u0105 regulacje prawne dotycz\u0105ce komunikacji przez media (prawo telekomunikacyjne, prawo autorskie, prawo prasowe, ochrona danych osobowych itd.)\r\n- wie, \u017ce zbiorem norm zwyczajowych w komunikacji on-line jest netykieta.",
-            "competence": 23,
-            "level": 4
-        }
-    },
-    {
-        "pk": 203,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- umie \u015bwiadomie zawrze\u0107 umow\u0119 na us\u0142ugi komunikacyjne, umie wskaza\u0107 wynikaj\u0105ce z niej swoje prawa i obowi\u0105zki.\r\n- umie egzekwowa\u0107 swoje prawa.\r\n- umie zwr\u00f3ci\u0107 si\u0119 o pomoc do organ\u00f3w regulacyjnych i rzecznik\u00f3w r\u00f3\u017cnych grup;\r\nnp. w przypadku naruszenia ochrony danych osobowych lub naruszenia praw autorskich.\r\n\r\n- umie zapisy traktatowe, konstytucyjne i ustawowe prze\u0142o\u017cy\u0107 na w\u0142asne otoczenie i dzia\u0142ania.",
-            "competence": 23,
-            "level": 5
-        }
-    },
-    {
-        "pk": 204,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- umie zinterpretowa\u0107 normy prawne i zastosowa\u0107 je w ci\u0105gle zmieniaj\u0105cym si\u0119 \u015brodowisku technologicznym.",
-            "competence": 23,
-            "level": 6
-        }
-    },
-    {
-        "pk": 205,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- wie, czym s\u0105 zwyczajowe normy komunikacyjne.\r\n- wie, \u017ce prawo obowi\u0105zuje tak\u017ce w komunikacji z innymi, a naruszenie go jest karane.\r\n- wie, \u017ce narusze\u0144 praw komunikacyjnych mo\u017ce dochodzi\u0107 w s\u0105dzie.\r\n- rozumie poj\u0119cia wolno\u015bci s\u0142owa, prawa do prywatno\u015bci (tajemnica korespondencji), ochrony dobrego imienia.\r\n- umie wskaza\u0107 przyk\u0142ady swoich praw i obowi\u0105zk\u00f3w w sferze komunikacji.\r\n- rozumie poj\u0119cie umowy.\r\n- wie, \u017ce korzystanie z us\u0142ug komunikacyjnych wi\u0105\u017ce si\u0119 z zawarciem umowy.\r\n- wie, \u017ce zbiorem norm zwyczajowych w komunikacji on-line jest netykieta.",
-            "competence": 23,
-            "level": 7
-        }
-    },
-    {
-        "pk": 206,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- umie zapisy traktatowe, konstytucyjne i ustawowe prze\u0142o\u017cy\u0107 na w\u0142asne otoczenie i dzia\u0142ania.\r\n- wie, \u017ce istniej\u0105 regulacje prawne dotycz\u0105ce komunikacji przez media (prawo telekomunikacyjne, prawo autorskie, prawo prasowe, ochrona danych osobowych itd.)",
-            "competence": 23,
-            "level": 8
-        }
-    },
-    {
-        "pk": 207,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- umie egzekwowa\u0107 swoje prawa.\r\n- umie zwr\u00f3ci\u0107 si\u0119 o pomoc do organ\u00f3w regulacyjnych i rzecznik\u00f3w r\u00f3\u017cnych grup.\r\n- umie zinterpretowa\u0107 normy prawne i zastosowa\u0107 je w ci\u0105gle zmieniaj\u0105cym si\u0119 \u015brodowisku technologicznym.",
-            "competence": 23,
-            "level": 9
-        }
-    },
-    {
-        "pk": 244,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- wie, \u017ce media \u0142\u0105cz\u0105 z lud\u017ami;\r\nnp. mo\u017ce zadzwoni\u0107 do babci.\r\n- wie, \u017ce nie nale\u017cy ura\u017ca\u0107 innych, zar\u00f3wno w kontakcie bezpo\u015brednim, jak i przez media.\r\n- umie powiadomi\u0107 rodzic\u00f3w lub opiekun\u00f3w, gdy korzystaj\u0105c z medi\u00f3w spotyka si\u0119 z nieprzyjemn\u0105 sytuacj\u0105.",
-            "competence": 28,
-            "level": 1
-        }
-    },
-    {
-        "pk": 245,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- wie, \u017ce ma prawo do anonimowo\u015bci, ale nie do bezkarno\u015bci;\r\nnp. mo\u017ce podpisa\u0107 rysunek pseudonimem i nie musi ujawnia\u0107 prawdziwego imienia.\r\n- umie sprzeciwi\u0107 si\u0119 naruszaniu norm komunikacyjnych.\r\n- wie, \u017ce ka\u017cdy ma prawo dost\u0119pu do wiedzy.",
-            "competence": 28,
-            "level": 2
-        }
-    },
-    {
-        "pk": 246,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- zna swoje prawa komunikacyjne jako dziecka, ucznia i obywatela\r\n(prawo do uczestnictwa w kulturze, wolno\u015b\u0107 s\u0142owa itd.) i wie, dlaczego s\u0105 wa\u017cne;\r\nnp. wie, \u017ce ma prawo czyta\u0107 ksi\u0105\u017cki, ma prawo komunikowa\u0107 si\u0119 z innymi.\r\n- umie dostrzec naruszenia praw, wolno\u015bci, r\u00f3wno\u015bci i prywatno\u015bci w mediach.\r\n- rozumie, \u017ce prawo ma chroni\u0107 u\u017cytkownik\u00f3w medi\u00f3w.",
-            "competence": 28,
-            "level": 3
-        }
-    },
-    {
-        "pk": 247,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- wie, jakie konkretnie prawa dziecka, cz\u0142owieka i obywatela dotycz\u0105 medi\u00f3w.\r\nnp. tejemnica korespondencji.\r\n- wie, \u017ce prawa komunikacyjne wymagaj\u0105 ochrony.\r\n- umie opisa\u0107 naruszenia praw i swob\u00f3d oraz reaguje na nie.",
-            "competence": 28,
-            "level": 4
-        }
-    },
-    {
-        "pk": 248,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- wie, jakie s\u0105 zadania regulator\u00f3w medi\u00f3w,\r\nrzecznik\u00f3w praw oraz s\u0105d\u00f3w krajowych i europejskich;\r\nnp. odr\u00f3\u017cnia rol\u0119, zadania i obszar dzia\u0142ania Europejskiego Trybuna\u0142u Sprawiedliwo\u015bci od Europejskiego Trybuna\u0142u Praw Cz\u0142owieka.\r\n- umie zwr\u00f3ci\u0107 si\u0119 o wsparcie urz\u0119du, rzecznika lub s\u0105du dla ochrony praw swoich i innych.\r\n- rozumie potrzeb\u0119 aktywnej obrony praw i swob\u00f3d komunikacyjnych.",
-            "competence": 28,
-            "level": 5
-        }
-    },
-    {
-        "pk": 249,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- umie u\u017cy\u0107 medi\u00f3w do publicznej obrony praw swoich i innych.",
-            "competence": 28,
-            "level": 6
-        }
-    },
-    {
-        "pk": 250,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- wie, \u017ce ma prawo do anonimowo\u015bci, ale nie do bezkarno\u015bci.\r\n- umie godnie si\u0119 zachowa\u0107 w sytuacjach komunikacyjnych.\r\n- rozumie, \u017ce ka\u017cdy ma prawo do nauki i dost\u0119pu do wiedzy.\r\n- zna swoje prawa komunikacyjne wynikaj\u0105ce z praw cz\u0142owieka i obywatela.",
-            "competence": 28,
-            "level": 7
-        }
-    },
-    {
-        "pk": 251,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- umie dostrzec naruszenia praw, wolno\u015bci, r\u00f3wno\u015bci i prywatno\u015bci w mediach i reaguje na nie.\r\n- rozumie rol\u0119 prawa do edukacji i do udzia\u0142u w kulturze.\r\n- wie, jakie konkretnie prawa cz\u0142owieka i obywatela dotycz\u0105 medi\u00f3w.",
-            "competence": 28,
-            "level": 8
-        }
-    },
-    {
-        "pk": 252,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- wie, jakie s\u0105 zadania regulator\u00f3w medi\u00f3w, rzecznik\u00f3w i s\u0105d\u00f3w krajowych i europejskich.\r\n- umie zwr\u00f3ci\u0107 si\u0119 o wsparcie urz\u0119du, rzecznika lub s\u0105du dla ochrony praw swoich i innych os\u00f3b.\r\n- umie u\u017cy\u0107 medi\u00f3w do publicznej obrony praw swoich i innych.\r\n- rozumie potrzeb\u0119 aktywnej obrony praw i swob\u00f3d.",
-            "competence": 28,
-            "level": 9
-        }
-    },
-    {
-        "pk": 235,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- wie, \u017ce ka\u017cde dzie\u0142o ma autora;\r\nnp. umie wskaza\u0107, \u017ce to rysunek Kasi, a ten wierszyk wymy\u015bli\u0142 Tomek.\r\n- wie, \u017ce nie powinno si\u0119 przypisywa\u0107 sobie cudzych dzie\u0142.",
-            "competence": 27,
-            "level": 1
-        }
-    },
-    {
-        "pk": 236,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- wie, \u017ce jest autorem i u\u017cytkownikiem informacji, np. kiedy rysuje czy ogl\u0105da bajki.\r\n- wie, \u017ce o publikacji decyduje autor, np. sam mo\u017ce zadecydowa\u0107 kiedy rysunek jest gotowy i kiedy pokaza\u0107 go kolegom.\r\n- wie, co to jest plagiat; np. umie wskaza\u0107, \u017ce ten wierszyk napisa\u0142 Tuwim, a nie kolega.\r\n- wie, czym jest cytat.\r\n- umie wskaza\u0107 cytat we w\u0142asnej i cudzej wypowiedzi.",
-            "competence": 27,
-            "level": 2
-        }
-    },
-    {
-        "pk": 237,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- wie, \u017ce s\u0105 r\u00f3\u017cne prawa wy\u0142\u0105czne: autorskie, patentowe, do znak\u00f3w towarowych.\r\n- wie, co to jest\r\ndozwolony u\u017cytek osobisty i publiczny: np. biblioteka, prawo do czytania, prawo do kopiowania informacji.\r\n- umie poprawnie cytowa\u0107 i oznacza\u0107 autorstwo\r\n- umie opisa\u0107 przyk\u0142ad dzie\u0142a zale\u017cnego:\r\nnp. t\u0142umaczenia.",
-            "competence": 27,
-            "level": 3
-        }
-    },
-    {
-        "pk": 238,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- potrafi rozr\u00f3\u017cni\u0107 r\u00f3\u017cne rodzaje praw wy\u0142\u0105cznych i umie wskaza\u0107, jakiego rodzaju prawo dotyczy danej sytuacji.\r\n- rozumie, \u017ce prawa wy\u0142\u0105czne ograniczaj\u0105 wolno\u015b\u0107 u\u017cytkownik\u00f3w.\r\n- wie, czym jest licencja.\r\n- rozumie i umie stosowa\u0107 prawa osobiste autora: prawo do oznaczenia autorstwa i zachowania integralno\u015bci dzie\u0142a.\r\n- wie, \u017ce prawa wy\u0142\u0105czne s\u0105 ograniczone w czasie.\r\n- wie, czym s\u0105 i czemu s\u0142u\u017c\u0105 wolne licencje.\r\n- wie, co to jest domena publiczna.\r\n- rozumie granice cytatu i dozwolonego u\u017cytku.",
-            "competence": 27,
-            "level": 4
-        }
-    },
-    {
-        "pk": 239,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- rozumie cele istnienia prawa autorskiego.\r\n- wie, \u017ce monopol tw\u00f3rczy jest kompromisem pomi\u0119dzy prawami u\u017cytkownika a prawami autora.\r\n- umie opisa\u0107, jak powstaj\u0105 r\u00f3\u017cne prawa wy\u0142\u0105czne i jak d\u0142ugo trwa ich ochrona;\r\nnp. wie, \u017ce dzie\u0142o uzyskuje ochron\u0119 w chwili ustalenia, a patent i znak towarowy trzeba rejestrowa\u0107.\r\n- wie, jakie s\u0105 cele organizacji zbiorowego zarz\u0105du prawami.\r\n- umie opisa\u0107 obszary stosowania monopolu autorskiego i patentowego;\r\nnp. wie, \u017ce prawo autorskie nie dotyczy dokument\u00f3w urz\u0119dowych, a ochrona patentowa odkry\u0107 naukowych, matematyki i program\u00f3w komputerowych.\r\n- umie opisa\u0107 konflikt mi\u0119dzy ochron\u0105 praw wy\u0142\u0105cznych a wolno\u015bci\u0105 dost\u0119pu do tre\u015bci.\r\n- umie stosowa\u0107 i rozumie cele wolnych licencji.\r\n- wie, czym jest copyleft.",
-            "competence": 27,
-            "level": 5
-        }
-    },
-    {
-        "pk": 240,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- umie ustali\u0107 status prawny dzie\u0142a lub rozwi\u0105zania technicznego.\r\n- rozumie konflikt mi\u0119dzy monopolem rozpowszechniania a modelem komunikowania si\u0119 w sieci.\r\n- rozumie przes\u0142anki i skutki wyboru licencji dla swoich dzie\u0142.\r\n- rozumie istot\u0119 sporu o patenty na programy, o obowi\u0105zki po\u015brednik\u00f3w oraz o prawa i wolno\u015bci prywatnego uczestnika obiegu kultury.\r\n- rozumie zasady ochrony patentowej i znak\u00f3w towarowych.\r\n- wie, czym jest ochrona baz danych.",
-            "competence": 27,
-            "level": 6
-        }
-    },
-    {
-        "pk": 241,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- wie, \u017ce o publikacji decyduje autor.\r\n- wie, co to jest plagiat.\r\n- wie, \u017ce s\u0105 r\u00f3\u017cne prawa wy\u0142\u0105czne: autorskie, patentowe, do znak\u00f3w towarowych.\r\n- umie poprawnie cytowa\u0107 i oznacza\u0107 autorstwo.",
-            "competence": 27,
-            "level": 7
-        }
-    },
-    {
-        "pk": 242,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- wie, czym jest licencja.\r\n- rozumie i umie stosowa\u0107 prawa osobiste autora: prawo do oznaczenia autorstwa i zachowania integralno\u015bci dzie\u0142a.\r\n- wie, co to jest domena publiczna.\r\n- wie, co to jest dozwolony u\u017cytek osobisty i publiczny.\r\n- wie, \u017ce prawa wy\u0142\u0105czne s\u0105 ograniczone w czasie.\r\n- wie, co to s\u0105 dzie\u0142a zale\u017cne.\r\n- umie wskaza\u0107, jaki rodzaj prawa wy\u0142\u0105cznego dotyczy danej sytuacji.\r\n- umie opisa\u0107, jak powstaj\u0105 r\u00f3\u017cne prawa wy\u0142\u0105czne i jak d\u0142ugo trwa ich ochrona.\r\n- wie, czym s\u0105 i czemu s\u0142u\u017c\u0105 wolne licencje oraz zna ich rodzaje.\r\n- umie post\u0105pi\u0107 w typowych sytuacjach zwi\u0105zanych z publikacj\u0105 w\u0142asnej i cudzej tw\u00f3rczo\u015bci.\r\n- rozumie granice cytatu i dozwolonego u\u017cytku.\r\n- rozumie, \u017ce prawa wy\u0142\u0105czne ograniczaj\u0105 wolno\u015b\u0107 u\u017cytkownik\u00f3w.",
-            "competence": 27,
-            "level": 8
-        }
-    },
-    {
-        "pk": 243,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- rozumie cele istnienia prawa autorskiego.\r\n- wie, \u017ce monopol tw\u00f3rczy jest kompromisem pomi\u0119dzy prawami u\u017cytkownika a prawami autora.\r\n- wie, jakie s\u0105 cele organizacji zbiorowego zarz\u0105du prawami.\r\n- umie opisa\u0107 konflikt mi\u0119dzy ochron\u0105 praw wy\u0142\u0105cznych a wolno\u015bci\u0105 dost\u0119pu do tre\u015bci.\r\n- umie stosowa\u0107 i rozumie cele wolnych licencji.\r\n- wie, czym jest copyleft.\r\n- umie prawid\u0142owo ustali\u0107 status prawny dzie\u0142a lub rozwi\u0105zania technicznego.\r\n- rozumie konflikt mi\u0119dzy monopolem rozpowszechniania a modelem komunikowania si\u0119 w sieci.\r\n- rozumie przes\u0142anki i skutki wyboru licencji dla swoich dzie\u0142.\r\n- rozumie istot\u0119 sporu o patenty na programy, o obowi\u0105zki po\u015brednik\u00f3w oraz o prawa i wolno\u015bci prywatnego uczestnika obiegu kultury.\r\n- rozumie zasady ochrony patentowej i znak\u00f3w towarowych.\r\n- wie, czym jest ochrona baz danych.",
-            "competence": 27,
-            "level": 9
-        }
-    },
-    {
-        "pk": 254,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- umie zg\u0142osi\u0107 doros\u0142emu problem techniczny i poprosi\u0107 o wsparcie.",
-            "competence": 29,
-            "level": 2
-        }
-    },
-    {
-        "pk": 255,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- umie opisa\u0107 r\u00f3\u017cnice mi\u0119dzy rodzajami us\u0142ug telekomunikacyjnych.\r\n- umie poda\u0107 przyk\u0142ady p\u0142atnych us\u0142ug.\r\n- wie, \u017ce operatorzy maj\u0105 obowi\u0105zki i potrafi wskaza\u0107 ich przyk\u0142ady.\r\n- wie, \u017ce nie mo\u017ce samodzielnie zawiera\u0107 um\u00f3w;\r\nnp. zak\u0142ada\u0107 kont w serwisach internetowych.\r\n- umie poprosi\u0107 opiekun\u00f3w o pomoc przy zak\u0142adaniu konta w serwisach internetowych.",
-            "competence": 29,
-            "level": 3
-        }
-    },
-    {
-        "pk": 256,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- umie opisa\u0107 rol\u0119 i zadania us\u0142ugodawcy sieciowego.\r\n- umie poda\u0107 przyk\u0142ady wzajemnych zobowi\u0105za\u0144 wynikaj\u0105cych z um\u00f3w zawartych z dostawcami us\u0142ug; np. na jaki okres zawarta jest umowa, jak j\u0105 mo\u017cna rozwi\u0105za\u0107, jakie s\u0105 standardy us\u0142ugi.",
-            "competence": 29,
-            "level": 4
-        }
-    },
-    {
-        "pk": 257,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- wie, co to jest us\u0142uga powszechna.\r\n- umie broni\u0107 swych praw, gdy operator odetnie go od us\u0142ugi lub danych;\r\nnp. skierowa\u0107 pismo do urz\u0119du.\r\n- umie oceni\u0107 i sprawdzi\u0107 jako\u015b\u0107 us\u0142ugi.\r\n- wie, \u017ce us\u0142ugi podlegaj\u0105 regulacji, umie wskaza\u0107 powo\u0142ane do tego urz\u0119dy;\r\nnp. rozr\u00f3\u017cnia zadania UKE, UOKiK, KRRiT i GIODO.",
-            "competence": 29,
-            "level": 5
-        }
-    },
-    {
-        "pk": 258,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- umie \u017c\u0105da\u0107 dostarczenia us\u0142ug powszechnych.\r\n- rozumie obowi\u0105zki po\u015brednika wynikaj\u0105ce z\r\npowiadomienia o naruszeniu regulaminu lub prawa.",
-            "competence": 29,
-            "level": 6
-        }
-    },
-    {
-        "pk": 259,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- wie, \u017ce operatorzy maj\u0105 obowi\u0105zki i potrafi wskaza\u0107 ich przyk\u0142ady.\r\n- umie poda\u0107 przyk\u0142ady wzajemnych zobowi\u0105za\u0144 wynikaj\u0105cych z um\u00f3w zawartych z dostawcami us\u0142ug.\r\n- wie, co to jest us\u0142uga powszechna.",
-            "competence": 29,
-            "level": 7
-        }
-    },
-    {
-        "pk": 260,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- wie, \u017ce us\u0142ugi podlegaj\u0105 regulacji, umie wskaza\u0107 powo\u0142ane do tego urz\u0119dy\r\n- umie broni\u0107 swych praw, gdy operator odetnie go od us\u0142ugi lub danych.\r\n- umie oceni\u0107 i sprawdzi\u0107 jako\u015b\u0107 us\u0142ugi.",
-            "competence": 29,
-            "level": 8
-        }
-    },
-    {
-        "pk": 261,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- umie \u017c\u0105da\u0107 dostarczenia us\u0142ug powszechnych.\r\n- rozumie obowi\u0105zki po\u015brednika wynikaj\u0105ce z powiadomienia o naruszeniu.",
-            "competence": 29,
-            "level": 9
-        }
-    },
-    {
-        "pk": 217,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- wie, \u017ce gazeta, audycja i portal maj\u0105 redakcj\u0119.\r\n- wie, \u017ce s\u0105 ksi\u0105\u017cki, gazety, audycje i aplikacje przeznaczone dla dzieci.",
-            "competence": 25,
-            "level": 1
-        }
-    },
-    {
-        "pk": 218,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- wie, \u017ce w mediach za tre\u015b\u0107 odpowiada redaktor.\r\n- umie rozpozna\u0107 oznaczenie programu dla dzieci i m\u0142odzie\u017cy.",
-            "competence": 25,
-            "level": 2
-        }
-    },
-    {
-        "pk": 219,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- wie, \u017ce gazety i portale s\u0105 prywatne, a radio i telewizja mog\u0105 by\u0107 prywatne lub publiczne.\r\n- wie o prawie do autoryzacji i sprostowania.\r\n- wie, \u017ce materia\u0142y reklamowe i sponsorowane musz\u0105 by\u0107 odpowiednio oznaczone.\r\n- umie rozpozna\u0107 reklam\u0119.",
-            "competence": 25,
-            "level": 3
-        }
-    },
-    {
-        "pk": 220,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- wie, \u017ce radio i telewizja s\u0105 regulowane\r\nprzez KRRiT.\r\n- umie opisa\u0107 zadania medi\u00f3w publicznych, ich misj\u0119 oraz spos\u00f3b finansowania;\r\nnp. abonament, reklamy, datki.\r\n- umie opisa\u0107 modele zarabiania pieni\u0119dzy przez media prywatne\r\nnp. reklamy, abonament, dost\u0119p na \u017c\u0105danie, datki.\r\n- umie rozpozna\u0107 lokowanie produktu.",
-            "competence": 25,
-            "level": 4
-        }
-    },
-    {
-        "pk": 221,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- wie, czym jest licencja programowa i przydzia\u0142 pasma.\r\n- umie rozpozna\u0107 ukryt\u0105 reklam\u0119 i przes\u0142anie marketingowe.\r\n- umie skorzysta\u0107 z prawa do sprostowania.\r\n- umie rozr\u00f3\u017cni\u0107 tre\u015bci informacyjne,\r\npublicystyczne i rozrywkowe.",
-            "competence": 25,
-            "level": 5
-        }
-    },
-    {
-        "pk": 222,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- umie przygotowa\u0107 komunikat medialny i wie, kt\u00f3re medium mo\u017ce lub musi go zamie\u015bci\u0107.\r\n- umie rozpozna\u0107 naruszenie obowi\u0105zk\u00f3w wydawcy lub nadawcy.\r\n- umie sprawdzi\u0107 dane rejestracyjne medium.",
-            "competence": 25,
-            "level": 6
-        }
-    },
-    {
-        "pk": 223,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- wie, \u017ce w mediach za tre\u015b\u0107 odpowiada redaktor.\r\n- umie rozpozna\u0107 oznaczenie programu dla dzieci i m\u0142odzie\u017cy.\r\n- wie, \u017ce gazety i portale s\u0105 prywatne, a radio i telewizja mog\u0105 by\u0107 prywatne lub publiczne.",
-            "competence": 25,
-            "level": 7
-        }
-    },
-    {
-        "pk": 224,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- wie, \u017ce radio i telewizja s\u0105 regulowane przez KRRiT.\r\n- wie o prawie do autoryzacji i sprostowania.\r\n- wie, \u017ce materia\u0142y reklamowe i sponsorowane musz\u0105 by\u0107 odpowiednio oznaczone.\r\n- umie rozpozna\u0107 reklam\u0119 i lokowanie produktu.\r\n- umie opisa\u0107 zadania medi\u00f3w publicznych, ich misj\u0119 oraz spos\u00f3b finansowania.\r\n- umie opisa\u0107 modele zarabiania przez media prywatne.",
-            "competence": 25,
-            "level": 8
-        }
-    },
-    {
-        "pk": 225,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- wie, czym jest licencja programowa i przydzia\u0142 pasma.\r\n- umie skorzysta\u0107 z prawa do sprostowania.\r\n- umie przygotowa\u0107 komunikat medialny i wie, kt\u00f3re medium mo\u017ce lub musi go zamie\u015bci\u0107.\r\n- umie rozpozna\u0107 naruszenie obowi\u0105zk\u00f3w wydawcy lub nadawcy.\r\n- umie sprawdzi\u0107 dane rejestracyjne medium.",
-            "competence": 25,
-            "level": 9
-        }
-    },
-    {
-        "pk": 208,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- wie, \u017ce ka\u017cdy ma prawo do korzystania z medi\u00f3w, bez wzgl\u0119du na stopie\u0144 sprawno\u015bci.\r\n- wie, \u017ce osoby niepe\u0142nosprawne maj\u0105 trudno\u015bci w korzystaniu z medi\u00f3w;\r\nnp. zdaje sobie spraw\u0119, \u017ce babcia musi nastawia\u0107 g\u0142o\u015bno telewizor, tata zak\u0142ada okulary do czytania gazety, a niewidomi nie mog\u0105 czyta\u0107 drukowanych ksi\u0105\u017cek.",
-            "competence": 24,
-            "level": 1
-        }
-    },
-    {
-        "pk": 209,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- wie, \u017ce niepe\u0142nosprawny ma r\u00f3wne prawo do wypowiedzi w mediach.\r\n- umie poda\u0107 przyk\u0142ady barier w dost\u0119pie do edukacji, informacji i kultury.\r\n- umie poda\u0107 przyk\u0142ad u\u0142atwie\u0144 dla niepe\u0142nosprawnych;\r\nnp. wie, \u017ce mo\u017cna powi\u0119kszy\u0107 litery, aby ka\u017cdy m\u00f3g\u0142 je przeczyta\u0107, do film\u00f3w mo\u017cna doda\u0107 napisy.",
-            "competence": 24,
-            "level": 2
-        }
-    },
-    {
-        "pk": 210,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- umie rozpozna\u0107 typowe bariery dost\u0119pno\u015bci w danym przekazie medialnym.\r\n- umie rozpozna\u0107 \u0142amanie praw s\u0142abszych w tre\u015bci przekazu.\r\n- umie dostrzec i opisa\u0107 bezpo\u015brednie bariery dost\u0119pno\u015bci; np. brak napis\u00f3w pod filmem.",
-            "competence": 24,
-            "level": 3
-        }
-    },
-    {
-        "pk": 211,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- wie, co to jest konwencja o prawach os\u00f3b niepe\u0142nosprawnych.\r\n- umie dostrzec i opisa\u0107 po\u015brednie bariery dost\u0119pno\u015bci; np. zbyt ma\u0142e czcionki, nieprawid\u0142owy kontrast, chaotyczny uk\u0142ad informacji.\r\n- umie reagowa\u0107 na \u0142amanie praw.",
-            "competence": 24,
-            "level": 4
-        }
-    },
-    {
-        "pk": 212,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- wie o ustawowych udogodnieniach dla niepe\u0142nosprawnych, kt\u00f3re musz\u0105 stosowa\u0107 wydawcy i nadawcy;\r\nnp. audiodeskrypcja, j\u0119zyk migowy, napisy pod filmem.\r\n- wie o istnieniu standard\u00f3w dost\u0119pno\u015bci i obowi\u0105zku ich stosowania;\r\nnp. znane mu s\u0105 <em>Wytyczne dotycz\u0105ce dost\u0119pno\u015bci tre\u015bci internetowych</em> (WCAG).\r\n- wie, \u017ce informacja przedstawiona w spos\u00f3b uniwersalny dociera do wi\u0119kszej liczby odbiorc\u00f3w, a niestosowanie standard\u00f3w dost\u0119pno\u015bci \u00a0powoduje wykluczenie cz\u0119\u015bci obywateli, np. os\u00f3b starszych.",
-            "competence": 24,
-            "level": 5
-        }
-    },
-    {
-        "pk": 213,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- umie sprawdzi\u0107 spe\u0142nienie wymog\u00f3w dost\u0119pno\u015bci;\r\nnp. korzysta z narz\u0119dzi do samodzielnego badania dost\u0119pno\u015bci.\r\n- umie skutecznie reagowa\u0107 na naruszenia wymog\u00f3w dost\u0119pno\u015bci.",
-            "competence": 24,
-            "level": 6
-        }
-    },
-    {
-        "pk": 214,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- wie, \u017ce niepe\u0142nosprawny ma r\u00f3wne prawo do wypowiedzi w mediach.\r\n- umie poda\u0107 przyk\u0142ady barier w dost\u0119pie do edukacji, informacji i kultury.",
-            "competence": 24,
-            "level": 7
-        }
-    },
-    {
-        "pk": 215,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- wie o istnieniu standard\u00f3w dost\u0119pno\u015bci.\r\n- wie, co to jest konwencja o prawach os\u00f3b niepe\u0142nosprawnych.\r\n- umie rozpozna\u0107 \u0142amanie praw s\u0142abszych w tre\u015bci przekazu.\r\n- umie dostrzec i opisa\u0107 bezpo\u015brednie i po\u015brednie bariery dost\u0119pno\u015bci.\r\n- umie reagowa\u0107 na \u0142amanie praw.",
-            "competence": 24,
-            "level": 8
-        }
-    },
-    {
-        "pk": 216,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- wie o ustawowych udogodnieniach dla niepe\u0142nosprawnych, kt\u00f3re musz\u0105 stosowa\u0107 wydawcy i nadawcy.\r\n- umie sprawdzi\u0107 spe\u0142nienie wymog\u00f3w dost\u0119pno\u015bci.\r\n- umie skutecznie reagowa\u0107 na naruszenia.",
-            "competence": 24,
-            "level": 9
-        }
-    },
-    {
-        "pk": 226,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- wie, \u017ce nie nale\u017cy m\u00f3wi\u0107 i pisa\u0107 o sobie i o rodzinie bez potrzeby;\r\nnp. nie m\u00f3wi obcym osobom, gdzie mieszka lub jaki samoch\u00f3d maj\u0105 rodzice.",
-            "competence": 26,
-            "level": 1
-        }
-    },
-    {
-        "pk": 227,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- rozumie ide\u0119 ochrony prywatno\u015bci, ochrony danych osobowych i swoje prawa do takiej ochrony.",
-            "competence": 26,
-            "level": 2
-        }
-    },
-    {
-        "pk": 228,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- wie, \u017ce komunikacja elektroniczna wi\u0105\u017ce si\u0119 z gromadzeniem i przechowywaniem informacji o u\u017cytkownikach.\r\n- umie rozpozna\u0107 sytuacje wymuszania danych osobowych.\r\n- umie odm\u00f3wi\u0107 podania danych osobowych.\r\n- umie zak\u0142ada\u0107 konta, korzystaj\u0105c z pseudonim\u00f3w.",
-            "competence": 26,
-            "level": 3
-        }
-    },
-    {
-        "pk": 229,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- umie poda\u0107 przyk\u0142ady gromadzenia i przechowywania informacji o u\u017cytkownikach;\r\nnp. billingi, dane geolokalizacyjne, emaile, wiadomo\u015bci, wpisy na forach i w mediach spo\u0142eczno\u015bciowych.\r\n- umie w praktyce chroni\u0107 prywatno\u015b\u0107 swoj\u0105 i innych.\r\n- wie o istnieniu obowi\u0105zk\u00f3w informacyjnych administrator\u00f3w danych np. wie, \u017ce mo\u017ce uzyska\u0107 informacj\u0119 na temat swoich danych przechowywanych przez w\u0142a\u015bciciela serwisu internetowego.\r\n- wie, czego dotyczy ustawa o ochronie danych osobowych.\r\n- umie opisa\u0107 obowi\u0105zki dostawc\u00f3w us\u0142ug w zakresie ochrony danych osobowych.\r\n- umie opisa\u0107 problemy zwi\u0105zane z ochron\u0105 danych;\r\nnp. bazy danych, wycieki, \u0142\u0105czenie danych z r\u00f3\u017cnych zasob\u00f3w, dane wra\u017cliwe.",
-            "competence": 26,
-            "level": 4
-        }
-    },
-    {
-        "pk": 230,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- wie, czym jest polityka prywatno\u015bci.\r\n- umie opisa\u0107 tre\u015b\u0107 ustawy o ochronie danych osobowych.\r\n- rozumie poj\u0119cia przetwarzania danych osobowych i administratora danych.\r\n- wie, co to s\u0105 dane wra\u017cliwe.\r\n- wie, co to jest GIODO i jakie s\u0105 jego zadania.",
-            "competence": 26,
-            "level": 5
-        }
-    },
-    {
-        "pk": 231,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- rozumie polityk\u0119 prywatno\u015bci firm, z kt\u00f3rych us\u0142ug korzysta.\r\n- umie stosowa\u0107 zasady ochrony we w\u0142asnych publikacjach i us\u0142ugach.\r\n- umie zwr\u00f3ci\u0107 si\u0119 do GIODO z pro\u015bb\u0105 o interwencj\u0119 lub interpretacj\u0119.\r\n- umie sprawdzi\u0107 w\u0142asne dane w zbiorach, w kt\u00f3rych s\u0105 zawarte.\r\n- umie zarejestrowa\u0107 zbi\u00f3r i sprawdzi\u0107, czy dany zbi\u00f3r jest zarejestrowany.",
-            "competence": 26,
-            "level": 6
-        }
-    },
-    {
-        "pk": 232,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- umie dba\u0107 o prywatno\u015b\u0107.\r\n- rozumie ide\u0119 ochrony danych osobowych i swoje prawa do takiej ochrony.\r\n- wie, \u017ce komunikacja elektroniczna wi\u0105\u017ce si\u0119 z gromadzeniem i przechowywaniem informacji o u\u017cytkownikach.\r\n- umie rozpozna\u0107 sytuacje wymuszania danych osobowych.\r\n- umie odm\u00f3wi\u0107 podania danych osobowych.",
-            "competence": 26,
-            "level": 7
-        }
-    },
-    {
-        "pk": 233,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- wie, co to jest polityka prywatno\u015bci.\r\n- wie, co to s\u0105 dane wra\u017cliwe.\r\n- wie, co to jest GIODO.\r\n- wie o istnieniu obowi\u0105zk\u00f3w informacyjnych administrator\u00f3w danych.\r\n- wie, co to jest powierzenie przetwarzania danych.\r\n- wie, czego dotyczy ustawa o ochronie danych osobowych.\r\n- umie opisa\u0107 obowi\u0105zki dostawc\u00f3w us\u0142ug w zakresie ochrony danych osobowych.\r\n- umie opisa\u0107 problemy zwi\u0105zane z ochron\u0105 danych.\r\n- umie w praktyce chroni\u0107 prywatno\u015b\u0107 swoj\u0105 i innych.",
-            "competence": 26,
-            "level": 8
-        }
-    },
-    {
-        "pk": 234,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- wie, jakie dane i jak d\u0142ugo gromadzi i przechowuje operator us\u0142ugi.\r\n- umie opisa\u0107 tre\u015b\u0107 ustawy o ochronie danych osobowych.\r\n- umie stosowa\u0107 zasady ochrony we w\u0142asnych publikacjach i us\u0142ugach.\r\n- umie zwr\u00f3ci\u0107 si\u0119 do GIODO z pro\u015bb\u0105 o interwencj\u0119 lub interpretacj\u0119.\r\n- umie sprawdzi\u0107 w\u0142asne dane w zbiorach, w kt\u00f3rych s\u0105 zawarte.\r\n- umie zarejestrowa\u0107 zbi\u00f3r i sprawdzi\u0107, czy dany zbi\u00f3r jest zarejestrowany.\r\n- rozumie polityk\u0119 prywatno\u015bci firm, z kt\u00f3rymi zawiera umowy.",
-            "competence": 26,
-            "level": 9
-        }
-    },
-    {
-        "pk": 262,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- wie, \u017ce s\u0105 r\u00f3\u017cne rodzaje medi\u00f3w i umie to pokaza\u0107 na przyk\u0142adach;\r\nnp. umie wymieni\u0107: pismo dla dzieci do czytania, audycja telewizyjna do ogl\u0105dania, audiobook do s\u0142uchania, gra w internecie do grania itp.\r\n- wie, \u017ce media maj\u0105 odbiorc\u00f3w / u\u017cytkownik\u00f3w.",
-            "competence": 30,
-            "level": 1
-        }
-    },
-    {
-        "pk": 263,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- wie, \u017ce media tworz\u0105 wraz z ich u\u017cytkownikami tzw. rynek medi\u00f3w.\r\n- umie nazwa\u0107 tradycyjne rodzaje medi\u00f3w: prasa, radio, telewizja.\r\n- wie i rozumie, \u017ce internet to medium innego rodzaju.",
-            "competence": 30,
-            "level": 2
-        }
-    },
-    {
-        "pk": 264,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- wie, \u017ce s\u0105 r\u00f3\u017cne typologie medi\u00f3w: np. media tradycyjne i tzw. nowe media, mass-media i media spo\u0142eczno\u015bciowe; prasa drukowana i media elektroniczne; media publiczne i media prywatne.\r\n- umie wskaza\u0107 podstawowe r\u00f3\u017cnice mi\u0119dzy tymi typami medi\u00f3w.\r\n- wie, \u017ce w obszarze medi\u00f3w dzia\u0142aj\u0105 przedsi\u0119biorstwa: kto\u015b tam pracuje i w ten spos\u00f3b zarabia na \u017cycie, kto\u015b tym zarz\u0105dza.\r\n- rozumie \u00a0zale\u017cno\u015b\u0107 mi\u0119dzy mediami i ich u\u017cytkownikami (relacja wymiany, uczestnictwa i wsp\u00f3\u0142tworzenia).",
-            "competence": 30,
-            "level": 3
-        }
-    },
-    {
-        "pk": 265,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- wie, \u017ce rynek medi\u00f3w tworz\u0105 nie tylko media i ich u\u017cytkownicy, ale te\u017c instytucje publiczne powo\u0142ane do nadzoru i kontroli rynku.\r\n- wie, \u017ce przedsi\u0119biorstwa medialne maj\u0105: w\u0142a\u015bciciela, organ zarz\u0105dczy i okre\u015blon\u0105 form\u0119 prawn\u0105; maj\u0105 te\u017c okre\u015blon\u0105 lini\u0119 redakcyjn\u0105.",
-            "competence": 30,
-            "level": 4
-        }
-    },
-    {
-        "pk": 266,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- umie rozr\u00f3\u017cni\u0107 media publiczne od medi\u00f3w prywatnych i wie, jakie s\u0105 podstawowe konsekwencje tego podzia\u0142u; np. obowi\u0105zek uzyskania koncesji lub jego brak, r\u00f3\u017cnice w formie finansowania.\r\n- wie, \u017ce na rynku medi\u00f3w wyst\u0119puje zjawisko konkurencji i koncentracji.\r\n- umie wskaza\u0107 r\u00f3\u017cnice mi\u0119dzy mediami tradycyjnymi a nowymi mediami w zakresie regulacji\r\n- rozumie, \u017ce bariery wej\u015bcia na rynek s\u0105 tak\u017ce tworzone przez regulatora, np. wie, \u017ce opr\u00f3cz wymog\u00f3w kapita\u0142owych potrzebne jest zdobycie koncesji lub rejestracja.",
-            "competence": 30,
-            "level": 5
-        }
-    },
-    {
-        "pk": 267,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- wie, czym jest pluralizm medi\u00f3w i rozumie, dlaczego nale\u017cy chroni\u0107 konkurencj\u0119 na rynku medi\u00f3w.\r\n- wie o istnieniu nieformalnej ekonomii medi\u00f3w, b\u0119d\u0105cej w du\u017cej cz\u0119\u015bci lub w ca\u0142o\u015bci poza zasi\u0119giem polityki pa\u0144stwa, jego regulacji i opodatkowania.\r\n- umie poda\u0107 przyk\u0142ady nieformalnej ekonomii medi\u00f3w; np. sie\u0107 wymiany plik\u00f3w.\r\n- wie, czym jest konsolidacja i koncentracja w\u0142asno\u015bci medi\u00f3w; rozumie ich podstawowe przyczyny i umie dostrzec efekty \u00a0(cho\u0107 nie musi zna\u0107 ich nazewnictwa; np. efekt skali, zakresu, czy synergii.\r\n- umie rozr\u00f3\u017cni\u0107: koncentracj\u0119 pionow\u0105, (wydawca gazety kupuje / tworzy radio) \u00a0od koncentracji poziomej (radio kupuje inne radio); np. wie, \u017ce Eurozet, kt\u00f3ry w 2008 r. naby\u0142 Radio J\u00f3zef to przyk\u0142ad koncentracji poziomej, a sp\u00f3\u0142ka Agora, do kt\u00f3rej nale\u017c\u0105 gazety, radio, portale internetowe i platformy blogerskie \u2013 koncentracji pionowej.\r\n- rozumie funkcjonowanie \u0142a\u0144cucha warto\u015bci w mediach i wie, \u017ce \u017caden z element\u00f3w nie pe\u0142ni w nim nadrz\u0119dnej roli (r\u00f3\u017cne etapy procesu s\u0105 wobec siebie komplementarne i \u201ewzajemnie si\u0119 karmi\u0105\u201d).",
-            "competence": 30,
-            "level": 6
-        }
-    },
-    {
-        "pk": 268,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- wie, \u017ce istniej\u0105 r\u00f3\u017cne rodzaje medi\u00f3w (radio, TV, internet, prasa).\r\n- wie, czym jest abonament radiowo-telewizyjny.\r\n- umie odr\u00f3\u017cni\u0107 media publiczne od prywatnych.\r\n- wie, \u017ce rynek medi\u00f3w jest regulowany.",
-            "competence": 30,
-            "level": 7
-        }
-    },
-    {
-        "pk": 269,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- wie, \u017ce prywatna stacja radiowa lub telewizyjna musi ubiega\u0107 si\u0119 o koncesj\u0119 na nadawanie, a publiczne stacje nie maj\u0105 tego obowi\u0105zku.\r\n- wie, \u017ce na rynku wyst\u0119puje zjawisko konkurencji i koncentracji i umie wskaza\u0107 ich przyk\u0142ady.\r\n- wie, \u017ce rynek medialny sk\u0142ada si\u0119 z medi\u00f3w, ich u\u017cytkownik\u00f3w oraz z otoczenia regulacyjnego.\r\n- umie wskaza\u0107 regulator\u00f3w medi\u00f3w (obecnie: KRRiT, UKE) oraz cia\u0142a samoreguluj\u0105ce (samorz\u0105dy bran\u017cowe, komisje etyki).",
-            "competence": 30,
-            "level": 8
-        }
-    },
-    {
-        "pk": 270,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- rozumie konsekwencje konsolidacji i koncentracji medi\u00f3w.\r\n- rozumie r\u00f3\u017cnice mi\u0119dzy koncentracj\u0105 poziom\u0105 i pionow\u0105.\r\n- umie wskaza\u0107 bariery wej\u015bcia na rynek medi\u00f3w.",
-            "competence": 30,
-            "level": 9
-        }
-    },
-    {
-        "pk": 271,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- intuicyjnie wie, czym jest informacja;\r\nnp. wie, na jakim kanale znajdzie ulubion\u0105 bajk\u0119, albo \u017ce ta bajka jest nadawana o takiej, a nie o innej porze dnia.\r\n- umie dzieli\u0107 si\u0119 informacjami z innymi.",
-            "competence": 31,
-            "level": 1
-        }
-    },
-    {
-        "pk": 272,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- wie, \u017ce informacj\u0119 mo\u017cna przekaza\u0107 bezpo\u015brednio lub po\u015brednio. Tym drugim zajmuj\u0105 si\u0119 media (prasa, media elektroniczne).\r\n- wie, \u017ce w j\u0119zyku medi\u00f3w informacje to: wydarzenia / newsy / wiadomo\u015bci.\r\n- rozumie poj\u0119cie reklamy. Wie, \u017ce s\u0105 komunikaty perswazyjne i informacyjne.",
-            "competence": 31,
-            "level": 2
-        }
-    },
-    {
-        "pk": 273,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- rozumie, \u017ce informacja ma sw\u00f3j kontekst, kt\u00f3ry decyduje, czy mamy do czynienia z przekazem perswazyjnym, czy czysto informacyjnym.\r\n- umie rozr\u00f3\u017cni\u0107 reklam\u0119 od przekazu informacyjnego.\r\n- wie, \u017ce r\u00f3wnie\u017c reklama zawiera element informacyjny, ale jest on podporz\u0105dkowany celowi perswazyjnemu.",
-            "competence": 31,
-            "level": 3
-        }
-    },
-    {
-        "pk": 274,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- wie, \u017ce informacja to dobro.\r\n- wie, \u017ce nie ka\u017cdy ma do niej dost\u0119p.\r\n- zna poj\u0119cie asymetrii informacji.\r\n- wie, \u017ce w cyfrowym \u015bwiecie informacja nie tylko nie traci na znaczeniu, ale zyskuje, tyle, \u017ce zmienia si\u0119 jej ekonomika (maleje / zanika asymetria informacyjna).\r\n- wie, \u017ce tworzenie informacji, jak r\u00f3wnie\u017c jej przekazywanie, niesie za sob\u0105 koszty. Te koszty nie s\u0105 dostrzegane przez bezpo\u015brednich odbiorc\u00f3w (czytelnik\u00f3w, s\u0142uchaczy, widz\u00f3w), bo ponosz\u0105 je np. producenci.\r\n- wie, \u017ce koszt wytworzenia danego dobra nie jest r\u00f3wnoznaczny z jego warto\u015bci\u0105 ani cen\u0105.\r\n- wie o istnieniu ekonomii daru i umie rozpozna\u0107 jej elementy w relacjach dotycz\u0105cych medi\u00f3w.\r\n- wie, \u017ce jedn\u0105 z zasad biznesu w sieci jest ekonomia uwagi i umie pokaza\u0107 ten mechanizm; np. na przyk\u0142adzie historii wyszukiwania w Google.\r\n- wie, \u017ce istnieje prawo w\u0142asno\u015bci intelektualnej (w tym w szczeg\u00f3lno\u015bci prawo autorskie) i wie, \u017ce przestrzeganie jego zasad ma wp\u0142yw na ekonomiczn\u0105 warto\u015b\u0107 oraz dost\u0119pno\u015b\u0107 danego dobra.\r\n- rozumie, \u017ce cena jest warto\u015bci\u0105 umown\u0105 \u2013 sprzedawca proponuje cen\u0119, a nabywca j\u0105 akceptuje lub odrzuca.",
-            "competence": 31,
-            "level": 4
-        }
-    },
-    {
-        "pk": 275,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- wie, \u017ce mi\u0119dzy mediami tradycyjnymi a odbiorcami odbywa si\u0119 wymiana na poziomie ekonomicznym (w sieci \u2013 na poziomie ekonomii uwagi), cho\u0107 odbiorca nie p\u0142aci bezpo\u015brednio za informacj\u0119, co wynika ze sposobu finansowania tych medi\u00f3w.\r\n- wie, \u017ce obowi\u0105zuj\u0105ce przepisy dot. w\u0142asno\u015bci intelektualnej mog\u0105 wp\u0142ywa\u0107 na postrzeganie informacji i cen\u0119 danego dobra np. wie, \u017ce idea nie ma w\u0142a\u015bciciela, ale zapisana na kartce papieru przez autora automatycznie podlega ochronie prawnej.\r\n- rozumie ekonomiczne i prawne konsekwencje obowi\u0105zuj\u0105cych przepis\u00f3w dotycz\u0105cych w\u0142asno\u015bci intelektualnej;\r\nnp. rozumie ograniczenie mo\u017cliwo\u015bci korzystania z prywatnej kopii filmu na DVD \u2013 mo\u017cna go ogl\u0105da\u0107 samemu w domu, ale wy\u015bwietlanie w szkole kopii bez licencji na publiczne odtwarzanie grozi konsekwencjami prawnymi i ekonomicznymi.\r\n- wie, czym jest informacja publiczna.",
-            "competence": 31,
-            "level": 5
-        }
-    },
-    {
-        "pk": 276,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- umie przeanalizowa\u0107 wp\u0142yw ustawodawstwa na polityk\u0119 informacyjn\u0105 i medialn\u0105.",
-            "competence": 31,
-            "level": 6
-        }
-    },
-    {
-        "pk": 277,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- rozumie kontekst informacji (umie przetwarza\u0107 informacje otrzymane za po\u015brednictwem\r\n- umie odr\u00f3\u017cni\u0107 przekaz informacyjny od reklamowego.\r\n- wie, \u017ce informacja to dobro i \u017ce cz\u0119\u015bciej si\u0119 p\u0142aci za dost\u0119p ni\u017c za sam\u0105 informacj\u0119; np. op\u0142ata za korzystanie z program\u00f3w TV w sieci kablowej.",
-            "competence": 31,
-            "level": 7
-        }
-    },
-    {
-        "pk": 278,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- wie, co oznacza poj\u0119cie \u201easymetria informacji\u201d i wie, \u017ce jej znaczenie maleje w \u015brodowisku cyfrowym.\r\n- wie, \u017ce koszt wytworzenia danego dobra nie jest r\u00f3wnoznaczny z jego cen\u0105 ani warto\u015bci\u0105; np. wie \u017ce minimalny koszt wyprodukowania telefonu kom\u00f3rkowego jest inny ni\u017c jego cena rynkowa, kt\u00f3ra ulega zmianom, m.in. w promocjach cenowych.\r\n- wie, \u017ce istnieje w\u0142asno\u015b\u0107 intelektualna (w tym prawo autorskie) i rozumie jej prawne oraz ekonomiczne konsekwencje.\r\n- umie poda\u0107 przyk\u0142ady ekonomii uwagi i ekonomii daru.",
-            "competence": 31,
-            "level": 8
-        }
-    },
-    {
-        "pk": 279,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- rozumie, na czym w \u015brodowisku cyfrowym polega zmiana ekonomicznego uj\u0119cia \u201einformacji jako dobra\u201d.\r\n- rozumie, na czym polega ekonomia uwagi i ekonomia daru.\r\n- rozumie ekonomiczne konsekwencje przepis\u00f3w dot. w\u0142asno\u015bci intelektualnej.\r\n- wie, czym jest informacja publiczna i jak uzyska\u0107 do niej dost\u0119p.",
-            "competence": 31,
-            "level": 9
-        }
-    },
-    {
-        "pk": 280,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- wie, \u017ce w mediach s\u0105 reklamy; np. umie wskaza\u0107 reklamy w ulubionym pi\u015bmie albo mi\u0119dzy \u00a0bajkami w telewizji.\r\n- wie, \u017ce za dost\u0119p do medi\u00f3w si\u0119 p\u0142aci np. kupowanie gazety w kiosku.\r\n- wie, \u017ce dobra mo\u017cna nabywa\u0107 w sklepie, ale te\u017c przez internet.",
-            "competence": 32,
-            "level": 1
-        }
-    },
-    {
-        "pk": 281,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- wie, \u017ce s\u0105 takie gry sieciowe, w kt\u00f3rych podstawowa us\u0142uga jest bezp\u0142atna, ale trzeba p\u0142aci\u0107 za dodatkowe funkcjonalno\u015bci.\r\n- wie, \u017ce jako nieletni nie mo\u017ce dokonywa\u0107 samodzielnie transakcji w internecie.\r\n- umie wskaza\u0107 r\u00f3\u017cne sposoby nabywania d\u00f3br; np. sklep w galerii handlowej, sklep internetowy, aukcja.\r\n- rozumie, \u017ce za dost\u0119p do medi\u00f3w si\u0119 p\u0142aci.",
-            "competence": 32,
-            "level": 2
-        }
-    },
-    {
-        "pk": 282,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- wie, \u017ce s\u0105 np. takie hostingi plik\u00f3w,czy takie gry sieciowe, w kt\u00f3rych podstawowa us\u0142uga jest bezp\u0142atna, ale trzeba p\u0142aci\u0107 za dodatkowe funkcjonalno\u015bci; wie, \u017ce w \u015bwietle prawa nie \u00a0mo\u017ce dokonywa\u0107 takich p\u0142atno\u015bci.\r\n- wie, \u017ce czasem informacja o podwy\u017cszonej p\u0142atno\u015bci za skorzystanie z jakiej\u015b us\u0142ugi nie jest do\u015b\u0107 wyeksponowana i trzeba umie\u0107 j\u0105 rozkodowa\u0107: np. koszt SMS-\u00f3w w g\u0142osowaniach telewizyjnych czy regu\u0142a dla telefonicznych numer\u00f3w specjalnych, gdzie cena zakodowana jest w pierwszych cyfrach danego numeru.\r\n- wie o istnieniu ukrytych p\u0142atno\u015bci w internecie; np. w serwisie Pobieraczek.\r\n- wie, \u017ce w mediach p\u0142aci si\u0119 za dost\u0119p, a nie za tre\u015b\u0107, st\u0105d potrzeba finansowania medi\u00f3w z innych \u017ar\u00f3de\u0142; np. w TVP reklamy nie przerywaj\u0105 audycji, ale jest abonament.\r\n\r\n- wie zatem, \u017ce reklama s\u0142u\u017cy r\u00f3wnie\u017c finansowaniu medi\u00f3w.\r\n- rozumie, dlaczego nie mo\u017ce samodzielnie dokonywa\u0107 transakcji w internecie.",
-            "competence": 32,
-            "level": 3
-        }
-    },
-    {
-        "pk": 283,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- wie, \u017ce media dziel\u0105 si\u0119 na prywatne i publiczne ze wzgl\u0119du na spos\u00f3b ich finansowania.\r\n- wie, czym jest i do czego s\u0142u\u017cy abonament radiowo-telewizyjny.\r\n- wie, \u017ce niekt\u00f3re blogi s\u0105 sponsorowane przez firmy i umie odr\u00f3\u017cni\u0107 zach\u0119t\u0119 do zakupu danego dobra od informacji o tym dobru.",
-            "competence": 32,
-            "level": 4
-        }
-    },
-    {
-        "pk": 284,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- wie, \u017ce serwisy, w kt\u00f3rych sprzedaje si\u0119 tre\u015bci, to wyj\u0105tek, a nie zasada finansowania medi\u00f3w; np. wie, \u017ce w internecie mo\u017cna kupi\u0107 uprzywilejowany dost\u0119p i czas \u00a0- \u00a0abonament dot. notowa\u0144 na gie\u0142dzie.\r\n- wie, na czym polegaj\u0105 podstawowe zasady handlu w sieci i p\u0142atno\u015bci on-line; np. wie, jak dzia\u0142aj\u0105 aukcje on-line.\r\n- biegle umie pos\u0142ugiwa\u0107 si\u0119 terminami dot. nast\u0119puj\u0105cych zagadnie\u0144 finansowania medi\u00f3w i rozumie ich znaczenie oraz powi\u0105zania: przychody z reklam, dotacje, abonament.\r\n- rozumie powi\u0105zanie malej\u0105cej asymetrii informacyjnej w \u015brodowisku cyfrowym z cen\u0105 na niekt\u00f3re produkty nabywane w sieci np. rozumie wp\u0142yw wyszukiwarek internetowych, por\u00f3wnywarek cenowych i internetowych platform handlowych na obni\u017ck\u0119 mar\u017c produkt\u00f3w nabywanych w sieci.",
-            "competence": 32,
-            "level": 5
-        }
-    },
-    {
-        "pk": 286,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- wie, na czym polegaj\u0105 podstawowe zasady handlu w sieci i p\u0142atno\u015bci on-line; np. wie, jak dzia\u0142aj\u0105 aukcje internetowe.\r\n- wie, \u017ce s\u0105 takie us\u0142ugi w internecie, gdzie podstawowa us\u0142uga jest bezp\u0142atna, ale trzeba p\u0142aci\u0107 za dodatkowe funkcjonalno\u015bci.\r\n- wie, \u017ce czasem us\u0142uga o podwy\u017cszonej p\u0142atno\u015bci nie jest do\u015b\u0107 wyeksponowana i trzeba umie\u0107 j\u0105 rozkodowa\u0107; np. koszt SMS-\u00f3w w g\u0142osowaniach telewizyjnych lub regu\u0142a telefonicznych numer\u00f3w specjalnych, w kt\u00f3rych cena jest zakodowana w pierwszych cyfrach danego numeru.\r\n- wie, \u017ce w mediach p\u0142aci si\u0119 za dost\u0119p, a nie za tre\u015b\u0107, st\u0105d potrzeba finansowania medi\u00f3w z innych \u017ar\u00f3de\u0142, takich jak reklama czy abonament rtv.\r\n- wie, \u017ce media dziel\u0105 si\u0119 na publiczne i prywatne ze wzgl\u0119du na spos\u00f3b finansowania.",
-            "competence": 32,
-            "level": 7
-        }
-    },
-    {
-        "pk": 287,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- wie, czym jest i do czego s\u0142u\u017cy abonament rtv.\r\n- wie, \u017ce niekt\u00f3re blogi s\u0105 sponsorowane przez firmy i umie odr\u00f3\u017cni\u0107 zach\u0119t\u0119 do zakupu danego dobra od informacji o nim.\r\n- wie o ukrytych p\u0142atno\u015bciach w internecie.\r\n- umie dokonywa\u0107 bezpiecznych i skutecznych transakcji internetowych oraz rozumie zasady handlu w sieci i p\u0142atno\u015bci on-line.",
-            "competence": 32,
-            "level": 8
-        }
-    },
-    {
-        "pk": 288,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- umie wskaza\u0107 \u017ar\u00f3d\u0142a presji politycznej i ekonomicznej wywieranej na media ze wzgl\u0119du na model finansowania.\r\n- rozumie, \u017ce serwisy, w kt\u00f3rych sprzedaje si\u0119 tre\u015bci, to wyj\u0105tek, a nie zasada finansowania medi\u00f3w; np. internecie mo\u017cna sprzedawa\u0107 uprzywilejowany dost\u0119p i czas",
-            "competence": 32,
-            "level": 9
-        }
-    },
-    {
-        "pk": 291,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- wie, \u017ce polityka medialna to og\u00f3\u0142 dzia\u0142a\u0144 zwi\u0105zanych z funkcjonowaniem medi\u00f3w (ich regulacj\u0105, nadzorem i kontrol\u0105) i umie wskaza\u0107 elementy tej polityki; np. umie wskaza\u0107 przyk\u0142ady regulacji rynku.",
-            "competence": 33,
-            "level": 3
-        }
-    },
-    {
-        "pk": 292,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- umie poda\u0107 przyk\u0142ady / elementy polityki medialnej.\r\n- umie wyja\u015bni\u0107 r\u00f3\u017cnice mi\u0119dzy mediami publicznymi a prywatnymi w zakresie kontroli i regulacji (struktura w\u0142a\u015bcicielska).",
-            "competence": 33,
-            "level": 4
-        }
-    },
-    {
-        "pk": 293,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- umie wyja\u015bni\u0107 poj\u0119cie polityki medialnej oraz wymieni\u0107 jej wybrane cele i narz\u0119dzia; np. \u00a0 prawo medialne i telekomunikacyjne, regulacja i otoczenie instytucjonalne.",
-            "competence": 33,
-            "level": 5
-        }
-    },
-    {
-        "pk": 294,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- wie o istnieniu mi\u0119dzynarodowego wymiaru polityki medialnej; zna rol\u0119 organizacji mi\u0119dzynarodowych: UE, ITU, WTO, OECD.\r\n- umie wskaza\u0107 \u017ar\u00f3d\u0142a presji politycznej i ekonomicznej wywieranej na media ze wzgl\u0119du na model finansowania.\r\n- rozumie wp\u0142yw polityki medialnej na zjawiska natury ekonomicznej zachodz\u0105ce w mediach; np. tworzenie barier wej\u015bcia na rynek, koncentracja, finansowanie medi\u00f3w.",
-            "competence": 33,
-            "level": 6
-        }
-    },
-    {
-        "pk": 295,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- wie, \u017ce rynek medi\u00f3w podlega nadzorowi i kontroli.",
-            "competence": 33,
-            "level": 7
-        }
-    },
-    {
-        "pk": 296,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- wie o istnieniu nieformalnych system\u00f3w medialnych, b\u0119d\u0105cych w du\u017cej cz\u0119\u015bci lub w ca\u0142o\u015bci s\u0105 poza zasi\u0119giem polityki pa\u0144stwa.\r\n- wie o istnieniu mi\u0119dzynarodowego wymiaru polityki medialnej i umie poda\u0107 przyk\u0142ady organizacji mi\u0119dzynarodowych maj\u0105cych wp\u0142yw na ten wymiar.\r\n- umie rozpozna\u0107 elementy polityki medialnej.",
-            "competence": 33,
-            "level": 8
-        }
-    },
-    {
-        "pk": 297,
-        "model": "curriculum.competencelevel",
-        "fields": {
-            "description": "- rozumie podstawowe funkcje, cele i narz\u0119dzia polityki medialnej.\r\n- umie poda\u0107 przyk\u0142ady wp\u0142ywu polityki medialnej na funkcjonowanie medi\u00f3w (spos\u00f3b ich finansowania, tworzenie nowych medi\u00f3w).",
-            "competence": 33,
-            "level": 9
-        }
-    }
-]
diff --git a/curriculum/fixtures/curriculum.json b/curriculum/fixtures/curriculum.json
deleted file mode 100644 (file)
index dc62f07..0000000
+++ /dev/null
@@ -1,567 +0,0 @@
-[
-    {
-        "pk": 1,
-        "model": "curriculum.curriculumlevel",
-        "fields": {
-            "title": "III"
-        }
-    },
-    {
-        "pk": 2,
-        "model": "curriculum.curriculumlevel",
-        "fields": {
-            "title": "IV"
-        }
-    },
-    {
-        "pk": 1,
-        "model": "curriculum.curriculumcourse",
-        "fields": {
-            "accusative": "j\u0119zyk polski",
-            "slug": "polski",
-            "title": "J\u0119zyk polski"
-        }
-    },
-    {
-        "pk": 2,
-        "model": "curriculum.curriculumcourse",
-        "fields": {
-            "accusative": "plastyk\u0119",
-            "slug": "plastyka",
-            "title": "Plastyka"
-        }
-    },
-    {
-        "pk": 3,
-        "model": "curriculum.curriculumcourse",
-        "fields": {
-            "accusative": "wiedz\u0119 o spo\u0142ecze\u0144stwie",
-            "slug": "wos",
-            "title": "Wiedza o spo\u0142ecze\u0144stwie"
-        }
-    },
-    {
-        "pk": 4,
-        "model": "curriculum.curriculumcourse",
-        "fields": {
-            "accusative": "informatyk\u0119",
-            "slug": "informatyka",
-            "title": "Informatyka"
-        }
-    },
-    {
-        "pk": 5,
-        "model": "curriculum.curriculumcourse",
-        "fields": {
-            "accusative": "etyk\u0119",
-            "slug": "etyka",
-            "title": "Etyka"
-        }
-    },
-    {
-        "pk": 1,
-        "model": "curriculum.curriculum",
-        "fields": {
-            "course": 1,
-            "level": 1,
-            "identifier": "2012/III/POLSKI/c1",
-            "type": "c",
-            "title": "I. Odbi\u00f3r wypowiedzi i wykorzystanie zawartych w nich informacji."
-        }
-    },
-    {
-        "pk": 2,
-        "model": "curriculum.curriculum",
-        "fields": {
-            "course": 1,
-            "level": 1,
-            "identifier": "2012/III/POLSKI/c2",
-            "type": "c",
-            "title": "II. Analiza i interpretacja tekst\u00f3w kultury."
-        }
-    },
-    {
-        "pk": 3,
-        "model": "curriculum.curriculum",
-        "fields": {
-            "course": 1,
-            "level": 1,
-            "identifier": "2012/III/POLSKI/c3",
-            "type": "c",
-            "title": "III. Tworzenie wypowiedzi."
-        }
-    },
-    {
-        "pk": 4,
-        "model": "curriculum.curriculum",
-        "fields": {
-            "course": 2,
-            "level": 1,
-            "identifier": "2012/III/PLASTYKA/c1",
-            "type": "c",
-            "title": "I. Odbi\u00f3r wypowiedzi i wykorzystanie zawartych w nich informacji \u2013 percepcja sztuki."
-        }
-    },
-    {
-        "pk": 5,
-        "model": "curriculum.curriculum",
-        "fields": {
-            "course": 2,
-            "level": 1,
-            "identifier": "2012/III/PLASTYKA/c2",
-            "type": "c",
-            "title": "II. Tworzenie wypowiedzi \u2013 ekspresja przez sztuk\u0119."
-        }
-    },
-    {
-        "pk": 6,
-        "model": "curriculum.curriculum",
-        "fields": {
-            "course": 2,
-            "level": 1,
-            "identifier": "2012/III/PLASTYKA/c3",
-            "type": "c",
-            "title": "III. Analiza i interpretacja tekst\u00f3w kultury \u2013 recepcja sztuki."
-        }
-    },
-    {
-        "pk": 7,
-        "model": "curriculum.curriculum",
-        "fields": {
-            "course": 3,
-            "level": 1,
-            "identifier": "2012/III/WOS/c1",
-            "type": "c",
-            "title": "I. Wykorzystanie i tworzenie informacji."
-        }
-    },
-    {
-        "pk": 8,
-        "model": "curriculum.curriculum",
-        "fields": {
-            "course": 3,
-            "level": 1,
-            "identifier": "2012/III/WOS/c2",
-            "type": "c",
-            "title": "II. Rozpoznawanie i rozwi\u0105zywanie problem\u00f3w."
-        }
-    },
-    {
-        "pk": 9,
-        "model": "curriculum.curriculum",
-        "fields": {
-            "course": 3,
-            "level": 1,
-            "identifier": "2012/III/WOS/c3",
-            "type": "c",
-            "title": "III. Wsp\u00f3\u0142dzia\u0142anie w sprawach publicznych."
-        }
-    },
-    {
-        "pk": 10,
-        "model": "curriculum.curriculum",
-        "fields": {
-            "course": 3,
-            "level": 1,
-            "identifier": "2012/III/WOS/c4",
-            "type": "c",
-            "title": "IV. Znajomo\u015b\u0107 zasad i procedur demokracji."
-        }
-    },
-    {
-        "pk": 11,
-        "model": "curriculum.curriculum",
-        "fields": {
-            "course": 3,
-            "level": 1,
-            "identifier": "2012/III/WOS/c5",
-            "type": "c",
-            "title": "V. Znajomo\u015b\u0107 podstaw ustroju Rzeczypospolitej Polskiej."
-        }
-    },
-    {
-        "pk": 12,
-        "model": "curriculum.curriculum",
-        "fields": {
-            "course": 3,
-            "level": 1,
-            "identifier": "2012/III/WOS/t1",
-            "type": "t",
-            "title": "Podstawowe umiej\u0119tno\u015bci \u017cycia w grupie."
-        }
-    },
-    {
-        "pk": 13,
-        "model": "curriculum.curriculum",
-        "fields": {
-            "course": 3,
-            "level": 1,
-            "identifier": "2012/III/WOS/t2",
-            "type": "t",
-            "title": "\u017bycie spo\u0142eczne"
-        }
-    },
-    {
-        "pk": 14,
-        "model": "curriculum.curriculum",
-        "fields": {
-            "course": 3,
-            "level": 1,
-            "identifier": "2012/III/WOS/t3",
-            "type": "t",
-            "title": "Wsp\u00f3\u0142czesne spo\u0142ecze\u0144stwo polskie."
-        }
-    },
-    {
-        "pk": 15,
-        "model": "curriculum.curriculum",
-        "fields": {
-            "course": 3,
-            "level": 1,
-            "identifier": "2012/III/WOS/t4",
-            "type": "t",
-            "title": "By\u0107 obywatelem."
-        }
-    },
-    {
-        "pk": 16,
-        "model": "curriculum.curriculum",
-        "fields": {
-            "course": 3,
-            "level": 1,
-            "identifier": "2012/III/WOS/t5",
-            "type": "t",
-            "title": "Udzia\u0142 obywateli w \u017cyciu publicznym"
-        }
-    },
-    {
-        "pk": 17,
-        "model": "curriculum.curriculum",
-        "fields": {
-            "course": 3,
-            "level": 1,
-            "identifier": "2012/III/WOS/t6",
-            "type": "t",
-            "title": "\u015arodki masowego przekazu."
-        }
-    },
-    {
-        "pk": 18,
-        "model": "curriculum.curriculum",
-        "fields": {
-            "course": 3,
-            "level": 1,
-            "identifier": "2012/III/WOS/t9",
-            "type": "t",
-            "title": "Patriotyzm dzisiaj."
-        }
-    },
-    {
-        "pk": 19,
-        "model": "curriculum.curriculum",
-        "fields": {
-            "course": 3,
-            "level": 1,
-            "identifier": "2012/III/WOS/t10",
-            "type": "t",
-            "title": "Pa\u0144stwo i w\u0142adza demokratyczna."
-        }
-    },
-    {
-        "pk": 20,
-        "model": "curriculum.curriculum",
-        "fields": {
-            "course": 3,
-            "level": 1,
-            "identifier": "2012/III/WOS/t11",
-            "type": "t",
-            "title": "Rzeczpospolita Polska jako demokracja konstytucyjna."
-        }
-    },
-    {
-        "pk": 21,
-        "model": "curriculum.curriculum",
-        "fields": {
-            "course": 3,
-            "level": 1,
-            "identifier": "2012/III/WOS/t24",
-            "type": "t",
-            "title": "Praca i przedsi\u0119biorczo\u015b\u0107."
-        }
-    },
-    {
-        "pk": 22,
-        "model": "curriculum.curriculum",
-        "fields": {
-            "course": 3,
-            "level": 1,
-            "identifier": "2012/III/WOS/t25",
-            "type": "t",
-            "title": "Gospodarka rynkowa."
-        }
-    },
-    {
-        "pk": 23,
-        "model": "curriculum.curriculum",
-        "fields": {
-            "course": 3,
-            "level": 1,
-            "identifier": "2012/III/WOS/t26",
-            "type": "t",
-            "title": "Gospodarstwo domowe."
-        }
-    },
-    {
-        "pk": 24,
-        "model": "curriculum.curriculum",
-        "fields": {
-            "course": 4,
-            "level": 1,
-            "identifier": "2012/III/INFORMATYKA/c1",
-            "type": "c",
-            "title": "I. Bezpieczne pos\u0142ugiwanie si\u0119 komputerem i jego oprogramowaniem, wykorzystanie sieci komputerowej; komunikowanie si\u0119 za pomoc\u0105 komputera i technologii informacyjno-komunikacyjnych."
-        }
-    },
-    {
-        "pk": 25,
-        "model": "curriculum.curriculum",
-        "fields": {
-            "course": 4,
-            "level": 1,
-            "identifier": "2012/III/INFORMATYKA/c2",
-            "type": "c",
-            "title": "II. Wyszukiwanie, gromadzenie i przetwarzanie informacji z r\u00f3\u017cnych \u017ar\u00f3de\u0142; opracowywanie za pomoc\u0105 komputera: rysunk\u00f3w, tekst\u00f3w, danych liczbowych, motyw\u00f3w, animacji, prezentacji multimedialnych."
-        }
-    },
-    {
-        "pk": 26,
-        "model": "curriculum.curriculum",
-        "fields": {
-            "course": 4,
-            "level": 1,
-            "identifier": "2012/III/INFORMATYKA/c5",
-            "type": "c",
-            "title": "V. Ocena zagro\u017ce\u0144 i ogranicze\u0144, docenianie spo\u0142ecznych aspekt\u00f3w rozwoju i zastosowa\u0144 informatyki."
-        }
-    },
-    {
-        "pk": 27,
-        "model": "curriculum.curriculum",
-        "fields": {
-            "course": 5,
-            "level": 1,
-            "identifier": "2012/III/ETYKA/c1",
-            "type": "c",
-            "title": "I. Kszta\u0142towanie refleksyjnej postawy wobec cz\u0142owieka, jego natury, powinno\u015bci moralnych oraz wobec r\u00f3\u017cnych sytuacji \u017cyciowych."
-        }
-    },
-    {
-        "pk": 28,
-        "model": "curriculum.curriculum",
-        "fields": {
-            "course": 5,
-            "level": 1,
-            "identifier": "2012/III/ETYKA/c4",
-            "type": "c",
-            "title": "IV. Podj\u0119cie odpowiedzialno\u015bci za siebie i innych oraz za dokonywane wybory moralne; rozstrzyganie w\u0105tpliwo\u015bci i problem\u00f3w moralnych zgodnie z przyj\u0119t\u0105 hierarchi\u0105 warto\u015bci i dobrem wsp\u00f3lnym."
-        }
-    },
-    {
-        "pk": 29,
-        "model": "curriculum.curriculum",
-        "fields": {
-            "course": 5,
-            "level": 1,
-            "identifier": "2012/III/ETYKA/t1",
-            "type": "t",
-            "title": "Cz\u0142owiek jako osoba; natura i godno\u015b\u0107 cz\u0142owieka."
-        }
-    },
-    {
-        "pk": 30,
-        "model": "curriculum.curriculum",
-        "fields": {
-            "course": 5,
-            "level": 1,
-            "identifier": "2012/III/ETYKA/t5",
-            "type": "t",
-            "title": "Cz\u0142owiek wobec warto\u015bci; cz\u0142owiek wobec cierpienia i \u015bmierci."
-        }
-    },
-    {
-        "pk": 31,
-        "model": "curriculum.curriculum",
-        "fields": {
-            "course": 5,
-            "level": 1,
-            "identifier": "2012/III/ETYKA/t9",
-            "type": "t",
-            "title": "Normy i warto\u015bci demokratyczne le\u017c\u0105ce u podstaw aktywno\u015bci spo\u0142ecznej na poziomie ma\u0142ej grupy, szko\u0142y, spo\u0142eczno\u015bci lokalnej."
-        }
-    },
-    {
-        "pk": 32,
-        "model": "curriculum.curriculum",
-        "fields": {
-            "course": 5,
-            "level": 1,
-            "identifier": "2012/III/ETYKA/t11",
-            "type": "t",
-            "title": "Praca i jej warto\u015b\u0107 dla cz\u0142owieka, znaczenie etyki zawodowej."
-        }
-    },
-    {
-        "pk": 33,
-        "model": "curriculum.curriculum",
-        "fields": {
-            "course": 3,
-            "level": 2,
-            "identifier": "2012/IV/WOS/c4",
-            "type": "c",
-            "title": "IV. Znajomo\u015b\u0107 zasad i procedur demokracji."
-        }
-    },
-    {
-        "pk": 34,
-        "model": "curriculum.curriculum",
-        "fields": {
-            "course": 3,
-            "level": 2,
-            "identifier": "2012/IV/WOS/c6",
-            "type": "c",
-            "title": "VI. Znajomo\u015b\u0107 praw cz\u0142owieka i sposob\u00f3w ich ochrony."
-        }
-    },
-    {
-        "pk": 35,
-        "model": "curriculum.curriculum",
-        "fields": {
-            "course": 3,
-            "level": 2,
-            "identifier": "2012/IV/WOS/t1",
-            "type": "t",
-            "title": "M\u0142ody obywatel w urz\u0119dzie."
-        }
-    },
-    {
-        "pk": 36,
-        "model": "curriculum.curriculum",
-        "fields": {
-            "course": 3,
-            "level": 2,
-            "identifier": "2012/IV/WOS/t2",
-            "type": "t",
-            "title": "Prawo i s\u0105dy."
-        }
-    },
-    {
-        "pk": 37,
-        "model": "curriculum.curriculum",
-        "fields": {
-            "course": 3,
-            "level": 2,
-            "identifier": "2012/IV/WOS/t5",
-            "type": "t",
-            "title": "Prawa cz\u0142owieka."
-        }
-    },
-    {
-        "pk": 38,
-        "model": "curriculum.curriculum",
-        "fields": {
-            "course": 3,
-            "level": 2,
-            "identifier": "2012/IV/WOS/t6",
-            "type": "t",
-            "title": "Ochrona praw i wolno\u015bci."
-        }
-    },
-    {
-        "pk": 39,
-        "model": "curriculum.curriculum",
-        "fields": {
-            "course": 3,
-            "level": 2,
-            "identifier": "2012/IV/WOS/t10/roz",
-            "type": "t",
-            "title": "Edukacja w XXI w. (zakres rozszerzony)"
-        }
-    },
-    {
-        "pk": 40,
-        "model": "curriculum.curriculum",
-        "fields": {
-            "course": 3,
-            "level": 2,
-            "identifier": "2012/IV/WOS/t14/roz",
-            "type": "t",
-            "title": "\u015arodki masowego przekazu. (zakres rozszerzony)"
-        }
-    },
-    {
-        "pk": 41,
-        "model": "curriculum.curriculum",
-        "fields": {
-            "course": 3,
-            "level": 2,
-            "identifier": "2012/IV/WOS/t15/roz",
-            "type": "t",
-            "title": "Demokracja \u2013 zasady i procedury. (zakres rozszerzony)"
-        }
-    },
-    {
-        "pk": 42,
-        "model": "curriculum.curriculum",
-        "fields": {
-            "course": 3,
-            "level": 2,
-            "identifier": "2012/IV/WOS/t27/roz",
-            "type": "t",
-            "title": "Organy kontroli pa\u0144stwowej, ochrony prawa i zaufania publicznego. (zakres rozszerzony)"
-        }
-    },
-    {
-        "pk": 43,
-        "model": "curriculum.curriculum",
-        "fields": {
-            "course": 3,
-            "level": 2,
-            "identifier": "2012/IV/WOS/t32/roz",
-            "type": "t",
-            "title": "Prawo cywilne i rodzinne. (zakres rozszerzony)"
-        }
-    },
-    {
-        "pk": 44,
-        "model": "curriculum.curriculum",
-        "fields": {
-            "course": 3,
-            "level": 2,
-            "identifier": "2012/IV/WOS/t36/roz",
-            "type": "t",
-            "title": "Obywatel wobec prawa. (zakres rozszerzony)"
-        }
-    },
-    {
-        "pk": 45,
-        "model": "curriculum.curriculum",
-        "fields": {
-            "course": 4,
-            "level": 2,
-            "identifier": "2012/IV/INFORMATYKA/c1",
-            "type": "c",
-            "title": "I. Bezpieczne pos\u0142ugiwanie si\u0119 komputerem i jego oprogramowaniem, wykorzystanie sieci komputerowej; komunikowanie si\u0119 za pomoc\u0105 komputera i technologii informacyjno-komunikacyjnych."
-        }
-    },
-    {
-        "pk": 46,
-        "model": "curriculum.curriculum",
-        "fields": {
-            "course": 4,
-            "level": 2,
-            "identifier": "2012/IV/INFORMATYKA/c5",
-            "type": "c",
-            "title": "V. Ocena zagro\u017ce\u0144 i ogranicze\u0144, docenianie spo\u0142ecznych aspekt\u00f3w rozwoju i zastosowa\u0144 informatyki."
-        }
-    }
-]
diff --git a/curriculum/locale/pl/LC_MESSAGES/django.mo b/curriculum/locale/pl/LC_MESSAGES/django.mo
deleted file mode 100644 (file)
index 16f5b95..0000000
Binary files a/curriculum/locale/pl/LC_MESSAGES/django.mo and /dev/null differ
diff --git a/curriculum/locale/pl/LC_MESSAGES/django.po b/curriculum/locale/pl/LC_MESSAGES/django.po
deleted file mode 100644 (file)
index 04048df..0000000
+++ /dev/null
@@ -1,131 +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: 2013-10-18 14:01+0200\n"
-"PO-Revision-Date: 2013-02-08 13:16+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"
-
-#: models.py:9 models.py:33 models.py:68
-msgid "slug"
-msgstr ""
-
-#: models.py:10 models.py:34 models.py:69
-msgid "order"
-msgstr "kolejność"
-
-#: models.py:14
-msgid "section"
-msgstr "dział"
-
-#: models.py:15
-msgid "sections"
-msgstr "działy"
-
-#: models.py:27 models.py:63 models.py:80
-msgid "name"
-msgstr "nazwa"
-
-#: models.py:38
-msgid "competence"
-msgstr "kompetencja"
-
-#: models.py:39
-msgid "competences"
-msgstr "kompetencje"
-
-#: models.py:73
-msgid "educational level"
-msgstr "poziom edukacyjny"
-
-#: models.py:74
-msgid "educational levels"
-msgstr "poziomy edukacyjne"
-
-#: models.py:81
-msgid "group"
-msgstr "grupa"
-
-#: models.py:91
-msgid "competence on level"
-msgstr "kompetencja na poziomie"
-
-#: models.py:92
-msgid "competences on levels"
-msgstr "kompetencje na poziomach"
-
-#: models.py:101
-msgid "description"
-msgstr "opis"
-
-#: models.py:109
-msgid "curriculum level"
-msgstr "poziom w podstawie programowej"
-
-#: models.py:110
-msgid "curriculum levels"
-msgstr "poziomy w podstawie programowej"
-
-#: models.py:122
-msgid "curriculum course"
-msgstr "przedmiot w podstawie programowej"
-
-#: models.py:123
-msgid "curriculum courses"
-msgstr "przedmioty w podstawie programowej"
-
-#: models.py:141
-msgid "curriculum item"
-msgstr "pozycja w podstawie programowej"
-
-#: models.py:142
-msgid "curriculum items"
-msgstr "podstawa programowa"
-
-#: views.py:51
-msgid "You must select at least one competency from the list."
-msgstr "Proszę wybrać kompetencje z listy."
-
-#: views.py:53
-msgid "You must select at least one education level."
-msgstr "Proszę wybrać poziom edukacyjny."
-
-#: templates/curriculum/competence_list.html:8
-msgid "Media, information and digital literacy competencies catalogue"
-msgstr "Katalog kompetencji medialnych, informacyjnych i cyfrowych"
-
-#: templates/curriculum/competence_list.html:15
-msgid "Browse competencies"
-msgstr "Przeglądaj kompetencje"
-
-#: templates/curriculum/competence_list.html:15
-msgid "expand"
-msgstr "rozwiń"
-
-#: templates/curriculum/competence_list.html:18
-msgid "Education level"
-msgstr "Poziom edukacyjny"
-
-#: templates/curriculum/competence_list.html:31
-msgid "Competency categories"
-msgstr "Kategorie kompetencji"
-
-#: templates/curriculum/competence_list.html:49
-msgid "Show"
-msgstr "Pokaż"
-
-#: templates/curriculum/competence_list.html:55
-msgid "Selected competencies"
-msgstr "Wybrane kompetencje"
diff --git a/curriculum/migrations/0001_initial.py b/curriculum/migrations/0001_initial.py
deleted file mode 100644 (file)
index 6ac7f4f..0000000
+++ /dev/null
@@ -1,95 +0,0 @@
-# -*- coding: utf-8 -*-
-import datetime
-from south.db import db
-from south.v2 import SchemaMigration
-from django.db import models
-
-
-class Migration(SchemaMigration):
-
-    def forwards(self, orm):
-        # Adding model 'Section'
-        db.create_table('curriculum_section', (
-            ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
-            ('name', self.gf('django.db.models.fields.CharField')(max_length=255)),
-            ('slug', self.gf('django.db.models.fields.SlugField')(max_length=50)),
-            ('order', self.gf('django.db.models.fields.IntegerField')()),
-        ))
-        db.send_create_signal('curriculum', ['Section'])
-
-        # Adding model 'Competence'
-        db.create_table('curriculum_competence', (
-            ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
-            ('section', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['curriculum.Section'])),
-            ('name', self.gf('django.db.models.fields.CharField')(max_length=255)),
-            ('slug', self.gf('django.db.models.fields.SlugField')(max_length=50)),
-            ('order', self.gf('django.db.models.fields.IntegerField')()),
-        ))
-        db.send_create_signal('curriculum', ['Competence'])
-
-        # Adding model 'Level'
-        db.create_table('curriculum_level', (
-            ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
-            ('name', self.gf('django.db.models.fields.CharField')(max_length=255)),
-            ('slug', self.gf('django.db.models.fields.SlugField')(max_length=50)),
-            ('order', self.gf('django.db.models.fields.IntegerField')()),
-        ))
-        db.send_create_signal('curriculum', ['Level'])
-
-        # Adding model 'CompetenceLevel'
-        db.create_table('curriculum_competencelevel', (
-            ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
-            ('competence', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['curriculum.Competence'])),
-            ('level', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['curriculum.Level'])),
-            ('description', self.gf('django.db.models.fields.TextField')()),
-        ))
-        db.send_create_signal('curriculum', ['CompetenceLevel'])
-
-
-    def backwards(self, orm):
-        # Deleting model 'Section'
-        db.delete_table('curriculum_section')
-
-        # Deleting model 'Competence'
-        db.delete_table('curriculum_competence')
-
-        # Deleting model 'Level'
-        db.delete_table('curriculum_level')
-
-        # Deleting model 'CompetenceLevel'
-        db.delete_table('curriculum_competencelevel')
-
-
-    models = {
-        'curriculum.competence': {
-            'Meta': {'ordering': "['order']", 'object_name': 'Competence'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
-            'order': ('django.db.models.fields.IntegerField', [], {}),
-            'section': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['curriculum.Section']"}),
-            'slug': ('django.db.models.fields.SlugField', [], {'max_length': '50'})
-        },
-        'curriculum.competencelevel': {
-            'Meta': {'ordering': "['competence', 'level']", 'object_name': 'CompetenceLevel'},
-            'competence': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['curriculum.Competence']"}),
-            'description': ('django.db.models.fields.TextField', [], {}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'level': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['curriculum.Level']"})
-        },
-        'curriculum.level': {
-            'Meta': {'ordering': "['order']", 'object_name': 'Level'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
-            'order': ('django.db.models.fields.IntegerField', [], {}),
-            'slug': ('django.db.models.fields.SlugField', [], {'max_length': '50'})
-        },
-        'curriculum.section': {
-            'Meta': {'ordering': "['order']", 'object_name': 'Section'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
-            'order': ('django.db.models.fields.IntegerField', [], {}),
-            'slug': ('django.db.models.fields.SlugField', [], {'max_length': '50'})
-        }
-    }
-
-    complete_apps = ['curriculum']
\ No newline at end of file
diff --git a/curriculum/migrations/0002_auto__add_field_level_group.py b/curriculum/migrations/0002_auto__add_field_level_group.py
deleted file mode 100644 (file)
index 0f7cf5d..0000000
+++ /dev/null
@@ -1,55 +0,0 @@
-# -*- coding: utf-8 -*-
-import datetime
-from south.db import db
-from south.v2 import SchemaMigration
-from django.db import models
-
-
-class Migration(SchemaMigration):
-
-    def forwards(self, orm):
-        # Adding field 'Level.group'
-        db.add_column('curriculum_level', 'group',
-                      self.gf('django.db.models.fields.CharField')(default='', max_length=255),
-                      keep_default=False)
-
-
-    def backwards(self, orm):
-        # Deleting field 'Level.group'
-        db.delete_column('curriculum_level', 'group')
-
-
-    models = {
-        'curriculum.competence': {
-            'Meta': {'ordering': "['order']", 'object_name': 'Competence'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
-            'order': ('django.db.models.fields.IntegerField', [], {}),
-            'section': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['curriculum.Section']"}),
-            'slug': ('django.db.models.fields.SlugField', [], {'max_length': '50'})
-        },
-        'curriculum.competencelevel': {
-            'Meta': {'ordering': "['competence', 'level']", 'object_name': 'CompetenceLevel'},
-            'competence': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['curriculum.Competence']"}),
-            'description': ('django.db.models.fields.TextField', [], {}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'level': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['curriculum.Level']"})
-        },
-        'curriculum.level': {
-            'Meta': {'ordering': "['order']", 'object_name': 'Level'},
-            'group': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
-            'order': ('django.db.models.fields.IntegerField', [], {}),
-            'slug': ('django.db.models.fields.SlugField', [], {'max_length': '50'})
-        },
-        'curriculum.section': {
-            'Meta': {'ordering': "['order']", 'object_name': 'Section'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
-            'order': ('django.db.models.fields.IntegerField', [], {}),
-            'slug': ('django.db.models.fields.SlugField', [], {'max_length': '50'})
-        }
-    }
-
-    complete_apps = ['curriculum']
\ No newline at end of file
diff --git a/curriculum/migrations/0003_auto__chg_field_level_slug.py b/curriculum/migrations/0003_auto__chg_field_level_slug.py
deleted file mode 100644 (file)
index f22e753..0000000
+++ /dev/null
@@ -1,59 +0,0 @@
-# -*- coding: utf-8 -*-
-import datetime
-from south.db import db
-from south.v2 import SchemaMigration
-from django.db import models
-
-
-class Migration(SchemaMigration):
-
-    def forwards(self, orm):
-
-        # Changing field 'Level.slug'
-        db.alter_column('curriculum_level', 'slug', self.gf('django.db.models.fields.CharField')(max_length=255))
-        # Removing index on 'Level', fields ['slug']
-        db.delete_index('curriculum_level', ['slug'])
-
-
-    def backwards(self, orm):
-        # Adding index on 'Level', fields ['slug']
-        db.create_index('curriculum_level', ['slug'])
-
-
-        # Changing field 'Level.slug'
-        db.alter_column('curriculum_level', 'slug', self.gf('django.db.models.fields.SlugField')(max_length=50))
-
-    models = {
-        'curriculum.competence': {
-            'Meta': {'ordering': "['order']", 'object_name': 'Competence'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
-            'order': ('django.db.models.fields.IntegerField', [], {}),
-            'section': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['curriculum.Section']"}),
-            'slug': ('django.db.models.fields.SlugField', [], {'max_length': '50'})
-        },
-        'curriculum.competencelevel': {
-            'Meta': {'ordering': "['competence', 'level']", 'object_name': 'CompetenceLevel'},
-            'competence': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['curriculum.Competence']"}),
-            'description': ('django.db.models.fields.TextField', [], {}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'level': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['curriculum.Level']"})
-        },
-        'curriculum.level': {
-            'Meta': {'ordering': "['order']", 'object_name': 'Level'},
-            'group': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
-            'order': ('django.db.models.fields.IntegerField', [], {}),
-            'slug': ('django.db.models.fields.CharField', [], {'max_length': '255'})
-        },
-        'curriculum.section': {
-            'Meta': {'ordering': "['order']", 'object_name': 'Section'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
-            'order': ('django.db.models.fields.IntegerField', [], {}),
-            'slug': ('django.db.models.fields.SlugField', [], {'max_length': '50'})
-        }
-    }
-
-    complete_apps = ['curriculum']
\ No newline at end of file
diff --git a/curriculum/migrations/0004_auto__add_curriculum__add_curriculumlevel__add_curriculumcourse.py b/curriculum/migrations/0004_auto__add_curriculum__add_curriculumlevel__add_curriculumcourse.py
deleted file mode 100644 (file)
index 3a45ff5..0000000
+++ /dev/null
@@ -1,102 +0,0 @@
-# -*- coding: utf-8 -*-
-import datetime
-from south.db import db
-from south.v2 import SchemaMigration
-from django.db import models
-
-
-class Migration(SchemaMigration):
-
-    def forwards(self, orm):
-        # Adding model 'Curriculum'
-        db.create_table('curriculum_curriculum', (
-            ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
-            ('identifier', self.gf('django.db.models.fields.CharField')(max_length=255, db_index=True)),
-            ('title', self.gf('django.db.models.fields.CharField')(max_length=255)),
-            ('course', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['curriculum.CurriculumCourse'])),
-            ('level', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['curriculum.CurriculumLevel'])),
-            ('type', self.gf('django.db.models.fields.CharField')(max_length=16)),
-        ))
-        db.send_create_signal('curriculum', ['Curriculum'])
-
-        # Adding model 'CurriculumLevel'
-        db.create_table('curriculum_curriculumlevel', (
-            ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
-            ('title', self.gf('django.db.models.fields.CharField')(max_length=16, db_index=True)),
-        ))
-        db.send_create_signal('curriculum', ['CurriculumLevel'])
-
-        # Adding model 'CurriculumCourse'
-        db.create_table('curriculum_curriculumcourse', (
-            ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
-            ('title', self.gf('django.db.models.fields.CharField')(max_length=255)),
-            ('slug', self.gf('django.db.models.fields.CharField')(max_length=255, db_index=True)),
-        ))
-        db.send_create_signal('curriculum', ['CurriculumCourse'])
-
-
-    def backwards(self, orm):
-        # Deleting model 'Curriculum'
-        db.delete_table('curriculum_curriculum')
-
-        # Deleting model 'CurriculumLevel'
-        db.delete_table('curriculum_curriculumlevel')
-
-        # Deleting model 'CurriculumCourse'
-        db.delete_table('curriculum_curriculumcourse')
-
-
-    models = {
-        'curriculum.competence': {
-            'Meta': {'ordering': "['order']", 'object_name': 'Competence'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
-            'order': ('django.db.models.fields.IntegerField', [], {}),
-            'section': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['curriculum.Section']"}),
-            'slug': ('django.db.models.fields.SlugField', [], {'max_length': '50'})
-        },
-        'curriculum.competencelevel': {
-            'Meta': {'ordering': "['competence', 'level']", 'object_name': 'CompetenceLevel'},
-            'competence': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['curriculum.Competence']"}),
-            'description': ('django.db.models.fields.TextField', [], {}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'level': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['curriculum.Level']"})
-        },
-        'curriculum.curriculum': {
-            'Meta': {'object_name': 'Curriculum'},
-            'course': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['curriculum.CurriculumCourse']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'identifier': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}),
-            'level': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['curriculum.CurriculumLevel']"}),
-            'title': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
-            'type': ('django.db.models.fields.CharField', [], {'max_length': '16'})
-        },
-        'curriculum.curriculumcourse': {
-            'Meta': {'object_name': 'CurriculumCourse'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'slug': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}),
-            'title': ('django.db.models.fields.CharField', [], {'max_length': '255'})
-        },
-        'curriculum.curriculumlevel': {
-            'Meta': {'object_name': 'CurriculumLevel'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'title': ('django.db.models.fields.CharField', [], {'max_length': '16', 'db_index': 'True'})
-        },
-        'curriculum.level': {
-            'Meta': {'ordering': "['order']", 'object_name': 'Level'},
-            'group': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
-            'order': ('django.db.models.fields.IntegerField', [], {}),
-            'slug': ('django.db.models.fields.CharField', [], {'max_length': '255'})
-        },
-        'curriculum.section': {
-            'Meta': {'ordering': "['order']", 'object_name': 'Section'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
-            'order': ('django.db.models.fields.IntegerField', [], {}),
-            'slug': ('django.db.models.fields.SlugField', [], {'max_length': '50'})
-        }
-    }
-
-    complete_apps = ['curriculum']
\ No newline at end of file
diff --git a/curriculum/migrations/0005_auto__add_field_curriculumcourse_accusative.py b/curriculum/migrations/0005_auto__add_field_curriculumcourse_accusative.py
deleted file mode 100644 (file)
index 0708f44..0000000
+++ /dev/null
@@ -1,79 +0,0 @@
-# -*- coding: utf-8 -*-
-import datetime
-from south.db import db
-from south.v2 import SchemaMigration
-from django.db import models
-
-
-class Migration(SchemaMigration):
-
-    def forwards(self, orm):
-        # Adding field 'CurriculumCourse.accusative'
-        db.add_column('curriculum_curriculumcourse', 'accusative',
-                      self.gf('django.db.models.fields.CharField')(default='', max_length=255),
-                      keep_default=False)
-
-        if not db.dry_run:
-            orm.CurriculumCourse.objects.all().update(accusative=models.F('title'))
-
-
-    def backwards(self, orm):
-        # Deleting field 'CurriculumCourse.accusative'
-        db.delete_column('curriculum_curriculumcourse', 'accusative')
-
-
-    models = {
-        'curriculum.competence': {
-            'Meta': {'ordering': "['order']", 'object_name': 'Competence'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
-            'order': ('django.db.models.fields.IntegerField', [], {}),
-            'section': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['curriculum.Section']"}),
-            'slug': ('django.db.models.fields.SlugField', [], {'max_length': '50'})
-        },
-        'curriculum.competencelevel': {
-            'Meta': {'ordering': "['competence', 'level']", 'object_name': 'CompetenceLevel'},
-            'competence': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['curriculum.Competence']"}),
-            'description': ('django.db.models.fields.TextField', [], {}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'level': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['curriculum.Level']"})
-        },
-        'curriculum.curriculum': {
-            'Meta': {'object_name': 'Curriculum'},
-            'course': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['curriculum.CurriculumCourse']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'identifier': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}),
-            'level': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['curriculum.CurriculumLevel']"}),
-            'title': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
-            'type': ('django.db.models.fields.CharField', [], {'max_length': '16'})
-        },
-        'curriculum.curriculumcourse': {
-            'Meta': {'object_name': 'CurriculumCourse'},
-            'accusative': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'slug': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}),
-            'title': ('django.db.models.fields.CharField', [], {'max_length': '255'})
-        },
-        'curriculum.curriculumlevel': {
-            'Meta': {'object_name': 'CurriculumLevel'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'title': ('django.db.models.fields.CharField', [], {'max_length': '16', 'db_index': 'True'})
-        },
-        'curriculum.level': {
-            'Meta': {'ordering': "['order']", 'object_name': 'Level'},
-            'group': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
-            'order': ('django.db.models.fields.IntegerField', [], {}),
-            'slug': ('django.db.models.fields.CharField', [], {'max_length': '255'})
-        },
-        'curriculum.section': {
-            'Meta': {'ordering': "['order']", 'object_name': 'Section'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
-            'order': ('django.db.models.fields.IntegerField', [], {}),
-            'slug': ('django.db.models.fields.SlugField', [], {'max_length': '50'})
-        }
-    }
-
-    complete_apps = ['curriculum']
diff --git a/curriculum/migrations/0006_auto__add_field_competencelevel_description_pl__add_field_competencele.py b/curriculum/migrations/0006_auto__add_field_competencelevel_description_pl__add_field_competencele.py
deleted file mode 100644 (file)
index d62e37a..0000000
+++ /dev/null
@@ -1,158 +0,0 @@
-# -*- coding: utf-8 -*-
-import datetime
-from south.db import db
-from south.v2 import SchemaMigration
-from django.db import models
-
-
-class Migration(SchemaMigration):
-
-    def forwards(self, orm):
-        # Adding field 'CompetenceLevel.description_pl'
-        db.add_column(u'curriculum_competencelevel', 'description_pl',
-                      self.gf('django.db.models.fields.TextField')(null=True),
-                      keep_default=False)
-
-        # Adding field 'CompetenceLevel.description_en'
-        db.add_column(u'curriculum_competencelevel', 'description_en',
-                      self.gf('django.db.models.fields.TextField')(null=True),
-                      keep_default=False)
-
-        # Adding field 'Section.name_pl'
-        db.add_column(u'curriculum_section', 'name_pl',
-                      self.gf('django.db.models.fields.CharField')(max_length=255, null=True),
-                      keep_default=False)
-
-        # Adding field 'Section.name_en'
-        db.add_column(u'curriculum_section', 'name_en',
-                      self.gf('django.db.models.fields.CharField')(max_length=255, null=True),
-                      keep_default=False)
-
-        # Adding field 'Competence.name_pl'
-        db.add_column(u'curriculum_competence', 'name_pl',
-                      self.gf('django.db.models.fields.CharField')(max_length=255, null=True),
-                      keep_default=False)
-
-        # Adding field 'Competence.name_en'
-        db.add_column(u'curriculum_competence', 'name_en',
-                      self.gf('django.db.models.fields.CharField')(max_length=255, null=True),
-                      keep_default=False)
-
-        # Adding field 'Level.name_pl'
-        db.add_column(u'curriculum_level', 'name_pl',
-                      self.gf('django.db.models.fields.CharField')(max_length=255, null=True),
-                      keep_default=False)
-
-        # Adding field 'Level.name_en'
-        db.add_column(u'curriculum_level', 'name_en',
-                      self.gf('django.db.models.fields.CharField')(max_length=255, null=True),
-                      keep_default=False)
-
-        # Adding field 'Level.group_pl'
-        db.add_column(u'curriculum_level', 'group_pl',
-                      self.gf('django.db.models.fields.CharField')(max_length=255, null=True),
-                      keep_default=False)
-
-        # Adding field 'Level.group_en'
-        db.add_column(u'curriculum_level', 'group_en',
-                      self.gf('django.db.models.fields.CharField')(max_length=255, null=True),
-                      keep_default=False)
-
-
-    def backwards(self, orm):
-        # Deleting field 'CompetenceLevel.description_pl'
-        db.delete_column(u'curriculum_competencelevel', 'description_pl')
-
-        # Deleting field 'CompetenceLevel.description_en'
-        db.delete_column(u'curriculum_competencelevel', 'description_en')
-
-        # Deleting field 'Section.name_pl'
-        db.delete_column(u'curriculum_section', 'name_pl')
-
-        # Deleting field 'Section.name_en'
-        db.delete_column(u'curriculum_section', 'name_en')
-
-        # Deleting field 'Competence.name_pl'
-        db.delete_column(u'curriculum_competence', 'name_pl')
-
-        # Deleting field 'Competence.name_en'
-        db.delete_column(u'curriculum_competence', 'name_en')
-
-        # Deleting field 'Level.name_pl'
-        db.delete_column(u'curriculum_level', 'name_pl')
-
-        # Deleting field 'Level.name_en'
-        db.delete_column(u'curriculum_level', 'name_en')
-
-        # Deleting field 'Level.group_pl'
-        db.delete_column(u'curriculum_level', 'group_pl')
-
-        # Deleting field 'Level.group_en'
-        db.delete_column(u'curriculum_level', 'group_en')
-
-
-    models = {
-        u'curriculum.competence': {
-            'Meta': {'ordering': "['section', 'order']", 'object_name': 'Competence'},
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
-            'name_en': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True'}),
-            'name_pl': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True'}),
-            'order': ('django.db.models.fields.IntegerField', [], {}),
-            'section': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['curriculum.Section']"}),
-            'slug': ('django.db.models.fields.SlugField', [], {'max_length': '50'})
-        },
-        u'curriculum.competencelevel': {
-            'Meta': {'ordering': "['competence', 'level']", 'object_name': 'CompetenceLevel'},
-            'competence': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['curriculum.Competence']"}),
-            'description': ('django.db.models.fields.TextField', [], {}),
-            'description_en': ('django.db.models.fields.TextField', [], {'null': 'True'}),
-            'description_pl': ('django.db.models.fields.TextField', [], {'null': 'True'}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'level': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['curriculum.Level']"})
-        },
-        u'curriculum.curriculum': {
-            'Meta': {'object_name': 'Curriculum'},
-            'course': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['curriculum.CurriculumCourse']"}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'identifier': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}),
-            'level': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['curriculum.CurriculumLevel']"}),
-            'title': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
-            'type': ('django.db.models.fields.CharField', [], {'max_length': '16'})
-        },
-        u'curriculum.curriculumcourse': {
-            'Meta': {'ordering': "['slug']", 'object_name': 'CurriculumCourse'},
-            'accusative': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'slug': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}),
-            'title': ('django.db.models.fields.CharField', [], {'max_length': '255'})
-        },
-        u'curriculum.curriculumlevel': {
-            'Meta': {'object_name': 'CurriculumLevel'},
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'title': ('django.db.models.fields.CharField', [], {'max_length': '16', 'db_index': 'True'})
-        },
-        u'curriculum.level': {
-            'Meta': {'ordering': "['order']", 'object_name': 'Level'},
-            'group': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
-            'group_en': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True'}),
-            'group_pl': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True'}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
-            'name_en': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True'}),
-            'name_pl': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True'}),
-            'order': ('django.db.models.fields.IntegerField', [], {}),
-            'slug': ('django.db.models.fields.CharField', [], {'max_length': '255'})
-        },
-        u'curriculum.section': {
-            'Meta': {'ordering': "['order']", 'object_name': 'Section'},
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
-            'name_en': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True'}),
-            'name_pl': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True'}),
-            'order': ('django.db.models.fields.IntegerField', [], {}),
-            'slug': ('django.db.models.fields.SlugField', [], {'max_length': '50'})
-        }
-    }
-
-    complete_apps = ['curriculum']
\ No newline at end of file
diff --git a/curriculum/migrations/0007_translatable_fields_data_migration.py b/curriculum/migrations/0007_translatable_fields_data_migration.py
deleted file mode 100644 (file)
index f881621..0000000
+++ /dev/null
@@ -1,92 +0,0 @@
-# -*- coding: utf-8 -*-
-import datetime
-from south.db import db
-from south.v2 import DataMigration
-from django.db import models
-
-class Migration(DataMigration):
-
-    def forwards(self, orm):
-        for section in orm.Section.objects.all():
-            section.name_pl = section.name_en = section.name
-            section.save()
-        for competence in orm.Competence.objects.all():
-            competence.name_pl = competence.name_en = competence.name
-            competence.save()
-        for level in orm.Level.objects.all():
-            level.name_pl = level.name_en = level.name
-            level.group_pl = level.group_en = level.group
-            level.save()
-        for competence_level in orm.CompetenceLevel.objects.all():
-            competence_level.description_pl = competence_level.description_en = competence_level.description
-            competence_level.save()
-
-    def backwards(self, orm):
-        raise RuntimeError("Cannot reverse this migration.")
-
-    models = {
-        u'curriculum.competence': {
-            'Meta': {'ordering': "['section', 'order']", 'object_name': 'Competence'},
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
-            'name_en': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True'}),
-            'name_pl': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True'}),
-            'order': ('django.db.models.fields.IntegerField', [], {}),
-            'section': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['curriculum.Section']"}),
-            'slug': ('django.db.models.fields.SlugField', [], {'max_length': '50'})
-        },
-        u'curriculum.competencelevel': {
-            'Meta': {'ordering': "['competence', 'level']", 'object_name': 'CompetenceLevel'},
-            'competence': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['curriculum.Competence']"}),
-            'description': ('django.db.models.fields.TextField', [], {}),
-            'description_en': ('django.db.models.fields.TextField', [], {'null': 'True'}),
-            'description_pl': ('django.db.models.fields.TextField', [], {'null': 'True'}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'level': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['curriculum.Level']"})
-        },
-        u'curriculum.curriculum': {
-            'Meta': {'object_name': 'Curriculum'},
-            'course': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['curriculum.CurriculumCourse']"}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'identifier': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}),
-            'level': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['curriculum.CurriculumLevel']"}),
-            'title': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
-            'type': ('django.db.models.fields.CharField', [], {'max_length': '16'})
-        },
-        u'curriculum.curriculumcourse': {
-            'Meta': {'ordering': "['slug']", 'object_name': 'CurriculumCourse'},
-            'accusative': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'slug': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}),
-            'title': ('django.db.models.fields.CharField', [], {'max_length': '255'})
-        },
-        u'curriculum.curriculumlevel': {
-            'Meta': {'object_name': 'CurriculumLevel'},
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'title': ('django.db.models.fields.CharField', [], {'max_length': '16', 'db_index': 'True'})
-        },
-        u'curriculum.level': {
-            'Meta': {'ordering': "['order']", 'object_name': 'Level'},
-            'group': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
-            'group_en': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True'}),
-            'group_pl': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True'}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
-            'name_en': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True'}),
-            'name_pl': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True'}),
-            'order': ('django.db.models.fields.IntegerField', [], {}),
-            'slug': ('django.db.models.fields.CharField', [], {'max_length': '255'})
-        },
-        u'curriculum.section': {
-            'Meta': {'ordering': "['order']", 'object_name': 'Section'},
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
-            'name_en': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True'}),
-            'name_pl': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True'}),
-            'order': ('django.db.models.fields.IntegerField', [], {}),
-            'slug': ('django.db.models.fields.SlugField', [], {'max_length': '50'})
-        }
-    }
-
-    complete_apps = ['curriculum']
-    symmetrical = True
diff --git a/curriculum/migrations/0008_auto__del_field_competencelevel_description__del_field_section_name__d.py b/curriculum/migrations/0008_auto__del_field_competencelevel_description__del_field_section_name__d.py
deleted file mode 100644 (file)
index 4c0a89a..0000000
+++ /dev/null
@@ -1,103 +0,0 @@
-# -*- coding: utf-8 -*-
-import datetime
-from south.db import db
-from south.v2 import SchemaMigration
-from django.db import models
-
-
-class Migration(SchemaMigration):
-
-    def forwards(self, orm):
-        # Deleting field 'CompetenceLevel.description'
-        db.delete_column(u'curriculum_competencelevel', 'description')
-
-        # Deleting field 'Section.name'
-        db.delete_column(u'curriculum_section', 'name')
-
-        # Deleting field 'Competence.name'
-        db.delete_column(u'curriculum_competence', 'name')
-
-        # Deleting field 'Level.group'
-        db.delete_column(u'curriculum_level', 'group')
-
-        # Deleting field 'Level.name'
-        db.delete_column(u'curriculum_level', 'name')
-
-
-    def backwards(self, orm):
-
-        # User chose to not deal with backwards NULL issues for 'CompetenceLevel.description'
-        raise RuntimeError("Cannot reverse this migration. 'CompetenceLevel.description' and its values cannot be restored.")
-
-        # User chose to not deal with backwards NULL issues for 'Section.name'
-        raise RuntimeError("Cannot reverse this migration. 'Section.name' and its values cannot be restored.")
-
-        # User chose to not deal with backwards NULL issues for 'Competence.name'
-        raise RuntimeError("Cannot reverse this migration. 'Competence.name' and its values cannot be restored.")
-
-        # User chose to not deal with backwards NULL issues for 'Level.group'
-        raise RuntimeError("Cannot reverse this migration. 'Level.group' and its values cannot be restored.")
-
-        # User chose to not deal with backwards NULL issues for 'Level.name'
-        raise RuntimeError("Cannot reverse this migration. 'Level.name' and its values cannot be restored.")
-
-    models = {
-        u'curriculum.competence': {
-            'Meta': {'ordering': "['section', 'order']", 'object_name': 'Competence'},
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name_en': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True'}),
-            'name_pl': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True'}),
-            'order': ('django.db.models.fields.IntegerField', [], {}),
-            'section': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['curriculum.Section']"}),
-            'slug': ('django.db.models.fields.SlugField', [], {'max_length': '50'})
-        },
-        u'curriculum.competencelevel': {
-            'Meta': {'ordering': "['competence', 'level']", 'object_name': 'CompetenceLevel'},
-            'competence': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['curriculum.Competence']"}),
-            'description_en': ('django.db.models.fields.TextField', [], {'null': 'True'}),
-            'description_pl': ('django.db.models.fields.TextField', [], {'null': 'True'}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'level': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['curriculum.Level']"})
-        },
-        u'curriculum.curriculum': {
-            'Meta': {'object_name': 'Curriculum'},
-            'course': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['curriculum.CurriculumCourse']"}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'identifier': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}),
-            'level': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['curriculum.CurriculumLevel']"}),
-            'title': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
-            'type': ('django.db.models.fields.CharField', [], {'max_length': '16'})
-        },
-        u'curriculum.curriculumcourse': {
-            'Meta': {'ordering': "['slug']", 'object_name': 'CurriculumCourse'},
-            'accusative': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'slug': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}),
-            'title': ('django.db.models.fields.CharField', [], {'max_length': '255'})
-        },
-        u'curriculum.curriculumlevel': {
-            'Meta': {'object_name': 'CurriculumLevel'},
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'title': ('django.db.models.fields.CharField', [], {'max_length': '16', 'db_index': 'True'})
-        },
-        u'curriculum.level': {
-            'Meta': {'ordering': "['order']", 'object_name': 'Level'},
-            'group_en': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True'}),
-            'group_pl': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True'}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name_en': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True'}),
-            'name_pl': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True'}),
-            'order': ('django.db.models.fields.IntegerField', [], {}),
-            'slug': ('django.db.models.fields.CharField', [], {'max_length': '255'})
-        },
-        u'curriculum.section': {
-            'Meta': {'ordering': "['order']", 'object_name': 'Section'},
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name_en': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True'}),
-            'name_pl': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True'}),
-            'order': ('django.db.models.fields.IntegerField', [], {}),
-            'slug': ('django.db.models.fields.SlugField', [], {'max_length': '50'})
-        }
-    }
-
-    complete_apps = ['curriculum']
\ No newline at end of file
diff --git a/curriculum/migrations/0009_auto__chg_field_competencelevel_description_en__chg_field_competencele.py b/curriculum/migrations/0009_auto__chg_field_competencelevel_description_en__chg_field_competencele.py
deleted file mode 100644 (file)
index 4fbdde5..0000000
+++ /dev/null
@@ -1,133 +0,0 @@
-# -*- coding: utf-8 -*-
-import datetime
-from south.db import db
-from south.v2 import SchemaMigration
-from django.db import models
-
-
-class Migration(SchemaMigration):
-
-    def forwards(self, orm):
-
-        # Changing field 'CompetenceLevel.description_en'
-        db.alter_column(u'curriculum_competencelevel', 'description_en', self.gf('django.db.models.fields.TextField')())
-
-        # Changing field 'CompetenceLevel.description_pl'
-        db.alter_column(u'curriculum_competencelevel', 'description_pl', self.gf('django.db.models.fields.TextField')())
-
-        # Changing field 'Section.name_en'
-        db.alter_column(u'curriculum_section', 'name_en', self.gf('django.db.models.fields.CharField')(max_length=255))
-
-        # Changing field 'Section.name_pl'
-        db.alter_column(u'curriculum_section', 'name_pl', self.gf('django.db.models.fields.CharField')(max_length=255))
-
-        # Changing field 'Competence.name_pl'
-        db.alter_column(u'curriculum_competence', 'name_pl', self.gf('django.db.models.fields.CharField')(max_length=255))
-
-        # Changing field 'Competence.name_en'
-        db.alter_column(u'curriculum_competence', 'name_en', self.gf('django.db.models.fields.CharField')(max_length=255))
-
-        # Changing field 'Level.name_pl'
-        db.alter_column(u'curriculum_level', 'name_pl', self.gf('django.db.models.fields.CharField')(max_length=255))
-
-        # Changing field 'Level.group_pl'
-        db.alter_column(u'curriculum_level', 'group_pl', self.gf('django.db.models.fields.CharField')(max_length=255))
-
-        # Changing field 'Level.group_en'
-        db.alter_column(u'curriculum_level', 'group_en', self.gf('django.db.models.fields.CharField')(max_length=255))
-
-        # Changing field 'Level.name_en'
-        db.alter_column(u'curriculum_level', 'name_en', self.gf('django.db.models.fields.CharField')(max_length=255))
-
-    def backwards(self, orm):
-
-        # Changing field 'CompetenceLevel.description_en'
-        db.alter_column(u'curriculum_competencelevel', 'description_en', self.gf('django.db.models.fields.TextField')(null=True))
-
-        # Changing field 'CompetenceLevel.description_pl'
-        db.alter_column(u'curriculum_competencelevel', 'description_pl', self.gf('django.db.models.fields.TextField')(null=True))
-
-        # Changing field 'Section.name_en'
-        db.alter_column(u'curriculum_section', 'name_en', self.gf('django.db.models.fields.CharField')(max_length=255, null=True))
-
-        # Changing field 'Section.name_pl'
-        db.alter_column(u'curriculum_section', 'name_pl', self.gf('django.db.models.fields.CharField')(max_length=255, null=True))
-
-        # Changing field 'Competence.name_pl'
-        db.alter_column(u'curriculum_competence', 'name_pl', self.gf('django.db.models.fields.CharField')(max_length=255, null=True))
-
-        # Changing field 'Competence.name_en'
-        db.alter_column(u'curriculum_competence', 'name_en', self.gf('django.db.models.fields.CharField')(max_length=255, null=True))
-
-        # Changing field 'Level.name_pl'
-        db.alter_column(u'curriculum_level', 'name_pl', self.gf('django.db.models.fields.CharField')(max_length=255, null=True))
-
-        # Changing field 'Level.group_pl'
-        db.alter_column(u'curriculum_level', 'group_pl', self.gf('django.db.models.fields.CharField')(max_length=255, null=True))
-
-        # Changing field 'Level.group_en'
-        db.alter_column(u'curriculum_level', 'group_en', self.gf('django.db.models.fields.CharField')(max_length=255, null=True))
-
-        # Changing field 'Level.name_en'
-        db.alter_column(u'curriculum_level', 'name_en', self.gf('django.db.models.fields.CharField')(max_length=255, null=True))
-
-    models = {
-        u'curriculum.competence': {
-            'Meta': {'ordering': "['section', 'order']", 'object_name': 'Competence'},
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name_en': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
-            'name_pl': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
-            'order': ('django.db.models.fields.IntegerField', [], {}),
-            'section': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['curriculum.Section']"}),
-            'slug': ('django.db.models.fields.SlugField', [], {'max_length': '50'})
-        },
-        u'curriculum.competencelevel': {
-            'Meta': {'ordering': "['competence', 'level']", 'object_name': 'CompetenceLevel'},
-            'competence': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['curriculum.Competence']"}),
-            'description_en': ('django.db.models.fields.TextField', [], {'default': "''"}),
-            'description_pl': ('django.db.models.fields.TextField', [], {'default': "''"}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'level': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['curriculum.Level']"})
-        },
-        u'curriculum.curriculum': {
-            'Meta': {'object_name': 'Curriculum'},
-            'course': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['curriculum.CurriculumCourse']"}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'identifier': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}),
-            'level': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['curriculum.CurriculumLevel']"}),
-            'title': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
-            'type': ('django.db.models.fields.CharField', [], {'max_length': '16'})
-        },
-        u'curriculum.curriculumcourse': {
-            'Meta': {'ordering': "['slug']", 'object_name': 'CurriculumCourse'},
-            'accusative': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'slug': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}),
-            'title': ('django.db.models.fields.CharField', [], {'max_length': '255'})
-        },
-        u'curriculum.curriculumlevel': {
-            'Meta': {'object_name': 'CurriculumLevel'},
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'title': ('django.db.models.fields.CharField', [], {'max_length': '16', 'db_index': 'True'})
-        },
-        u'curriculum.level': {
-            'Meta': {'ordering': "['order']", 'object_name': 'Level'},
-            'group_en': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
-            'group_pl': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name_en': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
-            'name_pl': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
-            'order': ('django.db.models.fields.IntegerField', [], {}),
-            'slug': ('django.db.models.fields.CharField', [], {'max_length': '255'})
-        },
-        u'curriculum.section': {
-            'Meta': {'ordering': "['order']", 'object_name': 'Section'},
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name_en': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
-            'name_pl': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
-            'order': ('django.db.models.fields.IntegerField', [], {}),
-            'slug': ('django.db.models.fields.SlugField', [], {'max_length': '50'})
-        }
-    }
-
-    complete_apps = ['curriculum']
\ No newline at end of file
diff --git a/curriculum/migrations/0010_auto__add_field_level_meta_name.py b/curriculum/migrations/0010_auto__add_field_level_meta_name.py
deleted file mode 100644 (file)
index 24fc996..0000000
+++ /dev/null
@@ -1,82 +0,0 @@
-# -*- coding: utf-8 -*-
-import datetime
-from south.db import db
-from south.v2 import SchemaMigration
-from django.db import models
-
-
-class Migration(SchemaMigration):
-
-    def forwards(self, orm):
-        # Adding field 'Level.meta_name'
-        db.add_column(u'curriculum_level', 'meta_name',
-                      self.gf('django.db.models.fields.CharField')(default=' ', max_length=255),
-                      keep_default=False)
-
-
-    def backwards(self, orm):
-        # Deleting field 'Level.meta_name'
-        db.delete_column(u'curriculum_level', 'meta_name')
-
-
-    models = {
-        u'curriculum.competence': {
-            'Meta': {'ordering': "['section', 'order']", 'object_name': 'Competence'},
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name_en': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
-            'name_pl': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
-            'order': ('django.db.models.fields.IntegerField', [], {}),
-            'section': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['curriculum.Section']"}),
-            'slug': ('django.db.models.fields.SlugField', [], {'max_length': '50'})
-        },
-        u'curriculum.competencelevel': {
-            'Meta': {'ordering': "['competence', 'level']", 'object_name': 'CompetenceLevel'},
-            'competence': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['curriculum.Competence']"}),
-            'description_en': ('django.db.models.fields.TextField', [], {'default': "''"}),
-            'description_pl': ('django.db.models.fields.TextField', [], {'default': "''"}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'level': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['curriculum.Level']"})
-        },
-        u'curriculum.curriculum': {
-            'Meta': {'object_name': 'Curriculum'},
-            'course': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['curriculum.CurriculumCourse']"}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'identifier': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}),
-            'level': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['curriculum.CurriculumLevel']"}),
-            'title': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
-            'type': ('django.db.models.fields.CharField', [], {'max_length': '16'})
-        },
-        u'curriculum.curriculumcourse': {
-            'Meta': {'ordering': "['slug']", 'object_name': 'CurriculumCourse'},
-            'accusative': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'slug': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}),
-            'title': ('django.db.models.fields.CharField', [], {'max_length': '255'})
-        },
-        u'curriculum.curriculumlevel': {
-            'Meta': {'object_name': 'CurriculumLevel'},
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'title': ('django.db.models.fields.CharField', [], {'max_length': '16', 'db_index': 'True'})
-        },
-        u'curriculum.level': {
-            'Meta': {'ordering': "['order']", 'object_name': 'Level'},
-            'group_en': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
-            'group_pl': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'meta_name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
-            'name_en': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
-            'name_pl': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
-            'order': ('django.db.models.fields.IntegerField', [], {}),
-            'slug': ('django.db.models.fields.CharField', [], {'max_length': '255'})
-        },
-        u'curriculum.section': {
-            'Meta': {'ordering': "['order']", 'object_name': 'Section'},
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name_en': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
-            'name_pl': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
-            'order': ('django.db.models.fields.IntegerField', [], {}),
-            'slug': ('django.db.models.fields.SlugField', [], {'max_length': '50'})
-        }
-    }
-
-    complete_apps = ['curriculum']
\ No newline at end of file
diff --git a/curriculum/migrations/0011_meta_name.py b/curriculum/migrations/0011_meta_name.py
deleted file mode 100644 (file)
index 0539ae7..0000000
+++ /dev/null
@@ -1,77 +0,0 @@
-# -*- coding: utf-8 -*-
-import datetime
-from south.db import db
-from south.v2 import DataMigration
-from django.db import models
-
-class Migration(DataMigration):
-
-    def forwards(self, orm):
-        "Write your forwards methods here."
-        orm.Level.objects.all().update(meta_name=models.F('slug'))
-
-    def backwards(self, orm):
-        "Write your backwards methods here."
-
-    models = {
-        u'curriculum.competence': {
-            'Meta': {'ordering': "['section', 'order']", 'object_name': 'Competence'},
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name_en': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
-            'name_pl': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
-            'order': ('django.db.models.fields.IntegerField', [], {}),
-            'section': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['curriculum.Section']"}),
-            'slug': ('django.db.models.fields.SlugField', [], {'max_length': '50'})
-        },
-        u'curriculum.competencelevel': {
-            'Meta': {'ordering': "['competence', 'level']", 'object_name': 'CompetenceLevel'},
-            'competence': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['curriculum.Competence']"}),
-            'description_en': ('django.db.models.fields.TextField', [], {'default': "''"}),
-            'description_pl': ('django.db.models.fields.TextField', [], {'default': "''"}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'level': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['curriculum.Level']"})
-        },
-        u'curriculum.curriculum': {
-            'Meta': {'object_name': 'Curriculum'},
-            'course': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['curriculum.CurriculumCourse']"}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'identifier': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}),
-            'level': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['curriculum.CurriculumLevel']"}),
-            'title': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
-            'type': ('django.db.models.fields.CharField', [], {'max_length': '16'})
-        },
-        u'curriculum.curriculumcourse': {
-            'Meta': {'ordering': "['slug']", 'object_name': 'CurriculumCourse'},
-            'accusative': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'slug': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}),
-            'title': ('django.db.models.fields.CharField', [], {'max_length': '255'})
-        },
-        u'curriculum.curriculumlevel': {
-            'Meta': {'object_name': 'CurriculumLevel'},
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'title': ('django.db.models.fields.CharField', [], {'max_length': '16', 'db_index': 'True'})
-        },
-        u'curriculum.level': {
-            'Meta': {'ordering': "['order']", 'object_name': 'Level'},
-            'group_en': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
-            'group_pl': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'meta_name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
-            'name_en': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
-            'name_pl': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
-            'order': ('django.db.models.fields.IntegerField', [], {}),
-            'slug': ('django.db.models.fields.CharField', [], {'max_length': '255'})
-        },
-        u'curriculum.section': {
-            'Meta': {'ordering': "['order']", 'object_name': 'Section'},
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name_en': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
-            'name_pl': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
-            'order': ('django.db.models.fields.IntegerField', [], {}),
-            'slug': ('django.db.models.fields.SlugField', [], {'max_length': '50'})
-        }
-    }
-
-    complete_apps = ['curriculum']
-    symmetrical = True
diff --git a/curriculum/migrations/0012_auto__add_unique_level_meta_name__add_unique_level_slug.py b/curriculum/migrations/0012_auto__add_unique_level_meta_name__add_unique_level_slug.py
deleted file mode 100644 (file)
index f9fa032..0000000
+++ /dev/null
@@ -1,86 +0,0 @@
-# -*- coding: utf-8 -*-
-import datetime
-from south.db import db
-from south.v2 import SchemaMigration
-from django.db import models
-
-
-class Migration(SchemaMigration):
-
-    def forwards(self, orm):
-        # Adding unique constraint on 'Level', fields ['meta_name']
-        db.create_unique(u'curriculum_level', ['meta_name'])
-
-        # Adding unique constraint on 'Level', fields ['slug']
-        db.create_unique(u'curriculum_level', ['slug'])
-
-
-    def backwards(self, orm):
-        # Removing unique constraint on 'Level', fields ['slug']
-        db.delete_unique(u'curriculum_level', ['slug'])
-
-        # Removing unique constraint on 'Level', fields ['meta_name']
-        db.delete_unique(u'curriculum_level', ['meta_name'])
-
-
-    models = {
-        u'curriculum.competence': {
-            'Meta': {'ordering': "['section', 'order']", 'object_name': 'Competence'},
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name_en': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
-            'name_pl': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
-            'order': ('django.db.models.fields.IntegerField', [], {}),
-            'section': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['curriculum.Section']"}),
-            'slug': ('django.db.models.fields.SlugField', [], {'max_length': '50'})
-        },
-        u'curriculum.competencelevel': {
-            'Meta': {'ordering': "['competence', 'level']", 'object_name': 'CompetenceLevel'},
-            'competence': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['curriculum.Competence']"}),
-            'description_en': ('django.db.models.fields.TextField', [], {'default': "''"}),
-            'description_pl': ('django.db.models.fields.TextField', [], {'default': "''"}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'level': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['curriculum.Level']"})
-        },
-        u'curriculum.curriculum': {
-            'Meta': {'object_name': 'Curriculum'},
-            'course': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['curriculum.CurriculumCourse']"}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'identifier': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}),
-            'level': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['curriculum.CurriculumLevel']"}),
-            'title': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
-            'type': ('django.db.models.fields.CharField', [], {'max_length': '16'})
-        },
-        u'curriculum.curriculumcourse': {
-            'Meta': {'ordering': "['slug']", 'object_name': 'CurriculumCourse'},
-            'accusative': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'slug': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}),
-            'title': ('django.db.models.fields.CharField', [], {'max_length': '255'})
-        },
-        u'curriculum.curriculumlevel': {
-            'Meta': {'object_name': 'CurriculumLevel'},
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'title': ('django.db.models.fields.CharField', [], {'max_length': '16', 'db_index': 'True'})
-        },
-        u'curriculum.level': {
-            'Meta': {'ordering': "['order']", 'object_name': 'Level'},
-            'group_en': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
-            'group_pl': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'meta_name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'}),
-            'name_en': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
-            'name_pl': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
-            'order': ('django.db.models.fields.IntegerField', [], {}),
-            'slug': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'})
-        },
-        u'curriculum.section': {
-            'Meta': {'ordering': "['order']", 'object_name': 'Section'},
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name_en': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
-            'name_pl': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
-            'order': ('django.db.models.fields.IntegerField', [], {}),
-            'slug': ('django.db.models.fields.SlugField', [], {'max_length': '50'})
-        }
-    }
-
-    complete_apps = ['curriculum']
\ No newline at end of file
diff --git a/curriculum/migrations/0013_auto__add_field_level_package__add_field_level_student_package.py b/curriculum/migrations/0013_auto__add_field_level_package__add_field_level_student_package.py
deleted file mode 100644 (file)
index 4e0ee70..0000000
+++ /dev/null
@@ -1,92 +0,0 @@
-# -*- coding: utf-8 -*-
-import datetime
-from south.db import db
-from south.v2 import SchemaMigration
-from django.db import models
-
-
-class Migration(SchemaMigration):
-
-    def forwards(self, orm):
-        # Adding field 'Level.package'
-        db.add_column(u'curriculum_level', 'package',
-                      self.gf('django.db.models.fields.files.FileField')(max_length=255, null=True, blank=True),
-                      keep_default=False)
-
-        # Adding field 'Level.student_package'
-        db.add_column(u'curriculum_level', 'student_package',
-                      self.gf('django.db.models.fields.files.FileField')(max_length=255, null=True, blank=True),
-                      keep_default=False)
-
-
-    def backwards(self, orm):
-        # Deleting field 'Level.package'
-        db.delete_column(u'curriculum_level', 'package')
-
-        # Deleting field 'Level.student_package'
-        db.delete_column(u'curriculum_level', 'student_package')
-
-
-    models = {
-        u'curriculum.competence': {
-            'Meta': {'ordering': "['section', 'order']", 'object_name': 'Competence'},
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name_en': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
-            'name_pl': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
-            'order': ('django.db.models.fields.IntegerField', [], {}),
-            'section': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['curriculum.Section']"}),
-            'slug': ('django.db.models.fields.SlugField', [], {'max_length': '50'})
-        },
-        u'curriculum.competencelevel': {
-            'Meta': {'ordering': "['competence', 'level']", 'object_name': 'CompetenceLevel'},
-            'competence': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['curriculum.Competence']"}),
-            'description_en': ('django.db.models.fields.TextField', [], {'default': "''"}),
-            'description_pl': ('django.db.models.fields.TextField', [], {'default': "''"}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'level': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['curriculum.Level']"})
-        },
-        u'curriculum.curriculum': {
-            'Meta': {'object_name': 'Curriculum'},
-            'course': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['curriculum.CurriculumCourse']"}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'identifier': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}),
-            'level': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['curriculum.CurriculumLevel']"}),
-            'title': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
-            'type': ('django.db.models.fields.CharField', [], {'max_length': '16'})
-        },
-        u'curriculum.curriculumcourse': {
-            'Meta': {'ordering': "['slug']", 'object_name': 'CurriculumCourse'},
-            'accusative': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'slug': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}),
-            'title': ('django.db.models.fields.CharField', [], {'max_length': '255'})
-        },
-        u'curriculum.curriculumlevel': {
-            'Meta': {'object_name': 'CurriculumLevel'},
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'title': ('django.db.models.fields.CharField', [], {'max_length': '16', 'db_index': 'True'})
-        },
-        u'curriculum.level': {
-            'Meta': {'ordering': "['order']", 'object_name': 'Level'},
-            'group_en': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
-            'group_pl': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'meta_name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'}),
-            'name_en': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
-            'name_pl': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
-            'order': ('django.db.models.fields.IntegerField', [], {}),
-            'package': ('django.db.models.fields.files.FileField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
-            'slug': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'}),
-            'student_package': ('django.db.models.fields.files.FileField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'})
-        },
-        u'curriculum.section': {
-            'Meta': {'ordering': "['order']", 'object_name': 'Section'},
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name_en': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
-            'name_pl': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
-            'order': ('django.db.models.fields.IntegerField', [], {}),
-            'slug': ('django.db.models.fields.SlugField', [], {'max_length': '50'})
-        }
-    }
-
-    complete_apps = ['curriculum']
\ No newline at end of file
diff --git a/curriculum/migrations/0014_auto__add_unique_curriculum_identifier.py b/curriculum/migrations/0014_auto__add_unique_curriculum_identifier.py
deleted file mode 100644 (file)
index 4c85c7e..0000000
+++ /dev/null
@@ -1,82 +0,0 @@
-# -*- coding: utf-8 -*-
-from south.utils import datetime_utils as datetime
-from south.db import db
-from south.v2 import SchemaMigration
-from django.db import models
-
-
-class Migration(SchemaMigration):
-
-    def forwards(self, orm):
-        # Adding unique constraint on 'Curriculum', fields ['identifier']
-        db.create_unique(u'curriculum_curriculum', ['identifier'])
-
-
-    def backwards(self, orm):
-        # Removing unique constraint on 'Curriculum', fields ['identifier']
-        db.delete_unique(u'curriculum_curriculum', ['identifier'])
-
-
-    models = {
-        u'curriculum.competence': {
-            'Meta': {'ordering': "['section', 'order']", 'object_name': 'Competence'},
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name_en': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
-            'name_pl': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
-            'order': ('django.db.models.fields.IntegerField', [], {}),
-            'section': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['curriculum.Section']"}),
-            'slug': ('django.db.models.fields.SlugField', [], {'max_length': '50'})
-        },
-        u'curriculum.competencelevel': {
-            'Meta': {'ordering': "['competence', 'level']", 'object_name': 'CompetenceLevel'},
-            'competence': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['curriculum.Competence']"}),
-            'description_en': ('django.db.models.fields.TextField', [], {'default': "''"}),
-            'description_pl': ('django.db.models.fields.TextField', [], {'default': "''"}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'level': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['curriculum.Level']"})
-        },
-        u'curriculum.curriculum': {
-            'Meta': {'ordering': "['identifier']", 'object_name': 'Curriculum'},
-            'course': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['curriculum.CurriculumCourse']"}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'identifier': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255', 'db_index': 'True'}),
-            'level': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['curriculum.CurriculumLevel']"}),
-            'title': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
-            'type': ('django.db.models.fields.CharField', [], {'max_length': '16'})
-        },
-        u'curriculum.curriculumcourse': {
-            'Meta': {'ordering': "['slug']", 'object_name': 'CurriculumCourse'},
-            'accusative': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'slug': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}),
-            'title': ('django.db.models.fields.CharField', [], {'max_length': '255'})
-        },
-        u'curriculum.curriculumlevel': {
-            'Meta': {'object_name': 'CurriculumLevel'},
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'title': ('django.db.models.fields.CharField', [], {'max_length': '16', 'db_index': 'True'})
-        },
-        u'curriculum.level': {
-            'Meta': {'ordering': "['order']", 'object_name': 'Level'},
-            'group_en': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
-            'group_pl': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'meta_name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'}),
-            'name_en': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
-            'name_pl': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
-            'order': ('django.db.models.fields.IntegerField', [], {}),
-            'package': ('django.db.models.fields.files.FileField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
-            'slug': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'}),
-            'student_package': ('django.db.models.fields.files.FileField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'})
-        },
-        u'curriculum.section': {
-            'Meta': {'ordering': "['order']", 'object_name': 'Section'},
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name_en': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
-            'name_pl': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
-            'order': ('django.db.models.fields.IntegerField', [], {}),
-            'slug': ('django.db.models.fields.SlugField', [], {'max_length': '50'})
-        }
-    }
-
-    complete_apps = ['curriculum']
\ No newline at end of file
diff --git a/curriculum/migrations/0015_auto__chg_field_curriculum_title.py b/curriculum/migrations/0015_auto__chg_field_curriculum_title.py
deleted file mode 100644 (file)
index 3100293..0000000
+++ /dev/null
@@ -1,82 +0,0 @@
-# -*- coding: utf-8 -*-
-from south.utils import datetime_utils as datetime
-from south.db import db
-from south.v2 import SchemaMigration
-from django.db import models
-
-
-class Migration(SchemaMigration):
-
-    def forwards(self, orm):
-
-        # Changing field 'Curriculum.title'
-        db.alter_column(u'curriculum_curriculum', 'title', self.gf('django.db.models.fields.CharField')(max_length=1024))
-
-    def backwards(self, orm):
-
-        # Changing field 'Curriculum.title'
-        db.alter_column(u'curriculum_curriculum', 'title', self.gf('django.db.models.fields.CharField')(max_length=255))
-
-    models = {
-        u'curriculum.competence': {
-            'Meta': {'ordering': "['section', 'order']", 'object_name': 'Competence'},
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name_en': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
-            'name_pl': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
-            'order': ('django.db.models.fields.IntegerField', [], {}),
-            'section': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['curriculum.Section']"}),
-            'slug': ('django.db.models.fields.SlugField', [], {'max_length': '50'})
-        },
-        u'curriculum.competencelevel': {
-            'Meta': {'ordering': "['competence', 'level']", 'object_name': 'CompetenceLevel'},
-            'competence': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['curriculum.Competence']"}),
-            'description_en': ('django.db.models.fields.TextField', [], {'default': "''"}),
-            'description_pl': ('django.db.models.fields.TextField', [], {'default': "''"}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'level': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['curriculum.Level']"})
-        },
-        u'curriculum.curriculum': {
-            'Meta': {'ordering': "['identifier']", 'object_name': 'Curriculum'},
-            'course': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['curriculum.CurriculumCourse']"}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'identifier': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255', 'db_index': 'True'}),
-            'level': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['curriculum.CurriculumLevel']"}),
-            'title': ('django.db.models.fields.CharField', [], {'max_length': '1024'}),
-            'type': ('django.db.models.fields.CharField', [], {'max_length': '16'})
-        },
-        u'curriculum.curriculumcourse': {
-            'Meta': {'ordering': "['slug']", 'object_name': 'CurriculumCourse'},
-            'accusative': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'slug': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}),
-            'title': ('django.db.models.fields.CharField', [], {'max_length': '255'})
-        },
-        u'curriculum.curriculumlevel': {
-            'Meta': {'object_name': 'CurriculumLevel'},
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'title': ('django.db.models.fields.CharField', [], {'max_length': '16', 'db_index': 'True'})
-        },
-        u'curriculum.level': {
-            'Meta': {'ordering': "['order']", 'object_name': 'Level'},
-            'group_en': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
-            'group_pl': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'meta_name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'}),
-            'name_en': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
-            'name_pl': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
-            'order': ('django.db.models.fields.IntegerField', [], {}),
-            'package': ('django.db.models.fields.files.FileField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
-            'slug': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'}),
-            'student_package': ('django.db.models.fields.files.FileField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'})
-        },
-        u'curriculum.section': {
-            'Meta': {'ordering': "['order']", 'object_name': 'Section'},
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name_en': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
-            'name_pl': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
-            'order': ('django.db.models.fields.IntegerField', [], {}),
-            'slug': ('django.db.models.fields.SlugField', [], {'max_length': '50'})
-        }
-    }
-
-    complete_apps = ['curriculum']
\ No newline at end of file
diff --git a/curriculum/migrations/0016_auto__add_field_curriculumlevel_verbose.py b/curriculum/migrations/0016_auto__add_field_curriculumlevel_verbose.py
deleted file mode 100644 (file)
index d60b155..0000000
+++ /dev/null
@@ -1,85 +0,0 @@
-# -*- coding: utf-8 -*-
-from south.utils import datetime_utils as datetime
-from south.db import db
-from south.v2 import SchemaMigration
-from django.db import models
-
-
-class Migration(SchemaMigration):
-
-    def forwards(self, orm):
-        # Adding field 'CurriculumLevel.verbose'
-        db.add_column(u'curriculum_curriculumlevel', 'verbose',
-                      self.gf('django.db.models.fields.CharField')(default='', max_length=32),
-                      keep_default=False)
-
-
-    def backwards(self, orm):
-        # Deleting field 'CurriculumLevel.verbose'
-        db.delete_column(u'curriculum_curriculumlevel', 'verbose')
-
-
-    models = {
-        u'curriculum.competence': {
-            'Meta': {'ordering': "['section', 'order']", 'object_name': 'Competence'},
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name_en': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
-            'name_pl': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
-            'order': ('django.db.models.fields.IntegerField', [], {}),
-            'section': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['curriculum.Section']"}),
-            'slug': ('django.db.models.fields.SlugField', [], {'max_length': '50'})
-        },
-        u'curriculum.competencelevel': {
-            'Meta': {'ordering': "['competence', 'level']", 'object_name': 'CompetenceLevel'},
-            'competence': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['curriculum.Competence']"}),
-            'description_en': ('django.db.models.fields.TextField', [], {'default': "''"}),
-            'description_pl': ('django.db.models.fields.TextField', [], {'default': "''"}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'level': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['curriculum.Level']"})
-        },
-        u'curriculum.curriculum': {
-            'Meta': {'ordering': "['identifier']", 'object_name': 'Curriculum'},
-            'course': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['curriculum.CurriculumCourse']"}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'identifier': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255', 'db_index': 'True'}),
-            'level': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['curriculum.CurriculumLevel']"}),
-            'title': ('django.db.models.fields.CharField', [], {'max_length': '1024'}),
-            'type': ('django.db.models.fields.CharField', [], {'max_length': '16'})
-        },
-        u'curriculum.curriculumcourse': {
-            'Meta': {'ordering': "['slug']", 'object_name': 'CurriculumCourse'},
-            'accusative': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'slug': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}),
-            'title': ('django.db.models.fields.CharField', [], {'max_length': '255'})
-        },
-        u'curriculum.curriculumlevel': {
-            'Meta': {'object_name': 'CurriculumLevel'},
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'title': ('django.db.models.fields.CharField', [], {'max_length': '16', 'db_index': 'True'}),
-            'verbose': ('django.db.models.fields.CharField', [], {'max_length': '32'})
-        },
-        u'curriculum.level': {
-            'Meta': {'ordering': "['order']", 'object_name': 'Level'},
-            'group_en': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
-            'group_pl': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'meta_name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'}),
-            'name_en': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
-            'name_pl': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
-            'order': ('django.db.models.fields.IntegerField', [], {}),
-            'package': ('django.db.models.fields.files.FileField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
-            'slug': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'}),
-            'student_package': ('django.db.models.fields.files.FileField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'})
-        },
-        u'curriculum.section': {
-            'Meta': {'ordering': "['order']", 'object_name': 'Section'},
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name_en': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
-            'name_pl': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
-            'order': ('django.db.models.fields.IntegerField', [], {}),
-            'slug': ('django.db.models.fields.SlugField', [], {'max_length': '50'})
-        }
-    }
-
-    complete_apps = ['curriculum']
\ No newline at end of file
diff --git a/curriculum/migrations/0017_verbose_level.py b/curriculum/migrations/0017_verbose_level.py
deleted file mode 100644 (file)
index c6a10a0..0000000
+++ /dev/null
@@ -1,95 +0,0 @@
-# -*- coding: utf-8 -*-
-from south.utils import datetime_utils as datetime
-from south.db import db
-from south.v2 import DataMigration
-from django.db import models
-
-
-KLASA = ['I-III', 'IV-VI', 'VII-VIII', 'IV-VIII']
-POZIOM = ['O', 'I', 'II', 'III', 'IV']
-OTHER = {
-    'LO': 'liceum i technikum',
-}
-
-
-class Migration(DataMigration):
-
-    def forwards(self, orm):
-        for level in orm.CurriculumLevel.objects.all():
-            if level.title in KLASA:
-                level.verbose = '%s klasa' % level.title
-            elif level.title in POZIOM:
-                level.verbose = '%s poziom edukacyjny' % level.title
-            elif level.title in OTHER:
-                level.verbose = OTHER[level.title]
-            else:
-                raise ValueError('Unknown level')
-            level.save()
-
-    def backwards(self, orm):
-        pass
-
-    models = {
-        u'curriculum.competence': {
-            'Meta': {'ordering': "['section', 'order']", 'object_name': 'Competence'},
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name_en': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
-            'name_pl': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
-            'order': ('django.db.models.fields.IntegerField', [], {}),
-            'section': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['curriculum.Section']"}),
-            'slug': ('django.db.models.fields.SlugField', [], {'max_length': '50'})
-        },
-        u'curriculum.competencelevel': {
-            'Meta': {'ordering': "['competence', 'level']", 'object_name': 'CompetenceLevel'},
-            'competence': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['curriculum.Competence']"}),
-            'description_en': ('django.db.models.fields.TextField', [], {'default': "''"}),
-            'description_pl': ('django.db.models.fields.TextField', [], {'default': "''"}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'level': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['curriculum.Level']"})
-        },
-        u'curriculum.curriculum': {
-            'Meta': {'ordering': "['identifier']", 'object_name': 'Curriculum'},
-            'course': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['curriculum.CurriculumCourse']"}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'identifier': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255', 'db_index': 'True'}),
-            'level': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['curriculum.CurriculumLevel']"}),
-            'title': ('django.db.models.fields.CharField', [], {'max_length': '1024'}),
-            'type': ('django.db.models.fields.CharField', [], {'max_length': '16'})
-        },
-        u'curriculum.curriculumcourse': {
-            'Meta': {'ordering': "['slug']", 'object_name': 'CurriculumCourse'},
-            'accusative': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'slug': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}),
-            'title': ('django.db.models.fields.CharField', [], {'max_length': '255'})
-        },
-        u'curriculum.curriculumlevel': {
-            'Meta': {'object_name': 'CurriculumLevel'},
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'title': ('django.db.models.fields.CharField', [], {'max_length': '16', 'db_index': 'True'}),
-            'verbose': ('django.db.models.fields.CharField', [], {'max_length': '32'})
-        },
-        u'curriculum.level': {
-            'Meta': {'ordering': "['order']", 'object_name': 'Level'},
-            'group_en': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
-            'group_pl': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'meta_name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'}),
-            'name_en': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
-            'name_pl': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
-            'order': ('django.db.models.fields.IntegerField', [], {}),
-            'package': ('django.db.models.fields.files.FileField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
-            'slug': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'}),
-            'student_package': ('django.db.models.fields.files.FileField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'})
-        },
-        u'curriculum.section': {
-            'Meta': {'ordering': "['order']", 'object_name': 'Section'},
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name_en': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
-            'name_pl': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
-            'order': ('django.db.models.fields.IntegerField', [], {}),
-            'slug': ('django.db.models.fields.SlugField', [], {'max_length': '50'})
-        }
-    }
-
-    complete_apps = ['curriculum']
\ No newline at end of file
diff --git a/curriculum/migrations/__init__.py b/curriculum/migrations/__init__.py
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/curriculum/models.py b/curriculum/models.py
deleted file mode 100644 (file)
index 0c3acb2..0000000
+++ /dev/null
@@ -1,242 +0,0 @@
-# -*- coding: utf-8
-import re
-from django.core.urlresolvers import reverse
-from django.db import models
-from django.utils.translation import ugettext_lazy as _, get_language
-from fnpdjango.storage import BofhFileSystemStorage
-from fnpdjango.utils.models.translation import add_translatable
-from fnpdjango.utils.text.slughifi import slughifi as slugify
-
-bofh_storage = BofhFileSystemStorage()
-
-
-class Section(models.Model):
-    slug = models.SlugField(_('slug'))
-    order = models.IntegerField(_('order'))
-
-    class Meta:
-        ordering = ['order']
-        verbose_name = _('section')
-        verbose_name_plural = _('sections')
-
-    def __unicode__(self):
-        return self.name
-
-    def get_absolute_url(self):
-        return "%s?s=%d" % (reverse("curriculum"), self.pk)
-
-    def url_for_level(self, level):
-        return "%s?s=%d&level=%s&d=1" % (reverse("curriculum"), self.pk, level.slug)
-
-add_translatable(Section, {
-    'name': models.CharField(_('name'), max_length=255, default='')
-})
-
-
-class Competence(models.Model):
-    section = models.ForeignKey(Section)
-    slug = models.SlugField(_('slug'))
-    order = models.IntegerField(_('order'))
-
-    class Meta:
-        ordering = ['section', 'order']
-        verbose_name = _('competence')
-        verbose_name_plural = _('competences')
-
-    def __unicode__(self):
-        return self.name
-
-    def get_absolute_url(self):
-        return "%s?c=%d" % (reverse("curriculum"), self.pk)
-
-    def for_level(self, level):
-        return self.competencelevel_set.get(level=level)
-
-    def url_for_level(self, level):
-        return self.for_level(level).get_absolute_url()
-
-    @classmethod
-    def from_text(cls, text):
-        """Tries to return a Competence or a Section."""
-        parts = re.split(ur'[-\u2013]', text, 1)
-        lookup_field_name = 'name_%s__iexact' % get_language()
-        if len(parts) == 1:
-            return Section.objects.get(**{lookup_field_name: text.strip()})
-        else:
-            return cls.objects.get(**{lookup_field_name: parts[1].strip()})
-
-add_translatable(Competence, {
-    'name': models.CharField(_('name'), max_length=255, default='')
-})
-
-
-class Level(models.Model):
-    slug = models.CharField(_('slug'), max_length=255, unique=True)
-    meta_name = models.CharField(_('meta name'), max_length=255, unique=True)
-    order = models.IntegerField(_('order'))
-    package = models.FileField(
-        upload_to=lambda i, f: "curriculum/pack/edukacjamedialna_%s.zip" % i.slug,
-        null=True, blank=True, max_length=255, storage=bofh_storage)
-    student_package = models.FileField(
-        upload_to=lambda i, f: "curriculum/pack/edukacjamedialna_%s_uczen.zip" % i.slug,
-        null=True, blank=True, max_length=255, storage=bofh_storage)
-
-    class Meta:
-        ordering = ['order']
-        verbose_name = _('educational level')
-        verbose_name_plural = _('educational levels')
-
-    def __unicode__(self):
-        return self.name
-
-    def length_course(self):
-        return self.lesson_set.filter(type='course').count()
-
-    def length_synthetic(self):
-        return self.lesson_set.filter(type='synthetic').count()
-
-    def build_package(self, student):
-        from StringIO import StringIO
-        import zipfile
-        from django.core.files.base import ContentFile
-        from catalogue.templatetags.catalogue_tags import level_box
-        from catalogue.models import Lesson
-
-        buff = StringIO()
-        zipf = zipfile.ZipFile(buff, 'w', zipfile.ZIP_STORED)
-
-        lessons = level_box(self)['lessons']
-        for i, lesson in enumerate(lessons['synthetic']):
-            prefix = 'Skrocony kurs/%d %s/' % (i, lesson.slug)
-            lesson.add_to_zip(zipf, student, prefix)
-        for c, (section, clessons) in enumerate(lessons['course'].items()):
-            assert section, clessons
-            for i, lesson in enumerate(clessons):
-                prefix = 'Pelny kurs/%d %s/%d %s/' % (c, section.slug, i, lesson.slug)
-                lesson.add_to_zip(zipf, student, prefix)
-        for i, lesson in enumerate(lessons['project']):
-            prefix = 'Projekty/%d %s/' % (i, lesson.slug)
-            lesson.add_to_zip(zipf, student, prefix)
-        # Add all appendix lessons, from all levels.
-        for lesson in Lesson.objects.filter(type='appendix'):
-            # ugly fix
-            if self.slug in ('przedszkole', 'sp1-3', 'sp4-6'):
-                if lesson.slug == 'slowniczek':
-                    continue
-            else:
-                if lesson.slug == 'slowniczek-sp':
-                    continue
-            prefix = '%s/' % lesson.slug
-            lesson.add_to_zip(zipf, student, prefix)
-        zipf.close()
-
-        fieldname = "student_package" if student else "package"
-        getattr(self, fieldname).save(None, ContentFile(buff.getvalue()))
-
-    def build_packages(self):
-        self.build_package(False)
-        self.build_package(True)
-
-
-add_translatable(Level, {
-    'name': models.CharField(_('name'), max_length=255, default=''),
-    'group': models.CharField(_('group'), max_length=255, default='')
-})
-
-
-class CompetenceLevel(models.Model):
-    competence = models.ForeignKey(Competence)
-    level = models.ForeignKey(Level)
-
-    class Meta:
-        ordering = ['competence', 'level']
-        verbose_name = _('competence on level')
-        verbose_name_plural = _('competences on levels')
-
-    def __unicode__(self):
-        return u"%s/%s" % (self.competence, self.level)
-
-    def get_absolute_url(self):
-        return "%s?c=%d&level=%s&d=1" % (reverse("curriculum"), self.competence.pk, self.level.slug)
-
-add_translatable(CompetenceLevel, {
-    'description': models.TextField(_('description'), default='')
-})
-
-
-class CurriculumLevel(models.Model):
-    title = models.CharField(max_length=16, db_index=True)
-    verbose = models.CharField(max_length=32)
-
-    class Meta:
-        verbose_name = _("curriculum level")
-        verbose_name_plural = _("curriculum levels")
-
-    def __unicode__(self):
-        return self.title
-
-
-class CurriculumCourse(models.Model):
-    title = models.CharField(max_length=255)
-    accusative = models.CharField(max_length=255)
-    slug = models.CharField(max_length=255, db_index=True)
-
-    class Meta:
-        verbose_name = _("curriculum course")
-        verbose_name_plural = _("curriculum courses")
-        ordering = ['slug']
-
-    def __unicode__(self):
-        return self.title
-
-
-class Curriculum(models.Model):
-    """Official curriculum."""
-    TYPES = {'c': u'Cele kształcenia', 't': u'Treści nauczania', 'o': u'Osiągnięcia'}
-
-    identifier = models.CharField(max_length=255, db_index=True, unique=True)
-    title = models.CharField(max_length=1024)
-    course = models.ForeignKey(CurriculumCourse)
-    level = models.ForeignKey(CurriculumLevel)
-    type = models.CharField(max_length=16, choices=TYPES.items())
-
-    class Meta:
-        ordering = ['identifier']
-        verbose_name = _("curriculum item")
-        verbose_name_plural = _("curriculum items")
-
-    def __unicode__(self):
-        return self.identifier
-
-    @classmethod
-    def from_text(cls, identifier, title):
-        m = re.match(r"^\d+/(?P<level>[^/]+)/(?P<course>[^/]+)/"
-                     r"(?P<type>(?:%s))[^/]+(?P<roz>/roz)?" % "|".join(cls.TYPES), identifier)
-        assert m is not None, "Curriculum identifier doesn't match template."
-        level, created = CurriculumLevel.objects.get_or_create(
-                                       title=m.group('level'))
-        if created:
-            print 'created level:', m.group('level')
-        def_title = m.group('course').capitalize()
-        course, created = CurriculumCourse.objects.get_or_create(
-                                        slug=slugify(m.group('course')),
-                                        defaults={
-                                            'title': def_title,
-                                            'accusative': def_title,
-                                        })
-        if created:
-            print 'created course:', slugify(m.group('course')), def_title
-        type_ = m.group('type')
-        if m.group('roz'):
-            title += " (zakres rozszerzony)"
-
-        try:
-            curr = cls.objects.get(identifier=identifier)
-        except cls.DoesNotExist:
-            curr = cls(identifier=identifier)
-        curr.title = title
-        curr.course = course
-        curr.level = level
-        curr.type = type_
-        curr.save()
-        return curr
diff --git a/curriculum/static/curriculum/curriculum.css b/curriculum/static/curriculum/curriculum.css
deleted file mode 100644 (file)
index 9ae2e35..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-.curriculum-form {
-  border: 1px solid #ddd;
-  padding: 1em;
-  border-radius: 0.688em;
-  background: #ADAEAF;
-  color: white; }
-  .curriculum-form a {
-    cursor: pointer; }
-  .curriculum-form a:hover {
-    text-decoration: underline; }
-  .curriculum-form .error {
-    padding-left: 1em;
-    border-radius: .5em;
-    background: #ed7831;
-    color: white;
-    font-weight: bold; }
-  .curriculum-form h2 {
-    margin: 0; }
-    .curriculum-form h2 a {
-      display: block;
-      color: white; }
-      .curriculum-form h2 a span {
-        display: none; }
-  .curriculum-form strong {
-    display: inline-block;
-    vertical-align: top;
-    width: 12em; }
-  .curriculum-form .curriculum-levels {
-    display: inline-block;
-    list-style: none;
-    padding: 0;
-    margin: 0;
-    width: 40em;
-    vertical-align: top; }
-    .curriculum-form .curriculum-levels li {
-      display: inline-block;
-      width: 13em; }
-  .curriculum-form .curriculum-section-toggler {
-    display: none;
-    color: white; }
diff --git a/curriculum/static/curriculum/curriculum.js b/curriculum/static/curriculum/curriculum.js
deleted file mode 100755 (executable)
index 0bdafc2..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-$(function() {
-    if (typeof(curriculum_hide_form) != "undefined") {
-        $('.curriculum-form form').hide();
-        $('.curriculum-form h2 a span').show();
-    }
-    $('.curriculum-form h2 a').click(function() {
-        $('.curriculum-form form').toggle('fast');
-        $('span', this).toggle();
-    });
-
-    /* show togglers */
-    $('.curriculum-section-toggler').show();
-
-    $('.curriculum-section').each(function() {
-        var category = this;
-
-        /* set up togglers */
-        $('.curriculum-section-toggler', this).click(function() {
-            $('ul', category).toggle('fast');
-        });
-
-        /* set up section checkboxes */
-        $('.s', category).change(function() {
-            if ($(this).attr('checked')) {
-                $('ul input', category).attr('checked', 'checked');
-            }
-            else {
-                $('ul input', category).removeAttr('checked');
-            }
-        });
-
-        /* unset section checkbox on unselect single competence */
-        $('ul input', category).change(function() {
-            if (!$(this).attr('checked')) {
-                $('.s', category).removeAttr('checked', 'checked');
-            }
-        });
-
-        /* hide unused section details on start */
-        if ($('.s', category).attr('checked') || !$('ul input[checked]', category).length)
-            $('ul', category).hide();
-    });
-});
diff --git a/curriculum/static/curriculum/curriculum.scss b/curriculum/static/curriculum/curriculum.scss
deleted file mode 100755 (executable)
index 355a6c5..0000000
+++ /dev/null
@@ -1,67 +0,0 @@
-$px: 0.0625em;
-$oranji: #ed7831;
-$ciemny: #363a3e;
-$zielony: #16a487;
-
-.curriculum-form {
-    border: 1px solid #ddd;
-    padding: 1em;
-    border-radius: 11*$px;
-    background: #ADAEAF;
-    color: white;
-
-    a {
-        cursor: pointer;
-    }
-    a:hover {
-        text-decoration: underline;
-    }
-
-    .error {
-        padding-left: 1em;
-        border-radius: .5em;
-        background: $oranji;
-        color: white;
-        font-weight: bold;
-        
-    }
-
-    h2 {
-        margin: 0;
-        a {
-            display: block;
-            color: white;
-            span {display: none;}
-        }
-    }
-
-    strong {
-        display: inline-block;
-        vertical-align: top;
-        width: 12em;
-    }
-
-    .curriculum-levels {
-        display: inline-block;
-        list-style: none;
-        padding: 0;
-        margin: 0;
-        width: 40em;
-        vertical-align: top;
-
-        li {
-            display: inline-block;
-            width: 13em;
-        }
-    }
-
-    .curriculum-section-toggler {
-        display: none;
-        color: white;
-    }
-
-    .categories {
-        
-    }
-
-}
diff --git a/curriculum/templates/curriculum/competence_detail.html b/curriculum/templates/curriculum/competence_detail.html
deleted file mode 100755 (executable)
index 7bb76e1..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-{% extends base_template %}
-
-{% block title %}{{ object }}{% endblock %}
-
-{% block body %}
-<h1>{{ object }}</h1>
-
-{% for cl in object.competencelevel_set.all %}
-    <h2>{{ cl }}</h2>
-    {{ cl.description|linebreaksbr }}
-{% endfor %}
-
-{% endblock %}
diff --git a/curriculum/templates/curriculum/competence_list.html b/curriculum/templates/curriculum/competence_list.html
deleted file mode 100755 (executable)
index cea4d4e..0000000
+++ /dev/null
@@ -1,73 +0,0 @@
-{% extends base_template %}
-{% load chunks %}
-{% load i18n %}
-
-{% block title %}{% trans 'Media, information and digital literacy competencies catalogue' %}{% endblock %}
-
-{% block body %}
-<h1>{% trans 'Media, information and digital literacy competencies catalogue' %}</h1>
-
-{% if request.LANGUAGE_CODE == 'pl' %}
-    {% chunk 'katalog_kompetencji' %}
-{% endif %}
-
-<div class="curriculum-form">
-<h2><a>{% trans 'Browse competencies' %} <span>({% trans 'expand' %})</span></a></h2>
-<form>
-
-<h3>{% trans 'Education level' %}:</h3>
-{% if errors.level %}<p class="error">{{ errors.level }}</p>{% endif %}
-{% for lev_group, levels in levels.items %}
-    <strong>{{ lev_group }}</strong>
-    <ul class="curriculum-levels">
-    {% for lev in levels %}
-    <li><label><input type="radio" name="level" value="{{ lev.slug }}"
-        {% if lev == level %}checked="checked"{% endif %} />
-        {{ lev }}</label></li>
-    {% endfor %}
-    </ul>
-{% endfor %}
-
-<h3>{% trans 'Competency categories' %}:</h3>
-{% if errors.competences %}<p class="error">{{ errors.competences }}</p>{% endif %}
-<ul class="curriculum-sections">
-{% for section in sections %}
-    <li class="curriculum-section">
-    <label><input type="checkbox" class="s" name="s" value="{{ section.pk }}"
-        {% if section.pk in sect_ids %}checked="checked"{% endif %} /> {{ section }}</label>
-        <a class="curriculum-section-toggler">({% trans 'expand' %})</a>
-    <ul class="competences">
-    {% for competence in section.competence_set.all %}
-        <li class="competence"><label><input class="c" type="checkbox" name="c" value="{{ competence.pk }}"
-            {% if competence.pk in comp_ids %}checked="checked"{% endif %} />
-            {{ competence }}</label></li>
-    {% endfor %}
-    </ul>
-    </li>
-{% endfor %}
-</ul>
-<button>{% trans 'Show' %}</button>
-</form>
-</div>
-
-{% if chosen_competences %}
-
-<h2>{% trans 'Selected competencies' %} – {{ level }}</h2>
-
-{% for section, competences in chosen_competences.items %}
-    <h3>{{ section }}</h3>
-    {% for competence in competences %}
-        <h4>{{ competence }}</h4>
-        {{ competence.for_level_.description|linebreaksbr }}
-    {% endfor %}
-{% endfor %}
-
-{% endif %}
-
-
-{% if request.GET.d %}
-<script type="text/javascript">
-    var curriculum_hide_form = true;
-</script>
-{% endif %}
-{% endblock %}
diff --git a/curriculum/templates/curriculum/snippets/competence.html b/curriculum/templates/curriculum/snippets/competence.html
deleted file mode 100755 (executable)
index 7f62ac8..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-{% load url_for_level from curriculum_tags %}
-{% if comps %}
-    {% for competence in comps %}
-        <li><a href="{{ competence|url_for_level:level }}">
-            {{ competence }}</a></li>
-    {% endfor %}
-{% else %}
-    {% for text in texts %}
-        <li>{{ text }}</li>
-    {% endfor %}
-{% endif %}
-
diff --git a/curriculum/templates/curriculum/snippets/course_box.html b/curriculum/templates/curriculum/snippets/course_box.html
deleted file mode 100755 (executable)
index f1bd074..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-{% for level, types in lessons.items %}
-{% if level.slug == "liceum" %}
-    <p><strong>{{ course }}</strong>: poziom zaawansowany
-        <span class="section-links"><a href="#top">wróć do spisu treści</a></span>
-    </p>
-{% endif %}
-<section class="section-level section-level-{{ level.slug }}">
-    {% spaceless %}
-    {% for lesson_type, lesson_list in types.items %}
-        <section class="section-type section-type-{{ lesson_type }}">
-            {% if lesson_type == 'synthetic' %}
-                <h1>Lekcje syntetyczne</h1>
-            {% elif lesson_type == 'project' %}
-                <h1>Projekty</h1>
-            {% else %}
-                <h1>Lekcje z pełnych kursów</h1>
-            {% endif %}
-            {% if lesson_list %}
-            <ul class="section-lessons link-list">
-                {% for lesson in lesson_list %}
-                    <li class="section-lesson">
-                        <a href="{{ lesson.get_absolute_url }}">{{ lesson }}{% if lesson_type == 'synthetic' %}
-                            <br/>(przegląd całego tematu „{{ lesson.section }}” w 45 minut)
-                        {% endif %}</a>
-                    </li>
-                {% endfor %}
-            </ul>
-            {% else %}
-                <p>(W przygotowaniu)</p>
-            {% endif %}
-        </section>
-    {% endfor %}
-    {% endspaceless %}
-</section>
-{% endfor %}
diff --git a/curriculum/templates/curriculum/snippets/course_boxes.html b/curriculum/templates/curriculum/snippets/course_boxes.html
deleted file mode 100755 (executable)
index c998121..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-{% load course_box from curriculum_tags %}
-{% for course in object_list %}
-    <div class="section-links">
-        <a href="#top">wróć do spisu treści</a>
-    </div>
-    <h3 id='{{ course.slug }}'>{{ course }}</h3>
-    {% course_box course %}
-{% endfor %}
diff --git a/curriculum/templates/curriculum/snippets/course_boxes_toc.html b/curriculum/templates/curriculum/snippets/course_boxes_toc.html
deleted file mode 100755 (executable)
index 0c22785..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-{% url "catalogue_lessons" as lessons_url %}
-{% for level, course_list in object_list %}
-<section class="levelth" style="float: left;">{{ level }}:
-<ul class="link-list">
-        {% for course in course_list %}
-            <li><a href="{{ lessons_url }}#{{ level.slug }}_{{ course.slug }}">
-            {% if accusative %}
-                {{ course.accusative }}{% else %}
-                {{ course|lower }}{% endif %}</a>
-                </li>
-        {% endfor %}
-</ul>
-</section>
-{% endfor %}
diff --git a/curriculum/templates/curriculum/snippets/curriculum.html b/curriculum/templates/curriculum/snippets/curriculum.html
deleted file mode 100755 (executable)
index a499a88..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-{% if currset %}
-    {% for what, types in currset.items %}
-        <li>
-            {{ what.0 }}, {{ what.1 }}<br/>
-            {% for type, currs in types.items %}
-                {{ type }}:<br>
-                {% for curr in currs %}
-                    {{ curr.title }}<br>
-                {% endfor %}
-            {% endfor %}
-        </li>
-    {% endfor %}
-{% else %}
-    {% for identifier in identifiers %}
-        <li>{{ identifier }}</li>
-    {% endfor %}
-{% endif %}
diff --git a/curriculum/templatetags/__init__.py b/curriculum/templatetags/__init__.py
deleted file mode 100755 (executable)
index e69de29..0000000
diff --git a/curriculum/templatetags/curriculum_tags.py b/curriculum/templatetags/curriculum_tags.py
deleted file mode 100755 (executable)
index 9525aec..0000000
+++ /dev/null
@@ -1,99 +0,0 @@
-# -*- coding: utf-8 -*-
-from django import template
-from django.utils.datastructures import SortedDict
-from ..models import Competence, Curriculum, CurriculumCourse
-from catalogue.models import Lesson
-
-register = template.Library()
-
-
-@register.inclusion_tag("curriculum/snippets/competence.html")
-def competence(texts, level):
-    try:
-        comps = [Competence.from_text(text) for text in texts]
-    except:
-        # WTF
-        return {'texts': texts}
-    return {
-        'comps': comps,
-        'level': level,
-    }
-
-
-@register.inclusion_tag("curriculum/snippets/curriculum.html")
-def curriculum(identifiers, new=False):
-    # shouldn't be needed, but is
-    identifiers = [id for id in identifiers if id]
-    try:
-        currs = [Curriculum.objects.get(identifier__iexact=identifier.replace(' ', ''))
-                 for identifier in identifiers]
-    except Curriculum.DoesNotExist:
-        return {'identifiers': identifiers}
-
-    currset = SortedDict()
-    for curr in currs:
-        k = curr.course, curr.level.verbose
-        if k not in currset:
-            currset[k] = SortedDict()
-        typename = Curriculum.TYPES[curr.type]
-        if typename not in currset[k]:
-            currset[k][typename] = []
-        currset[k][typename].append(curr)
-
-    return {
-        'currset': currset,
-        'new': new,
-    }
-    
-
-@register.filter
-def url_for_level(comp, level):
-    try:
-        return comp.url_for_level(level)
-    except:
-        # WTF
-        return comp.get_absolute_url()
-
-
-@register.inclusion_tag("curriculum/snippets/course_box.html")
-def course_box(course):
-    lessons = SortedDict()
-    for lesson in course.lesson_set.all():
-        if lesson.level not in lessons:
-            newdict = SortedDict()
-            newdict['synthetic'] = []
-            newdict['course'] = []
-            lessons[lesson.level] = newdict
-        if lesson.type not in lessons[lesson.level]:
-            lessons[lesson.level][lesson.type] = []
-        lessons[lesson.level][lesson.type].append(lesson)
-    return {
-        "course": course,
-        "lessons": lessons,
-    }
-
-
-@register.inclusion_tag("curriculum/snippets/course_boxes.html")
-def course_boxes():
-    return {'object_list': CurriculumCourse.objects.all()}
-
-
-@register.inclusion_tag("curriculum/snippets/course_boxes_toc.html")
-def course_boxes_toc(accusative=False):
-    last = None, None
-    object_list = []
-    lessons = Lesson.curriculum_courses.through.objects\
-        .select_related('lesson__level', 'curriculumcourse')\
-        .order_by('lesson__level', 'curriculumcourse')
-    for l in lessons:
-        level, course = l.lesson.level, l.curriculumcourse
-        if (level, course) == last:
-            continue
-        if level != last[0]:
-            object_list.append((level, []))
-        object_list[-1][1].append(course)
-        last = (level, course)
-    return {
-        'object_list': object_list,
-        'accusative': accusative,
-    }
diff --git a/curriculum/tests.py b/curriculum/tests.py
deleted file mode 100644 (file)
index b967c44..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-# -*- coding: utf-8 -*-
-"""
-This file demonstrates writing tests using the unittest module. These will pass
-when you run "manage.py test".
-
-Replace this with more appropriate tests for your application.
-"""
-
-from django.test import TestCase
-
-
-class SimpleTest(TestCase):
-    def test_basic_addition(self):
-        """
-        Tests that 1 + 1 always equals 2.
-        """
-        self.assertEqual(1 + 1, 2)
diff --git a/curriculum/urls.py b/curriculum/urls.py
deleted file mode 100755 (executable)
index 7553a66..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-# -*- coding: utf-8 -*-
-from django.conf.urls import patterns, url
-from .views import CompetenceDetailView, CompetencesView
-
-urlpatterns = patterns(
-    '',
-    url(r'^$', CompetencesView.as_view(), name='curriculum'),
-    url(r'^(?P<slug>[^/]+)/$', CompetenceDetailView.as_view(), name='curriculum_competence'),
-)
diff --git a/curriculum/views.py b/curriculum/views.py
deleted file mode 100644 (file)
index 25606f1..0000000
+++ /dev/null
@@ -1,66 +0,0 @@
-# -*- coding: utf-8
-from django.db import models
-from django.views.generic import DetailView, ListView
-from django.utils.datastructures import SortedDict
-from django.utils.translation import ugettext as _
-
-from .models import Competence, Section, Level, CompetenceLevel
-
-
-class CompetenceDetailView(DetailView):
-    model = Competence
-
-
-class CompetencesView(ListView):
-    model = Competence
-
-    def get_context_data(self, **kwargs):
-        context = super(CompetencesView, self).get_context_data(**kwargs)
-        
-        context['levels'] = SortedDict()
-        for level in Level.objects.all():
-            context['levels'].setdefault(level.group, []).append(level)
-
-        context['sections'] = Section.objects.all()
-
-        errors = {}
-
-        try:
-            level = Level.objects.get(slug=self.request.GET.get('level'))
-        except Level.DoesNotExist:
-            level = None
-        context['level'] = level
-
-        comp_ids = set()
-        for c in self.request.GET.getlist('c'):
-            try:
-                comp_ids.add(int(c))
-            except ValueError:
-                pass
-        context['comp_ids'] = comp_ids
-        sect_ids = set()
-        for c in self.request.GET.getlist('s'):
-            try:
-                sect_ids.add(int(c))
-            except ValueError:
-                pass
-        context['sect_ids'] = sect_ids
-
-        if not (comp_ids or sect_ids):
-            if level:
-                errors["competences"] = _('You must select at least one competency from the list.')
-        elif level is None:
-            errors["level"] = _('You must select at least one education level.')
-        else:
-            chosen_competences = SortedDict()
-            for competence in Competence.objects.filter(
-                    models.Q(pk__in=comp_ids) | models.Q(section__pk__in=sect_ids)):
-                try:
-                    competence.for_level_ = competence.for_level(level)
-                except CompetenceLevel.DoesNotExist:
-                    pass
-                chosen_competences.setdefault(competence.section, []).append(competence)
-            context['chosen_competences'] = chosen_competences
-
-        context["errors"] = errors
-        return context
index b027789..249139d 100644 (file)
@@ -6,4 +6,5 @@ services:
       context: .
       target: dev
     volumes:
       context: .
       target: dev
     volumes:
-      - .:/app
+      - ./src:/app/src
+      - ./media:/app/media
diff --git a/edumed/__init__.py b/edumed/__init__.py
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/edumed/contact_forms.py b/edumed/contact_forms.py
deleted file mode 100644 (file)
index 88d2c84..0000000
+++ /dev/null
@@ -1,873 +0,0 @@
-# -*- coding: utf-8 -*-
-import re
-
-from django import forms
-from django.forms.formsets import BaseFormSet
-from django.utils.safestring import mark_safe
-from markdown2 import Markdown
-
-from contact.fields import HeaderField
-from contact.forms import ContactForm
-from django.core.mail import send_mail
-from django.core.exceptions import ValidationError
-from django.core.validators import validate_email
-from django.template.loader import render_to_string
-from django.utils.translation import ugettext_lazy as _
-
-from edumed.contact_forms_test import TestForm, CollegiumTestForm
-
-LINK_PATTERNS = [
-    (re.compile(r'((http|ftp|https)://([\w_-]+(?:(?:\.[\w_-]+)+))([\w.,;@?^=%&:/~+#-]*[\w@?^=%&/~+#-])?)'),
-     r'\1')
-]
-
-markdown = Markdown(extras=["link-patterns", 'code-friendly'], link_patterns=LINK_PATTERNS)
-
-WOJEWODZTWA = (
-    u'dolnośląskie',
-    u'kujawsko-pomorskie',
-    u'lubelskie',
-    u'lubuskie',
-    u'łódzkie',
-    u'małopolskie',
-    u'mazowieckie',
-    u'opolskie',
-    u'podkarpackie',
-    u'podlaskie',
-    u'pomorskie',
-    u'śląskie',
-    u'świętokrzyskie',
-    u'warmińsko-mazurskie',
-    u'wielkopolskie',
-    u'zachodniopomorskie',
-)
-
-WOJEWODZTWO_CHOICES = [(u'', u'(wybierz)')] + [(w, w) for w in WOJEWODZTWA]
-
-
-def make_data_processing(middle_text):
-    return mark_safe(u'''\
-Administratorem danych osobowych jest Fundacja Nowoczesna Polska (ul. Marszałkowska 84/92 lok. 125, 00-514 Warszawa). \
-Podanie danych osobowych jest dobrowolne. %s Osobom, których dane są zbierane, przysługuje prawo dostępu do treści \
-swoich danych oraz ich poprawiania. Więcej informacji w <a href="https://nowoczesnapolska.org.pl/prywatnosc/">\
-polityce prywatności</a>.''' % middle_text)
-
-
-class SuggestionForm(ContactForm):
-    form_tag = 'sugestie'
-    form_title = u"Zgłoś sugestię"
-    admin_list = ['podpis', 'contact', 'temat']
-    data_processing = make_data_processing(u'Dane są przetwarzane w zakresie niezbędnym do obsługi zgłoszenia.')
-
-    contact = forms.EmailField(label=u'E-mail', max_length=128, required=False)
-    podpis = forms.CharField(label=u'Podpis', max_length=128, required=False)
-    temat = forms.CharField(label=u'Temat zgłoszenia', max_length=255)
-    tresc = forms.CharField(label=u'Treść', widget=forms.Textarea, max_length=1800)
-
-
-class CooperateForm(ContactForm):
-    form_tag = 'wspolpraca'
-    form_title = u"Bądź z nami w kontakcie"
-    admin_list = ['contact']
-    mailing = True
-    data_processing = make_data_processing(
-        u'Dane są przetwarzane w zakresie niezbędnym do wysyłania newslettera odbiorcom.')
-    submit_label = u'Wyślij'
-
-    contact = forms.EmailField(label=u'E-mail', max_length=128)
-
-
-class ContestForm(ContactForm):
-    disabled = True
-    form_tag = 'konkurs'
-    form_title = u"Zgłoś się do konkursu"
-    admin_list = ['nazwisko', 'instytucja', 'tytul']
-    mailing_field = 'zgoda_informacje'
-
-    nazwisko = forms.CharField(label=u'Imię i nazwisko', max_length=128)
-    contact = forms.EmailField(label=u'Adres e-mail', max_length=128)
-    instytucja = forms.CharField(label=u'Instytucja (nazwa, adres)', widget=forms.Textarea, max_length=1000)
-    tytul = forms.CharField(
-        label=u'Tytuł przeprowadzonej lekcji',
-        help_text=u'proszę wymienić wszystkie, jeśli zostały przeprowadzone więcej niż jedne zajęcia',
-        widget=forms.Textarea, max_length=1000)
-    uczestnicy = forms.CharField(label=u'Liczba uczestników', max_length=64)
-    trudnosci = forms.CharField(
-        label=u'Czy w trakcie zajęć pojawiły się jakieś trudności? Jeśli tak, to jakie?',
-        widget=forms.Textarea, max_length=2000)
-    pomocne = forms.CharField(
-        label=u'Co w materiałach okazało się najbardziej pomocne w przygotowaniu i prowadzeniu lekcji?',
-        widget=forms.Textarea, max_length=2000)
-    nieprzydatne = forms.CharField(
-        label=u'Co w materiałach okazało się nieprzydatne w przygotowaniu i prowadzeniu lekcji?',
-        widget=forms.Textarea, max_length=2000)
-    poprawic = forms.CharField(
-        label=u'Jak możemy poprawić serwis edukacjamedialna.edu.pl?',
-        widget=forms.Textarea, max_length=2000, required=False)
-    inne = forms.CharField(label=u'Inne uwagi i komentarze', widget=forms.Textarea, max_length=2000, required=False)
-    zgoda_regulamin = forms.BooleanField(
-        label=u'Znam i akceptuję regulamin konkursu Medialog.',
-        help_text=u'Zobacz <a href="/media/chunks/attachment/Regulamin_konkursu_MediaLog_1.pdf">'
-                  u'regulamin konkursu MediaLog</a>.')
-    zgoda_informacje = forms.BooleanField(
-        label=u'Wyrażam zgodę na otrzymywanie informacji od Fundacji Nowoczesna Polska związanych z edukacją medialną.',
-        required=False
-    )
-
-
-class UdzialForm(ContactForm):
-    disabled = True
-    form_tag = 'udzial'
-    form_title = u"Udział"
-    admin_list = ['nazwisko', 'miejscowosc', 'instytucja']
-
-    nazwisko = forms.CharField(label=u'Imię i nazwisko', max_length=128)
-    miejscowosc = forms.CharField(label=u'Miejscowość', max_length=128)
-    instytucja = forms.CharField(label=u'Nazwa organizacji/instytucji', max_length=128)
-    contact = forms.EmailField(label=u'Adres e-mail', max_length=128)
-    telefon = forms.CharField(label=u'Telefon', max_length=32)
-    uczestnicy = forms.IntegerField(label=u'Przewidywana liczba uczestników zajęć')
-
-
-class WTEMStudentForm(forms.Form):
-    first_name = forms.CharField(label=u'Imię', max_length=128)
-    last_name = forms.CharField(label=u'Nazwisko', max_length=128)
-    email = forms.EmailField(label=u'Adres e-mail', max_length=128)
-    form_tag = "student"
-
-
-class NonEmptyBaseFormSet(BaseFormSet):
-    """
-    Won't allow formset_factory to be submitted with no forms
-    """
-    def clean(self):
-        for form in self.forms:
-            if form.cleaned_data:
-                return
-        forms.ValidationError(u"Proszę podać dane przynajmniej jednej osoby.")
-
-
-class WTEMForm(ContactForm):
-    disabled = True
-    disabled_template = 'wtem/disabled_contact_form.html'
-    form_tag = "wtem"
-    old_form_tags = ["wtem2013", "wtem2014"]
-    form_title = u"WTEM - rejestracja uczestników"
-    submit_label = u"Wyślij zgłoszenie"
-    admin_list = ['imie', 'nazwisko', 'institution']
-    form_formsets = {
-        'student': forms.formsets.formset_factory(
-            WTEMStudentForm, formset=NonEmptyBaseFormSet, max_num=5, validate_max=True, extra=5),
-    }
-    mailing_field = 'zgoda_informacje'
-
-    contact = forms.EmailField(label=u'Adres e-mail opiekuna/opiekunki', max_length=128)
-    imie = forms.CharField(label=u'Imię', max_length=128)
-    nazwisko = forms.CharField(label=u'Nazwisko', max_length=128)
-    function = forms.CharField(label=u'Pełniona funkcja', max_length=255)
-    institution = forms.CharField(label=u'Nazwa instytucji', max_length=255)
-    institution_address = forms.CharField(label=u'Adres instytucji', widget=forms.Textarea, max_length=1000)
-    institution_email = forms.EmailField(label=u'Adres e-mail instytucji', max_length=128)
-    institution_phone = forms.CharField(label=u'Telefon do instytucji', max_length=32)
-    institution_www = forms.URLField(label=u'Strona WWW instytucji', max_length=255, required=False)
-
-    zgoda_regulamin = forms.BooleanField(
-        label=u'Znam i akceptuję regulamin Wielkiego Turnieju Edukacji Medialnej.',
-        help_text=u'Zobacz <a href="/media/chunks/attachment/regulamin_III_edycja.pdf">'
-                  u'regulamin Wielkiego Turnieju Edukacji Medialnej</a>.'
-    )
-    zgoda_dane = forms.BooleanField(
-        label=u'Wyrażam zgodę na przetwarzanie moich danych osobowych oraz danych osobowych moich podopiecznych.',
-        # help_text=u'Zobacz <a href="/media/chunks/attachment/Oswiadczenie_o_danych_osobowych.pdf">'
-        # 'pełną treść oświadczenia</a>.'
-    )
-
-    potw_uczniowie = forms.BooleanField(
-        label=u'Potwierdzam, że zgłoszeni Uczestnicy/Uczestniczki w chwili rejestracji są '
-              u'uczniami/uczennicami szkoły ponadgimnazjalnej.',
-    )
-    zgoda_informacje = forms.BooleanField(
-        label=u'Wyrażam zgodę na otrzymywanie informacji od Fundacji Nowoczesna Polska '
-              u'związanych z edukacją medialną.',
-        required=False
-    )
-
-    extract_types = (dict(slug='extended', label=_('extended')),)
-
-    @staticmethod
-    def get_extract_fields(contact, extract_type_slug):
-        fields = contact.body.keys()
-        fields.pop(fields.index('student'))
-        fields.extend(['contact', 'student_first_name', 'student_last_name', 'student_email'])
-        return fields
-
-    @staticmethod
-    def get_extract_records(keys, contact, extract_type_slug):
-        toret = [dict()]
-        for field_name in keys:
-            if field_name.startswith('student_'):
-                continue
-            if field_name == 'contact':
-                val = contact.contact
-            else:
-                val = contact.body[field_name]
-            toret[0][field_name] = val
-        
-        current = toret[0]
-        for student in contact.body['student']:
-            for attr in ('first_name', 'last_name', 'email'):
-                current['student_' + attr] = student[attr]
-            if current not in toret:
-                toret.append(current)
-            current = dict()
-        return toret
-
-    def save(self, request, formsets=None):
-        contact = super(WTEMForm, self).save(request, formsets)
-
-        mail_subject = render_to_string('contact/wtem/student_mail_subject.html').strip()
-        mail_body = render_to_string('contact/wtem/student_mail_body.html')
-        for formset in formsets or []:
-            for f in formset.forms:
-                email = f.cleaned_data.get('email', None)
-                try:
-                    validate_email(email)
-                except ValidationError:
-                    pass
-                else:
-                    send_mail(mail_subject, mail_body, 'edukacjamedialna@nowoczesnapolska.org.pl', [email],
-                              fail_silently=True)
-
-        return contact
-
-
-class CommissionForm(forms.Form):
-    name = forms.CharField(label=u'Imię i nazwisko Członka Komisji', max_length=128)
-    form_tag = "commission"
-
-
-class OlimpiadaForm(ContactForm):
-    disabled = True
-    disabled_template = 'wtem/disabled_contact_form.html'
-    form_tag = "olimpiada"
-    old_form_tags = ["olimpiada-2016"]
-    form_title = u"Olimpiada Cyfrowa - Elektroniczny System Zgłoszeń"
-    submit_label = u"Wyślij zgłoszenie"
-    admin_list = ['nazwisko', 'school']
-    form_formsets = {
-        'student': forms.formsets.formset_factory(WTEMStudentForm, formset=NonEmptyBaseFormSet),
-        'commission': forms.formsets.formset_factory(CommissionForm, formset=BaseFormSet),
-    }
-
-    contact = forms.EmailField(label=u'Adres e-mail Przewodniczącego/Przewodniczącej', max_length=128)
-    przewodniczacy = forms.CharField(label=u'Imię i nazwisko Przewodniczącego/Przewodniczącej', max_length=128)
-    school = forms.CharField(label=u'Nazwa szkoły', max_length=255)
-    school_address = forms.CharField(label=u'Adres szkoły', widget=forms.Textarea, max_length=1000)
-    school_email = forms.EmailField(label=u'Adres e-mail szkoły', max_length=128)
-    school_phone = forms.CharField(label=u'Numer telefonu szkoły', max_length=32)
-    school_www = forms.URLField(label=u'Strona WWW szkoły', max_length=255, required=False)
-
-    zgoda_regulamin = forms.BooleanField(
-        label=u'Znam i akceptuję Regulamin Olimpiady Cyfrowej.',
-        help_text=u'Zobacz <a href="https://olimpiadacyfrowa.pl/regulamin/" target="_blank">'
-                  u'regulamin Olimpiady Cyfrowej</a>.'
-    )
-    zgoda_dane = forms.BooleanField(
-        label=u'Oświadczam, że wyrażam zgodę na przetwarzanie danych osobowych zawartych w niniejszym formularzu '
-              u'zgłoszeniowym przez Fundację Nowoczesna Polska (administratora danych) z siedzibą w Warszawie (00-514) '
-              u'przy ul. Marszałkowskiej 84/92 lok. 125 na potrzeby organizacji Olimpiady Cyfrowej. Jednocześnie '
-              u'oświadczam, że zostałam/em poinformowana/y o tym, że mam prawo wglądu w treść swoich danych '
-              u'i możliwość ich poprawiania oraz że ich podanie jest dobrowolne, ale niezbędne do dokonania '
-              u'zgłoszenia.')
-
-    extract_types = (dict(slug='extended', label=_('extended')),)
-
-    @staticmethod
-    def get_extract_fields(contact, extract_type_slug):
-        fields = contact.body.keys()
-        if 'student' in fields:
-            fields.remove('student')
-        fields.extend(['contact', 'student_first_name', 'student_last_name', 'student_email'])
-        return fields
-
-    @staticmethod
-    def get_extract_records(keys, contact, extract_type_slug):
-        toret = [{}]
-        for field_name in keys:
-            if field_name.startswith('student_'):
-                continue
-            if field_name == 'contact':
-                val = contact.contact
-            else:
-                val = contact.body[field_name]
-            toret[0][field_name] = val
-
-        current = toret[0]
-        if 'student' in contact.body:
-            for student in contact.body['student']:
-                for attr in ('first_name', 'last_name', 'email'):
-                    current['student_' + attr] = student[attr]
-                if current not in toret:
-                    toret.append(current)
-                current = {}
-        return toret
-
-    def save(self, request, formsets=None):
-        contact = super(OlimpiadaForm, self).save(request, formsets)
-
-        mail_subject = render_to_string('contact/olimpiada/student_mail_subject.html').strip()
-        mail_body = render_to_string('contact/olimpiada/student_mail_body.html')
-        for formset in formsets or []:
-            if formset.prefix == 'student':
-                for f in formset.forms:
-                    email = f.cleaned_data.get('email', None)
-                    try:
-                        validate_email(email)
-                    except ValidationError:
-                        pass
-                    else:
-                        send_mail(mail_subject, mail_body, 'edukacjamedialna@nowoczesnapolska.org.pl', [email],
-                                  fail_silently=True)
-
-        return contact
-
-
-class MILForm(ContactForm):
-    disabled = True
-    form_tag = 'mil'
-    form_title = _('Share your thoughts on the "Media and information literacy competencies catalogue"')
-    submit_label = _('Submit')
-    base_template = 'base_mil.html'
-    site_name = site_domain = 'katalog.nowoczesnapolska.org.pl'
-
-    name = forms.CharField(label=_('Name and Surname'), max_length=255)
-    contact = forms.EmailField(label=_('E-mail'), max_length=255)
-
-    institution = forms.CharField(label=_('Institution'), widget=forms.Textarea, max_length=8192)
-
-    question_stages = forms.CharField(
-        label=_('What do you think about the proposed educational stages classification?'),
-        widget=forms.Textarea,
-        max_length=255,
-        required=False)
-
-    question_fields = forms.CharField(
-        label=_('What do you think about the proposed thematic fields?'),
-        widget=forms.Textarea,
-        max_length=255,
-        required=False)
-
-    question_left_out = forms.CharField(
-        label=_('What important areas of media and information literacy have been left out?'),
-        widget=forms.Textarea,
-        max_length=255,
-        required=False)
-
-    other = forms.CharField(
-        label=_('Other suggestions and comments'),
-        widget=forms.Textarea,
-        max_length=255,
-        required=False)
-
-
-class TEMForm(ContactForm):
-    disabled = True
-    form_tag = 'tem'
-    form_title = u"TEM - szkolenie dla trenerów edukacji medialnej"
-    admin_list = ['imie', 'nazwisko', 'instytucja', 'contact']
-    mailing_field = 'zgoda_informacje'
-
-    imie = forms.CharField(label=u'Imię', max_length=128)
-    nazwisko = forms.CharField(label=u'Nazwisko', max_length=128)
-    contact = forms.EmailField(label=u'E-mail', max_length=128)
-    telefon = forms.CharField(label=u'Tel. kontaktowy', max_length=128)
-    instytucja = forms.CharField(label=u'Instytucja', max_length=256)
-    adres = forms.CharField(label=u'Adres', widget=forms.Textarea, max_length=1000)
-    stanowisko = forms.CharField(label=u'Stanowisko', max_length=256)
-    doswiadczenie = forms.CharField(
-        label=u'Jakie jest Pani/Pana doświadczenie w zakresie edukacji medialnej?',
-        widget=forms.Textarea, max_length=500, help_text=u'(max 500 znaków)')
-    dlaczego = forms.CharField(
-        label=u'Dlaczego chce Pani/Pan wziąć udział w szkoleniu?',
-        widget=forms.Textarea, max_length=500, help_text=u'(max 500 znaków)')
-    jak_wykorzystac = forms.CharField(
-        label=u'Jak zamierza Pan/Pani wykorzystać wiedzę zdobytą w czasie szkolenia?',
-        widget=forms.Textarea, max_length=500, help_text=u'(max 500 znaków)')
-
-    zajecia = forms.BooleanField(
-        label=u'W okresie wrzesień-październik 2015 r. przeprowadzę min. 2 godziny zajęć edukacji medialnej '
-              u'z wybraną grupą dzieci lub młodzieży.', required=True)
-    zgoda_informacje = forms.BooleanField(
-        label=u'Wyrażam zgodę na otrzymywanie informacji od Fundacji Nowoczesna Polska '
-              u'związanych z edukacją medialną.', required=False)
-
-
-class SuperwizjaForm(ContactForm):
-    disabled = True
-    form_tag = 'superwizja'
-    form_title = u"Informacje o zajęciach"
-    admin_list = ['nazwisko', 'contact', 'skype', 'temat']
-    submit_label = u'Wyślij'
-
-    nazwisko = forms.CharField(label=u'Imię i nazwisko', max_length=1024)
-    contact = forms.CharField(label=u'E-mail kontaktowy', required=False)
-    skype = forms.CharField(label=u'Nazwa użytkownika Skype', max_length=255)
-    temat = forms.CharField(label=u'Temat zajęć', max_length=1024)
-    termin = forms.CharField(label=u'Termin zajęć', max_length=1024)
-    czas_trwania = forms.CharField(label=u'Czas trwania zajęć', max_length=1024)
-    miejsce = forms.CharField(label=u'Miejsce prowadzenia zajęć', max_length=1024)
-    rodzaj = forms.ChoiceField(
-        label=u'Rodzaj zajęć', widget=forms.RadioSelect,
-        choices=[('jednorazowe', 'jednorazowe'), ('w ramach cyklu', 'w ramach cyklu')])
-    cykl = forms.CharField(label=u'Jeśli w ramach cyklu, to podaj jego temat i czas trwania', required=False)
-    sposob = forms.ChoiceField(
-        label=u'Sposób prowadzenia zajęć', widget=forms.RadioSelect,
-        choices=[('samodzielnie', 'samodzielnie'), (u'z drugą osobą', 'z drugą osobą')])
-    wrazenia = forms.CharField(
-        label=u'Opisz Twoje ogólne wrażenia po warsztacie.', widget=forms.Textarea, max_length=4096)
-    opiekun = forms.CharField(
-        label=u'Czy opiekun grupy był obecny podczas zajęć? Jeśli tak, opisz krótko jego rolę.',
-        widget=forms.Textarea, max_length=4096)
-    grupa = forms.CharField(
-        label=u'Opisz krótko grupę uczestników zajęć (wiek, liczba osób, czy to pierwszy kontakt z grupą).',
-        widget=forms.Textarea, max_length=4096)
-    cel = forms.CharField(
-        label=u'Jaki był założony cel zajęć? Dlaczego wybrałaś/eś taki cel?', widget=forms.Textarea, max_length=4096)
-    ewaluacja = forms.CharField(
-        label=u'W jaki sposób sprawdziłeś/aś, czy cel zajęć został zrealizowany? Opisz krótko efekty zajęć.',
-        widget=forms.Textarea, max_length=4096)
-    # header
-    przygotowania = forms.CharField(
-        label=u'Opisz w punktach proces przygotowania się do zajęć.', widget=forms.Textarea, max_length=4096)
-    przygotowania_trudnosci = forms.CharField(
-        label=u'Co na etapie przygotowań sprawiło Ci największą trudność?', widget=forms.Textarea, max_length=4096)
-    przygotowania_pomoc = forms.CharField(
-        label=u'Co było pomocne w przygotowaniu zajęć? '
-              u'(Czy korzystałaś/eś z materiałów z serwisu edukacjamedialna.edu.pl? Jeśli tak, to jakich?)',
-        widget=forms.Textarea, max_length=4096)
-    narzedzia = forms.CharField(
-        label=u'Jakie narzędzie/a planowałaś/eś wykorzystać, a jakie wykorzystałaś/eś?',
-        widget=forms.Textarea, max_length=4096)
-    struktura = forms.CharField(
-        label=u'Opisz w punktach strukturę zajęć. '
-              u'Zaznacz ile czasu planowałaś/eś na każdą część, a ile czasu faktycznie Ci to zajęło.',
-        widget=forms.Textarea, max_length=4096)
-    prowadzenie_trudnosci = forms.CharField(
-        label=u'Co sprawiało Ci trudność w prowadzeniu zajęć?', widget=forms.Textarea, max_length=4096)
-    prowadzenie_pomoc = forms.CharField(
-        label=u'Co było pomocne w prowadzeniu zajęć?', widget=forms.Textarea, max_length=4096)
-    kontrakt = forms.CharField(
-        label=u'W jakiej formie został zawarty kontrakt z uczestnikami? Jakie zasady zostały przyjęte? '
-              u'Czy w trakcie zajęć Ty bądź uczestnicy odwoływaliście się do kontraktu?',
-        widget=forms.Textarea, max_length=4096)
-    trudne_sytuacje = forms.CharField(
-        label=u'Czy podczas zajęć miały miejsce tzw. „trudne sytuacje”. '
-              u'Jak na nie zareagowałaś/eś? Czy potrzebowałabyś/łbyś czegoś w związku z nimi?',
-        widget=forms.Textarea, max_length=4096)
-    informacje_zwrotne = forms.CharField(
-        label=u'Czy zbierałaś/eś informacje zwrotne od uczestników? Jeśli tak, na co zwrócili uwagę? '
-              u'W jaki sposób zbierałaś/eś informacje zwrotne?', widget=forms.Textarea, max_length=4096)
-
-    mocne_strony = forms.CharField(
-        label=u'Opisz w punktach mocne strony przeprowadzonych zajęć.', widget=forms.Textarea, max_length=4096)
-    zmiany = forms.CharField(
-        label=u'Opisz w punktach, co byś zmienił(a) na przyszłość.', widget=forms.Textarea, max_length=4096)
-    potrzeby = forms.CharField(
-        label=u'Czy potrzebowałbyś/łbyś czegoś przed następnymi zajęciami?', widget=forms.Textarea, max_length=4096)
-    uwagi = forms.CharField(label=u'Inne uwagi', widget=forms.Textarea, max_length=4096, required=False)
-
-
-def textarea_field(label, max_length=500):
-    return forms.CharField(
-        label=label, widget=forms.Textarea, max_length=max_length, help_text=u'(do %s znaków)' % max_length)
-
-
-class CybernauciForm(ContactForm):
-    disabled = True
-    disabled_template = 'contact/disabled_contact_form.html'
-    form_tag = 'trenerzy-cybernauci2017'
-    old_form_tags = ['trenerzy-cybernauci']
-    form_title = u"Cybernauci – szkolenie dla trenerów"
-    admin_list = ['nazwisko', 'instytucja', 'contact']
-    submit_label = u'Wyślij'
-    mailing_field = 'zgoda_newsletter'
-
-    nazwisko = forms.CharField(label=u'Imię i nazwisko', max_length=1024)
-    adres = forms.CharField(label=u'Adres zamieszkania')
-    wojewodztwo = forms.ChoiceField(label=u'Województwo', choices=WOJEWODZTWO_CHOICES)
-    contact = forms.CharField(label=u'Adres e-mail')
-    telefon = forms.CharField(label=u'Telefon kontaktowy', max_length=32)
-    dlaczego = textarea_field(
-        label=u'Proszę opisać, dlaczego chce Pan/Pani zostać Emisariuszem Bezpiecznego Internetu.')
-    grupy = forms.MultipleChoiceField(
-        label=u'Proszę wskazać, dla których grup realizował Pan/realizowała Pani zajęcia warsztatowe',
-        widget=forms.CheckboxSelectMultiple,
-        choices=[
-            ('Uczniowie klas 1-3', 'Uczniowie klas 1-3'),
-            ('Uczniowie klas 4-6', 'Uczniowie klas 4-6'),
-            ('Uczniowie szkół gimnazjalnych', 'Uczniowie szkół gimnazjalnych'),
-            ('Uczniowie szkół ponadgimnazjalnych', 'Uczniowie szkół ponadgimnazjalnych'),
-            ('Nauczyciele', 'Nauczyciele'),
-            ('Rodzice', 'Rodzice'),
-        ])
-    doswiadczenie_grupy = textarea_field(
-        label=u'Proszę opisać swoje doświadczenie w pracy warsztatowej z grupami docelowymi Projektu '
-              u'(dziećmi, młodzieżą, osobami dorosłymi: nauczycielami, rodzicami).',
-        max_length=750)
-    doswiadczenie_edumed = textarea_field(
-        label=u'Jakie jest Pana/Pani doświadczenie w zakresie edukacji medialnej, '
-              u'zwłaszcza w zakresie bezpieczeństwa w Internecie i korzystania z TIK? '
-              u'Skąd czerpie Pan/Pani wiedzę w tym zakresie? W jakich projektach brał '
-              u'Pan/brała Pani udział dotychczas?',
-        max_length=750)
-    szkolenia = textarea_field(
-        label=u'Proszę wymienić studia, szkolenia albo kursy (maks. 5 najważniejszych) '
-              u'powiązane z tematyką Projektu, w których Pan/Pani uczestniczył/ła, '
-              u'w tym dane na temat instytucji czy osoby prowadzącej (z JEDNOZDANIOWYM '
-              u'omówieniem i terminami, w których się odbyły).')
-    realizacje = textarea_field(
-        label=u'Proszę opisać swoje doświadczenie w zakresie realizacji działań w lokalnym środowisku '
-              u'szkolnym (np. na terenie gminy/powiatu/województwa).')
-    cel = textarea_field(
-        label=u'Proszę opisać, jaką wiedzę i umiejętności chce Pan/Pani zdobyć '
-              u'lub doskonalić poprzez uczestnictwo w Szkoleniu trenerskim.')
-    skad = forms.CharField(label=u'Skąd dowiedział/dowiedziała się Pan/Pani o projekcie „Cybernauci”?')
-    zgoda_regulamin = forms.BooleanField(
-        label=u'Oświadczam, że zapoznałem/zapoznałam się z Regulaminem Rekrutacji '
-              u'i Uczestnictwa w Projekcie „Cybernauci – kompleksowy projekt '
-              u'kształtowania bezpiecznych zachowań w sieci” i akceptuję jego warunki.',
-        help_text=u'Zobacz <a href="https://cybernauci.edu.pl/wp-content/uploads/2017/04/'
-                  u'regulamin_Cybernauci_szkolenie_trenerskie_2017.pdf">regulamin</a>.')
-    zgoda_dane = forms.BooleanField(
-        label=u'Wyrażam zgodę na przetwarzanie moich danych osobowych zawartych '
-              u'w niniejszym dokumencie dla potrzeb niezbędnych do realizacji Projektu '
-              u'„Cybernauci – kompleksowy projekt kształtowania bezpiecznych zachowań '
-              u'w sieci”  zgodnie z ustawą z dnia 29.08.1997 roku o Ochronie Danych '
-              u'Osobowych (Dz. U. z 2002 r. Nr 101, poz. 926 z późniejszymi zmianami).')
-    zgoda_niekaralnosc = forms.BooleanField(
-        label=u'W przypadku zakwalifikowania się na kurs zobowiązuję się '
-              u'do dostarczenia świadectwa o niekaralności – najpóźniej w dniu rozpoczęcia Szkolenia.')
-    zgoda_newsletter = forms.BooleanField(
-        required=False,
-        label=u'Chcę otrzymywać newsletter Edukacja Medialna.')
-    cv = forms.FileField(
-        label=u'Wgraj plik CV.',
-        help_text=u'Prosimy o nazwanie pliku swoim imieniem i nazwiskiem. Preferowany format: PDF.')
-
-
-class WLEMForm(ContactForm):
-    disabled = True
-    form_tag = 'wlem'
-    form_title = u"WLEM - szkolenie dla warszawskich liderów edukacji medialnej"
-    admin_list = ['nazwisko', 'instytucja', 'contact']
-    submit_label = u'Wyślij'
-    mailing_field = 'zgoda_newsletter'
-
-    nazwisko = forms.CharField(label=u'Imię i nazwisko', max_length=128)
-    contact = forms.CharField(label=u'Adres e-mail')
-    telefon = forms.CharField(label=u'Tel. kontaktowy', max_length=32)
-    instytucja = forms.CharField(label=u'Instytucja', max_length=128)
-    instytucja_adres = forms.CharField(label=u'Adres (instytucji)', max_length=1024)
-    stanowisko = forms.CharField(label=u'Stanowisko', max_length=256)
-    doswiadczenie = forms.CharField(
-        label=u'Jakie jest Pani/Pana doświadczenie w zakresie edukacji medialnej?',
-        widget=forms.Textarea, max_length=4096)
-    dlaczego = forms.CharField(
-        label=u'Dlaczego chce Pani/Pan wziąć udział w szkoleniu?',
-        widget=forms.Textarea, max_length=4096)
-    cel = forms.CharField(
-        label=u'Jaką wiedzę i umiejętności chce Pan/Pani zdobyć lub doskonalić poprzez uczestnictwo w szkoleniu?',
-        widget=forms.Textarea, max_length=4096)
-    jak_wykorzystac = forms.CharField(
-        label=u'Jak zamierza Pan/Pani wykorzystać wiedzę i umiejętności zdobyte w czasie szkolenia?',
-        widget=forms.Textarea, max_length=4096)
-    zgoda_zajecia = forms.BooleanField(
-        label=u'W okresie lipiec-październik 2016 r. przeprowadzę min. 2 godziny zajęć '
-              u'edukacji medialnej z grupą warszawiaków.')
-    zgoda_dane = forms.BooleanField(
-        label=u'Wyrażam zgodę na przetwarzanie moich danych osobowych zawartych '
-              u'w niniejszym dokumencie dla potrzeb niezbędnych do realizacji Projektu '
-              u'„Warszawscy Liderzy Edukacji Medialnej” zgodnie z ustawą z dnia 29.08.1997 '
-              u'roku o Ochronie Danych Osobowych (Dz. U. z 2002 r. Nr 101, poz. 926 '
-              u'z późniejszymi zmianami).')
-    zgoda_newsletter = forms.BooleanField(
-        required=False,
-        label=u'Wyrażam zgodę na otrzymywanie informacji od Fundacji Nowoczesna Polska '
-              u'związanych z edukacją medialną.')
-
-
-def ordered_textarea_field(start, pre_label=u'', label=u'', max_length=500):
-    return textarea_field(
-        mark_safe(u'%s<ol type="a" start="%s"><li>%s</li></ol>' % (pre_label, start, label)),
-        max_length=max_length)
-
-
-def simple_choices(*choices):
-    return tuple((choice, choice) for choice in choices)
-
-
-class CybernauciAnkietaForm(ContactForm):
-    def __init__(self, *args, **kwargs):
-        super(CybernauciAnkietaForm, self).__init__(*args, **kwargs)
-        self.label_suffix = ''
-
-    disabled = True
-    form_tag = 'cybernauci-ankieta-trenera-2017'
-    old_form_tags = ['cybernauci-ankieta-trenera']
-    form_title = u"Cybernauci – ankieta trenerska"
-    nazwisko = forms.CharField(label=u'Imię i nazwisko', max_length=128)
-    contact = forms.CharField(label=u'Adres e-mail')
-    pyt1a = ordered_textarea_field(
-        1, pre_label=u'1. W kontekście planowanego szkolenia jakie są Twoje oczekiwania w zakresie:',
-        label=u'przekazywanej wiedzy')
-    pyt1b = ordered_textarea_field(2, label=u'tematyki szkoleń z bezpieczeństwa w sieci')
-    pyt1c = ordered_textarea_field(3, label=u'materiałów dydaktycznych')
-    pyt1d = ordered_textarea_field(4, label=u'organizacji  i prowadzenia szkoleń w projekcie')
-    pyt1e = ordered_textarea_field(5, label=u'umiejętności trenerskich')
-    pyt1f = ordered_textarea_field(6, label=u'inne, jakie?')
-    pyt2 = textarea_field(u'2. W których tematach z obszaru bezpieczeństwa w sieci czujesz się najpewniej? '
-                          u'Dlaczego?')
-    pyt3 = textarea_field(u'3. Które z tematów znasz słabej lub których nie znasz zupełnie?')
-    pyt4 = textarea_field(u'4. Jakie są Twoje mocne strony jako osoby prowadzącej warsztaty?')
-    pyt5 = textarea_field(u'5. Nad jakimi elementami pracy trenerskiej chciałbyś/chciałabyś popracować?')
-    pyt6 = textarea_field(u'6. Co jest dla Ciebie najważniejsze w pracy z grupą? '
-                          u'Na co zwracasz uwagę w tym obszarze jako osoba prowadząca warsztaty?')
-    pyt7 = textarea_field(
-        u'7. Jakie są Twoje największe obawy wobec realizacji szkoleń w placówkach oświatowych?')
-    pyt8a = ordered_textarea_field(
-        1, pre_label=u'8. Opisz szczegółowo doświadczenie z różnymi grupami:', label=u'rodzice')
-    pyt8b = ordered_textarea_field(2, label=u'nauczyciele')
-    pyt8c = ordered_textarea_field(3, label=u'młodzież ponadgimnazjalna')
-    pyt8d = ordered_textarea_field(4, label=u'młodzież gimnazjalna')
-    pyt8e = ordered_textarea_field(5, label=u'dzieci i młodzież szkół podstawowych')
-    pyt9 = textarea_field(
-        u'9. Z jakimi grupami wiekowymi najlepiej Ci się współpracuje? '
-        u'Umiejętności w zakresie pracy z którą grupą najbardziej chciałabyś/chciałbyś zdobyć/doskonalić?')
-    pyt10 = textarea_field(
-        u'10. W jaki sposób na co dzień dbasz o swój rozwój jako trenera/trenerki, '
-        u'osoby prowadzącej warsztaty czy inne formy szkoleniowe?')
-    pyt11 = textarea_field(u'11. Jakie są Twoje potrzeby żywieniowe?')
-    pyt12 = forms.ChoiceField(
-        label=u'12. Jak przyjedziesz do Wilgi?',
-        widget=forms.RadioSelect,
-        choices=simple_choices(
-            u'publiczna komunikacja do/z Warszawy (i wesoły bus do/z Wilgi)',
-            u'publiczna komunikacja do/z Wilgi',
-            u'samochód prywatny'))
-
-
-class SciezkiKopernikaForm(ContactForm):
-    form_tag = 'sciezki-kopernika'
-    form_title = u'Formularz zgłoszeniowy na warsztaty'
-    disabled = True
-
-    nazwisko = forms.CharField(label=u'Imię i nazwisko uczestnika/uczestniczki', max_length=128)
-    rok_urodzenia = forms.IntegerField(label=u'Rok urodzenia')
-    adres_dom = forms.CharField(label=u'Adres zamieszkania – ulica i numer', max_length=128)
-    adres_poczta = forms.CharField(label=u'Adres zamieszkania – kod pocztowy i miejscowość', max_length=128)
-    contact = forms.EmailField(label=u'Adres e-mail')
-    szkola = forms.CharField(label=u'Nazwa szkoły', max_length=128)
-    adres_szkola = forms.CharField(label=u'Adres szkoły – ulica i numer', max_length=128)
-    poczta_szkola = forms.CharField(label=u'Adres szkoły – kod pocztowy i miejscowość', max_length=128)
-    opiekun = forms.CharField(label=u'Imię i nazwisko rodzica/opiekuna', max_length=128)
-    adres_opiekun = forms.CharField(label=u'Adres zamieszkania rodzica/opiekuna – ulica i numer', max_length=128)
-    poczta_opiekun = forms.CharField(
-        label=u'Adres zamieszkania rodzica/opiekuna – kod pocztowy i miejscowość', max_length=128)
-    telefon_opiekun = forms.CharField(label=u'Numer telefonu rodzica/opiekuna', max_length=32)
-    email_opiekun = forms.EmailField(label=u'Adres e-mail rodzica/opiekuna', max_length=32)
-    specjalne_potrzeby = forms.ChoiceField(
-        label=u'Czy uczestnik/uczestniczka ma specjalne potrzeby wynikające z niepełnosprawności', required=True,
-        choices=[('tak', 'tak'), ('nie', 'nie')], widget=forms.RadioSelect)
-    zgoda_regulamin = forms.BooleanField(
-        label=mark_safe(
-            u'Oświadczam, że zapoznałem/am się z <a href="/media/chunks/attachment/Regulamin.pdf" target="_blank">'
-            u'Regulaminem udziału w projekcie</a> '
-            u'i spełniam kryteria kwalifikowalności do udziału w projekcie.'))
-
-
-class CollegiumMlodychForm(ContactForm):
-    form_tag = 'collegium-mlodych'
-    form_title = u'Formularz zgłoszeniowy na warsztaty'
-    disabled = True
-    disabled_template = 'contact/collegium-mlodych/on_hold.html'
-
-    nazwisko = forms.CharField(label=u'Imię i nazwisko uczestnika/uczestniczki', max_length=128)
-    pesel = forms.CharField(label=u'PESEL', max_length=11)
-    adres_dom = forms.CharField(label=u'Adres zamieszkania – ulica i numer', max_length=128)
-    adres_poczta = forms.CharField(label=u'Adres zamieszkania – kod pocztowy i miejscowość', max_length=128)
-    contact = forms.EmailField(label=u'Adres e-mail')
-    szkola = forms.CharField(label=u'Nazwa szkoły', max_length=128)
-    adres_szkola = forms.CharField(label=u'Adres szkoły – ulica i numer', max_length=128)
-    poczta_szkola = forms.CharField(label=u'Adres szkoły – kod pocztowy i miejscowość', max_length=128)
-    opiekun = forms.CharField(label=u'Imię i nazwisko rodzica/opiekuna prawnego', max_length=128)
-    telefon_opiekun = forms.CharField(label=u'Numer telefonu rodzica/opiekuna prawnego', max_length=32)
-    email_opiekun = forms.EmailField(label=u'Adres e-mail rodzica/opiekuna prawnego')
-    specjalne_potrzeby = forms.ChoiceField(
-        label=u'Czy uczestnik/uczestniczka ma specjalne potrzeby wynikające z niepełnosprawności',
-        choices=[('tak', 'tak'), ('nie', 'nie')], widget=forms.RadioSelect)
-    skad = forms.CharField(label=u'Skąd dowiedziałeś/aś się o warsztatach?')
-    zgoda_regulamin = forms.BooleanField(
-        label=mark_safe(
-            u'Oświadczam, że zapoznałem/am się z <a href="/media/chunks/attachment/REGULAMIN-UCZESTNICTWA-W-PROJEKCIE_aktualizacja.pdf" target="_blank">'
-            u'Regulaminem udziału w projekcie</a> '
-            u'i spełniam kryteria kwalifikowalności do udziału w projekcie.'))
-
-
-class SciezkiKopernikaTestForm(TestForm):
-    def __init__(self, *args, **kwargs):
-        super(SciezkiKopernikaTestForm, self).__init__(*args, **kwargs)
-        self.label_suffix = ''
-
-    result_page = True
-    form_tag = 'sciezki-kopernika-test'
-    form_title = u'Test wiedzy w zakresie edukacji medialnej i cyfrowej'
-    submit_label = u'Wyślij'
-
-    contact = forms.EmailField(label=u'Adres e-mail, na który przyślemy informację o wynikach')
-    head1 = HeaderField(
-        label=u'Test powstał w ramach projektu "Collegium Młodych - media i technologie" realizowany w ramach '
-              u'III Osi priorytetowej: Szkolnictwo wyższe dla gospodarki i rozwoju, Działanie 3.1 Kompetencje '
-              u'w szkolnictwie wyższym Programu Operacyjnego Wiedza Edukacja Rozwój, współfinansowanego przez '
-              u'Unię Europejską w ramach Europejskiego Funduszu Społecznego. Nr umowy POWR.03.01.00-00-C078/16-00.')
-
-    @classmethod
-    def results(cls, contact):
-        fields = cls().fields
-
-        def get_idx(choices, answer):
-            return dict((score, i) for i, (score, text) in enumerate(choices))[answer]
-
-        def question_data(i):
-            field = 'pyt%s' % i
-            choices = fields[field].choices
-            score = contact.body[field]
-            chosen_idx = get_idx(choices, score)
-            correct_idx = get_idx(choices, 2)
-            return {
-                'score': score,
-                'chosen_idx': chosen_idx,
-                'correct_idx': correct_idx,
-                'chosen': 'abc'[chosen_idx],
-                'correct': 'abc'[correct_idx],
-                'label': fields[field].label,
-                'comment': mark_safe(markdown.convert(cls.ANSWER_COMMENTS[i-1][chosen_idx])),
-                'answers': [(text, a_score == score, a_score == 2) for a_score, text in choices],
-            }
-        question_count = 20
-        questions = [question_data(i) for i in xrange(1, question_count + 1)]
-        points = sum(question['score'] for question in questions)
-        return {'questions': questions, 'points': points/2., 'total': question_count}
-
-
-class CollegiumMlodychTestForm(CollegiumTestForm):
-    def __init__(self, *args, **kwargs):
-        super(CollegiumMlodychTestForm, self).__init__(*args, **kwargs)
-        self.label_suffix = ''
-
-    result_page = True
-    form_tag = 'collegium-mlodych-test'
-    form_title = u'Test wiedzy w zakresie edukacji medialnej i cyfrowej'
-    submit_label = u'Wyślij'
-
-    contact = forms.EmailField(label=u'Adres e-mail, na który przyślemy informację o wynikach')
-
-    @classmethod
-    def results(cls, contact):
-        fields = cls().fields
-
-        def question_data(i):
-            field = 'pyt%s' % i
-            choices = fields[field].choices
-            answers = contact.body[field]
-            answer_data = []
-            for answer in answers:
-                idx = answer // 10
-                answer_data.append(
-                    {
-                        'score': answer % 10,
-                        'index': idx,
-                        'letter': 'abcdef'[idx],
-                        'comment': mark_safe(markdown.convert(cls.ANSWER_COMMENTS[i-1][idx])),
-                    })
-            correct = [answer // 10 for answer, text in choices if answer % 10 == 1]
-            return {
-                'answer_data': answer_data,
-                'correct': correct,
-                'correct_letters': ['abcdef'[idx] for idx in correct],
-                'label': fields[field].label,
-                'answers': [(text, a_score in answers, a_score % 10 == 1) for a_score, text in choices],
-                'full_match': set(answer['index'] for answer in answer_data) == set(correct)
-            }
-        question_count = 20
-        questions = [question_data(i) for i in xrange(1, question_count + 1)]
-        points = sum(1 for question in questions if question['full_match'])
-        return {'questions': questions, 'points': points, 'total': question_count}
-
-
-class ESEMWarszawaForm(ContactForm):
-    form_tag = 'emels-warszawa'
-    form_title = u"Ja i młodzież w cyfrowym świecie"
-    admin_list = ['imie', 'nazwisko', 'instytucja', 'contact']
-    submit_label = u'Wyślij'
-    mailing_field = 'zgoda_newsletter'
-    disabled = True
-    disabled_template = 'contact/disabled_contact_form.html'
-
-    imie = forms.CharField(label=u'Imię', max_length=128)
-    nazwisko = forms.CharField(label=u'Nazwisko', max_length=128)
-    contact = forms.EmailField(
-        label=u'Adres e-mail', max_length=128, help_text=u'Wyślemy na niego informacje organizacyjne.')
-    telefon = forms.CharField(
-        label=u'Numer telefonu', max_length=20,
-        help_text=u'Liczba miejsc na warsztatach jest ograniczona, będziemy telefonicznie potwierdzać '
-                  u'obecność, a w przypadku rezygnacji chcielibyśmy móc udostępnić miejsce kolejnej '
-                  u'zainteresowanej osobie.')
-    motywacja = forms.CharField(
-        label=u'W jaki sposób wykorzystasz wiedzę zdobytą na warsztatach?', max_length=1000,
-        widget=forms.Textarea)
-    instytucja = forms.CharField(label=u'Organizacja/instytucja', max_length=255)
-    zgoda_newsletter = forms.BooleanField(
-        required=False,
-        label=u'Chcę otrzymywać newsletter Edukacja medialna.')
-
-
-class ESEMGdanskForm(ESEMWarszawaForm):
-    form_tag = 'emels-gdansk'
-
-
-class MisjaCybernautowForm(ContactForm):
-    form_tag = 'misja-cybernautow'
-    form_title = u"Misja Cybernautów"
-    submit_label = u'Zapisz'
-    updatable = True
-    contact = forms.EmailField(label=u'Adres e-mail', max_length=128)
-    szkola = forms.CharField(label=u'Szkoła, do której chodzicie', max_length=255)
-    zespol = forms.CharField(label=u'Nazwa zespołu', max_length=255)
-    zdjecie_warszawa = forms.FileField(
-        label=u'Dołączcie zdjęcie pokazujące, że jesteście dziś w Warszawie', required=False)
-    zdjecie_planetarium = forms.FileField(
-        label=u'Dołączcie zdjęcie grupy na scenie przy planetarium', required=False)
-    zdjecie_zasady = forms.FileField(
-        label=u'Dołączcie zdjęcie napisanych przez Was zasad bezpiecznego korzystania z internetu', required=False)
-    zdjecie_piasek = forms.FileField(
-        label=u'Dołączcie zdjęcie zdjęcie notatki zrobionej na piasku', required=False)
-    sonda = forms.CharField(
-        widget=forms.Textarea, max_length=1000, required=False,
-        label=u'Jaki macie wnioski z sondy zrobionej w BUW-ie?')
-    fasada = forms.FileField(
-        label=u'Dołączcie zdjęcie kodu programu umieszczonego na fasadzie BUW-u', required=False)
-    ochrona = forms.CharField(
-        label=u'Jakie są Wasze pomysły na ochronę przed zagrożeniami na podstawie filmiku z kanału '
-              u'„To już jutro” na YouTube',
-        widget=forms.Textarea, max_length=1000, required=False)
-    obraz = forms.CharField(
-        label=u'Który obraz z Galerii Sztuki Polskiej wybraliście? Załączcie link', required=False, max_length=255)
-    haslo = forms.CharField(
-        label=mark_safe(u'Jaka jest Wasza propozycja mocne hasło, które stworzyliście i sprawdziliście na stronie '
-                        u'<a href="https://howsecureismypassword.net" target="_blank">'
-                        u'https://howsecureismypassword.net</a>?'),
-        required=False, max_length=255)
-    syrenka = forms.FileField(
-        label=u'Dołaczcie zdjęcie pomysłu podpisu na pomniku Syrenki', required=False)
-    mem = forms.FileField(label=u'Dołączcie stworzony mem', required=False)
-    gif = forms.FileField(label=u'Dołączcie stworzony gif', required=False)
diff --git a/edumed/contact_forms_test.py b/edumed/contact_forms_test.py
deleted file mode 100644 (file)
index ebfe2fd..0000000
+++ /dev/null
@@ -1,1312 +0,0 @@
-# -*- coding: utf-8 -*-
-from django import forms
-from django.utils.safestring import mark_safe
-
-from contact.forms import ContactForm
-
-
-def quiz_question(label, choices):
-    return forms.TypedChoiceField(label=label, choices=choices, coerce=int, widget=forms.RadioSelect)
-
-
-def quiz_question_multiple(label, choices):
-    return forms.TypedMultipleChoiceField(label=label, choices=choices, coerce=int, widget=forms.CheckboxSelectMultiple)
-
-
-def make_link(text, url):
-    return u'<a href="%s">%s</a>' % (url, text)
-
-
-class TestForm(ContactForm):
-    pyt1 = quiz_question(
-        label=u'1. Na stronie portalu internetowego pod jednym z artykułów opublikowano komentarz o treści '
-              u'„Nie wszyscy muzułmanie to terroryści, ale wszyscy terroryści to muzułmanie”. '
-              u'Komentarz podlega moderacji i powinien:',
-        choices=[
-            (1, u'zostać zachowany, ponieważ jest prywatną opinią korzystającą z wolności słowa,'),
-            (0, u'zostać zachowany, ponieważ informuje o fakcie,'),
-            (2, u'zostać usunięty, ponieważ jest wprowadzającą w błąd interpretacją faktów.'),
-        ])
-    pyt2 = quiz_question(
-        label=u'2. Aby przygotować podcast, należy posiadać przynajmniej:',
-        choices=[
-            (0, u'półprofesjonalny mikrofon radiowy, z wbudowanym interfejsem dźwiękowym, '
-                u'komercyjne oprogramowanie typu DAW, średnio-zaawansowane umiejętności cyfrowej obróbki dźwięku,'),
-            (1, u'urządzenie do nagrywania dźwięku, laptop, oprogramowanie dedykowane do tworzenia podcastów,'),
-            (2, u'urządzenie do nagrywania dźwięku, podstawowe oprogramowanie do edycji dźwięku, '
-                u'podstawowe umiejętności cyfrowej obróbki dźwięku.')])
-    pyt3 = quiz_question(
-        label=u'3. Muzeum cyfrowe chce udostępnić skan XIV-wiecznego kodeksu. '
-              u'Zgodnym z ideą domeny publicznej sposobem jego udostępnienia będzie:',
-        choices=[
-            (0, u'udostępnienie go na licencji Creative Commons,'),
-            (2, u'udostępnienie go bez licencji z czytelnym wskazaniem praw do dowolnego wykorzystania,'),
-            (1, u'udostępnienie go w pliku jakości produkcyjnej.')])
-    pyt4 = quiz_question(
-        label=u'4. Aby uniknąć możliwości podejrzenia przez niepowołane osoby, jakie strony internetowe '
-              u'odwiedzałaś/eś ostatnio, powinieneś/powinnaś:',
-        choices=[
-            (0, u'ustawić opcję otwierania nowej sesji przeglądarki bez wyświetlania ostatnio używanych kart '
-                u'oraz regularnie czyścić historię wyszukiwania,'),
-            (2, u'wylogowywać się lub blokować ekran za każdym razem, kiedy odchodzisz od komputera, tabletu '
-                u'lub odkładasz gdzieś telefon, regularnie czyścić dane zgromadzone przez przeglądarkę internetową,'),
-            (1, u'wylogowywać się lub blokować ekran za każdym razem, kiedy odchodzisz od komputera, tabletu '
-                u'lub odkładasz gdzieś telefon, regularnie czyścić historię przeglądanych stron.')])
-    pyt5 = quiz_question(
-        label=u'5. Komentarz opublikowany w Internecie ma taką samą wartość bez względu na to, '
-              u'czy jest anonimowy czy podpisany imieniem i nazwiskiem:',
-        choices=[
-            (0, u'tak, ze względu na zasadę wolności słowa,'),
-            (2, u'to zależy od jego treści i kontekstu, w którym go opublikowano,'),
-            (1, u'tak, z punktu widzenia odpowiedzialności prawnej.')])
-    pyt6 = quiz_question(
-        label=u'6. Wraz z grupą osób zamierzasz przygotować cyfrową opowieść (narrację) na temat współczesnych '
-              u'nastolatków i ich stosunku do szkoły. Żeby praca była efektywna, a jej rezultat efektowny, warto '
-              u'zorganizować wspólną pracę w następujących krokach:',
-        choices=[
-            (2, u'przeprowadzić wspólną dyskusję odnośnie możliwych tematów opowieści, wybrać jeden, ustalić, '
-                u'co należy zrobić, podzielić zadania w grupie i przygotować scenariusz narracji '
-                u'(opisać poszczególne sceny, co się w nich znajdzie, co będzie potrzebne do ich przygotowania),'),
-            (0, u'zgromadzić jak najwięcej materiałów wideo i zdjęć, wybrać oprogramowanie do obróbki wideo i wspólnie '
-                u'decydować o kolejności scen i zawartości opowieści,'),
-            (1, u'wybrać temat opowieści, zgromadzić jak najwięcej filmików i zdjęć, podzielić się zadaniami w grupie, '
-                u'zmontować narrację z części przygotowanych przez uczestników zespołu.')])
-    pyt7 = quiz_question(
-        label=u'7. Firma telekomunikacyjna wykorzystuje boty do automatycznego odpowiadania na pytania klientów '
-              u'zadawane w serwisie społecznościowym. Boty zwracają się do wszystkich po imieniu. Kiedy użytkownik, '
-              u'który sobie tego nie życzy, wyraża swoje niezadowolenie z takiej formy rozmowy, firma powinna:',
-        choices=[
-            (2, u'przeprosić użytkownika, szanując preferowane przez niego reguły komunikacji,'),
-            (0, u'zignorować użytkownika odwołując się do zasad netykiety,'),
-            (1, u'zareagować zgodnie z wypracowanymi wewnętrznie zasadami komunikacji.')])
-    pyt8 = quiz_question(
-        label=u'8. Jesteś członkiem/członkinią grupy, która przygotowuje aplikację mającą ułatwić osobom '
-              u'z niepełnosprawnościami poruszanie się po Twojej miejscowości. Oprogramowanie będzie m.in. informować, '
-              u'czy przy określonej instytucji, firmie, sklepie, znajdują się miejsca parkingowe dla osób '
-              u'z niepełnosprawnościami i ile ich jest. Aby aplikacja działała prawidłowo, powinieneś/powinnaś:',
-        choices=[
-            (1, u'przygotować listę najważniejszych obiektów w Twoim mieście i skontaktować się z ich administracją, '
-                u'pytając o liczbę miejsc parkingowych,'),
-            (0, u'poszukać informacji o dostępnych miejscach parkingowych na stronach instytucji, firm i sklepów,'),
-            (2, u'skontaktować się z administracją obiektów, o których będzie informować aplikacja, udać się również '
-                u'do tych obiektów, aby potwierdzić ilość dostępnych miejsc, spróbować zgromadzić informacje o tym, '
-                u'jak często miejsca parkingowe są zajmowane przez ludzi pełnosprawnych.')])
-    pyt9 = quiz_question(
-        label=u'9. Pojęcie „niewidzialnej pracy” może dotyczyć:',
-        choices=[
-            (2, u'moderatorów mediów społecznościowych zatrudnianych w krajach o niskich kosztach pracy,'),
-            (1, u'użytkowników serwisów społecznościowych publikujących codziennie i bez wynagrodzenia własne '
-                u'materiały w tym serwisie,'),
-            (0, u'informatyków budujących rozwiązania IT dla firm.')])
-
-    pyt10 = quiz_question(
-        label=u'10. Możesz uważać, że informacje, do których docierasz, są wiarygodne, ponieważ:',
-        choices=[
-            (1, u'pojawiają się w wielu telewizyjnych serwisach informacyjnych, na profilach społecznościowych '
-                u'moich znajomych i w różnorodnych internetowych serwisach informacyjnych, wszędzie przedstawiane '
-                u'są w podobny sposób,'),
-            (2, u'pojawiają się w wielu serwisach informacyjnych, na profilach moich znajomych, zawierają odnośniki '
-                u'do oryginalnych źródeł, do których można dotrzeć,'),
-            (0, u'pojawiają się na profilach wielu moich znajomych w serwisach społecznościowych i '
-                u'w kilku internetowych serwisach informacyjnych.')])
-    pyt11 = quiz_question(
-        label=u'11. W pewnym mieście prokuratura bada umowy z wykonawcami projektów budżetu obywatelskiego. '
-              u'Nikomu, jak dotąd, nie postawiono zarzutów. Która postać tytułu newsa opublikowanego '
-              u'na lokalnym portalu internetowym będzie najbardziej zgodna z zasadami etyki dziennikarskiej?',
-        choices=[
-            (1, u'„Budżet obywatelski: niejasne umowy z wykonawcami?”,'),
-            (2, u'„Prokuratura zbada umowy z wykonawcami projektów budżetu obywatelskiego.”,'),
-            (0, u'„Zobacz, które firmy mogły obłowić się na projektach budżetu obywatelskiego!”.')])
-    pyt12 = quiz_question(
-        label=u'12. Dołączyłeś/aś do grupy, która zbiera informacje o problemach dotyczących młodych ludzi '
-              u'w Twojej okolicy. Zamierzacie zaprezentować zgromadzone informacje w interesujący sposób, '
-              u'tak by zainteresować lokalne media, służby miejskie, zwykłych obywateli i Waszych rówieśników. '
-              u'Grupa nie ma możliwości regularnego spotykania się, dlatego wybraliście pracę wyłącznie '
-              u'przez Internet. Który zestaw narzędzi pozwoli Wam na jak najlepszą, wspólną pracę?',
-        choices=[
-            (0, u'mail grupowy, komunikator tekstowy (np. Messenger), oprogramowanie do tworzenia podcastów, '
-                u'stacjonarne narzędzie do tworzenia prezentacji (np. Power Point),'),
-            (1, u'mail grupowy, komunikator tekstowy zespołu (np. Slack), narzędzie do kolektywnego tworzenia '
-                u'map myśli (np. Coggle), blog redagowany przez wszystkich uczestników projektu, aplikacja do '
-                u'synchronizowania plików w chmurze (np. Dropbox), narzędzie do grupowej komunikacji za pomocą wideo '
-                u'(np. Skype),'),
-            (2, u'aplikacja do zarządzania zadaniami zespołu i terminami do wykonania (np. Wunderlist), '
-                u'narzędzie do tworzenia kolektywnych notatek (np. OneNote) lub wspólnej pracy z tekstem '
-                u'(np. EtherPad, Google Dokumenty), grupa w serwisie społecznościowym lub tekstowy komunikator '
-                u'zespołu (np. Messenger lub Slack), narzędzia do gromadzenia lub prezentowania materiałów '
-                u'(np. wspólny blog, kanał w serwisie społecznościowym).')])
-    pyt13 = quiz_question(
-        label=u'13. Poniżej podano wybrane cechy hasła opublikowanego w Wikipedii. '
-              u'Która z nich jest najbardziej pomocna przy analizie jakości hasła?',
-        choices=[
-            (0, u'liczba edycji hasła,'),
-            (1, u'długość i struktura hasła,'),
-            (2, u'obecność i jakość przypisów.')])
-    pyt14 = quiz_question(
-        label=u'14. Na przeglądanej stronie internetowej znalazłeś/aś interesującą grafikę, którą chciał(a)byś '
-              u'wykorzystać w przygotowywanej cyfrowej narracji. Nie jest ona jednak podpisana. Co robisz?',
-        choices=[
-            (0, u'podpisuję grafikę adresem strony, na której ją znalazłem/am,'),
-            (1, u'korzystam z opcji wyszukiwania obrazem w wyszukiwarce grafiki, chcąc znaleźć inne strony, '
-                u'gdzie pojawiła się grafika,'),
-            (2, u'korzystam z opcji wyszukiwania obrazem, a jeśli to się nie powiedzie, skontaktuję się '
-                u'z administratorem strony, na której znalazłem/am grafikę, pytając o autora; przeglądam także '
-                u'informacje o stronie, szukając ewentualnych informacji o zasadach publikacji treści; być może '
-                u'autor informuje, że wszystkie grafiki są jego autorstwa.')])
-    pyt15 = quiz_question(
-        label=mark_safe(
-            u'15. W nieistniejącym języku programowania TEST dana jest funkcja zapisana w następujący sposób:'
-            u'<p><code>funkcja f(a) { wyświetl a + b;<br>'
-            u'}</code></p>'
-            u'<strong>Przeczytaj uważnie kod i zastanów się, jak działa ta funkcja.'
-            u'Główną wadą tego kodu jest przetwarzanie brakującego argumentu:</strong>'),
-        choices=[
-            (2, u'b,'),
-            (1, u'b będącego dowolną liczbą,'),
-            (0, u'f.')])
-    pyt16 = quiz_question(
-        label=u'16. Przygotowujesz teledysk do utworu nagranego przez Twój zespół. Efekt swojej pracy opublikujesz '
-              u'na kanale zespołu na YouTube. Teledysk nie może łamać praw autorskich, w przeciwnym razie zostanie '
-              u'usunięty z serwisu. W teledysku możesz wykorzystać zdjęcia, ikony, fragmenty filmów:',
-        choices=[
-            (1, mark_safe(
-                u'znalezionych w wyszukiwarce serwisu Flickr na licencji %s, przygotowanych przez Ciebie, '
-                u'ściągniętych z serwisu %s,' % (
-                    make_link(u'CC BY-SA', 'https://www.flickr.com/creativecommons/by-sa-2.0/'),
-                    make_link(u'The Noun Project', 'https://thenounproject.com')))),
-            (2, mark_safe(
-                u'znalezionych w wyszukiwarce serwisu Flickr na licencji %s, przygotowanych przez Ciebie, '
-                u'ściągniętych z %s,' % (
-                    make_link(u'CC-BY', 'https://www.flickr.com/creativecommons/by-2.0/'),
-                    make_link(u'serwisu ze zdjęciami NASA',
-                              'https://www.nasa.gov/multimedia/imagegallery/index.html')))),
-            (0, mark_safe(
-                u'znalezionych w wyszukiwarce serwisu Flickr na licencji %s, przygotowanych przez Ciebie, '
-                u'ściągniętych z wyszukiwarki grafiki Google.' %
-                make_link('CC-BY-NC', 'https://www.flickr.com/creativecommons/by-nc-2.0/')))])
-    pyt17 = quiz_question(
-        label=mark_safe(
-            u'17. Muzeum cyfrowe udostępniło skan druku propagandowego z pierwszej połowy XVII w. '
-            u'w humorystyczny sposób przedstawiający strony angielskiej wojny domowej (trwającej z przerwami '
-            u'między 1642 a 1651 rokiem):'
-            u'<p><a href="https://commons.wikimedia.org/wiki/File:Engl-Bürgerkrieg.JPG">'
-            u'<img src="https://upload.wikimedia.org/wikipedia/commons/c/c6/Engl-B%C3%BCrgerkrieg.JPG"></a></p>'
-            u'<p><a href="https://commons.wikimedia.org/wiki/File:Engl-Bürgerkrieg.JPG">'
-            u'https://commons.wikimedia.org/wiki/File:Engl-Bürgerkrieg.JPG</a></p>'
-            u'<strong>Najlepszym zestawem tagów dla osoby katalogującej pliki cyfrowe w muzeum, '
-            u'a równocześnie najbardziej użytecznym dla użytkowników przeszukujących stronę '
-            u'zestawem słów kluczowych opisujących ten obiekt będzie:</strong>'),
-        choices=[
-            (2, u'Anglia, wojna domowa, karykatura, propaganda,'),
-            (0, u'komiks, śmiech, Anglicy, Wielka Brytania, psy,'),
-            (1, u'Angielska Wojna Domowa 1642-1651, propaganda.')])
-    pyt18 = quiz_question(
-        label=u'18. Podczas wycieczki szkolnej zrobiłaś/eś sporo zdjęć znajomym, w różnych sytuacjach. '
-              u'Masz również dostęp do wielu fotografii, które przygotowali Twoi koledzy i koleżanki. '
-              u'Zamierzasz niektóre z nich zamieścić na swoim kanale w serwisie społecznościowym. Możesz opublikować:',
-        choices=[
-            (0, u'zdjęcia prezentujące selfie (o ile nie przedstawiają więcej niż dwóch osób), '
-                u'zdjęcia grupy podczas zwiedzania, zdjęcia, które ktoś zrobił Tobie na tle zwiedzanych obiektów, '
-                u'zdjęcia, na których ludzie się uśmiechają i cieszą, że robisz im zdjęcie,'),
-            (1, u'zdjęcia prezentujące selfie (ale tylko Twoje), zdjęcia pokazujące w oddali grupę na tle '
-                u'zwiedzanych obiektów, zdjęcia, zdjęcia na których widać tylko Ciebie, na tle zwiedzanych obiektów,'),
-            (2, u'zdjęcia prezentujące selfie (na których jesteś Ty, ale również inne osoby, które potwierdziły, '
-                u'że możesz opublikować fotografie), zdjęcia na których widać tylko Ciebie '
-                u'i masz zgodę na ich publikację od osoby, która wykonała fotografię, '
-                u'wykonane przez Ciebie zdjęcia zwiedzanych obiektów.')])
-    pyt19 = quiz_question(
-        label=u'19. Korzystając z sieci, natrafiamy na różne interesujące informacje. '
-              u'Pojawiają się w wielu serwisach informacyjnych, społecznościowych, w postaci reklam '
-              u'dołączanych do materiałów wideo, reklam zamieszczonych w tekstach itp. '
-              u'Na co warto zwracać uwagę, podczas codziennego korzystania z mediów, '
-              u'żeby efektywnie wykorzystać czas spędzony w Internecie?',
-        choices=[
-            (1, u'zaplanować czas spędzany na korzystaniu z mediów i starać się trzymać swojego planu, '
-                u'nie unikasz jednak nagłych rozmów przez komunikator, oglądania postów, '
-                u'zdjęć i filmików dodawanych przez znajomych,'),
-            (0, u'zaplanować, co będziesz robił(a), ale traktujesz to jako ramę działania, wiesz, '
-                u'że po drodze pojawi się wiele interesujących informacji, z których skorzystasz,'),
-            (2, u'zaplanować czas spędzany na korzystaniu z mediów i rejestrować, co, '
-                u'kiedy i przez ile czasu robisz, np. instalując aplikację do mierzenia czasu spędzanego w sieci. '
-                u'Następnie analizujesz zebrane informacje i starasz się określić, co robisz zbyt często '
-                u'i jakie rzeczy odciągają Twoją uwagę od tych zaplanowanych.')])
-    pyt20 = quiz_question(
-        label=u'20. Blokująca reklamy wtyczka do przeglądarki działa w następujący sposób:',
-        choices=[
-            (0, u'analizuje treść tekstów oraz obrazków i blokuje te, które zawierają reklamy,'),
-            (1, u'blokuje wyświetlanie plików reklam zanim wyświetli je przeglądarka,'),
-            (2, u'blokuje komunikację przeglądarki z serwerami publikującymi reklamy.')])
-
-    ANSWER_COMMENTS = [
-        (
-            u"Stwierdzenie „Nie wszyscy muzułmanie to terroryści, ale wszyscy terroryści to muzułmanie” nie "
-            u"odzwierciedla faktów. O ile prawdą jest, że „Nie wszyscy muzułmanie to terroryści”, to błędnym "
-            u"założeniem jest, że „wszyscy terroryści są muzułmanami”. Terroryzm jako akt agresji fizycznej wymierzony"
-            u" przeciwko innym osobom nie jest domeną tej, czy innej religii. Wynika on często z fundamentalistycznych "
-            u"postaw i może pojawić się w różnych kontekstach politycznych i społecznych, a nie tylko religijnych. "
-            u"Z drugiej strony, każdemu użytkownikowi Internetu przysługuje wolność słowa, która oznacza prawo "
-            u"do publicznego wyrażania własnych poglądów w przestrzenie publicznej. Zachęca do tego zwłaszcza możliwość"
-            u" zostawiania komentarzy pod różnego rodzaju artykułami. Należy liczyć się z tym, że część z nich może "
-            u"wprowadzać w błąd. Jeśli przyjmiemy interpretację, zgodnie z którą wpis użytkownika na portalu "
-            u"internetowym jest opinią, to mamy prawo do jego zachowania.\n"
-            u"Jeśli chcesz pogłębić swoją wiedzę na temat „terroryzmu” możesz przeczytać artykuł "
-            u"pt. „Zjawisko terroryzmu”: "
-            u"http://www.ies.krakow.pl/wydawnictwo/prokuratura/pdf/2012/07-08/11resztak.pdf.\n"
-            u"\n"
-            u"O prawie do wolności wypowiedzi w Internecie i zagrożeniach związanych z jego ograniczeniem możesz "
-            u"przeczytać w komentarzu prawnika pt. „Masz prawo swobodnie wypowiadać się w Internecie, tak samo jak "
-            u"wyjść z domu i chodzić po ulicach!”: "
-            u"http://prawokultury.pl/newsy/masz-prawo-swobodnie-wypowiadac-sie-w-internecie-t/.",
-
-            u"Stwierdzenie „Nie wszyscy muzułmanie to terroryści, ale wszyscy terroryści to muzułmanie” nie "
-            u"odzwierciedla faktów. W tym przypadku należy odróżnić fakt, czyli coś co naprawdę się wydarzyło, "
-            u"od opinii, która określa nasz sąd na temat wybranych przez nas kwestii. O ile prawdą jest, że "
-            u"„Nie wszyscy muzułmanie to terroryści”, to błędnym założeniem jest, że „wszyscy terroryści są "
-            u"muzułmanami”. Terroryzm jako akt agresji fizycznej wymierzony przeciwko innym osobom nie jest domeną "
-            u"tej, czy innej religii. Wynika on często z fundamentalistycznych postaw i może pojawić się w różnych "
-            u"kontekstach politycznych i społecznych, a nie tylko religijnych. Zachowanie wpisu zawierającego powyższą "
-            u"treść może wprowadzać w błąd jego czytelników ponieważ nie odnosi się do faktów, dlatego najlepszą opcją "
-            u"jest jego usunięcie.\n"
-            u"\n"
-            u"Jeśli chcesz pogłębić swoją wiedzę na temat „terroryzmu” możesz przeczytać artykuł "
-            u"pt. „Zjawisko terroryzmu”: "
-            u"http://www.ies.krakow.pl/wydawnictwo/prokuratura/pdf/2012/07-08/11resztak.pdf.",
-
-            u"Stwierdzenie „Nie wszyscy muzułmanie to terroryści, ale wszyscy terroryści to muzułmanie” "
-            u"nie odzwierciedla faktów i jest błędną ich interpretacją W tym przypadku należy odróżnić fakt, "
-            u"czyli coś, co naprawdę się wydarzyło, od opinii, która określa nasz sąd na temat wybranych przez nas "
-            u"kwestii. O ile prawdą jest, że „Nie wszyscy muzułmanie to terroryści”, to błędnym założeniem jest, że "
-            u"„wszyscy terroryści są muzułmanami”. Terroryzm jako akt agresji fizycznej wymierzony przeciwko innym "
-            u"osobom nie jest domeną tej, czy innej religii. Wynika on często z fundamentalistycznych postaw i może "
-            u"pojawić się w różnych kontekstach politycznych i społecznych, a nie tylko religijnych. Zachowanie wpisu "
-            u"zawierającego powyższą treść może wprowadzać w błąd jego czytelników, dlatego najlepszą opcją jest jego "
-            u"usunięcie.\n"
-            u"\n"
-            u"Jeśli chcesz pogłębić swoją wiedzę na temat „terroryzmu” możesz przeczytać artykuł "
-            u"pt. „Zjawisko terroryzmu”: "
-            u"http://www.ies.krakow.pl/wydawnictwo/prokuratura/pdf/2012/07-08/11resztak.pdf."),
-        (
-            u"Wymienione narzędzia i umiejętności brzmią bardzo profesjonalnie, a ich wartość wydaje się być "
-            u"bardzo wysoka. Jeśli każdy zakładałby, że wszystkie one są potrzebne do rozpoczęcia nagrywania audycji, "
-            u"nigdy by tego nie zrobił.\n"
-            u"\n"
-            u"Tak jak nie od razu Rzym zbudowano, tak nie od razu trzeba nagrywać w profesjonalnym studio. Nawet "
-            u"zawodowi podcasterzy od czegoś musieli zacząć – w większości od mikrofonu wbudowanego w komputer. Prawie "
-            u"każdy młody człowiek ma w ręku znacznie doskonalsze narzędzie, jakim jest smartfon. W Internecie można "
-            u"łatwo znaleźć darmowe oprogramowanie do obróbki dźwięku i tutoriale, które pomogą w tworzeniu podcastu.\n"
-            u"\n"
-            u"O tym, jak zacząć tworzyć podcast, nie wydając nawet złotówki przeczytasz tu: "
-            u"https://malawielkafirma.pl/wlasny-podcast-za-darmo/.",
-
-            u"Wymienione narzędzia i umiejętności brzmią profesjonalnie, nie wszyscy mogą pozwolić sobie na taki "
-            u"zakup. Ale czy faktycznie jest to konieczne? Jeśli każdy zakładałby, że wszystkie one są potrzebne do "
-            u"rozpoczęcia nagrywania audycji, nigdy by tego nie zrobił. Do przygotowania podcastu nie trzeba "
-            u"wykorzystywać komputera. Potrzebne jest urządzenie, które pozwoli na nagrywanie dźwięku i jego "
-            u"podstawową obróbkę (może to być zatem także smartfon).\n"
-            u"\n"
-            u"O tym, jak zacząć tworzyć podcast nie wydając nawet złotówki przeczytasz tu: "
-            u"https://malawielkafirma.pl/wlasny-podcast-za-darmo/.",
-
-            u"Urządzenie do nagrywania dźwięku i możliwość jego podstawowej edycji (zarówno jeśli chodzi o dostępne "
-            u"oprogramowanie, jak i posiadane umiejętności), to wystarczający początek. Z czasem, jeśli tworzenie "
-            u"podcastu okaże się pasją, można zdecydować się na poszerzenie wachlarza narzędzi, którymi będzie się "
-            u"posługiwać.\n"
-            u"\n"
-            u"O tym, jak zacząć tworzyć podcast nie wydając nawet złotówki przeczytasz tu: "
-            u"https://malawielkafirma.pl/wlasny-podcast-za-darmo/."),
-        (
-            u"Utwory powstałe w czasach kiedy nie obowiązywały prawa autorskie należą do tak zwanej domeny publicznej. "
-            u"Domeną publiczną oznaczany tę twórczość i te utwory, do których wygasły majątkowe prawa autorskie, "
-            u"więc żadna licencja nie ma w tym przypadku zastosowania. Poprzez publikowanie utworu na licencjach "
-            u"Creative Commons przekazujemy informację o tym, że chcemy dzielić się swoimi utworami (w szerszym bądź "
-            u"węższym zakresie). Zasada ta nie dotyczy wszystkich licencji CC. Tą, która dają największą dowolność "
-            u"korzystania z utworu, jest licencja CC BY (Creative Commons Uznanie Autorstwa).\n"
-            u"Mówiąc inaczej, łatwiej nam jest wykorzystywać zdjęcia, obrazy, czy też muzykę na licencji CC "
-            u"do własnych celów (np. w prezentacji lub na swojej stronie internetowej), ponieważ nie musimy prosić "
-            u"autora o pozwolenie na ich użytkowanie – wszystko oczywiście zależy od rodzaju licencji CC, a tych jest "
-            u"kilka. Warto wcześniej się z nimi zapoznać na stronie: https://creativecommons.pl.\n"
-            u"\n"
-            u"Z definicją domeny publicznej można zapoznać się na stronie: "
-            u"http://domenapubliczna.org/co-to-jest-domena-publiczna/.\n"
-            u"\n"
-            u"Więcej o prawach autorskich można przeczytać w Ustawie z dnia 4 lutego 1994 r. o prawie autorskich "
-            u"i prawach pokrewnych: "
-            u"http://isap.sejm.gov.pl/Download?id=WDU19940240083&type=3 "
-            u"oraz na stronie http://prawokultury.pl.",
-
-            u"XIV-wieczny kodeks powstał w czasach, w których nie obowiązywały tak zwane prawa autorskie. "
-            u"Z tego względu jego udostępnienie i rozpowszechnianie w jakikolwiek sposób jest dozwolone bez podawania "
-            u"licencji, ponieważ kodeks ten należy już do domeny publicznej. Prawa autorskie to zbiór reguł "
-            u"dotyczących praw osobistych i majątkowych, jakie nam przysługują przy utworach (np. zdjęciach, muzyce), "
-            u"który stworzyliśmy osobiście. Z kolei domeną publiczną określamy tę twórczość i te utwory, z których "
-            u"możemy korzystać w dowolny sposób, ponieważ prawa autorskie wygasły (minęło 70 lat od śmierci ich "
-            u"twórców) lub utwory powstały wtedy, kiedy prawa autorskie nie istniały.\n"
-            u"\n"
-            u"O idei udostępniania utworów na zasadach licencji Creative Commons można przeczytać na stronie: "
-            u"https://creativecommons.pl.\n"
-            u"\n"
-            u"Z definicją domeny publicznej można zapoznać się na stronie: "
-            u"http://domenapubliczna.org/co-to-jest-domena-publiczna/.\n"
-            u"\n"
-            u"Więcej o prawa autorskich można przeczytać w Ustawie z dnia 4 lutego 1994 r. o prawie autorskich "
-            u"i prawach pokrewnych: http://isap.sejm.gov.pl/Download?id=WDU19940240083&type=3 oraz na stronie "
-            u"http://prawokultury.pl.",
-
-            u"Ważne jest, aby wszystkie dokumenty o znaczeniu historycznym udostępnianie były odbiorcom w jak "
-            u"najlepszej jakości produkcyjnej. W przypadku XIV-wiecznego kodeksu oznacza to, że muzeum cyfrowe powinno "
-            u"postarać się o zeskanowanie dokumenty w wysokiej rozdzielczości, która umożliwi dokładne zaznajomienie "
-            u"się z jego treścią szerokim rzeszom odbiorców. Jednak idea domeny publicznej zakłada przede wszystkim "
-            u"możliwość korzystania z udostępnianego utworu bez ograniczeń wynikających z praw autorskich. Domeną "
-            u"publiczną określamy tę twórczość i te utwory, z których możemy korzystać w dowolny sposób, ponieważ "
-            u"prawa autorskie dawno wygasły lub powstały wtedy, kiedy prawa autorskie nie istniały. Prawa autorskie to "
-            u"zbiór reguł dotyczących praw jakie nam przysługują przy utworach (np. zdjęciach, muzyce), które "
-            u"stworzyliśmy osobiście. Na przykład jedną z ważniejszych kwestii dotyczących praw autorskich jest "
-            u"pobieranie opłat za każdorazowe użycie skomponowanego przez nas utworu.\n"
-            u"\n"
-            u"O idei udostępniania utworów na zasadach licencji Creative Commons można przeczytać na stronie: "
-            u"https://creativecommons.pl.\n"
-            u"\n"
-            u"Z definicją domeny publicznej można zapoznać się na stronie: "
-            u"http://domenapubliczna.org/co-to-jest-domena-publiczna/.\n"
-            u"\n"
-            u"Więcej o prawa autorskich można przeczytać w Ustawie z dnia 4 lutego 1994 r. o prawie autorskich "
-            u"i prawach pokrewnych: http://isap.sejm.gov.pl/Download?id=WDU19940240083&type=3 oraz na stronie "
-            u"http://prawokultury.pl."),
-        (
-            u"Zastosowanie takich metod ochrony swojej prywatności nie gwarantuje skutecznego działania. "
-            u"Komputer odnotowuje nasze działania na różne sposoby – historia odwiedzanych stron to tylko jeden "
-            u"z nich. Dane zapisane w formularzach, „ciasteczka” (niewielkie informacje, wysyłane przez serwis "
-            u"internetowy, który odwiedzamy i zapisywane na urządzeniu końcowym – komputerze, laptopie, smartfonie – "
-            u"z którego korzystamy podczas przeglądania stron internetowych: http://wszystkoociasteczkach.pl/) "
-            u"pozwolą zainteresowanej osobie ustalić, co robiłeś. Ważne jest także chronienie swoich kont i ich danych,"
-            u" zawsze pamiętaj o wylogowaniu się i zablokowaniu komputera, jeśli odchodzisz od niego na chwilę.\n"
-            u"\n"
-            u"Pamiętaj także, że jeśli korzystasz ze swojego konta Google na wielu urządzeniach, sam serwis tworzy "
-            u"synchronizowaną historię aktywności. Jak ją usunąć, dowiesz się tu:\n"
-            u"https://support.google.com/websearch/answer/54068?hl=pl&ref_topic=1638123.\n"
-            u"\n"
-            u"Więcej o ochronie prywatności w Internecie dowiesz się tu: https://panoptykon.org/ i tu: "
-            u"http://www.saferinternet.pl/pl/ochrona-prywatnosci.",
-
-            u"Kompleksowe stosowanie różnych metod ochrony swojej prywatności pozwala nam na zachowanie prywatności w "
-            u"Internecie. Pamiętanie o tym, że komputer odnotowuje nasze działania na różne sposoby – historia "
-            u"odwiedzanych stron to tylko jeden z nich – to istotny element skutecznej ochrony. Dane zapisane w "
-            u"formularzach, „ciasteczka” (niewielkie informacje, wysyłane przez serwis internetowy, który odwiedzamy i "
-            u"zapisywane na urządzeniu końcowym – komputerze, laptopie, smartfonie – z którego korzystamy podczas "
-            u"przeglądania stron internetowych: http://wszystkoociasteczkach.pl/) pozwolą zainteresowanej osobie "
-            u"ustalić, co robiłeś, dlatego usuwanie historii i wszystkich pozostałych danych gromadzonych przez "
-            u"przeglądarkę to czynności, które są niezbędne. Ważne jest także chronienie swoich kont i ich danych, "
-            u"zawsze pamiętaj o wylogowaniu się i zablokowaniu komputera, jeśli odchodzisz od niego na chwilę.\n"
-            u"\n"
-            u"Pamiętaj także, że jeśli korzystasz ze swojego konta Google na wielu urządzeniach, sam serwis Google "
-            u"tworzy synchronizowaną historię aktywności. Jak ją usunąć, dowiesz się tu:\n"
-            u"https://support.google.com/websearch/answer/54068?hl=pl&ref_topic=1638123.\n"
-            u"\n"
-            u"\n"
-            u"Więcej o ochronie prywatności w Internecie dowiesz się tu:\n"
-            u"http://www.saferinternet.pl/pl/ochrona-prywatnosci.",
-
-            u"Kompleksowe stosowanie różnych metod ochrony swojej prywatności pozwala nam na zachowanie prywatności "
-            u"w Internecie. Pamiętanie o tym, że komputer odnotowuje nasze działania na różne sposoby – historia "
-            u"odwiedzanych stron to tylko jeden z nich – to istotny element skutecznej ochrony. Dane zapisane "
-            u"w formularzach, „ciasteczka” (niewielkie informacje, wysyłane przez serwis internetowy, który odwiedzamy "
-            u"i zapisywane na urządzeniu końcowym – komputerze, laptopie, smartfonie – z którego korzystamy podczas "
-            u"przeglądania stron internetowych: http://wszystkoociasteczkach.pl/) pozwolą zainteresowanej osobie "
-            u"ustalić, co robiłeś. Dlatego usuwanie historii nie wystarczy, konieczne jest kasowanie wszystkich "
-            u"pozostałych danych gromadzonych przez przeglądarkę. Ważne jest także chronienie swoich kont i ich "
-            u"danych, zawsze pamiętaj o wylogowaniu się i zablokowaniu komputera, jeśli odchodzisz od niego na chwilę."
-            u"\n"
-            u"\n"
-            u"Pamiętaj także, że jeśli korzystasz ze swojego konta Google na wielu urządzeniach, sam serwis Google "
-            u"tworzy synchronizowaną historię aktywności. Jak ją usunąć, dowiesz się tu:\n"
-            u"https://support.google.com/websearch/answer/54068?hl=pl&ref_topic=1638123.\n"
-            u"\n"
-            u"Więcej o ochronie prywatności w Internecie dowiesz się tu:\n"
-            u"http://www.saferinternet.pl/pl/ochrona-prywatnosci."),
-        (
-            u"Wolność słowa oznacza przede wszystkim nasze prawo do wyrażania swoich własnych poglądów i w przypadku "
-            u"skorzystania z tej wolności nie ma większego znaczenia czy swoje poglądy wyrażamy anonimowo, "
-            u"czy też podpisujemy się pod nimi imieniem i nazwiskiem. Wolność słowa nie ma związku z wartością "
-            u"komentarzy w Internecie. Z drugiej strony jednak należy pamiętać, że korzystanie z wolności słowa "
-            u"nie oznacza, że nie możemy czuć się odpowiedzialni za swoje opinie wyrażane w Internecie i publikować "
-            u"na przykład obraźliwe komentarze. Poza tym pełna anonimowość w sieci nie istnieje – jeśli zrobimy coś "
-            u"złego w Internecie, to łatwo będzie można nas namierzyć.\n"
-            u"\n"
-            u"Z tematem problematyki wolności w Internecie można zapoznać się w artykule "
-            u"pt. „Problem wolności w Internecie”: "
-            u"http://www.ujk.edu.pl/infotezy/ojs/index.php/infotezy/about/submissions#authorGuidelines.",
-
-            u"To, czy wartość komentarza opublikowanego w Internecie zależy od jego podpisania przez autora, wynika "
-            u"z kontekstu, treści i często miejsca, w którym się ten komentarz znajduje. Wartość komentarza możemy "
-            u"na przykład łatwo ocenić wtedy, kiedy jesteśmy w stanie zidentyfikować osobę, która go umieszcza w "
-            u"Internecie. Ma to szczególne znaczenie, jeśli dana osoba jest uznanym ekspertem w dziedzinie, w której "
-            u"się wypowiada. Bywają jednak sytuacje, w których anonimowe komentarze bywają również wartościowe. "
-            u"Można to zaobserwować w sytuacjach, w których anonimowy komentarz dostarcza nam informacji, które "
-            u"nie mogłyby zostać rozpowszechnione w inny sposób, jak tylko właśnie anonimowo – na przykład "
-            u"udostępnienie informacji w Internecie o trudnych warunkach pracy w pewnej firmie pod imieniem "
-            u"i nazwiskiem mogłoby zaszkodzić autorowi, który prawdopodobnie straciłby pracę. Pamiętajmy jednak "
-            u"o tym, aby każdy komentarz w Internecie weryfikować we własnym zakresie i że nigdy nie istnieje pełna "
-            u"anonimowość w sieci.\n"
-            u"\n"
-            u"Z tematem problematyki wolności w Internecie można zapoznać się w artykule "
-            u"pt. „Problem wolności w Internecie”: "
-            u"http://www.ujk.edu.pl/infotezy/ojs/index.php/infotezy/about/submissions#authorGuidelines.",
-
-            u"Odpowiedzialność prawna to konsekwencje, jakie możemy ponieść w wyniku złamania prawa. Z punktu widzenia "
-            u"odpowiedzialności prawnej nie ma znaczenia czy komentarz w Internecie jest anonimowy, czy też podpisany "
-            u"imieniem i nazwiskiem. Na przykład za pomówienie kogoś w Internecie kodeks karny przewiduje różnego "
-            u"rodzaju kary, w tym więzienie. Jeśli osoba pomawiająca dokonała tego czynu używając anonimowych danych, "
-            u"to i tak na wniosek prokuratury prowadzącej śledztwo administrator strony, na której doszło do "
-            u"pomówienia ma obowiązek udostępnić adres IP użytkownika (numer służący identyfikacji komputerów i innych "
-            u"urządzeń w sieci). A stąd już prosta droga do uzyskania dokładnych danych adresowych osoby pomawiającej."
-            u"\n"
-            u"\n"
-            u"Na temat odpowiedzialności prawnej za komentarze umieszczane w Internecie można przeczytać w artykule "
-            u"pt. „Ten komentarz mnie obraża. Co mam zrobić?” "
-            u"https://panoptykon.org/wiadomosc/ten-komentarz-mnie-obraza-co-mam-zrobic."),
-        (
-            u"Oryginalny pomysł i scenariusz – oparte na własnych odczuciach, czyli „twórcze, a nie odtwórcze” to "
-            u"najważniejszy etap opowiadania historii. Im więcej własnych idei i koncepcji włożycie w opowiadaną "
-            u"historię, tym będzie Wam bliższa, i tym lepiej będzie przemawiała do jej odbiorców. I, co także bardzo "
-            u"ważne, historia, którą wymyślicie sami, na pewno nie będzie naruszać niczyich praw autorskich…\n"
-            u"\n"
-            u"Ważne są także kolejne kroki, które podejmiecie. Po wyborze tematu musicie podzielić się zadaniami, "
-            u"aby każdy element zadania był wykonany. Jeśli tego nie zrobicie, w grupie szybko zapanuje chaos – "
-            u"jednymi sprawami zajmie się kilka osób, a innymi – nikt. Warto też opracować harmonogram, aby ze "
-            u"wszystkim zdążyć na czas. Podczas realizacji zadania bądźcie w stałym kontakcie, żeby na bieżąco "
-            u"wymieniać się uwagami na temat wspólnej pracy.\n"
-            u"\n"
-            u"Więcej o tym, jak zorganizować wspólną pracę, znaleźć można tutaj: "
-            u"https://edukacjamedialna.edu.pl/lekcje/sieciowa-wspolpraca/ i tutaj: "
-            u"https://edukacjamedialna.edu.pl/lekcje/dokumentacja-i-narracje-cyfrowe/.",
-
-            u"Jeśli nie zaczniecie pracy od zastanowienia się nad tym, jaką historię chcecie opowiedzieć, nie dacie "
-            u"sobie szansy, aby opowiadała ona o rzeczach ważnych dla Was. Stworzycie – zamiast własnej historii – "
-            u"zbitek cudzych opowieści. Oryginalny pomysł i scenariusz – oparte na własnych odczuciach, czyli "
-            u"„twórcze, a nie odtwórcze” to najważniejszy etap opowiadania historii. Im więcej własnych idei "
-            u"i koncepcji włożycie w opowiadaną historię, tym będzie Wam bliższa, i tym lepiej będzie przemawiała "
-            u"do jej odbiorców. I, co także bardzo ważne, historia, którą wymyślicie sami, na pewno nie będzie "
-            u"naruszać niczyich praw autorskich…\n"
-            u"\n"
-            u"Ważne są także kolejne kroki, które podejmiecie. Po wyborze tematu musicie podzielić się zadaniami, "
-            u"aby każdy element zadania był wykonany. Jeśli tego nie zrobicie, w grupie szybko zapanuje chaos – "
-            u"jednymi sprawami zajmie się kilka osób, a innymi – nikt. Warto też opracować harmonogram, aby ze "
-            u"wszystkim zdążyć na czas. Podczas realizacji zadania bądźcie w stałym kontakcie, aby na bieżąco "
-            u"wymieniać się uwagami na temat wspólnej pracy.\n"
-            u"\n"
-            u"Więcej o tym, jak zorganizować wspólną pracę, znaleźć można tutaj: "
-            u"https://edukacjamedialna.edu.pl/lekcje/sieciowa-wspolpraca/ i tutaj: "
-            u"https://edukacjamedialna.edu.pl/lekcje/dokumentacja-i-narracje-cyfrowe/.",
-
-            u"Temat opowieści, który wybieracie razem, jest jednocześnie jej początkiem. Jeśli zrodzi się w dyskusji "
-            u"między Wami, to dacie sobie możliwość opowiedzenia własnej historii. Jeśli jednak na tym "
-            u"poprzestaniecie, wykorzystując cudze filmiki i zdjęcia, nie będzie ona wyłącznie Wasza, bowiem będziecie "
-            u"opowiadać cudzymi słowami i obrazami. Oryginalny pomysł i scenariusz – oparte na własnych pomysłach, "
-            u"czyli „twórcze, a nie odtwórcze” to najważniejszy etap opowiadania historii. Im więcej własnych idei "
-            u"i koncepcji włożycie w opowiadaną historię, tym będzie Wam bliższa, i tym lepiej będzie przemawiała "
-            u"do jej odbiorców. I, co także bardzo ważne, historia, którą wymyślicie sami, na pewno nie będzie "
-            u"naruszać niczyich praw autorskich…\n"
-            u"\n"
-            u"Ważne są także kolejne kroki, które podejmiecie. Po wyborze tematu musicie podzielić się zadaniami, "
-            u"aby każdy element zadania był wykonany. Jeśli tego nie zrobicie, w grupie szybko zapanuje chaos – "
-            u"jednymi sprawami zajmie się kilka osób, a innymi – nikt. Warto też opracować harmonogram, aby ze "
-            u"wszystkim zdążyć na czas. Podczas realizacji zadania bądźcie w stałym kontakcie, aby na bieżąco "
-            u"wymieniać się uwagami na temat wspólnej pracy.\n"
-            u"\n"
-            u"Więcej o tym, jak zorganizować wspólną pracę, znaleźć można tutaj: "
-            u"https://edukacjamedialna.edu.pl/lekcje/sieciowa-wspolpraca/ i tutaj: "
-            u"https://edukacjamedialna.edu.pl/lekcje/dokumentacja-i-narracje-cyfrowe/."),
-        (
-            u"Korzystając z Internetu i komunikując się z innymi użytkownikami możemy odnieść wrażenie, że użytkownicy "
-            u"zwracają się do siebie w bardzo bezpośredni sposób. Nie można jednak nikogo zmuszać do zaakceptowania "
-            u"powszechnych reguł komunikacji w Internecie, jeśli w rzeczywistości na co dzień dana osoba nie stosuje "
-            u"nieformalnej komunikacji w kontaktach z nieznajomymi, w tym również przedstawicielami różnych firm "
-            u"i organizacji. Trudno nam sobie w rzeczywistości niewirtualnej wyobrazić pracownika jakiejś firmy, "
-            u"który po imieniu odpowiada nam na zadane przez nas pytania. Najlepszą reakcja firmy na zaistniały "
-            u"problem jest więc przeproszenie użytkownika za bezpośredni i nieformalny zwrot po imieniu.\n"
-            u"\n"
-            u"Prof. Jerzy Bralczyk o netykiecie: https://www.youtube.com/watch?v=thwUHPXbBoo.\n"
-            u"\n"
-            u"O zwracaniu się w Internecie do innych użytkowników per „pani” / „pan” można posłuchać na kanale "
-            u"„Czas Gentelmanów”: https://www.youtube.com/watch?v=A8qznS7LjQY.",
-
-            u"Korzystając z Internetu i komunikując się z innymi użytkownikami możemy odnieść wrażenie, że użytkownicy "
-            u"zwracają się do siebie w bardzo bezpośredni sposób. Nie można jednak nikogo zmuszać do zaakceptowania "
-            u"powszechnych reguł komunikacji w Internecie, zwłaszcza, jeśli w rzeczywistości na co dzień dana osoba "
-            u"nie stosuje nieformalnej komunikacji w kontaktach z nieznajomymi, w tym również przedstawicielami "
-            u"różnych firm i organizacji. Trudno nam w rzeczywistości niewirtualnej wyobrazić sobie pracownika "
-            u"jakiejś firmy, który po imieniu odpowiada nam na zadane przez nas pytania. Najlepszą reakcją firmy "
-            u"na zaistniały problem jest więc przeproszenie użytkownika za bezpośredni formalny zwrot po imieniu. "
-            u"Pod żadnym pozorem nie powinna ignorować użytkownika odwołując się do zasady netykiety, czyli zbioru "
-            u"zasad porozumiewania się w Internecie. Chociaż zgodnie z jej zasadami, przyjęte jest zwracanie się "
-            u"do siebie po imieniu, to nie możemy innym narzucać własnych reguł komunikacji. Dotyczy to przede "
-            u"wszystkim firm, które komunikują się w Internecie ze swoimi klientami.\n"
-            u"\n"
-            u"Prof. Jerzy Bralczyk o netykiecie: https://www.youtube.com/watch?v=thwUHPXbBoo.\n"
-            u"\n"
-            u"O zwracaniu się w Internecie do innych użytkowników per „pani” / „pan” można posłuchać na kanale "
-            u"„Czas Gentelmanów”: https://www.youtube.com/watch?v=A8qznS7LjQY.",
-
-            u"Korzystając z Internetu i komunikując się z innymi użytkownikami możemy odnieść wrażenie, że użytkownicy "
-            u"zwracają się do siebie w bardzo bezpośredni sposób. Nie można jednak nikogo zmuszać do zaakceptowania "
-            u"powszechnych reguł komunikacji w Internecie, jeśli w rzeczywistości na co dzień dana osoba stosuje "
-            u"formalna komunikację w kontaktach z osobami nieznajomymi, w tym również przedstawicielami różnych firm "
-            u"i organizacji. Trudno nam sobie w rzeczywistości niewirtualnej wyobrazić pracownika jakiejś firmy, "
-            u"który po imieniu odpowiada nam na zadane przez nas pytania. Poprawną reakcją firmy na zaistniały problem "
-            u"w komunikacji internetowej jest działanie zgodne z wypracowanymi wewnętrznie zasadami komunikacji. "
-            u"Stanowią one coś na wzór kodeksu opracowanego przez daną firmę, który mówi pracownikom firmy, "
-            u"jak należy zachowywać się w kontaktach z klientami. Niezależnie od zasad obowiązujących w firmie, "
-            u"najlepszym rozwiązaniem będzie przeproszenie urażonego użytkownika.\n"
-            u"\n"
-            u"Prof. Jerzy Bralczyk o netykiecie: https://www.youtube.com/watch?v=thwUHPXbBoo.\n"
-            u"\n"
-            u"O zwracaniu się w Internecie do innych użytkowników per „pani” / „pan” można posłuchać na kanale "
-            u"„Czas Gentelmanów”: https://www.youtube.com/watch?v=A8qznS7LjQY."),
-        (
-            u"Krytyczne podejście do informacji to jedna z najważniejszych umiejętności we współczesnym świecie, "
-            u"w którym informacja otacza nas i dociera zewsząd. Przy tworzeniu aplikacji warto skontaktować się "
-            u"z administracją, aby ustalić liczbę dostępnych miejsc. Pamiętaj jednak, że osoba udzielająca informacji "
-            u"może nie mieć pełnej wiedzy – lub popełnić błąd. Dobrze byłoby zweryfikować otrzymane informacje "
-            u"osobiście (aby Twoje dane pochodziły z więcej niż jednego źródła).\n"
-            u"\n"
-            u"Więcej o tym, dlaczego warto weryfikować informacje, dowiesz się tu:\n"
-            u"https://www.youtube.com/watch?v=ZHHmEi9VAbY.\n"
-            u"\n"
-            u"Więcej o weryfikacji informacji w Internecie dowiesz się stąd:\n"
-            u"http://www.heuristic.pl/blog/internet/Wiarygodnosc-informacji-zamieszczanych-w-Internecie;204.html.",
-
-            u"Krytyczne podejście do informacji to jedna z najważniejszych umiejętności we współczesnym świecie, "
-            u"w którym informacja otacza nas i dociera zewsząd. Ważne jest, aby uzyskana przez Ciebie informacja była "
-            u"aktualna i najlepiej, aby pochodziła z więcej niż jednego źródła. Dlatego optymalnym rozwiązaniem byłoby "
-            u"sprawdzenie danych ze strony (która mogła dawno nie być aktualizowana), na przykład poprzez kontakt "
-            u"z administracją oraz osobiste udanie się na miejsce i sprawdzenie uzyskanych odpowiedzi.\n"
-            u"\n"
-            u"Więcej o tym, dlaczego warto weryfikować informacje dowiesz się tu:\n"
-            u"https://www.youtube.com/watch?v=ZHHmEi9VAbY.\n"
-            u"\n"
-            u"Więcej o weryfikacji informacji w Internecie dowiesz się stąd:\n"
-            u"http://www.heuristic.pl/blog/internet/Wiarygodnosc-informacji-zamieszczanych-w-Internecie;204.html.",
-
-            u"Krytyczne podejście do informacji to jedna z najważniejszych umiejętności we współczesnym świecie, "
-            u"w którym informacja otacza nas i dociera zewsząd. Ważne jest, aby uzyskana przez Ciebie informacja była "
-            u"aktualna, wiarygodna i wyczerpująca. Dlatego optymalnym rozwiązaniem jest właśnie kontakt "
-            u"z administracją oraz osobiste udanie się na miejsce i sprawdzenie uzyskanych odpowiedzi. Ważne jest "
-            u"także sprawdzenie, jakie okoliczności mogą wpływać na stan „formalny” badanej rzeczywistości – "
-            u"częstotliwość łamania przepisów przez pełnosprawnych kierowców stanowi taką incydentalną okoliczność, "
-            u"której częste występowanie może całkowicie zniweczyć sens używania aplikacji, jeśli nie zostanie "
-            u"uwzględnione w jej działaniu.\n"
-            u"\n"
-            u"Więcej o tym, dlaczego warto weryfikować informacje dowiesz się tu:\n"
-            u"https://www.youtube.com/watch?v=ZHHmEi9VAbY.\n"
-            u"\n"
-            u"Więcej o weryfikacji informacji w Internecie dowiesz się tu:\n"
-            u"http://www.heuristic.pl/blog/internet/Wiarygodnosc-informacji-zamieszczanych-w-Internecie;204.html."),
-        (
-            u"Niewidzialna praca to między innymi praca wykonywana na rzecz swojej rodziny / wolontariat. Chociaż "
-            u"zazwyczaj kojarzona jest z pracą w domu (na przykład kobiety opiekujące się dziećmi), to odnosi się też "
-            u"do „szarych pracowników” wielkich korporacji, którzy stoją za sukcesem tych przedsiębiorstw, w tym "
-            u"moderatorów mediów społecznościowych, których rola jest niezastąpiona i niezbędna dla sprawnego "
-            u"funkcjonowania biznesu.\n"
-            u"„Niewidzialną pracą” można nazwać również aktywność użytkowników mediów społecznościowych, którzy "
-            u"poprzez komentarze pod wpisami i newsami podtrzymują zainteresowanie innych użytkowników, a co za tym "
-            u"idzie zwiększają zainteresowanie potencjalnych reklamodawców.\n"
-            u"\n"
-            u"O niewidzialnej pracy można przeczytać w artykule pt. „Niewidzialna praca o wielkiej mocy”: "
-            u"http://www.praca.pl/poradniki/rynek-pracy/niewidzialna-praca-o-wielkiej-mocy_pr-1711.html.",
-
-            u"Niewidzialna praca to między innymi praca wykonywana na rzecz swojej rodziny / wolontariat. Chociaż "
-            u"zazwyczaj kojarzona jest z pracą w domu (na przykład kobiety opiekujące się dziećmi), to odnosi się też "
-            u"do „szarych pracowników” wielkich korporacji, którzy stoją za sukcesem tych przedsiębiorstw, w tym "
-            u"moderatorów mediów społecznościowych, których rola jest niezastąpiona i niezastąpiona i niezbędna dla "
-            u"sprawnego funkcjonowania biznesu.\n"
-            u"„Niewidzialną pracą” można nazwać również aktywność użytkowników mediów społecznościowych, którzy "
-            u"poprzez komentarze pod wpisami i newsami oraz udostępnianie różnego rodzaju treści podtrzymują "
-            u"zainteresowanie innych użytkowników, a co za tym idzie zwiększają zainteresowanie potencjalnych "
-            u"reklamodawców.\n"
-            u"\n"
-            u"O niewidzialnej pracy można przeczytać w artykule pt. „Niewidzialna praca o wielkiej mocy”: "
-            u"http://www.praca.pl/poradniki/rynek-pracy/niewidzialna-praca-o-wielkiej-mocy_pr-1711.html.",
-
-            u"Niewidzialna praca to między innymi praca wykonywana na rzecz swojej rodziny / wolontariat. Chociaż "
-            u"zazwyczaj kojarzona jest z pracą w domu (na przykład kobiety opiekujące się dziećmi), to odnosi się "
-            u"też do „szarych pracowników” wielkich korporacji, którzy stoją za sukcesem tych przedsiębiorstw, "
-            u"w tym moderatorów mediów społecznościowych, których rola jest niezastąpiona i niezbędna dla sprawnego "
-            u"funkcjonowania biznesu.\n"
-            u"„Niewidzialną pracą” można nazwać również aktywność użytkowników mediów społecznościowych, którzy "
-            u"poprzez komentarze pod wpisami i newsami podtrzymują zainteresowanie innych użytkowników, a co za tym "
-            u"idzie zwiększają zainteresowanie potencjalnych reklamodawców.\n"
-            u"Z całą pewnością informatycy budujący rozwiązania IT dla firm nie są osobami wykonującymi „niewidzialną "
-            u"pracę”, chociażby z tego względu, że swoją pracę wykonują najczęściej poza domem, jej efekty są "
-            u"dostrzegane i doceniane oraz pobierają za nią wysokie wynagrodzenia (pracownicy IT są jedną z najlepiej "
-            u"opłacanych grup zawodowych na całym świecie).\n"
-            u"\n"
-            u"O niewidzialnej pracy można przeczytać w artykule pt. „Niewidzialna praca o wielkiej mocy”: "
-            u"http://www.praca.pl/poradniki/rynek-pracy/niewidzialna-praca-o-wielkiej-mocy_pr-1711.html."),
-        (
-            u"Informacja nazywana jest we współczesnym świecie „zasobem strategicznym”. Pozwala działać, planować, "
-            u"podejmować decyzje w świadomy sposób – i z prawdopodobieństwem osiągnięcia dobrych skutków. Jednak, "
-            u"aby informacja spełniała takie funkcje, musi być wiarygodna, aktualna, kompletna. Jej wiarygodność "
-            u"należy zatem sprawdzać i weryfikować. Jeśli pojawia się w więcej niż jednym źródle, rośnie "
-            u"prawdopodobieństwo, że nie jest manipulacją ani dezinformacją. Czasami zdarza się, że kolejne media "
-            u"bezmyślnie powtarzają informację za tym, kto podał ją jako pierwszy, i trafia ona do wielu odbiorców, "
-            u"ostatecznie okazuje się nieprawdziwa. Bez dotarcia do jej właściwego, oryginalnego źródła, trudno mieć "
-            u"100-procentową pewność, że mamy do czynienia z wartościową informacją.",
-
-            u"Informacja nazywana jest we współczesnym świecie „zasobem strategicznym”. Pozwala działać, planować, "
-            u"podejmować decyzje w świadomy sposób – i z prawdopodobieństwem osiągnięcia dobrych skutków. Jednak, aby "
-            u"informacja spełnia takie funkcje, musi być wiarygodna, aktualna, kompletna. Jej wiarygodność należy "
-            u"zatem sprawdzać i weryfikować. Jeśli pojawia się w więcej niż jednym źródle, rośnie prawdopodobieństwo, "
-            u"że nie jest manipulacją ani dezinformacją. Jeśli dodatkowo informacja potwierdzona jest możliwością "
-            u"dotarcia do oryginalnego jej źródła, zamiast opracowania lub interpretacji, można z wysokim "
-            u"prawdopodobieństwem zakładać, że jest prawdziwa.",
-
-            u"Informacja nazywana jest we współczesnym świecie „zasobem strategicznym”. Pozwala działać, planować, "
-            u"podejmować decyzje w świadomy sposób – i z prawdopodobieństwem osiągnięcia dobrych skutków. Jednak, aby "
-            u"informacja spełnia takie funkcje, musi być wiarygodna, aktualna, kompletna. Informacja pochodząca "
-            u"jedynie z serwisów społecznościowych i nielicznych portali informacyjnych, a także nie można ustalić jej "
-            u"oryginalnego źródła, nie wolno zakładać, że jest prawdziwa. Możemy pozwolić wprowadzić się w błąd – "
-            u"a nasi znajomi, na których profilach społecznościowych będziemy się opierać, mogą nawet nie mieć "
-            u"świadomości, że rozprzestrzeniają nieprawdziwe informacje.\n"
-            u"\n"
-            u"O potencjalnych konsekwencjach fałszywych informacji w prawdziwym świecie przeczytasz tu:\n"
-            u"https://www.wprost.pl/swiat/10030588/"
-            u"Facebook-wplynal-na-wynik-amerykanskich-wyborow-Zuckerberg-komentuje.html."),
-        (
-            u"Samo podjęcie czynności kontrolnych przez prokuraturę nie musi oznaczać, że umowy podpisywane "
-            u"z wykonawcami budżetu obywatelskiego odbyły się z naruszeniem prawa. Każdy z nas może paść ofiarą "
-            u"niesłusznych oskarżeń, dlatego powinno unikać się ocen dotyczących ewentualnej winy. Dopóki zarzuty "
-            u"postawione przez prokuraturę (jeśli w ogóle zostaną postawione) nie zostaną uprawomocnione wyrokiem "
-            u"sądowym, obowiązuje tzw. domniemanie niewinności. Tytuł zastosowanego newsa jest akceptowalny, ponieważ "
-            u"nie rozstrzyga ewentualnej winy wykonawców budżetu obywatelskiego. Niestety, z drugiej strony "
-            u"sformułowanie „niejasne umowy” sugeruje pewnego rodzaju nieprawidłowości. Dziennikarze tworzący newsy "
-            u"powinni działać zgodnie z etyką zawodową. Są oni zobowiązani do rzetelnego informowania o faktach "
-            u"i unikaniu prasowych przekłamań, nie tylko w treści newsów, ale również w ich tytułach. Bywa jednak tak, "
-            u"że dziennikarze tworzący tytuły wiadomości manipulują nami, aby podstępnie zmusić nas do zaznajomienia "
-            u"się z ich treścią. Robią to najczęściej w celu wygenerowania dodatkowych zysków z reklam, które "
-            u"pojawiają się obok treści wiadomości. To zjawisko nosi nazwę „clickbait”.\n"
-            u"\n"
-            u"Jeśli chcesz dowiedzieć się czym jest dokładnie „clickbait” posłuchaj audycji pt. „Clickbait w sieci, "
-            u"czyli kto chce cię oszukać”: "
-            u"http://www.polskieradio.pl/9/3850/Artykul/1665036,Clickbait-w-sieci-czyli-kto-chce-cie-oszukac.\n"
-            u"\n"
-            u"W celu zapoznania się ze standardami pracy dziennikarskiej warto przeczytać:\n"
-            u"Kartę Etyczną Mediów: http://www.dziennikarzerp.pl/wp-content/uploads/2010/06/karta_dziennikarzy.pdf.\n"
-            u"Kodeks etyki dziennikarskiej Stowarzyszenia Dziennikarzy Polskich: "
-            u"http://sdp.pl/s/kodeks-etyki-dziennikarskiej-sdp.\n"
-            u"Dziennikarski kodeks obyczajowy Stowarzyszenia Dziennikarzy RP: "
-            u"http://www.dziennikarzerp.pl/wp-content/uploads/2010/06/kodeks.pdf.",
-
-            u"Zastosowanie takiego tytułu jest najlepsze, ponieważ stwierdza tylko pewien fakt, a jednocześnie "
-            u"nie przesądza o rezultatach działań kontrolnych prokuratury. Samo podjęcie czynności kontrolnych "
-            u"przez prokuraturę nie musi oznaczać, że umowy podpisywane z wykonawcami budżetu obywatelskiego odbyły "
-            u"się z naruszeniem prawa. Każdy z nas może paść ofiarą niesłusznych oskarżeń, dlatego powinno unikać się "
-            u"skrajnych ocen dotyczących ewentualnej winy. Dopóki zarzuty postawione przez prokuraturę (jeśli w ogóle "
-            u"zostaną postawione) nie zostaną uprawomocnione wyrokiem sądowym obowiązuje tzw. domniemanie niewinności. "
-            u"Tytuł zastosowanego newsa jest poprawny i zgodny z etyką zawodową dziennikarza. Pamiętajmy, "
-            u"że dziennikarze zobowiązani są do rzetelnego informowania o faktach i unikaniu prasowych przekłamań, "
-            u"nie tylko w treści newsów, ale również w ich tytułach.\n"
-            u"\n"
-            u"W celu zapoznania się ze standardami pracy dziennikarskiej warto przeczytać:\n"
-            u"Kartę Etyczną Mediów: http://www.dziennikarzerp.pl/wp-content/uploads/2010/06/karta_dziennikarzy.pdf.\n"
-            u"Kodeks etyki dziennikarskiej Stowarzyszenia Dziennikarzy Polskich: "
-            u"http://sdp.pl/s/kodeks-etyki-dziennikarskiej-sdp.\n"
-            u"Dziennikarski kodeks obyczajowy Stowarzyszenia Dziennikarzy RP: "
-            u"http://www.dziennikarzerp.pl/wp-content/uploads/2010/06/kodeks.pdf.",
-
-            u"Zastosowanie takiego tytułu wprowadza tylko niepotrzebny zamęt i nosi znamiona manipulacji skierowanej "
-            u"wobec czytelników. Taki tytuł może być krzywdzący dla wykonawców, ponieważ wprost sugeruje ich winę. "
-            u"Samo podjęcie czynności kontrolnych przez prokuraturę nie musi oznaczać, że umowy podpisywane "
-            u"z wykonawcami budżetu obywatelskiego odbyły się z naruszeniem prawa. Każdy z nas może paść ofiarą "
-            u"niesłusznych oskarżeń, dlatego powinno unikać się skrajnych ocen dotyczących ewentualnej winy. "
-            u"Dopóki zarzuty postawione przez prokuraturę (jeśli w ogóle zostaną postawione) nie zostaną "
-            u"uprawomocnione wyrokiem sądowym obowiązuje tzw. domniemanie niewinności. Tytuł zastosowanego newsa jest "
-            u"nieakceptowalny, ponieważ zakłada winę, której nie udowodniono. Dziennikarze tworzący newsy powinni "
-            u"działać zgodnie z etyką zawodową. Są oni zobowiązani do rzetelnego informowania o faktach i unikaniu "
-            u"prasowych przekłamań, nie tylko w treści newsów, ale również w ich tytułach. Bywa jednak tak, że "
-            u"dziennikarze tworzący tytuły wiadomości manipulują nami, aby podstępnie zmusić nas do zaznajomienia się "
-            u"z ich treścią. Robią to najczęściej w celu wygenerowania dodatkowych zysków z reklam, które pojawiają "
-            u"się obok treści wiadomości. To zjawisko nosi nazwę „clickbait”.\n"
-            u"\n"
-            u"Jeśli chcesz dowiedzieć się czym jest dokładnie „clickbait” posłuchaj audycji pt. „Clickbait w sieci, "
-            u"czyli kto chce cię oszukać”: "
-            u"http://www.polskieradio.pl/9/3850/Artykul/1665036,Clickbait-w-sieci-czyli-kto-chce-cie-oszukac.\n"
-            u"\n"
-            u"W celu zapoznania się ze standardami pracy dziennikarskiej warto przeczytać:\n"
-            u"Kartę Etyczną Mediów: http://www.dziennikarzerp.pl/wp-content/uploads/2010/06/karta_dziennikarzy.pdf.\n"
-            u"Kodeks etyki dziennikarskiej Stowarzyszenia Dziennikarzy Polskich: "
-            u"http://sdp.pl/s/kodeks-etyki-dziennikarskiej-sdp.\n"
-            u"Dziennikarski kodeks obyczajowy Stowarzyszenia Dziennikarzy RP: "
-            u"http://www.dziennikarzerp.pl/wp-content/uploads/2010/06/kodeks.pdf."),
-        (
-            u"Wymienione w odpowiedzi narzędzia służą raczej dystrybucji informacji i prezentowaniu własnych wniosków "
-            u"/ przemyśleń (Power Point lub podcast), a nie pracy w grupie. Stosowane przy realizacji projektu "
-            u"narzędzia muszą pozwalać na komunikację zwrotną, wymianę myśli i ustalenia – a także wprowadzanie "
-            u"zmian w tworzonych treściach (muszą zatem pozwalać na tworzenie treści w formie wspólnie realizowanego "
-            u"procesu, a nie prezentować je statycznie).\n"
-            u"\n"
-            u"Informacje o komunikacji w projektach znajdziesz tu:\n"
-            u"http://www.ptzp.org.pl/files/konferencje/kzz/artyk_pdf_2017/T1/t1_200.pdf.",
-
-            u"Wymienione w odpowiedzi narzędzia służą wspólnej pracy nad projektem, mogą jednak nie pozwalać "
-            u"na przykład na pełne śledzenie chronologii wypowiedzi i ustaleń (Coggle) lub też odnotowanie efektów "
-            u"i ustaleń (Skype). Stosowane przy realizacji Waszego projektu narzędzia muszą pozwalać na komunikację "
-            u"zwrotną, wymianę myśli i ustalenia – a także wprowadzanie zmian w tworzonych treściach (muszą zatem "
-            u"pozwalać na tworzenie treści w formie wspólnie realizowanego procesu, a nie prezentować je statycznie) "
-            u"i umożliwiać śledzenie historii dokonywanych ustaleń i wprowadzanych zmian.\n"
-            u"\n"
-            u"Informacje o komunikacji w projektach znajdziesz tu:\n"
-            u"http://www.ptzp.org.pl/files/konferencje/kzz/artyk_pdf_2017/T1/t1_200.pdf.",
-
-            u"Wybrane narzędzia powinny doskonale odpowiedzieć na potrzeby współpracy przy realizacji projektu. "
-            u"Pozwalają zarówno na zarządzanie wewnątrz projektu (Wunderlist), jak i wspólne tworzenie koncepcji "
-            u"opracowywanego dzieła (OneNote, Google Docs). Szybka, grupowa komunikacja, uwzględniająca wszystkich "
-            u"uczestników projektu, zachowująca historię konwersacji, pozwala nie tylko na dokonywanie ustaleń, "
-            u"ale i odnoszenie się do nich w przyszłości.\n"
-            u"\n"
-            u"Informacje o komunikacji w projektach znajdziesz tu:\n"
-            u"http://www.ptzp.org.pl/files/konferencje/kzz/artyk_pdf_2017/T1/t1_200.pdf."),
-        (
-            u"Liczba edycji hasła na Wikipedii nie jest wskaźnikiem jego jakości. Przy niektórych hasłach, szczególnie "
-            u"społecznie drażliwych i kontrowersyjnych, liczba edycji może wynikać z braku zgody społeczności "
-            u"wikipedystów co do jednej neutralnej definicji. Przyczyną dużej liczby edycji bywa również zamierzone "
-            u"i złośliwe działanie internautów, którzy stosując tzw. trolling zmieniają znaczenie danego hasła, "
-            u"obniżając jego wartość merytoryczną lub przedstawiając skrajny punkt widzenia. Liczba edycji może "
-            u"wynikać też ze zmieniającej się stale wiedzy na temat danego zjawiska.\n"
-            u"\n"
-            u"Na temat oceny jakości haseł tworzonych na Wikipedii można przeczytać tutaj: "
-            u"https://pl.wikipedia.org/wiki/Wikipedia:Ocena_jakości.",
-
-            u"Długość hasła na Wikipedii może być dobry miernikiem jego jakości, ale też niewystarczającym. "
-            u"Podobnie z jego strukturą. Nawet jeśli hasło zawiera odpowiedni wstęp definicyjny oraz dalsze "
-            u"skonkretyzowanie omawianej problematyki, nie oznacza to automatycznie, że mamy do czynienia z hasłem "
-            u"wysokiej jakości. Długość i odpowiednia struktura nie będą niosły ze sobą wartości, jeśli hasło "
-            u"nie będzie zawierało odpowiednich przypisów i odnośników do innych rzetelnych źródeł, w których "
-            u"potwierdzone są tezy i informacje zawarte w opisie hasła. Po zapoznaniu się z interesującym hasłem "
-            u"warto zawsze sprawdzić źródła, do których się ono odnosi. Sama obecność odnośników nie oznacza, że są "
-            u"one aktualne i rzetelne.\n"
-            u"\n"
-            u"Na temat oceny jakości haseł tworzonych na Wikipedii można przeczytać tutaj: "
-            u"https://pl.wikipedia.org/wiki/Wikipedia:Ocena_jakości.",
-
-            u"Ani liczba edycji hasła, ani jego długość i struktura nie ma znaczenia dla jego jakości, jeśli w opisie "
-            u"hasła nie znajdziemy odpowiednich przypisów. To źródła, do których odnosi się opis hasła, stanowią "
-            u"przede wszystkim o jego wartości merytorycznej. Należy jednak pamiętać, że sama obecność odnośników "
-            u"jeszcze nic nie znaczy, warto samemu sprawdzić, czy są one aktualne i odnoszą do rzetelnej wiedzy.\n"
-            u"Na temat oceny jakości haseł tworzonych na Wikipedii można przeczytać tutaj: "
-            u"https://pl.wikipedia.org/wiki/Wikipedia:Ocena_jakości."),
-        (
-            u"Ochrona praw autorskich oraz przestrzeganie przepisów i norm związanych z tymi prawami jest szczególnie "
-            u"istotna w cyfrowym świecie, w którym skopiowanie cudzego pomysłu wymaga często jedynie zastosowanie "
-            u"funkcji „Kopiuj – Wklej”. Wykorzystanie podpisanej grafiki z podaniem jedynie adresu strony nie "
-            u"gwarantuje ochrony praw jej autora – grafika mogła znaleźć się na stronie w sposób niezgodny z prawem, "
-            u"z naruszeniem praw jej autora, poza tym autor interesującej nas grafiki ma prawo do bycia docenionym "
-            u"poprzez podanie imienia i nazwiska lub pseudonimu. Dlatego, jeśli masz wątpliwości, zrób co możesz, "
-            u"aby ustalić jej pierwotne źródło i autora i sprawdzić, czy pozwolił on na jej wykorzystywanie przez inne "
-            u"osoby.\n"
-            u"\n"
-            u"O tym, że nawet wielkie firmy popełniają plagiaty przeczytasz tu:\n"
-            u"http://noizz.pl/lifestyle/"
-            u"zara-kopiuje-grafiki-artystki-my-jestesmy-znani-a-ty-nie-odpowiadaja-prawnicy-firmy/p9y17wp.\n"
-            u"\n"
-            u"O ochronie praw autorskich więcej dowiesz się tu: http://prawokultury.pl.",
-
-            u"Ochrona praw autorskich oraz przestrzeganie przepisów i norm związanych z tymi prawami jest szczególnie "
-            u"istotna w cyfrowym świecie, w którym skopiowanie cudzego pomysłu wymaga często jedynie zastosowanie "
-            u"funkcji „Kopiuj – Wklej”. Wykorzystanie podpisanej grafiki z podaniem jedynie adresu strony "
-            u"nie gwarantuje ochrony praw jej autora – grafika mogła znaleźć się na stronie w sposób niezgodny "
-            u"z prawem, z naruszeniem praw jej autora. Z takiego jednego naruszenia mogą rodzić się kolejne – "
-            u"grafika może być zamieszczana przez administratorów kolejnych stron. Dlatego, jeśli masz wątpliwości, "
-            u"zrób co możesz, aby ustalić jej pierwotne źródło i autora i sprawdzić, czy pozwolił on na jej "
-            u"wykorzystywanie przez inne osoby.\n"
-            u"\n"
-            u"O ochronie praw autorskich więcej dowiesz się tu: http://prawokultury.pl.",
-
-            u"Ochrona praw autorskich oraz przestrzeganie przepisów i norm związanych z tymi prawami jest szczególnie "
-            u"istotna w cyfrowym świecie, w którym skopiowanie cudzego pomysłu wymaga często jedynie zastosowanie "
-            u"funkcji „Kopiuj – Wklej”. Wykorzystanie podpisanej grafiki z podaniem jedynie adresu strony "
-            u"nie gwarantuje ochrony praw jej autora – grafika mogła znaleźć się na stronie w sposób niezgodny "
-            u"z prawem, z naruszeniem praw jej autora. Zrobienie wszystkiego, co możliwe, aby ustalić jej pierwotne "
-            u"źródło i autora i sprawdzić, czy pozwolił on na jej wykorzystywanie przez inne osoby, sprawia, "
-            u"że zachowujemy się nie tylko fair w stosunku do autora, ale także przestrzegamy obowiązujących w tym "
-            u"zakresie przepisów.\n"
-            u"\n"
-            u"O ochronie praw autorskich więcej dowiesz się tu: http://prawokultury.pl."),
-        (
-            u"Przedstawiona w kodzie funkcja zawiera niepełną listę argumentów. Zadaniem funkcji f(a) jest "
-            u"wyświetlenie sumy argumentu „a” oraz argumentu „b”. Niestety, sama funkcja pozwala określić wyłącznie "
-            u"argument „a” – z tego względu jej zapis jest niezgodny z zadaniem, które ma zrealizować. Główną wadą "
-            u"tego kodu jest więc przetwarzanie brakującego argumentu „b”.",
-
-            u"Przedstawiona w kodzie funkcja zawiera niepełną listę argumentów. Zadaniem funkcji f(a) jest "
-            u"wyświetlenie sumy argumentu „a” oraz argumentu „b”. Niestety, sama funkcja pozwala określić wyłącznie "
-            u"argument „a” – z tego względu jej zapis jest niezgodny z zadaniem, które ma zrealizować. Odpowiedź ta "
-            u"jest niepoprawna, ponieważ funkcja nie określa, czy argument zarówno „a” jak i „b” muszą mieć charakter "
-            u"liczbowy. Mogą mieć również charakter łańcuchowy (tj. tekstowy).",
-
-            u"Jest to błędna odpowiedź, ponieważ litera „f” w podanym kodzie nie oznacza argumentów funkcji. Argument "
-            u"funkcji oznaczony jest literą „a” i znajduje się w nawiasie. Litera „f” oznacza funkcje, która w tym "
-            u"przypadku przetwarza argument „a”. Ponadto przedstawiona w kodzie funkcja zawiera niepełną listę "
-            u"argumentów. Zadaniem przedstawione funkcji f(a) jest wyświetlenie sumy argumentu „a” oraz argumentu „b”. "
-            u"Niestety, sama funkcja pozwala określić wyłącznie argument „a” – z tego względu jej zapis jest niezgodny "
-            u"z zadaniem, które ma zrealizować.\n"
-            u"\n"
-            u"O definicji funkcji na przykładzie języka programowania C można przeczytać tutaj: "
-            u"https://pl.wikibooks.org/wiki/C/Funkcje#cite_note-1."),
-        (
-            u"Licencje Creative Commons pozwalają zastąpić tradycyjny model ochrony praw autorskich „Wszystkie prawa "
-            u"zastrzeżone” zasadą „Pewne prawa zastrzeżone” – przy jednoczesnym poszanowaniu zasad prawa autorskiego "
-            u"(http://creativecommons.pl/poznaj-licencje-creative-commons/). Licencja CC-BY-SA pozwala na kopiowanie, "
-            u"zmienianie, rozprowadzanie, przedstawianie i wykonywanie utworu oraz utworów zależnych, które muszą być "
-            u"opublikowane na tej samej licencji. Musisz jednak zwrócić uwagę na to, jaka licencja obowiązuje "
-            u"dla materiałów ściągniętych z serwisu The Noun Project, aby nie naruszyć praw ich autorów.",
-
-            u"Licencje Creative Commons pozwalają zastąpić tradycyjny model ochrony praw autorskich „Wszystkie prawa "
-            u"zastrzeżone” zasadą „Pewne prawa zastrzeżone” – przy jednoczesnym poszanowaniu zasad prawa autorskiego "
-            u"(http://creativecommons.pl/poznaj-licencje-creative-commons/). Licencja CC-BY pozwala na kopiowanie, "
-            u"zmienianie, rozprowadzanie, przedstawianie i wykonywanie utworu jedynie pod warunkiem oznaczenia "
-            u"autorstwa i gwarantuje najszersze swobody licencjobiorcy. Materiały z serwisu NASA należą natomiast – "
-            u"jak wszystkie dzieła stworzone przez rząd federalny USA – do domeny publicznej, która daje wszystkim "
-            u"nieograniczone prawo do dzieł, których wykorzystanie nie podlega restrykcjom i ograniczeniom, ponieważ "
-            u"prawa majątkowe do twórczości wygasły lub twórczość ta nigdy nie była lub nie jest przedmiotem prawa "
-            u"autorskiego (http://domenapubliczna.org/co-to-jest-domena-publiczna/).",
-
-            u"Wykorzystanie materiałów ściągniętych z wyszukiwarki grafiki Google, bez sprawdzenia ich pochodzenia, "
-            u"udzielonej przez twórcę licencji oraz bez znajomości praw, jakie przysługują przy ich użyciu, w znacznej "
-            u"większości mogą narazić Cię na zarzut nieuprawnionego wykorzystania cudzej twórczości, a zatem "
-            u"naruszenia praw autorskich. Wyszukiwarka Google umożliwia filtrowanie wyników m.in. na podstawie "
-            u"licencji, na jakiej zostały udostępnione materiały. Opcję tę znajdziesz w zakładce Narzędzia – Prawa do "
-            u"użytkowania."),
-        (
-            u"Podczas wyszukiwaniu w Internecie obiektów takich jak zdjęcia lub grafiki istotna jest nie tyle liczba "
-            u"słów kluczowych, co ich trafność. Wybrane przez Ciebie słowa kluczowe zawierają odniesienie do "
-            u"wydarzenia historycznego, miejsca, formy przekazu – są więc one wyczerpujące i pozwolą otrzymać "
-            u"najlepsze rezultaty odnoszące się do poszukiwanego przez nas obiektu.",
-
-            u"Podczas wyszukiwaniu w Internecie obiektów takich jak zdjęcia lub grafiki istotna jest nie tyle liczba "
-            u"słów kluczowych, co ich trafność. Wybrane przez Ciebie słowa kluczowe zawierają odniesienia wyłącznie "
-            u"do miejsca związanego z wydarzeniem oraz jego zawartości wizualnej – są więc one niewyczerpujące i "
-            u"nie pozwolą uzyskać najlepszych rezultatów odnoszących się do poszukiwanego przez nas obiektu. Brakuje "
-            u"przede wszystkim odniesienia do samego wydarzenia, czyli angielskiej wojny domowej w latach 1642-1651.",
-
-            u"Podczas wyszukiwaniu w Internecie obiektów takich jak zdjęcia lub grafiki istotna jest nie tyle liczba "
-            u"słów kluczowych, co ich trafność. Wybrane przez Ciebie słowa kluczowe zawierają odniesienia do miejsca "
-            u"związanego z wydarzeniem, okresu oraz jego formy – są one trafne, a co za tym idzie powinniśmy uzyskać "
-            u"rezultat odnoszący się do poszukiwanego przez nas obiektu. Warto jednak poszerzyć zakres słów kluczowych "
-            u"o dodatkowe informacje, na przykład użyć hasła „karykatura”. Dodatkowe słowa mogą zwiększyć skuteczność "
-            u"naszych poszukiwań."),
-        (
-            u"Ochrona praw jednostki w Internecie dotyczy różnych aspektów naszego funkcjonowania w przestrzeni "
-            u"cyfrowej. Jedną z nich jest ochrona naszych praw do stworzonego dzieła, a zatem naszych praw autorskich. "
-            u"Nie można zatem wykorzystywać bez pozwolenia niczyich zdjęć do tworzenia własnej relacji z wydarzeń, "
-            u"nawet organizowanych i przeżytych wspólnie.\n"
-            u"\n"
-            u"Co więcej, ludzie mają prawo do samodzielnego decydowania o tym, w jaki sposób ich wizerunek będzie "
-            u"upubliczniony. Dlatego zanim zamieścisz zdjęcie innej osoby, nawet wspólne selfie, upewnij się, "
-            u"że sfotografowana osoba wyraża zgodę na zamieszczenie zdjęcia w Internecie.\n"
-            u"\n"
-            u"Więcej o ochronie wizerunku dowiesz się tu:\n"
-            u"https://portal.uw.edu.pl/web/ado/ochrona-wizerunku.",
-
-            u"Ochrona praw jednostki w Internecie dotyczy różnych aspektów naszego funkcjonowania w przestrzeni "
-            u"cyfrowej. Jedną z nich jest ochrona naszych praw do stworzonego dzieła, a zatem naszych praw autorskich. "
-            u"Nie można zatem wykorzystywać bez pozwolenia niczyich zdjęć do tworzenia własnej relacji z wydarzeń, "
-            u"nawet organizowanych i przeżytych wspólnie. Zanim wykorzystasz czyjeś zdjęcie – nawet takie, na którym "
-            u"jesteś – zapytaj o zgodę jego autorkę / autora o możliwość jego wykorzystania.",
-
-            u"Ochrona praw jednostki w Internecie dotyczy różnych aspektów naszego funkcjonowania w przestrzeni "
-            u"cyfrowej. Jedną z nich jest ochrona naszych praw do stworzonego dzieła, a zatem naszych praw autorskich. "
-            u"Nie można zatem wykorzystywać bez pozwolenia niczyich zdjęć do tworzenia własnej relacji z wydarzeń, "
-            u"nawet organizowanych i przeżytych wspólnie. Jeśli jednak uzyskałeś zgodę autorki / autora na "
-            u"publikowanie zdjęć, możesz to bez wahania zrobić. Co więcej, ludzie mają prawo do samodzielnego "
-            u"decydowania o tym, w jaki sposób ich wizerunek będzie upubliczniony. Jeśli jednak przed publikacją "
-            u"zdjęcia upewniłeś się, że sfotografowana osoba wyraża na zamieszczenie zdjęcia w Internecie zgodę, "
-            u"również możesz bez wątpliwości zamieścić zdjęcie.\n"
-            u"\n"
-            u"Więcej o ochronie wizerunku dowiesz się tu:\n"
-            u"https://portal.uw.edu.pl/web/ado/ochrona-wizerunku."),
-        (
-            u"Internet to niemal nieskończone źródło informacji, edukacji, rozrywki. Często trudno jest zapanować nad "
-            u"otwieraniem kolejnych, coraz bardziej interesujących (jak się może zdawać), stron. Zachowanie dyscypliny "
-            u"i świadomości własnych działań – oraz świadomości upływającego czasu – pozwala na zarządzanie własnym "
-            u"czasem i efektywne wykorzystanie narzędzia, jakim jest światowa sieć. Warto pamiętać, że taka dyscyplina "
-            u"bywa trudna, szczególnie jeśli bez żadnego zastanowienia będziesz pozwalać na to, aby kolejne bodźce "
-            u"odrywały Cię od realizowania zaplanowanych działań.\n"
-            u"\n"
-            u"Więcej o zarządzaniu czasem dowiesz się tu:\n"
-            u"http://michalpasterski.pl/2012/06/zarzadzanie-czasem-w-5-cwiczeniach/.\n"
-            u"\n"
-            u"Co nas denerwuje i rozprasza i jak sobie z tym radzić? Zajrzyj tu:\n"
-            u"http://gazetapraca.pl/gazetapraca/1,95288,13425980,Co_nas_denerwuje__co_nas_rozprasza.html.\n"
-            u"\n"
-            u"Pomidor pomoże? Prosty sposób na zarządzanie czasem znajdziesz tu:\n"
-            u"http://projektantczasu.pl/technika-pomodoro-pommodoro-pomidora/.",
-
-            u"Internet to niemal nieskończone źródło informacji, edukacji, rozrywki. Często trudno jest zapanować nad "
-            u"otwieraniem kolejnych, coraz bardziej interesujących (jak się może zdawać), stron. Zachowanie dyscypliny "
-            u"i świadomości własnych działań – oraz świadomości upływającego czasu – pozwala na zarządzanie własnym "
-            u"czasem i efektywne wykorzystanie narzędzia, jakim jest światowa sieć. Jeśli nie narzucisz sam sobie "
-            u"granic i nie będziesz świadomie panował nad podejmowanymi działaniami, Twój plan nigdy się nie ziści.\n"
-            u"\n"
-            u"Więcej o zarządzaniu czasem dowiesz się tu:\n"
-            u"http://michalpasterski.pl/2012/06/zarzadzanie-czasem-w-5-cwiczeniach/.\n"
-            u"\n"
-            u"Co nas denerwuje i rozprasza i jak sobie z tym radzić? Zajrzyj tu:\n"
-            u"http://gazetapraca.pl/gazetapraca/1,95288,13425980,Co_nas_denerwuje__co_nas_rozprasza.html.\n"
-            u"\n"
-            u"Pomidor pomoże? Prosty sposób na zarządzanie czasem znajdziesz tu:\n"
-            u"http://projektantczasu.pl/technika-pomodoro-pommodoro-pomidora/.",
-
-            u"Internet to niemal nieskończone źródło informacji, edukacji, rozrywki. Często trudno jest zapanować nad "
-            u"otwieraniem kolejnych, coraz bardziej interesujących (jak się może zdawać), stron. Zachowanie dyscypliny "
-            u"i świadomości własnych działań – oraz świadomości upływającego czasu – pozwala na zarządzanie własnym "
-            u"czasem i efektywne wykorzystanie narzędzia, jakim jest światowa sieć. Wykorzystanie zewnętrznych "
-            u"narzędzi, które pozwalają nam obiektywnie oceniać własne zachowania i dokonywać ich stosownej korekty – "
-            u"jeśli to niezbędne – to sposób nie tylko na efektywne działanie, ale i na zwiększenie prawdopodobieństwa "
-            u"osiągnięcia sukcesu w podejmowanych przedsięwzięciach.\n"
-            u"\n"
-            u"Więcej o zarządzaniu czasem dowiesz się tu:\n"
-            u"http://michalpasterski.pl/2012/06/zarzadzanie-czasem-w-5-cwiczeniach/.\n"
-            u"\n"
-            u"Co nas denerwuje i rozprasza i jak sobie z tym radzić? Zajrzyj tu:\n"
-            u"http://gazetapraca.pl/gazetapraca/1,95288,13425980,Co_nas_denerwuje__co_nas_rozprasza.html.\n"
-            u"\n"
-            u"Pomidor pomoże? Prosty sposób na zarządzanie czasem znajdziesz tu:\n"
-            u"http://projektantczasu.pl/technika-pomodoro-pommodoro-pomidora/."),
-        (
-            u"Wtyczki do przeglądarek, których zadaniem jest blokowanie reklam, nie analizują treści zawartych "
-            u"na stronach internetowych. Jeśli posiadałyby taką funkcjonalność, to zapewne odczulibyśmy spowolnienie "
-            u"w działaniu przeglądarki internetowej. Wtyczki blokujące reklamy działają w oparciu o listę plików "
-            u"graficznych, animacji i wyskakujących okien. To przede wszystkim sam użytkownik decyduje, jakie elementy "
-            u"strony mają podlegać zablokowaniu w oparciu o zdefiniowane obiekty.\n"
-            u"\n"
-            u"O mechanizmie blokowania reklam można przeczytać na stronie producenta najpopularniejszej wtyczki "
-            u"Adblock Plus: https://adblockplus.org/en/about.",
-
-            u"Faktycznie, korzystając z wtyczki blokującej reklamy zauważymy, że reklamy te nie wyświetlają się nam "
-            u"podczas użytkowania przeglądarki. Co więcej nasza przeglądarka nie tylko nie wyświetla nam zablokowanych "
-            u"reklam, ale wcześniej przerywa komunikację z serwerami, które odpowiadają za ich publikacje. Za to, jaki "
-            u"serwer powinien być niedopuszczony do komunikacji z przeglądarką, odpowiada sam użytkownik. Wtyczki "
-            u"blokujące reklamy działają bowiem w oparciu o listę plików graficznych, animacji i wyskakujących okien. "
-            u"To przede wszystkim sam użytkownik decyduje, jakie elementy strony mają znaleźć się na stronie i "
-            u"podlegać zablokowaniu.\n"
-            u"\n"
-            u"O mechanizmie blokowania reklam można przeczytać na stronie producenta najpopularniejszej wtyczki "
-            u"Adblock Plus: https://adblockplus.org/en/about.",
-
-            u"Przeglądarka internetowa z zainstalowaną wtyczką nie tylko nie wyświetla nam zablokowane reklamy, "
-            u"ale przede wszystkim blokuję komunikację z serwerami, które odpowiadają za ich publikacje. Za to, "
-            u"jaki serwer powinien być niedopuszczony do komunikacji z przeglądarką, odpowiada sam użytkownik. Wtyczki "
-            u"blokujące reklamy działają bowiem w oparciu o listę plików graficznych, animacji i wyskakujących okien. "
-            u"To przede wszystkim sam użytkownik decyduje, jakie elementy strony mają znaleźć się na stronie "
-            u"i podlegać zablokowaniu. Wtyczka nie tylko zablokuje te elementy, ale również nie dopuści do komunikacji "
-            u"z serwerami odpowiedzialnymi za ich treść.\n"
-            u"\n"
-            u"O mechanizmie blokowania reklam można przeczytać na stronie producenta najpopularniejszej wtyczki "
-            u"Adblock Plus: https://adblockplus.org/en/about."),
-    ]
-
-
-class CollegiumTestForm(ContactForm):
-    pyt1 = quiz_question_multiple(
-        label=u'1. Crowdfunding to inaczej:',
-        choices=[
-            (01, u'finansowanie społecznościowe'),
-            (10, u'finansowanie wydawnicze'),
-            (20, u'finansowanie przez wielkie wytwórnie'),
-            (30, u'finansowanie wielkich sponsorów')])
-    pyt2 = quiz_question_multiple(
-        label=u'2. Powracające problemy z dostępem do internetu u danego usługodawcy to materiał '
-              u'na reklamację telekomunikacyjną składaną do:',
-        choices=[
-            (01, u'Urzędu Komunikacji Elektronicznej'),
-            (10, u'Urzędu Kontroli Skarbowej'),
-            (20, u'Urzędu Marszałkowskiego'),
-            (30, u'Urzędu Ochrony Państwa')])
-    pyt3 = quiz_question_multiple(
-        label=u'3. Śledzone przez firmę zachowanie internauty w internecie:',
-        choices=[
-            (01, u'zdradzać może preferencje internauty'),
-            (11, u'zdradzać może cechy osobowości internauty'),
-            (21, u'możliwe jest dzięki programom komputerowym'),
-            (31, u'pozwala emitować wstępnie dopasowane oferty na ekranie komputera internauty'),
-            (41, u'pozwala badać reakcję na reklamy'),
-            (50, u'żadna z powyższych odpowiedzi nie jest prawdziwa')])
-    pyt4 = quiz_question_multiple(
-        label=u'4. Profilowanie nie wiąże się z:',
-        choices=[
-            (00, u'kategoryzowaniem ludzi według cech i zachowań'),
-            (10, u'doborem reklam do użytkownika pod kątem wieku i płci'),
-            (20, u'doborem reklam do użytkownika pod kątem wykonanych przez niego polubień i kliknięć'),
-            (31, u'żadna z powyższych odpowiedzi nie jest prawidłowa')])
-    pyt5 = quiz_question_multiple(
-        label=u'5. Dobór reklam do użytkownika nie jest w internecie możliwy na podstawie:',
-        choices=[
-            (00, u'produktów oglądanych w sklepach internetowych'),
-            (10, u'słów wyszukiwanych w wyszukiwarkach'),
-            (20, u'treści e-maili w usługach poczty elektronicznej'),
-            (31, u'żadna z powyższych odpowiedzi nie jest prawidłowa')])
-    pyt6 = quiz_question_multiple(
-        label=u'6. Jeżeli sąd odmówi osobie poniżej 16 roku życia prawa dostępu do informacji publicznej, '
-              u'a informacja ta jest dla zainteresowanej osoby subiektywnie ważna, to jaki kolejny krok warto wykonać?',
-        choices=[
-            (00, u'zrezygnować z uzyskania dostępu do informacji publicznej'),
-            (10, u'odłożyć wniosek o dostęp do informacji publicznej do ukończenia 18 roku życia'),
-            (21, u'udać się po pomoc do Rzecznika Praw Obywatelskich'),
-            (30, u'żadne z powyższych')])
-    pyt7 = quiz_question_multiple(
-        label=u'7. W przypadku, gdy informacje o sprzęcie w sklepie internetowym są niepełne, a sprzedawca '
-              u'konsekwentnie wprowadza klientów indywidualnych w błąd, gdzie warto kierować się po pomoc?',
-        choices=[
-            (01, u'Urząd Ochrony Konkurencji i Konsumentów'),
-            (10, u'Urząd Kontroli Skarbowej'),
-            (20, u'Urząd do Spraw Cudzoziemców'),
-            (30, u'Urząd Ochrony Państwa')])
-    pyt8 = quiz_question_multiple(
-        label=u'8. W ramach dozwolonego użytku wolno nam bez zgody twórcy przygotować spektakl teatralny '
-              u'i wystawić go w szkole oraz:',
-        choices=[
-            (00, u'Sprzedawać widzom bilety, a zysk przeznaczyć na zakup sprzętu uczniowskiego koła naukowego'),
-            (10, u'Sprzedawać widzom bilety, a zysk podzielić pomiędzy występujących artystów'),
-            (20, u'Nagrać spektakl i udostępnić go wszystkim za darmo w internecie'),
-            (30, u'Nagrać spektakl i udostępniać go odpłatnie w internecie'),
-            (41, u'Żadna z odpowiedzi nie jest prawidłowa')])
-    pyt9 = quiz_question_multiple(
-        label=u'9. Osoby niepełnosprawne często korzystają z nietypowych narzędzi. Osoby niewidome w internecie '
-              u'surfują posługując się specjalnymi “gadającymi” przeglądarkami. Osoby nie mogące korzystać z rąk '
-              u'mają specjalne urządzenia umożliwiające nawigację po stronach lub systemy rozpoznawania głosu. '
-              u'Zestaw norm dzięki którym strony internetowe są przyjazne dla osób niepełnosprawnych to:',
-        choices=[
-            (00, u'IDPD – Internet for Disabled People Directive'),
-            (11, u'WCAG – Web Content Accessibility Guidelines'),
-            (20, u'HTTP – HyperText Markup Language'),
-            (30, u'EAA – European Accessibility Act')])
-    pyt10 = quiz_question_multiple(
-        label=u'10. Dane osobowe są chronione mocą prawa, ale niektóre z nich uznaje się za dane wrażliwe i poddaje '
-              u'dodatkowym rygorom, m.in. nie wolno ich przetwarzać bez naszej pisemnej zgody lub w celu innym '
-              u'niż szczegółowo określony. Do danych wrażliwych zaliczamy:',
-        choices=[
-            (01, u'pochodzenie rasowe lub etniczne'),
-            (11, u'przynależność partyjną'),
-            (21, u'dane o stanie zdrowia'),
-            (30, u'numer PESEL')])
-    pyt11 = quiz_question_multiple(
-        label=u'11. Majątkowe prawa autorskie są ograniczone w czasie. Kiedy wygasną utwór przechodzi '
-              u'do domeny publicznej i staje się własnością wspólną. Dzieje się to:',
-        choices=[
-            (00, u'50 lat po śmierci twórcy (ze skutkiem na koniec roku kalendarzowego)'),
-            (10, u' 50 lat po pierwszym rozpowszechnieniu dzieła, jeśli twórca był anonimowy'),
-            (21, u'70 lat po śmierci twórcy (ze skutkiem na koniec roku kalendarzowego)'),
-            (31, u'70 lat po pierwszym rozpowszechnieniu dzieła, jeśli miało ono miejsce po śmierci twórcy')])
-    pyt12 = quiz_question_multiple(
-        label=u'12. Wszystkim twórcom przysługują autorskie prawa osobiste, które – w przeciwieństwie '
-              u'do praw majątkowych – są wieczne i niezbywalne. Zaliczamy do nich:',
-        choices=[
-            (01, u'Prawo do rozpoznania autorstwa'),
-            (11, u'Prawo do decyzji o pierwszym rozpowszechnieniu dzieła'),
-            (21, u'Prawo do zachowania integralności utworu'),
-            (30, u'Prawo do wycofania utworu z obiegu')])
-    pyt13 = quiz_question_multiple(
-        label=u'13. Telewizje utrzymują się przede wszystkim z reklam emitowanych w trakcie trwania programów. '
-              u'Przepisy prawa:',
-        choices=[
-            (00, u'nie regulują sposobu w jaki sposób reklamy te są wyświetlane, decyduje o tym nadawca '
-                u'kierując się rachunkiem ekonomicznym, tj. wybiera takie formy wyświetlania reklam, '
-                u'które są najbardziej zyskowne'),
-            (11, u'ograniczają typ reklam które można emitować ze względu na ich treść lub reklamowane produkty – '
-                u'np. nie wolno przedstawiać w pozytywnym świetle ludzi niszczących środowisko naturalne '
-                u'lub reklamować gry w kości'),
-            (20, u'zabraniają reklamowania produktów w treści filmów'),
-            (31, u'uniemożliwiają telewizji publicznej przerywanie filmów reklamami')])
-    pyt14 = quiz_question_multiple(
-        label=u'14. Urzędy które zajmują się ochroną praw obywateli w mediach cyfrowych to:',
-        choices=[
-            (01, u'Rzecznik Praw Obywatelskich'),
-            (10, u'Minister Cyfryzacji'),
-            (21, u'Rzecznik Praw Dziecka'),
-            (31, u'Urząd Ochrony Danych Osobowych')])
-    pyt15 = quiz_question_multiple(
-        label=u'15. W odniesieniu do internetu tak zwane prawo do zapomnienia to:',
-        choices=[
-            (00, u'Prawo niewysłania w Unii Europejskiej e-maila z potwierdzeniem udziału bez podania przyczyny'),
-            (10, u'Prawo niewysłania w Unii Europejskiej e-maila z potwierdzeniem udziału z podaniem zapomnienia '
-                u'jako przyczyny'),
-            (21, u'Prawo każdego obywatela Unii Europejskiej do zażądania usunięcia jego imienia i nazwiska '
-                u'z wyszukiwarki internetowej'),
-            (30, u'Prawo każdego obywatela Unii Europejskiej do założenia konta w serwisie społecznościowym'),
-            (40, u'Prawo każdego obywatela Unii Europejskiej do zapomnienia adresu wyszukiwarki internetowej '
-                u'albo serwisu społecznościowego')])
-    pyt16 = quiz_question_multiple(
-        label=u'16. Autorskie prawa osobiste chronią twórców utworów bezterminowo i bezwarunkowo. Zaliczamy do nich:',
-        choices=[
-            (01, u'prawo do oznaczania utworu imieniem i nazwiskiem twórcy'),
-            (10, u'zakaz parodiowania utworu bez zgody twórcy'),
-            (21, u'prawo do zachowania integralności utworu (czyli np. obowiązek wiernego cytowania)'),
-            (30, u'prawo do wycofania utworu z obiegu'),
-            (41, u'prawo do decyzji o pierwszym rozpowszechnieniu utworu'),
-            (50, u'zakaz kopiowania utworu bez zgody twórcy')])
-    pyt17 = quiz_question_multiple(
-        label=u'17. Wykonałeś/wykonałaś remiks cudzych utworów. W jakich sytuacjach możesz rozpowszechnić swój utwór?',
-        choices=[
-            (01, u'mam zgodę autora/autorki oryginalnego utworu'),
-            (10, u'materiały do remiksu zostały ściągnięte z serwisu do przechowywania plików'),
-            (20, u'wykorzystane piosenki przesłała mi na Facebooku koleżanka'),
-            (31, u'zezwala na to licencja, na której są opublikowane wykorzystane utwory'),
-            (41, u'wykorzystane w remiksie utwory są dostępne w domenie publicznej (minęło 70 lat od śmierci autora)'),
-            (50, u'utwory użyte w remiksie były udostępnione do odsłuchania na stronach twórców w formie plików mp3')])
-    pyt18 = quiz_question_multiple(
-        label=u'18. Chcesz dowiedzieć się, co sklep internetowy robi z twoimi danymi osobowymi. '
-              u'Gdzie szukasz tej informacji?',
-        choices=[
-            (00, u'w zakładce „O nas”'),
-            (10, u'w zakładce „Twój profil”'),
-            (21, u'w „Polityce prywatności”'),
-            (30, u'w „Regulaminie zakupów”')])
-    pyt19 = quiz_question_multiple(
-        label=u'19. Czy możesz opublikować niekomercyjnie remiks wierszy dostępnych w bibliotece internetowej '
-              u'Wolne Lektury?',
-        choices=[
-            (00, u'nie mogę'),
-            (10, u'mogę, ale dopiero kiedy uzyskam zgodę autorów/autorek lub ich spadkobierców'),
-            (20, u'mogę, uiściłem/-am opłaty na rzecz Funduszu Promocji Twórczości'),
-            (31, u'mogę, wiersze z biblioteki Wolne Lektury znajdują się w domenie publicznej '
-                u'albo publikowane są na licencji CC BY-SA 3.0, która umożliwia taką publikację')])
-    pyt20 = quiz_question_multiple(
-        label=u'20. Na co NIE pozwala ci dozwolony użytek?',
-        choices=[
-            (01, u'na sprzedawanie kopii płyt z muzyką twojego ulubionego zespołu'),
-            (10, u'na oglądanie filmu pobranego z internetu'),
-            (20, u'na nagranie serialu na płytę i obejrzenie go z rodziną'),
-            (30, u'żadna z odpowiedzi nie jest prawidłowa')])
-
-    ANSWER_COMMENTS = [
-        (
-            u'Początków crowfoundingu można szukać już XVIII wieku, jednak jego największy rozwój przypada na czasy kiedy funkcjonował już internet. Dzięki powstającym internetowym społecznościom możliwe było stworzenie modelu płatności opartego na niewielkich wpłatach od dużej liczby osób. Finansowanie społecznościowe pomaga zapaleńcom, niszowym twórcom czy organizacjom pozarządowym w zbieraniu pieniędzy na cele, które znajdują poparcie w oczach pewnej społeczności. W ramach crowdfoundingu osoby angażujące się finansowo w dany projekt otrzymują coś w zamian. Może to być np. dostęp do wersji testowej wynalazku czy przedpremierowy pokaz filmu, na powstanie których wpłaciło się pieniądze. Zasada nagradzania osób wpłacających w ramach crowdfoundingu zwykle opiera się na tym, że im więcej ktoś wpłaci pieniędzy na dany projekt tym bardziej atrakcyjną formę wynagrodzenia otrzymuje.',
-            u'Jeśli chcesz wydać np. książkę możesz to zrobić podpisując umowę z wydawnictwem, które płaci za druk, skład, korektę i inne czynności niezbędne do pojawienia się książki na rynku. Wydawnictwo autorowi płaci wynagrodzenie w postaci ustalonego umownie procentu od ceny książki. Jednak to nie jedyny sposób na wydanie książki. Coraz popularniejszy jest trend selfpublishingu (tj. samodzielne wydanie książki) oraz crowdfoundingu, w ramach którego społeczność przekazuje na pewien cel finanse. Finansowanie społecznościowe pomaga m.in. twórcom w zbieraniu pieniędzy na cele, które znajdują poparcie w oczach pewnej społeczności. W ramach crowdfoundingu osoby angażujące się finansowo w dany projekt otrzymują coś w zamian. Zasada nagradzania osób wpłacających w ramach crowdfoundingu zwykle opiera się na tym, że im więcej ktoś wpłaci pieniędzy na dany projekt tym bardziej atrakcyjną formę wynagrodzenia otrzymuje np. podziękowania we wstępie do książki czy też zniżkę na zakup książki po jej wydaniu.',
-            u'Chcąc wydać swoją własną płytę albo wyprodukować film możesz wejść we współpracę z dużą wytwórnią – płytową czy filmową. Ona pokryje wszelkie koszty związane z powstaniem, dystrybucja i sprzedażą Twojego dzieła. Jednak to nie jedyny sposób na wydanie własnej płyty czy stworzenie swojego filmu. Coraz popularniejszy jest trend zwany crowdfoundingiem, w ramach którego społeczność przekazuje na pewien cel finanse. Finansowanie społecznościowe pomaga m.in. twórcom w zbieraniu pieniędzy na cele, które znajdują poparcie w oczach pewnej społeczności. W ramach crowdfoundingu osoby angażujące się finansowo w dany projekt otrzymują coś w zamian. Zasada nagradzania osób wpłacających w ramach crowdfoundingu zwykle opiera się na tym, że im więcej ktoś wpłaci pieniędzy na dany projekt tym bardziej atrakcyjną formę wynagrodzenia otrzymuje np. ekskluzywny materiał z nagrania płyty płyty czy też zaproszenie na przedpremierowy pokaz filmu.',
-            u'Sponsoring to jeden z bardziej popularnych sposobów zdobywania pieniędzy na prowadzenie działań z zakresu sportu czy kultury. Pozyskiwanie sponsorów w postaci dużych marek, które wykładają pieniądze na dany cel w zamian za promocję ich firmy np. podczas wydarzenia nie jest jednak zadaniem łatwym. Nie tylko dotarcie do sponsorów jest trudne, ale również cały proces pozyskania finansowania ze względu na wewnętrzną politykę firmy, strategię czy wizerunek marki. Dlatego też na znaczeniu nabiera trend crowdfoundingu, w ramach którego społeczność przekazuje na pewien cel finanse. Finansowanie społecznościowe pomaga m.in. twórcom czy organizatorom eventów w zbieraniu pieniędzy na cele, które znajdują poparcie w oczach pewnej społeczności. W ramach crowdfoundingu osoby angażujące się finansowo w dany projekt otrzymują coś w zamian. Zasada nagradzania osób wpłacających w ramach crowdfoundingu zwykle opiera się na tym, że im więcej ktoś wpłaci pieniędzy na dany projekt tym bardziej atrakcyjną formę wynagrodzenia otrzymuje np. podziękowanie ustne w trakcie wydarzenia czy możliwość wystąpienia podczas wydarzenia.',
-        ),
-        (
-            u'Urząd Komunikacji Elektronicznej, w skrócie UKE, to organ regulujący działalność telekomunikacyjną, pocztową, gospodarkę zasobami częstotliwości oraz kontrolny spełniania wymagań dotyczących kompatybilności elektromagnetycznej. Dlatego też w sytuacji problemów z dostępem do internetu u danego dostawcy, która związana jest bezpośrednio z usługami telekomunikacyjnymi to właśnie ten Urząd będzie właściwym do złożenia reklamacji.',
-            u'Urząd Kontroli Skarbowej chroni interesy i prawa majątkowe Skarbu Państwa. Prowadząc kontrole dba o zapewnienie skuteczności wykonywania zobowiązań podatkowych i innych należności stanowiących dochód do budżetu państwa. Bada także czy gospodarowanie mieniem państwowym jest zgodne z prawem, przeciwdziała i zwalcza naruszeniom prawa w tym zakresie. Jak widać więc Urząd ten nie ma wiele wspólnego z reklamacjami telekomunikacyjnymi. W celu złożenia takiej reklamacji należy się udać do UKE – Urzędu Komunikacji Elektronicznej.',
-            u'Urząd Marszałkowski jest organem pomocniczym marszałka województwa. Dzięki niemu możliwa jest obsługa kadrowa, prawna, techniczna, organizacyjna i ekspercka komisji organów wykonawczych w województwie tj. zarządu i marszałka oraz uchwałodawczych - sejmiku województwa. Urząd Marszałkowski nie rozpatruje skarg ani reklamacji telekomunikacyjnych. W celu złożenia takiej reklamacji należy udać się do UKE – Urzędu Komunikacji Elektronicznej.',
-            u'Jest to organizacja będąca częścią służb specjalnych RP. Jej pracownicy są odpowiedzialni za zapewnienie bezpieczeństwa i obronności kraju, czy też zapobieganie różnorodnym przestępstwom, które mogą mieć konsekwencje w skali całego kraju. UOP nie rozpatruje skarg telekomunikacyjnych. Dlatego chcąc złożyć reklamację należy udać się do UKE, czyli Urzędu Komunikacji Elektronicznej.'
-        ),
-        (
-            u'Śledząc IP danego komputera można odczytywać preferencje czy też poznawać osobowość internauty. Wiadomo bowiem jakie strony odwiedza, w co klika, co kupuje, jakie posty lajkuje na Facebooku. Internet to kopalnia wiedzy o użytkownikach sieci. Gromadzone online dane nazywane są Big Data, a ich analizę umożliwia rozwój specjalnego oprogramowania i sztucznej inteligencji. Maszyny analizują dane, a następnie wysnuwają wnioski i dopasowują np. przekaz marketingowy i reklamowy do preferencji internauty. Pozwalają także na badanie reakcji odbiorcy na prezentowany przekaz. Wszystko to odbywa się za pomocą maszyn, dlatego też nie musisz martwić się, że jesteś pod stałą obserwacją.',
-            u'Śledząc IP danego komputera można odczytywać preferencje czy też poznawać osobowość internauty. Wiadomo bowiem jakie strony odwiedza, w co klika, co kupuje, jakie posty lajkuje na Facebooku. Internet to kopalnia wiedzy o użytkownikach sieci. Gromadzone online dane nazywane są Big Data, a ich analizę umożliwia rozwój specjalnego oprogramowania i sztucznej inteligencji. Maszyny analizują dane, a następnie wysnuwają wnioski i dopasowują np. przekaz marketingowy i reklamowy do preferencji internauty. Pozwalają także na badanie reakcji odbiorcy na prezentowany przekaz. Wszystko to odbywa się za pomocą maszyn, dlatego też nie musisz martwić się, że jesteś pod stałą obserwacją.',
-            u'Śledząc IP danego komputera można odczytywać preferencje czy też poznawać osobowość internauty. Wiadomo bowiem jakie strony odwiedza, w co klika, co kupuje, jakie posty lajkuje na Facebooku. Internet to kopalnia wiedzy o użytkownikach sieci. Gromadzone online dane nazywane są Big Data, a ich analizę umożliwia rozwój specjalnego oprogramowania i sztucznej inteligencji. Maszyny analizują dane, a następnie wysnuwają wnioski i dopasowują np. przekaz marketingowy i reklamowy do preferencji internauty. Pozwalają także na badanie reakcji odbiorcy na prezentowany przekaz. Wszystko to odbywa się za pomocą maszyn, dlatego też nie musisz martwić się, że jesteś pod stałą obserwacją.',
-            u'Śledząc IP danego komputera można odczytywać preferencje czy też poznawać osobowość internauty. Wiadomo bowiem jakie strony odwiedza, w co klika, co kupuje, jakie posty lajkuje na Facebooku. Internet to kopalnia wiedzy o użytkownikach sieci. Gromadzone online dane nazywane są Big Data, a ich analizę umożliwia rozwój specjalnego oprogramowania i sztucznej inteligencji. Maszyny analizują dane, a następnie wysnuwają wnioski i dopasowują np. przekaz marketingowy i reklamowy do preferencji internauty. Pozwalają także na badanie reakcji odbiorcy na prezentowany przekaz. Wszystko to odbywa się za pomocą maszyn, dlatego też nie musisz martwić się, że jesteś pod stałą obserwacją.',
-            u'Śledząc IP danego komputera można odczytywać preferencje czy też poznawać osobowość internauty. Wiadomo bowiem jakie strony odwiedza, w co klika, co kupuje, jakie posty lajkuje na Facebooku. Internet to kopalnia wiedzy o użytkownikach sieci. Gromadzone online dane nazywane są Big Data, a ich analizę umożliwia rozwój specjalnego oprogramowania i sztucznej inteligencji. Maszyny analizują dane, a następnie wysnuwają wnioski i dopasowują np. przekaz marketingowy i reklamowy do preferencji internauty. Pozwalają także na badanie reakcji odbiorcy na prezentowany przekaz. Wszystko to odbywa się za pomocą maszyn, dlatego też nie musisz martwić się, że jesteś pod stałą obserwacją.',
-            u'Śledząc IP danego komputera można odczytywać preferencje czy też poznawać osobowość internauty. Wiadomo bowiem jakie strony odwiedza, w co klika, co kupuje, jakie posty lajkuje na Facebooku. Internet to kopalnia wiedzy o użytkownikach sieci. Gromadzone online dane nazywane są Big Data, a ich analizę umożliwia rozwój specjalnego oprogramowania i sztucznej inteligencji. Maszyny analizują dane, a następnie wysnuwają wnioski i dopasowują np. przekaz marketingowy i reklamowy do preferencji internauty. Pozwalają także na badanie reakcji odbiorcy na prezentowany przekaz. Wszystko to odbywa się za pomocą maszyn, dlatego też nie musisz martwić się, że jesteś pod stałą obserwacją.',
-        ),
-        (
-            u'Profilowanie w internecie jest stosowane w większości procesów marketingowych. Dzięki czemu można poprzez kategoryzowanie ludzi według cech i zachowań, danych demograficznych i wielu innych czynników dopasować do niego spersonalizowany komunikat reklamowy. Jest to proces, który nie wymaga zgody użytkownika internetu. Zgodnie z rozporządzeniem RODO, które wchodzi w życie wraz z początkiem 2018 roku zabronione jest profilowanie prowadzące do dyskryminacji np. ze względu na rasę.',
-            u'Profilowanie w internecie jest stosowane w większości procesów marketingowych. Dzięki czemu można poprzez kategoryzowanie ludzi według cech i zachowań, danych demograficznych i wielu innych czynników dopasować do niego spersonalizowany komunikat reklamowy. Jest to proces, który nie wymaga zgody użytkownika internetu. Zgodnie z rozporządzeniem RODO, które wchodzi w życie wraz z początkiem 2018 roku zabronione jest profilowanie prowadzące do dyskryminacji np. ze względu na rasę.',
-            u'Profilowanie w internecie jest stosowane w większości procesów marketingowych. Dzięki czemu można poprzez kategoryzowanie ludzi według cech i zachowań, danych demograficznych i wielu innych czynników dopasować do niego spersonalizowany komunikat reklamowy. Jest to proces, który nie wymaga zgody użytkownika internetu. Zgodnie z rozporządzeniem RODO, które wchodzi w życie wraz z początkiem 2018 roku zabronione jest profilowanie prowadzące do dyskryminacji np. ze względu na rasę.',
-            u'Profilowanie w internecie jest stosowane w większości procesów marketingowych. Dzięki czemu można poprzez kategoryzowanie ludzi według cech i zachowań, danych demograficznych i wielu innych czynników dopasować do niego spersonalizowany komunikat reklamowy. Jest to proces, który nie wymaga zgody użytkownika internetu. Zgodnie z rozporządzeniem RODO, które wchodzi w życie wraz z początkiem 2018 roku zabronione jest profilowanie prowadzące do dyskryminacji np. ze względu na rasę. To sprawia, że wszystkie powyższe odpowiedzi są związane z profilowaniem. Odpowiadając na pytanie, które nie są związane z tematem należało więc zaznaczyć odpowiedź żadna z powyższych odpowiedzi nie jest prawdziwa.',
-        ),
-        (
-            u'Personalizacja i dobór reklam do indywidualnego użytkownika w internecie odbywa się na podstawie jego zachowań w sieci – stron internetowych, które odwiedzał, słów wyszukiwanych w wyszukiwarkach, treści e-mail w usługach poczty elektronicznych, produktów oglądanych w sklepach. Dane te są przetwarzane, a następnie analizowane tak aby dobrać przekaz komunikatu reklamowego do potrzeb internauty.',
-            u'Personalizacja i dobór reklam do indywidualnego użytkownika w internecie odbywa się na podstawie jego zachowań w sieci – stron internetowych, które odwiedzał, słów wyszukiwanych w wyszukiwarkach, treści e-mail w usługach poczty elektronicznych, produktów oglądanych w sklepach. Dane te są przetwarzane, a następnie analizowane tak aby dobrać przekaz komunikatu reklamowego do potrzeb internauty.',
-            u'Personalizacja i dobór reklam do indywidualnego użytkownika w internecie odbywa się na podstawie jego zachowań w sieci – stron internetowych, które odwiedzał, słów wyszukiwanych w wyszukiwarkach, treści e-mail w usługach poczty elektronicznych, produktów oglądanych w sklepach. Dane te są przetwarzane, a następnie analizowane tak aby dobrać przekaz komunikatu reklamowego do potrzeb internauty.',
-            u'Personalizacja i dobór reklam do indywidualnego użytkownika w internecie odbywa się na podstawie jego zachowań w sieci – stron internetowych, które odwiedzał, słów wyszukiwanych w wyszukiwarkach, treści e-mail w usługach poczty elektronicznych, produktów oglądanych w sklepach. Dane te są przetwarzane, a następnie analizowane tak aby dobrać przekaz komunikatu reklamowego do potrzeb internauty. Dlatego też dobór reklam jest możliwy na podstawie wszystkich wymienionych działań użytkownika sieci. Odpowiadając na to pytanie należy więc zaznaczyć odpowiedź: żadna z powyższych odpowiedzi nie jest prawidłowa.',
-        ),
-        (
-            u'Prawo dostępu do informacji publicznej jest prawem człowieka i przysługuje każdemu. W prawodawstwie polskim regulacje dotyczące dostępu do informacji publicznej zawarte są w Konstytucji RP (art. 61) wg której prawo dostępu do informacji publicznej posiada każdy. Również osoby nieletnie. Dlatego jeśli osobie poniżej 16 roku życia został odmówiony dostęp do informacji publicznej należy zgłosić się do Rzecznika Praw Obywatelskich z prośbą o pomoc.',
-            u'Prawo dostępu do informacji publicznej jest prawem człowieka i przysługuje każdemu. W prawodawstwie polskim regulacje dotyczące dostępu do informacji publicznej zawarte są w Konstytucji RP (art. 61) wg której prawo dostępu do informacji publicznej posiada każdy. Również osoby nieletnie. Dlatego jeśli osobie poniżej 16 roku życia został odmówiony dostęp do informacji publicznej należy zgłosić się do Rzecznika Praw Obywatelskich z prośbą o pomoc.',
-            u'Prawo dostępu do informacji publicznej jest prawem człowieka i przysługuje każdemu. W prawodawstwie polskim regulacje dotyczące dostępu do informacji publicznej zawarte są w Konstytucji RP (art. 61) wg której prawo dostępu do informacji publicznej posiada każdy. Również osoby nieletnie. Dlatego jeśli osobie poniżej 16 roku życia został odmówiony dostęp do informacji publicznej należy zgłosić się do Rzecznika Praw Obywatelskich z prośbą o pomoc.',
-            u'Prawo dostępu do informacji publicznej jest prawem człowieka i przysługuje każdemu. W prawodawstwie polskim regulacje dotyczące dostępu do informacji publicznej zawarte są w Konstytucji RP (art. 61) wg której prawo dostępu do informacji publicznej posiada każdy. Również osoby nieletnie. Dlatego jeśli osobie poniżej 16 roku życia został odmówiony dostęp do informacji publicznej należy zgłosić się do Rzecznika Praw Obywatelskich z prośbą o pomoc.',
-        ),
-        (
-            u'Jak sama nazwa wskazuje UOKiK za zadanie ma ochronę konsumentów przed niewłaściwymi praktykami ze strony producentów i sprzedawców. Celowe wprowadzanie w błąd jest działaniem na szkodę konsumenta, dlatego też każdy kto jest ofiarą niewłaściwych praktyk, szkodliwych dla interesu konsumenta może skierować się do UOKiK z prośbą o pomoc.',
-            u'Urząd Kontroli Skarbowej chroni interesy i prawa majątkowe Skarbu Państwa. Prowadząc kontrole dba o zapewnienie skuteczności wykonywania zobowiązań podatkowych i innych należności stanowiących dochód do budżetu państwa. Bada także czy gospodarowanie mieniem państwowym jest zgodne z prawem, przeciwdziała i zwalcza naruszeniom prawa w tym zakresie. Urząd ten nie zajmuje się sprawami konsumenckimi. W celu rozwiązania opisanego w pytaniu problemu należy udać się do Urzędu Ochrony Konkurencji i Konsumentów.',
-            u'Jak można przeczytać na stronie Urzędu do Spraw Cudzoziemców powstał on „by zapewnić kompleksową i profesjonalną obsługę w zakresie legalizacji pobytu i udzielenia ochrony cudzoziemców przebywających na terytorium Rzeczpospolitej Polskiej.” Kwestie związane z ochroną praw konsumenckich nie leżą w kompetencjach urzędu. Aby uzyskać właściwą pomoc należy zgłosić się do Urzędu Ochrony Konkurencji i Konsumentów.',
-            u'Jest to organizacja będąca częścią służb specjalnych RP. Jej pracownicy są odpowiedzialni za zapewnienie bezpieczeństwa i obronności kraju, czy też zapobieganie różnorodnym przestępstwom, które mogą mieć konsekwencje w skali całego kraju. UOP nie rozpatruje skarg konsumenckich. Aby uzyskać pomoc w opisanym w pytaniu przykładzie należy zgłosić się do UOKiK – Urzędu Ochrony Konkurencji i Konsumentów.',
-        ),
-        (
-            u'Zgodnie z art. 31 ust. 2 prawa autorskiego "Wolno nieodpłatnie publicznie wykonywać lub odtwarzać przy pomocy urządzeń lub nośników znajdujących się w tym samym miejscu co publiczność rozpowszechnione utwory podczas imprez szkolnych oraz akademickich, jeżeli nie łączy się z tym osiąganie pośrednio lub bezpośrednio korzyści majątkowej i artyści wykonawcy oraz osoby odtwarzające utwory nie otrzymują wynagrodzenia." Przygotowanie spektaklu teatralnego i jego wystawienie w szkole będzie w rozumieniu prawa autorskiego "wykonaniem utworu", zatem nie można w tej sytuacji osiągać żadnych korzyści majątkowych, niezależnie od tego na co miałyby być przeznaczone zdobyte środki.',
-            u'Zgodnie z art. 31 ust. 2 prawa autorskiego "Wolno nieodpłatnie publicznie wykonywać lub odtwarzać przy pomocy urządzeń lub nośników znajdujących się w tym samym miejscu co publiczność rozpowszechnione utwory podczas imprez szkolnych oraz akademickich, jeżeli nie łączy się z tym osiąganie pośrednio lub bezpośrednio korzyści majątkowej i artyści wykonawcy oraz osoby odtwarzające utwory nie otrzymują wynagrodzenia." Przygotowanie spektaklu teatralnego i jego wystawienie w szkole będzie w rozumieniu prawa autorskiego "wykonaniem utworu", zatem nie można w tej sytuacji osiągać żadnych korzyści majątkowych, niezależnie od tego na co miałyby być przeznaczone zdobyte środki.',
-            u'Udostępnianie w internecie spektaklu wykracza poza ramy prawne publicznego wykonywania utworu, zatem odpowiedź ta jest błędna.',
-            u'Udostępnianie w internecie spektaklu wykracza poza ramy prawne publicznego wykonywania utworu, zatem odpowiedź ta jest błędna.',
-            u'Zgodnie z art. 31 ust. 2 prawa autorskiego "Wolno nieodpłatnie publicznie wykonywać lub odtwarzać przy pomocy urządzeń lub nośników znajdujących się w tym samym miejscu co publiczność rozpowszechnione utwory podczas imprez szkolnych oraz akademickich, jeżeli nie łączy się z tym osiąganie pośrednio lub bezpośrednio korzyści majątkowej i artyści wykonawcy oraz osoby odtwarzające utwory nie otrzymują wynagrodzenia." Przygotowanie spektaklu teatralnego i jego wystawienie w szkole będzie w rozumieniu prawa autorskiego "wykonaniem utworu", zatem nie można w tej sytuacji osiągać żadnych korzyści majątkowych, niezależnie od tego na co miałyby być przeznaczone zdobyte środki. Z kolei udostępnianie w internecie spektaklu wykracza poza ramy prawne publicznego wykonywania utworu, zatem żadna z odpowiedzi nie jest poprawna.',
-        ),
-        (
-            u'Ta dyrektywa unijna dotyczy dostępności stron internetowych i aplikacji dla osób niepełnosprawnych. Jednak dotyczy tylko stron z sektora poublicznego. Opisane w pytaniu mechanizmy normuje Web Content Accessibillity Guidelines.',
-            u'Dokument będący wytycznymi dotyczącymi ułatwień w dostępie do treści publikowanych w internecie normuje zasady tworzenia stron internetowych na potrzeby osób niepełnosprawnych, tak aby treści online były dostępne dla wszystkich. Wśród zasad pojawiających się w WCAG i dokumentach rozszerzających jego zapisy pojawiają się m.in. takie zalecenia: wszystkie pliki dźwiękowe powinny być uzupełnione o transkrypcję dźwiękową czy też wszystkie pliki wideo powinny być uzupełnione o napisy dla osób niesłyszących. To właśnie w WCAG można znaleźć zestaw norm dzięki, którym strony internetowe są przyjazne dla osób niepełnosprawnych.',
-            u'Protokół ten odpowiedzialny jest za przesyłanie dokumentów hipertekstowych w sieci WWW. Nie jest to ani zestaw norm, ani tym bardziej norm określających zasady tworzenia stron internetowych tak aby były przyjazne niepełnosprawnym. Wspomniane zasady znajdują się w dokumencie o nazwie WCAG – Web Content Accessibillity Guidelines.',
-            u'Europejski Akt o Dostępności to kolejny krok do ułatwienia życia osobom niepełnosprawnym. Dzięki tym normom uniijnym sprzęty elektroniczne – komputery, smartfony czy nawet bankomaty ale też chociażby proces zakupów przez internet ma być dostosowany do potrzeb osób niepełnosprawnych. To bardzo ważny dokument jednak nie określa on zasad tworzenia stron internetowych tak aby były one dopasowane do potrzeb osób niepełnosprawnych. Normy te zawarte są w WCAG – Web Content Accessibillity Guidelines.',
-        ),
-        (
-            u'Ustawa o ochronie danych osobowych z dnia 29 sierpnia 1997 roku szczegółowo określa jakie dane zalicza się do danych wrażliwych. Są to informacje dotyczące pochodzenia rasowego lub etnicznego, poglądów politycznych, przekonań religijnych lub filozoficznych, przynależności wyznaniowej, partyjnej lub związkowej, stanu zdrowia, kodu genetycznego, nałogów lub życia seksualnego, skazań, orzeczeń o ukaraniu i mandatów karnych, orzeczeń wydanych w postępowaniu sądowych lub administracyjnym. Co ważne od maja 2018 definicja danych wrażliwych ulegnie zmianie!',
-            u'Ustawa o ochronie danych osobowych z dnia 29 sierpnia 1997 roku szczegółowo określa jakie dane zalicza się do danych wrażliwych. Są to informacje dotyczące pochodzenia rasowego lub etnicznego, poglądów politycznych, przekonań religijnych lub filozoficznych, przynależności wyznaniowej, partyjnej lub związkowej, stanu zdrowia, kodu genetycznego, nałogów lub życia seksualnego, skazań, orzeczeń o ukaraniu i mandatów karnych, orzeczeń wydanych w postępowaniu sądowych lub administracyjnym. Co ważne od maja 2018 definicja danych wrażliwych ulegnie zmianie!',
-            u'Ustawa o ochronie danych osobowych z dnia 29 sierpnia 1997 roku szczegółowo określa jakie dane zalicza się do danych wrażliwych. Są to informacje dotyczące pochodzenia rasowego lub etnicznego, poglądów politycznych, przekonań religijnych lub filozoficznych, przynależności wyznaniowej, partyjnej lub związkowej, stanu zdrowia, kodu genetycznego, nałogów lub życia seksualnego, skazań, orzeczeń o ukaraniu i mandatów karnych, orzeczeń wydanych w postępowaniu sądowych lub administracyjnym. Co ważne od maja 2018 definicja danych wrażliwych ulegnie zmianie!',
-            u'Ustawa o ochronie danych osobowych z dnia 29 sierpnia 1997 roku szczegółowo określa jakie dane zalicza się do danych wrażliwych. Są to informacje dotyczące pochodzenia rasowego lub etnicznego, poglądów politycznych, przekonań religijnych lub filozoficznych, przynależności wyznaniowej, partyjnej lub związkowej, stanu zdrowia, kodu genetycznego, nałogów lub życia seksualnego, skazań, orzeczeń o ukaraniu i mandatów karnych, orzeczeń wydanych w postępowaniu sądowych lub administracyjnym. Co ważne od maja 2018 definicja danych wrażliwych ulegnie zmianie! Jednak numer PESEL nie należy, ani nie będzie należał do kategorii danych wrażliwych.',
-        ),
-        (
-            u'Zgodnie z treścią art. 36 Ustawy o prawie autorskim i prawach pokrewnych majątkowe prawa autorskie wygasają z upływem lat siedemdziesięciu od: od śmierci twórcy, a do utworów współautorskich - od śmierci współtwórcy, który przeżył pozostałych; w odniesieniu do utworu, którego twórca nie jest znany - od daty pierwszego rozpowszechnienia, chyba że pseudonim nie pozostawia wątpliwości co do tożsamości autora lub jeżeli autor ujawnił swoją tożsamość; w odniesieniu do utworu, do którego autorskie prawa majątkowe przysługują z mocy ustawy innej osobie niż twórca - od daty rozpowszechnienia utworu, a gdy utwór nie został rozpowszechniony - od daty jego ustalenia; w odniesieniu do utworu audiowizualnego - od śmierci najpóźniej zmarłej z wymienionych osób: głównego reżysera, autora scenariusza, autora dialogów, kompozytora muzyki skomponowanej do utworu audiowizualnego; w odniesieniu do utworu słowno-muzycznego, jeżeli utwór słowny i utwór muzyczny zostały stworzone specjalnie dla danego utworu słowno-muzycznego - od śmierci później zmarłej z wymienionych osób: autora utworu słownego albo kompozytora utworu muzycznego.',
-            u'Zgodnie z treścią art. 36 Ustawy o prawie autorskim i prawach pokrewnych majątkowe prawa autorskie  wygasają z upływem lat siedemdziesięciu od: od śmierci twórcy, a do utworów współautorskich - od śmierci współtwórcy, który przeżył pozostałych; w odniesieniu do utworu, którego twórca nie jest znany - od daty pierwszego rozpowszechnienia, chyba że pseudonim nie pozostawia wątpliwości co do tożsamości autora lub jeżeli autor ujawnił swoją tożsamość; w odniesieniu do utworu, do którego autorskie prawa majątkowe przysługują z mocy ustawy innej osobie niż twórca - od daty rozpowszechnienia utworu, a gdy utwór nie został rozpowszechniony - od daty jego ustalenia; w odniesieniu do utworu audiowizualnego - od śmierci najpóźniej zmarłej z wymienionych osób: głównego reżysera, autora scenariusza, autora dialogów, kompozytora muzyki skomponowanej do utworu audiowizualnego; w odniesieniu do utworu słowno-muzycznego, jeżeli utwór słowny i utwór muzyczny zostały stworzone specjalnie dla danego utworu słowno-muzycznego - od śmierci później zmarłej z wymienionych osób: autora utworu słownego albo kompozytora utworu muzycznego.',
-            u'Zgodnie z treścią art. 36 Ustawy o prawie autorskim i prawach pokrewnych majątkowe prawa autorskie  wygasają z upływem lat siedemdziesięciu od: od śmierci twórcy, a do utworów współautorskich - od śmierci współtwórcy, który przeżył pozostałych; w odniesieniu do utworu, którego twórca nie jest znany - od daty pierwszego rozpowszechnienia, chyba że pseudonim nie pozostawia wątpliwości co do tożsamości autora lub jeżeli autor ujawnił swoją tożsamość; w odniesieniu do utworu, do którego autorskie prawa majątkowe przysługują z mocy ustawy innej osobie niż twórca - od daty rozpowszechnienia utworu, a gdy utwór nie został rozpowszechniony - od daty jego ustalenia; w odniesieniu do utworu audiowizualnego - od śmierci najpóźniej zmarłej z wymienionych osób: głównego reżysera, autora scenariusza, autora dialogów, kompozytora muzyki skomponowanej do utworu audiowizualnego; w odniesieniu do utworu słowno-muzycznego, jeżeli utwór słowny i utwór muzyczny zostały stworzone specjalnie dla danego utworu słowno-muzycznego - od śmierci później zmarłej z wymienionych osób: autora utworu słownego albo kompozytora utworu muzycznego.',
-            u'Zgodnie z treścią art. 36 Ustawy o prawie autorskim i prawach pokrewnych majątkowe prawa autorskie  wygasają z upływem lat siedemdziesięciu od: od śmierci twórcy, a do utworów współautorskich - od śmierci współtwórcy, który przeżył pozostałych; w odniesieniu do utworu, którego twórca nie jest znany - od daty pierwszego rozpowszechnienia, chyba że pseudonim nie pozostawia wątpliwości co do tożsamości autora lub jeżeli autor ujawnił swoją tożsamość; w odniesieniu do utworu, do którego autorskie prawa majątkowe przysługują z mocy ustawy innej osobie niż twórca - od daty rozpowszechnienia utworu, a gdy utwór nie został rozpowszechniony - od daty jego ustalenia; w odniesieniu do utworu audiowizualnego - od śmierci najpóźniej zmarłej z wymienionych osób: głównego reżysera, autora scenariusza, autora dialogów, kompozytora muzyki skomponowanej do utworu audiowizualnego; w odniesieniu do utworu słowno-muzycznego, jeżeli utwór słowny i utwór muzyczny zostały stworzone specjalnie dla danego utworu słowno-muzycznego - od śmierci później zmarłej z wymienionych osób: autora utworu słownego albo kompozytora utworu muzycznego.',
-        ),
-        (
-            u'Zgodnie z treścią artykułu 16 ustawy o prawie autorskim i prawach pokrewnych katalog autorskich praw to między innymi uprawnienia do autorstwa utworu, oznaczenia go swoim imieniem i nazwiskiem, pod pseudonimem lub anonimowo, nienaruszalności treści utworu, integralności, decyzji o pierwszym udostępnieniu utworu publiczności czy też nadzoru nad sposobem korzystania z utworu.',
-            u'Zgodnie z treścią artykułu 16 ustawy o prawie autorskim i prawach pokrewnych katalog autorskich praw to między innymi uprawnienia do autorstwa utworu, oznaczenia go swoim imieniem i nazwiskiem, pod pseudonimem lub anonimowo, nienaruszalności treści utworu, integralności, decyzji o pierwszym udostępnieniu utworu publiczności czy też nadzoru nad sposobem korzystania z utworu.',
-            u'Zgodnie z treścią artykułu 16 ustawy o prawie autorskim i prawach pokrewnych katalog autorskich praw to między innymi uprawnienia do autorstwa utworu, oznaczenia go swoim imieniem i nazwiskiem, pod pseudonimem lub anonimowo, nienaruszalności treści utworu, integralności, decyzji o pierwszym udostępnieniu utworu publiczności czy też nadzoru nad sposobem korzystania z utworu.',
-            u'Zgodnie z treścią artykułu 16 ustawy o prawie autorskim i prawach pokrewnych katalog autorskich praw to między innymi uprawnienia do autorstwa utworu, oznaczenia go swoim imieniem i nazwiskiem, pod pseudonimem lub anonimowo, nienaruszalności treści utworu, integralności, decyzji o pierwszym udostępnieniu utworu publiczności czy też nadzoru nad sposobem korzystania z utworu. Do katalogu praw nie przynależy jednak prawo do wycofania utworu z obiegu.',
-        ),
-        (
-            u'Regulacje dotyczące zasad wyświetlania reklam w Polsce, zawarte zostały w Ustawie o Radiofonii  i Telewizji. Ustawa określa m.in. to jak powinny być wyświetlane reklamy, jakie reklamy są zakazane, czy też określają jakie zasady wyświetlania reklam obowiązują w telewizji publicznej.',
-            u'Regulacje dotyczące zasad wyświetlania  reklam w Polsce, zawarte zostały w Ustawie o Radiofonii  I Telewizji. Ustawa określa m.in. to jak powinny być wyświetlane reklamy, jakie reklamy są zakazane m.in. te które ukazują ludzi niszczących środowisko w pozytywnym świetle, czy też określają jakie zasady wyświetlania reklam obowiązują w telewizji publicznej. ',
-
-            u'Regulacje dotyczące zasad wyświetlania reklam w Polsce, zawarte zostały w Ustawie o Radiofonii  I Telewizji. Ustawa określa m.in. to jak powinny być wyświetlane reklamy, jakie reklamy są zakazane, czy też określają jakie zasady wyświetlania reklam obowiązują w telewizji publicznej. Działania takie jak reklamowanie produktów w treści filmów, zwane potocznie lokowaniem produktu jest dozwolone prawnie. Jednak program powinien zawierać stosowną adnotację, która informuje widza o tym, że audycja zawierała lokowanie produktu. ',
-
-            u'Regulacje dotyczące zasad wyświetlania reklam w Polsce, zawarte zostały w Ustawie o Radiofonii  I Telewizji. Ustawa określa m.in. to jak powinny być wyświetlane reklamy, jakie reklamy są zakazane, czy też określają jakie zasady wyświetlania reklam obowiązują w telewizji publicznej. Regulacje prawne uniemożliwiają telewizji publicznej np. przerywanie filmów reklamami. ',
-        ),
-        (
-            u'Rzecznik Praw Obywatelskich stoi na straży wolności, praw człowieka i obywatela, niezależnie od tego do jakiego obszaru życia odnoszą się wspomniane prawa i wolności. Zatem również jeśli w mediach cyfrowych łamane są zagwarantowane w Konstytucji i innych aktach prawnych prawa i wolności Rzecznik Praw Obywatelskich powinien zareagować.',
-            u'Minister Cyfryzacji i podlegające mu ministerstwo wprowadzają zmiany, które za zadanie mają pogłębiać rozwój cyfryzacji w Polsce. Choć wprowadzane przez Ministerstwo rozwiązania powinny być zgodne z Konstytucją i powinny chronić praw obywateli to Minister nie jest organem, przed którym można dociekać swoich praw w mediach cyfrowych.',
-            u'Rzecznik stoi na straży praw dziecka. Ponieważ osoby niepełnoletnie są ogromną grupą użytkowników internetu, również w mediach cyfrowych ich gwarantowane w Konstytucji i innych aktach prawnych prawa powinny być respektowane, o co dba Rzecznik Praw Dziecka.',
-            u'UODO bardzo szczegółowo określa zasady związane z ochroną danych osobowych w ramach mediów cyfrowych, dbając w ten sposób o prawa obywateli w określonym zakresie.',
-        ),
-        (
-            u'Mówi się, że internet nie zapomina. A jednak w ramach ochrony danych osobowych, w prawodawstwie funkcjonuje pojęcie takie jak Prawo do zapomnienia. Pozwala ono na zażądanie usunięcia imienia i nazwiska konkretnej osoby z wyszukiwarki internetowej. W maju 2016 roku Europejski Trybunał Praw Człowieka zmusił Google do respektowania tego prawa. Jednak nie każdy z wniosków, które wpływają do Google jest rozpatrywany pozytywnie, ponieważ samo Google kieruje się prawem do informacji i wolności słowa. Przez co prawo do zapomnienia, choć jest rozpatrywane, nie zawsze musi zakończyć się po myśli osoby składającej żądanie.',
-            u'Mówi się, że internet nie zapomina. A jednak w ramach ochrony danych osobowych, w prawodawstwie funkcjonuje pojęcie takie jak Prawo do zapomnienia. Pozwala ono na zażądanie usunięcia imienia i nazwiska konkretnej osoby z wyszukiwarki internetowej. W maju 2016 roku Europejski Trybunał Praw Człowieka zmusił Google do respektowania tego prawa. Jednak nie każdy z wniosków, które wpływają do Google jest rozpatrywany pozytywnie, ponieważ samo Google kieruje się prawem do informacji i wolności słowa. Przez co prawo do zapomnienia, choć jest rozpatrywane, nie zawsze musi zakończyć się po myśli osoby składającej żądanie.',
-            u'Mówi się, że internet nie zapomina. A jednak w ramach ochrony danych osobowych, w prawodawstwie funkcjonuje pojęcie takie jak Prawo do zapomnienia. Pozwala ono na zażądanie usunięcia imienia i nazwiska konkretnej osoby z wyszukiwarki internetowej. W maju 2016 roku Europejski Trybunał Praw Człowieka zmusił Google do respektowania tego prawa. Jednak nie każdy z wniosków, które wpływają do Google jest rozpatrywany pozytywnie, ponieważ samo Google kieruje się prawem do informacji i wolności słowa. Przez co prawo do zapomnienia, choć jest rozpatrywane, nie zawsze musi zakończyć się po myśli osoby składającej żądanie.',
-            u'Mówi się, że internet nie zapomina. A jednak w ramach ochrony danych osobowych, w prawodawstwie funkcjonuje pojęcie takie jak Prawo do zapomnienia. Pozwala ono na zażądanie usunięcia imienia i nazwiska konkretnej osoby z wyszukiwarki internetowej. W maju 2016 roku Europejski Trybunał Praw Człowieka zmusił Google do respektowania tego prawa. Jednak nie każdy z wniosków, które wpływają do Google jest rozpatrywany pozytywnie, ponieważ samo Google kieruje się prawem do informacji i wolności słowa. Przez co prawo do zapomnienia, choć jest rozpatrywane, nie zawsze musi zakończyć się po myśli osoby składającej żądanie.',
-            u'Mówi się, że internet nie zapomina. A jednak w ramach ochrony danych osobowych, w prawodawstwie funkcjonuje pojęcie takie jak Prawo do zapomnienia. Pozwala ono na zażądanie usunięcia imienia i nazwiska konkretnej osoby z wyszukiwarki internetowej. W maju 2016 roku Europejski Trybunał Praw Człowieka zmusił Google do respektowania tego prawa. Jednak nie każdy z wniosków, które wpływają do Google jest rozpatrywany pozytywnie, ponieważ samo Google kieruje się prawem do informacji i wolności słowa. Przez co prawo do zapomnienia, choć jest rozpatrywane nie zawsze musi zakończyć się po myśli osoby składającej żądanie.',
-        ),
-        (
-            u'Zgodnie z treścią artykułu 16 ustawy o prawie autorskim i prawach pokrewnych katalog autorskich praw to między innymi uprawnienia do autorstwa utworu, oznaczenia go swoim imieniem i nazwiskiem, pod pseudonimem lub anonimowo, nienaruszalności treści utworu, integralności, decyzji o pierwszym udostępnieniu utworu publiczności czy też nadzoru nad sposobem korzystania z utworu.',
-            u'Artykuł 29 ustawy o prawie autorskim mówi, że wolno korzystać z utworów na potrzeby parodii, pastiszu lub karykatury, w zakresie uzasadnionym prawami tych gatunków twórczości. Zatem prawo nie chroni autorów przed parodiowaniem ich dzieł.',
-            u'Zgodnie z treścią artykułu 16 ustawy o prawie autorskim i prawach pokrewnych katalog autorskich praw to między innymi uprawnienia do autorstwa utworu, oznaczenia go swoim imieniem i nazwiskiem, pod pseudonimem lub anonimowo, nienaruszalności treści utworu, integralności, decyzji o pierwszym udostępnieniu utworu publiczności czy też nadzoru nad sposobem korzystania z utworu. ',
-            u'Zgodnie z treścią artykułu 16 ustawy o prawie autorskim i prawach pokrewnych katalog autorskich praw to między innymi uprawnienia do autorstwa utworu, oznaczenia go swoim imieniem i nazwiskiem, pod pseudonimem lub anonimowo, nienaruszalności treści utworu, integralności, decyzji o pierwszym udostępnieniu utworu publiczności czy też nadzoru nad sposobem korzystania z utworu. Do katalogu praw nie przynależy jednak prawo do wycofania utworu z obiegu. ',
-            u'Zgodnie z treścią artykułu 16 ustawy o prawie autorskim i prawach pokrewnych katalog autorskich praw to między innymi uprawnienia do autorstwa utworu, oznaczenia go swoim imieniem i nazwiskiem, pod pseudonimem lub anonimowo, nienaruszalności treści utworu, integralności, decyzji o pierwszym udostępnieniu utworu publiczności czy też nadzoru nad sposobem korzystania z utworu. ',
-            u'Autorskie prawa osobiste nie obejmują zakazu kopiowania utworu bez zgody twórcy. Dlatego też ta odpowiedź jest błędna. Zgodnie z treścią artykułu 16 ustawy o prawie autorskim i prawach pokrewnych katalog autorskich praw to między innymi uprawnienia do autorstwa utworu, oznaczenia go swoim imieniem i nazwiskiem, pod pseudonimem lub anonimowo, nienaruszalności treści utworu, integralności, decyzji o pierwszym udostępnieniu utworu publiczności czy też nadzoru nad sposobem korzystania z utworu. ',
-        ),
-        (
-            u'Remiks to stworzenie nowego utworu wykorzystując przy tym już istniejące dzieła. Poprzez zestawienie wybranych elementów, tworzeniu kolaży czy zmienianie uporządkowanych części.  Fragmenty innych utworów wykorzystywać można, a następnie rozpowszechniać pod wieloma warunkami m.in. wówczas gdy posiada się zgodę autora/autorki oryginalnego utworu, zezwala na to licencja, wygasły majątkowe prawa autorskie, czyli minęło 70 lat od śmierci autora, przez co utwory są dostępne w domenie publicznej.',
-            u'Remiks to stworzenie nowego utworu wykorzystując przy tym już istniejące dzieła. Poprzez zestawienie wybranych elementów, tworzeniu kolaży czy zmienianie uporządkowanych części.  Fragmenty innych utworów wykorzystywać można, a następnie rozpowszechniać pod wieloma warunkami m.in. wówczas gdy posiada się zgodę autora/autorki oryginalnego utworu, zezwala na to licencja, wygasły majątkowe prawa autorskie, czyli minęło 70 lat od śmierci autora, przez co utwory są dostępne w domenie publicznej. Ściągnięcie materiałów z serwisu do przechowywania plików nie daje prawa do ich rozpowszechniania. ',
-            u'Remiks to stworzenie nowego utworu wykorzystując przy tym już istniejące dzieła. Poprzez zestawienie wybranych elementów, tworzeniu kolaży czy zmienianie uporządkowanych części.  Fragmenty innych utworów wykorzystywać można, a następnie rozpowszechniać pod wieloma warunkami m.in. wówczas gdy posiada się zgodę autora/autorki oryginalnego utworu, zezwala na to licencja, wygasły majątkowe prawa autorskie, czyli minęło 70 lat od śmierci autora, przez co utwory są dostępne w domenie publicznej. Dostęp do utworu poprzez media społecznościowe nie daje gwarancji, że można z niego korzystać i go rozpowszechniać.',
-            u'Remiks to stworzenie nowego utworu wykorzystując przy tym już istniejące dzieła. Poprzez zestawienie wybranych elementów, tworzeniu kolaży czy zmienianie uporządkowanych części.  Fragmenty innych utworów wykorzystywać można, a następnie rozpowszechniać pod wieloma warunkami m.in. wówczas gdy posiada się zgodę autora/autorki oryginalnego utworu, zezwala na to licencja, wygasły majątkowe prawa autorskie, czyli minęło 70 lat od śmierci autora, przez co utwory są dostępne w domenie publicznej.',
-            u'Remiks to stworzenie nowego utworu wykorzystując przy tym już istniejące dzieła. Poprzez zestawienie wybranych elementów, tworzeniu kolaży czy zmienianie uporządkowanych części.  Fragmenty innych utworów wykorzystywać można, a następnie rozpowszechniać pod wieloma warunkami m.in. wówczas gdy posiada się zgodę autora/autorki oryginalnego utworu, zezwala na to licencja, wygasły majątkowe prawa autorskie, czyli minęło 70 lat od śmierci autora, przez co utwory są dostępne w domenie publicznej.',
-            u'Remiks to stworzenie nowego utworu wykorzystując przy tym już istniejące dzieła. Poprzez zestawienie wybranych elementów, tworzeniu kolaży czy zmienianie uporządkowanych części.  Fragmenty innych utworów wykorzystywać można, a następnie rozpowszechniać pod wieloma warunkami m.in. wówczas gdy posiada się zgodę autora/autorki oryginalnego utworu, zezwala na to licencja, wygasły majątkowe prawa autorskie, czyli minęło 70 lat od śmierci autora, przez co utwory są dostępne w domenie publicznej. Udostępnienie plików MP3, nawet przez twórców nie uprawnia do rozpowszechniania zremiksowanego utworu.',
-        ),
-        (
-            u'Dane osobowe są chronione i istnieją specjalne przepisy normujące to w jakim zakresie można pobierać i przetwarzać dane osobowe. Ze względu na to każdy sklep internetowy musi udostępniać  informacje o tym co robi z danymi swoich użytkowników. Takie informacje znajdują się w ramach tzw. polityki prywatności. ',
-            u'Dane osobowe są chronione i istnieją specjalne przepisy normujące to w jakim zakresie można pobierać i przetwarzać dane osobowe. Ze względu na to każdy sklep internetowy musi udostępniać  informacje o tym co robi z danymi swoich użytkowników. Takie informacje znajdują się w ramach tzw. polityki prywatności. ',
-            u'Dane osobowe są chronione i istnieją specjalne przepisy normujące to w jakim zakresie można pobierać i przetwarzać dane osobowe. Ze względu na to każdy sklep internetowy musi udostępniać  informacje o tym co robi z danymi swoich użytkowników. Takie informacje znajdują się w ramach tzw. polityki prywatności. ',
-            u'Dane osobowe są chronione i istnieją specjalne przepisy normujące to w jakim zakresie można pobierać i przetwarzać dane osobowe. Ze względu na to każdy sklep internetowy musi udostępniać  informacje o tym co robi z danymi swoich użytkowników. Takie informacje znajdują się w ramach tzw. polityki prywatności. Nie każdy sklep musi natomiast posiadać regulamin. Choć jest to pożądane przez klientów i zwiększa wiarygodność e-sklepu.',
-        ),
-        (
-            u'Wiersze z biblioteki Wolne Lektury znajdują się w domenie publicznej albo publikowane są na licencji CC BY-SA 3.0, która umożliwia taką publikację. Wspomniana licencja Creative Commons zezwala na dzielenie się, tj. kopiowanie i rozpowszechnianie utworów na tej licencji w dowolnym medium i formacie oraz adaptacje, czyli remiksy na bazie utworu dla dowolnego celu, także komercyjnego. W domenie publicznej znajdują się zaś utwory, co do których majątkowe prawa autorskie albo wygasły albo nie były nigdy objęte prawem autorskim. Z tego też względu bez problemu można publikować niekomercyjnie remiks wspomnianych w pytaniu wierszy.',
-            u'Wiersze z biblioteki Wolne Lektury znajdują się w domenie publicznej albo publikowane są na licencji CC BY-SA 3.0, która umożliwia taką publikację. Wspomniana licencja Creative Commons zezwala na dzielenie się, tj. kopiowanie i rozpowszechnianie utworów na tej licencji w dowolnym medium i formacie oraz adaptacje, czyli remiksy na bazie utworu dla dowolnego celu, także komercyjnego. W domenie publicznej znajdują się zaś utwory, co do których majątkowe prawa autorskie albo wygasły albo nie były nigdy objęte prawem autorskim. Z tego też względu bez problemu można publikować niekomercyjnie remiks wspomnianych w pytaniu wierszy. ',
-            u'Wiersze z biblioteki Wolne Lektury znajdują się w domenie publicznej albo publikowane są na licencji CC BY-SA 3.0, która umożliwia taką publikację. Wspomniana licencja Creative Commons zezwala na dzielenie się, tj. kopiowanie i rozpowszechnianie utworów na tej licencji w dowolnym medium i formacie oraz adaptacje, czyli remiksy na bazie utworu dla dowolnego celu, także komercyjnego. W domenie publicznej znajdują się zaś utwory, co do których majątkowe prawa autorskie albo wygasły albo nie były nigdy objęte prawem autorskim. Z tego też względu bez problemu można publikować niekomercyjnie remiks wspomnianych w pytaniu wierszy. Nie jest do tego potrzebne wnoszenie żadnych dodatkowych opłat.',
-            u'Wiersze z biblioteki Wolne Lektury znajdują się w domenie publicznej albo publikowane są na licencji CC BY-SA 3.0, która umożliwia taką publikację. Wspomniana licencja Creative Commons zezwala na dzielenie się, tj. kopiowanie i rozpowszechnianie utworów na tej licencji w dowolnym medium i formacie oraz adaptacje, czyli remiksy na bazie utworu dla dowolnego celu, także komercyjnego. W domenie publicznej znajdują się zaś utwory, co do których majątkowe prawa autorskie albo wygasły albo nie były nigdy objęte prawem autorskim. Z tego też względu bez problemu można publikować niekomercyjnie remiks wspomnianych w pytaniu wierszy.',
-        ),
-        (
-            u'Dozwolony użytek to określenie w polskim prawie autorskim na ustawowe ograniczenie treści wyłącznych praw autorskich, które to określa ustawa o prawie autorskim i prawach pokrewnych. Prawo rozgranicza dozwolony użytek na ten realizowany w zakresie prywatnym oraz publicznym. W ramach dozwolonego użytku prywatnego w większości przypadków nie można wnosić roszczeń finansowych związanych z majątkowym prawem autorskim. Użytkownik może bez zgody twórcy nieodpłatnie korzystać z już rozpowszechnionego utworu, a także udostępniać go nieodpłatnie określonej grupie osób. Zatem sprzedaż kopii płyt z muzyką jest według prawa związanego z dozwolonym użytkiem zabronione. ',
-            u'Dozwolony użytek to określenie w polskim prawie autorskim na ustawowe ograniczenie treści wyłącznych praw autorskich, które to określa ustawa o prawie autorskim i prawach pokrewnych. Prawo rozgranicza dozwolony użytek na ten realizowany w zakresie prywatnym oraz publicznym. W ramach dozwolonego użytku prywatnego w większości przypadków nie można wnosić roszczeń finansowych związanych z majątkowym prawem autorskim. Użytkownik może bez zgody twórcy nieodpłatnie korzystać z już rozpowszechnionego utworu, a także udostępniać go nieodpłatnie określonej grupie osób. Nawet w sytuacji gdy film został pobrany z nielegalnego internetowego źródła, oglądanie go nie jest zabronione właśnie ze względu na dozwolony użytek prywatny.',
-            u'Dozwolony użytek to określenie w polskim prawie autorskim na ustawowe ograniczenie treści wyłącznych praw autorskich, które to określa ustawa o prawie autorskim i prawach pokrewnych. Prawo rozgranicza dozwolony użytek na ten realizowany w zakresie prywatnym oraz publicznym. W ramach dozwolonego użytku prywatnego w większości przypadków nie można wnosić roszczeń finansowych związanych z majątkowym prawem autorskim. Użytkownik może bez zgody twórcy nieodpłatnie korzystać z już rozpowszechnionego utworu, a także udostępniać go nieodpłatnie określonej grupie osób – w tym także rodzinie.',
-            u'Dozwolony użytek to określenie w polskim prawie autorskim na ustawowe ograniczenie treści wyłącznych praw autorskich, które to określa ustawa o prawie autorskim i prawach pokrewnych. Prawo rozgranicza dozwolony użytek na ten realizowany w zakresie prywatnym oraz publicznym. W ramach dozwolonego użytku prywatnego w większości przypadków nie można wnosić roszczeń finansowych związanych z majątkowym prawem autorskim. Użytkownik może bez zgody twórcy nieodpłatnie korzystać z już rozpowszechnionego utworu, a także udostępniać go nieodpłatnie określonej grupie osób.',
-        )
-    ]
diff --git a/edumed/context_processors.py b/edumed/context_processors.py
deleted file mode 100644 (file)
index ed57c24..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-# -*- coding: utf-8 -*-
-def base_template(request):
-    base_template = 'base_mil.html' if request.META.get('HTTP_HOST').startswith('katalog') else 'base.html'
-    return dict(base_template = base_template)
diff --git a/edumed/forms.py b/edumed/forms.py
deleted file mode 100644 (file)
index 650197b..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-# -*- coding: utf-8 -*-
-from django import forms
-from django.utils.translation import ugettext_lazy as _
-from pybb.forms import EditProfileForm
-from pybb import util
-
-
-class AvatarlessEditProfileForm(EditProfileForm):
-    signature = forms.CharField(
-        widget=forms.Textarea(attrs={'rows': 2, 'cols:': 60}),
-        required=False,
-        label=_('Signature')
-    )
-
-    class Meta:
-        model = util.get_pybb_profile_model()
-        fields = ['signature', 'time_zone', 'language', 'show_signatures']
diff --git a/edumed/forum.py b/edumed/forum.py
deleted file mode 100644 (file)
index 86cfb0c..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-# -*- coding: utf-8 -*-
-from pybb.permissions import DefaultPermissionHandler
-
-
-class ForumPermissionHandler(DefaultPermissionHandler):
-    def may_post_as_admin(self, user):
-        """ return True if `user` may post as admin """
-        return False
-
-    def may_create_topic(self, user, forum):
-        """ return True if `user` is allowed to create a new topic in `forum` """
-        return user.is_authenticated()
-
-    def may_create_post(self, user, topic):
-        """ return True if `user` is allowed to create a new post in `topic` """
-
-        if topic.forum.hidden and (not user.is_staff):
-            # if topic is hidden, only staff may post
-            return False
-
-        if topic.closed and (not user.is_staff):
-            # if topic is closed, only staff may post
-            return False
-
-        return user.is_authenticated()
diff --git a/edumed/locale-contrib/django.pot b/edumed/locale-contrib/django.pot
deleted file mode 100644 (file)
index c231cd9..0000000
+++ /dev/null
@@ -1,715 +0,0 @@
-# Translations template for PROJECT.
-# Copyright (C) 2013 ORGANIZATION
-# This file is distributed under the same license as the PROJECT project.
-# FIRST AUTHOR <EMAIL@ADDRESS>, 2013.
-#
-#, fuzzy
-msgid ""
-msgstr ""
-"Project-Id-Version: PROJECT VERSION\n"
-"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
-"POT-Creation-Date: 2013-08-09 11:40+0200\n"
-"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
-"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
-"Language-Team: LANGUAGE <LL@li.org>\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=utf-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"Generated-By: Babel 1.3\n"
-
-#: pybb/admin.py:40
-#: pybb/admin.py:66
-#: pybb/admin.py:94
-#: pybb/admin.py:116
-msgid "Additional options"
-msgstr ""
-
-#: pybb/admin.py:99
-#: pybb/models.py:254
-msgid "Message"
-msgstr ""
-
-#: pybb/admin.py:130
-msgid "View post"
-msgstr ""
-
-#: pybb/admin.py:135
-msgid "Edit post"
-msgstr ""
-
-#: pybb/feeds.py:25
-#: pybb/feeds.py:26
-#: pybb/templates/pybb/base.html:12
-msgid "Latest posts on forum"
-msgstr ""
-
-#: pybb/feeds.py:35
-#: pybb/feeds.py:36
-#: pybb/templates/pybb/base.html:13
-msgid "Latest topics on forum"
-msgstr ""
-
-#: pybb/forms.py:27
-msgid "Attachment is too big"
-msgstr ""
-
-#: pybb/forms.py:47
-#, python-format
-msgid "You cant add more than %s answers for poll"
-msgstr ""
-
-#: pybb/forms.py:49
-msgid "Add two or more answers for this poll"
-msgstr ""
-
-#: pybb/forms.py:109
-msgid "Polls question is required when adding a poll"
-msgstr ""
-
-#: pybb/forms.py:192
-#, python-format
-msgid "Avatar is too large, max size: %s bytes"
-msgstr ""
-
-#: pybb/models.py:68
-#: pybb/models.py:99
-msgid "Name"
-msgstr ""
-
-#: pybb/models.py:69
-#: pybb/models.py:100
-msgid "Position"
-msgstr ""
-
-#: pybb/models.py:70
-#: pybb/models.py:106
-#: pybb/templates/pybb/category.html:5
-#: pybb/templates/pybb/category.html:28
-msgid "Hidden"
-msgstr ""
-
-#: pybb/models.py:71
-msgid "If checked, this category will be visible only for staff"
-msgstr ""
-
-#: pybb/models.py:76
-#: pybb/models.py:98
-msgid "Category"
-msgstr ""
-
-#: pybb/models.py:77
-msgid "Categories"
-msgstr ""
-
-#: pybb/models.py:101
-msgid "Description"
-msgstr ""
-
-#: pybb/models.py:102
-msgid "Moderators"
-msgstr ""
-
-#: pybb/models.py:103
-#: pybb/models.py:165
-#: pybb/models.py:270
-msgid "Updated"
-msgstr ""
-
-#: pybb/models.py:104
-#: pybb/models.py:172
-#: pybb/models.py:357
-msgid "Post count"
-msgstr ""
-
-#: pybb/models.py:105
-msgid "Topic count"
-msgstr ""
-
-#: pybb/models.py:108
-msgid "Headline"
-msgstr ""
-
-#: pybb/models.py:112
-#: pybb/models.py:162
-#: pybb/templates/pybb/category.html:10
-msgid "Forum"
-msgstr ""
-
-#: pybb/models.py:113
-msgid "Forums"
-msgstr ""
-
-#: pybb/models.py:157
-msgid "None"
-msgstr ""
-
-#: pybb/models.py:158
-msgid "Single answer"
-msgstr ""
-
-#: pybb/models.py:159
-msgid "Multiple answers"
-msgstr ""
-
-#: pybb/models.py:163
-msgid "Subject"
-msgstr ""
-
-#: pybb/models.py:164
-#: pybb/models.py:269
-msgid "Created"
-msgstr ""
-
-#: pybb/models.py:166
-#: pybb/models.py:268
-#: pybb/models.py:381
-#: pybb/models.py:512
-#: pybb/templates/pybb/mail_templates/subscription_email_body.html:3
-msgid "User"
-msgstr ""
-
-#: pybb/models.py:167
-msgid "Views count"
-msgstr ""
-
-#: pybb/models.py:168
-#: pybb/templates/pybb/topic_list.html:27
-msgid "Sticky"
-msgstr ""
-
-#: pybb/models.py:169
-#: pybb/templates/pybb/topic_list.html:28
-msgid "Closed"
-msgstr ""
-
-#: pybb/models.py:170
-#: pybb/templates/pybb/topic.html:92
-msgid "Subscribers"
-msgstr ""
-
-#: pybb/models.py:174
-#: pybb/models.py:272
-msgid "On moderation"
-msgstr ""
-
-#: pybb/models.py:175
-msgid "Poll type"
-msgstr ""
-
-#: pybb/models.py:176
-msgid "Poll question"
-msgstr ""
-
-#: pybb/models.py:180
-#: pybb/models.py:267
-#: pybb/models.py:489
-#: pybb/templates/pybb/topic_list.html:7
-msgid "Topic"
-msgstr ""
-
-#: pybb/models.py:181
-#: pybb/templates/pybb/category.html:13
-msgid "Topics"
-msgstr ""
-
-#: pybb/models.py:255
-msgid "HTML version"
-msgstr ""
-
-#: pybb/models.py:256
-msgid "Text version"
-msgstr ""
-
-#: pybb/models.py:271
-msgid "User IP"
-msgstr ""
-
-#: pybb/models.py:276
-#: pybb/models.py:397
-msgid "Post"
-msgstr ""
-
-#: pybb/models.py:277
-#: pybb/templates/pybb/category.html:16
-#: pybb/templates/pybb/topic_list.html:10
-msgid "Posts"
-msgstr ""
-
-#: pybb/models.py:346
-msgid "Signature"
-msgstr ""
-
-#: pybb/models.py:348
-msgid "Signature HTML Version"
-msgstr ""
-
-#: pybb/models.py:350
-msgid "Time zone"
-msgstr ""
-
-#: pybb/models.py:352
-msgid "Language"
-msgstr ""
-
-#: pybb/models.py:355
-msgid "Show signatures"
-msgstr ""
-
-#: pybb/models.py:358
-msgid "Avatar"
-msgstr ""
-
-#: pybb/models.py:360
-msgid "Automatically subscribe"
-msgstr ""
-
-#: pybb/models.py:361
-msgid "Automatically subscribe to topics that you answer"
-msgstr ""
-
-#: pybb/models.py:384
-msgid "Profile"
-msgstr ""
-
-#: pybb/models.py:385
-msgid "Profiles"
-msgstr ""
-
-#: pybb/models.py:394
-#: pybb/templates/pybb/post_template.html:73
-msgid "Attachment"
-msgstr ""
-
-#: pybb/models.py:395
-msgid "Attachments"
-msgstr ""
-
-#: pybb/models.py:398
-msgid "Size"
-msgstr ""
-
-#: pybb/models.py:399
-msgid "File"
-msgstr ""
-
-#: pybb/models.py:447
-msgid "Topic read tracker"
-msgstr ""
-
-#: pybb/models.py:448
-msgid "Topic read trackers"
-msgstr ""
-
-#: pybb/models.py:483
-msgid "Forum read tracker"
-msgstr ""
-
-#: pybb/models.py:484
-msgid "Forum read trackers"
-msgstr ""
-
-#: pybb/models.py:490
-msgid "Text"
-msgstr ""
-
-#: pybb/models.py:493
-#: pybb/models.py:511
-msgid "Poll answer"
-msgstr ""
-
-#: pybb/models.py:494
-msgid "Polls answers"
-msgstr ""
-
-#: pybb/models.py:516
-msgid "Poll answer user"
-msgstr ""
-
-#: pybb/models.py:517
-msgid "Polls answers users"
-msgstr ""
-
-#: pybb/util.py:58
-msgid "Can't get profile for anonymous user"
-msgstr ""
-
-#: pybb/views.py:648
-msgid "All forums marked as read"
-msgstr ""
-
-#: pybb/views.py:668
-msgid "User successfuly blocked"
-msgstr ""
-
-#: pybb/templates/pybb/_button_new_topic.html:2
-#: pybb/templates/pybb/add_post.html:24
-msgid "New topic"
-msgstr ""
-
-#: pybb/templates/pybb/_button_save.html:1
-msgid "Save"
-msgstr ""
-
-#: pybb/templates/pybb/_button_submit.html:1
-msgid "Submit"
-msgstr ""
-
-#: pybb/templates/pybb/_markitup.html:15
-msgid "Bold"
-msgstr ""
-
-#: pybb/templates/pybb/_markitup.html:16
-msgid "Italic"
-msgstr ""
-
-#: pybb/templates/pybb/_markitup.html:17
-msgid "Underline"
-msgstr ""
-
-#: pybb/templates/pybb/_markitup.html:18
-msgid "Stroke"
-msgstr ""
-
-#: pybb/templates/pybb/_markitup.html:20
-msgid "Picture"
-msgstr ""
-
-#: pybb/templates/pybb/_markitup.html:21
-msgid "Link"
-msgstr ""
-
-#: pybb/templates/pybb/_markitup.html:23
-msgid "Bulleted list"
-msgstr ""
-
-#: pybb/templates/pybb/_markitup.html:24
-msgid "Numeric list"
-msgstr ""
-
-#: pybb/templates/pybb/_markitup.html:25
-msgid "List item"
-msgstr ""
-
-#: pybb/templates/pybb/_markitup.html:27
-msgid "Quotes"
-msgstr ""
-
-#: pybb/templates/pybb/_markitup.html:28
-msgid "Code"
-msgstr ""
-
-#: pybb/templates/pybb/_markitup.html:30
-msgid "Clean"
-msgstr ""
-
-#: pybb/templates/pybb/_markitup.html:31
-msgid "Preview"
-msgstr ""
-
-#: pybb/templates/pybb/_need_to_login_message.html:3
-msgid "Register"
-msgstr ""
-
-#: pybb/templates/pybb/_need_to_login_message.html:3
-msgid "or"
-msgstr ""
-
-#: pybb/templates/pybb/_need_to_login_message.html:3
-msgid "login"
-msgstr ""
-
-#: pybb/templates/pybb/_need_to_login_message.html:3
-msgid "to create to post a reply"
-msgstr ""
-
-#: pybb/templates/pybb/add_post.html:24
-msgid "New reply"
-msgstr ""
-
-#: pybb/templates/pybb/attachments_formset.html:4
-msgid "Add attachments"
-msgstr ""
-
-#: pybb/templates/pybb/attachments_formset.html:10
-#: pybb/templates/pybb/edit_profile.html:27
-msgid "delete"
-msgstr ""
-
-#: pybb/templates/pybb/breadcrumb.html:5
-msgid "Home"
-msgstr ""
-
-#: pybb/templates/pybb/category.html:19
-msgid "Last posts"
-msgstr ""
-
-#: pybb/templates/pybb/category.html:44
-msgid "No forums created"
-msgstr ""
-
-#: pybb/templates/pybb/category.html:45
-msgid "Add forum now"
-msgstr ""
-
-#: pybb/templates/pybb/delete_post.html:5
-msgid "Are you sure you want to delete this message?"
-msgstr ""
-
-#: pybb/templates/pybb/delete_post.html:12
-msgid "No, take me back"
-msgstr ""
-
-#: pybb/templates/pybb/delete_post.html:13
-msgid "Yes, I am sure"
-msgstr ""
-
-#: pybb/templates/pybb/edit_post.html:4
-#: pybb/templates/pybb/edit_post.html:13
-msgid "Editing the post"
-msgstr ""
-
-#: pybb/templates/pybb/edit_profile.html:7
-#: pybb/templates/pybb/edit_profile.html:10
-#: pybb/templates/pybb/edit_profile.html:15
-msgid "Profile editing"
-msgstr ""
-
-#: pybb/templates/pybb/edit_profile.html:20
-msgid "Subscriptions on topics"
-msgstr ""
-
-#: pybb/templates/pybb/index.html:19
-msgid "Forum categories are not created"
-msgstr ""
-
-#: pybb/templates/pybb/index.html:20
-msgid "Add a category now"
-msgstr ""
-
-#: pybb/templates/pybb/index.html:25
-#: pybb/templates/pybb/latest_topics.html:7
-#: pybb/templates/pybb/latest_topics.html:17
-msgid "Last updates in topics"
-msgstr ""
-
-#: pybb/templates/pybb/index.html:28
-msgid "Mark all forums as read"
-msgstr ""
-
-#: pybb/templates/pybb/latest_topics.html:10
-msgid "\"Last updates in topics\""
-msgstr ""
-
-#: pybb/templates/pybb/latest_topics.html:33
-msgid "Mark all topics as read"
-msgstr ""
-
-#: pybb/templates/pybb/pagination.html:7
-msgid "previous page"
-msgstr ""
-
-#: pybb/templates/pybb/pagination.html:21
-msgid "next page"
-msgstr ""
-
-#: pybb/templates/pybb/poll.html:5
-msgid "Poll"
-msgstr ""
-
-#: pybb/templates/pybb/poll.html:37
-msgid "'Cancel my poll vote'"
-msgstr ""
-
-#: pybb/templates/pybb/poll_edit_form.html:7
-msgid "Poll answers"
-msgstr ""
-
-#: pybb/templates/pybb/poll_edit_form.html:20
-msgid "remove answer"
-msgstr ""
-
-#: pybb/templates/pybb/poll_edit_form.html:21
-msgid "add answer"
-msgstr ""
-
-#: pybb/templates/pybb/post_template.html:25
-msgid "Rank"
-msgstr ""
-
-#: pybb/templates/pybb/post_template.html:38
-#: pybb/templates/pybb/user.html:41
-msgid "Edit"
-msgstr ""
-
-#: pybb/templates/pybb/post_template.html:42
-msgid "Delete post?"
-msgstr ""
-
-#: pybb/templates/pybb/post_template.html:43
-msgid "Delete"
-msgstr ""
-
-#: pybb/templates/pybb/post_template.html:45
-msgid "Approve post"
-msgstr ""
-
-#: pybb/templates/pybb/post_template.html:50
-#: pybb/templates/pybb/topic.html:63
-msgid "Admin"
-msgstr ""
-
-#: pybb/templates/pybb/post_template.html:66
-msgid "Edited"
-msgstr ""
-
-#: pybb/templates/pybb/post_template.html:78
-msgid "quote"
-msgstr ""
-
-#: pybb/templates/pybb/topic.html:24
-#: pybb/templates/pybb/topic.html:44
-#: pybb/templates/pybb/user_posts.html:8
-msgid "'Posts'"
-msgstr ""
-
-#: pybb/templates/pybb/topic.html:52
-msgid "Unstick topic"
-msgstr ""
-
-#: pybb/templates/pybb/topic.html:54
-msgid "Stick topic"
-msgstr ""
-
-#: pybb/templates/pybb/topic.html:58
-msgid "Open topic"
-msgstr ""
-
-#: pybb/templates/pybb/topic.html:60
-msgid "Close topic"
-msgstr ""
-
-#: pybb/templates/pybb/topic.html:66
-msgid "Merge topics"
-msgstr ""
-
-#: pybb/templates/pybb/topic.html:71
-msgid "Unsubscribe"
-msgstr ""
-
-#: pybb/templates/pybb/topic.html:73
-msgid "Subscribe"
-msgstr ""
-
-#: pybb/templates/pybb/topic_list.html:13
-msgid "Views"
-msgstr ""
-
-#: pybb/templates/pybb/topic_list.html:16
-msgid "Last post"
-msgstr ""
-
-#: pybb/templates/pybb/topic_list.html:26
-msgid "Go to first unread post"
-msgstr ""
-
-#: pybb/templates/pybb/topic_list.html:32
-msgid "pages"
-msgstr ""
-
-#: pybb/templates/pybb/user.html:15
-msgid "Statistics"
-msgstr ""
-
-#: pybb/templates/pybb/user.html:18
-msgid "Number of topics"
-msgstr ""
-
-#: pybb/templates/pybb/user.html:24
-msgid "Number of posts"
-msgstr ""
-
-#: pybb/templates/pybb/user.html:28
-msgid "Date of registration"
-msgstr ""
-
-#: pybb/templates/pybb/user.html:35
-msgid "Block"
-msgstr ""
-
-#: pybb/templates/pybb/user.html:36
-msgid "Block and delete all messages"
-msgstr ""
-
-#: pybb/templates/pybb/user_posts.html:13
-msgid "All posts created by"
-msgstr ""
-
-#: pybb/templates/pybb/user_topics.html:8
-msgid "'Topics'"
-msgstr ""
-
-#: pybb/templates/pybb/user_topics.html:11
-#: pybb/templates/pybb/user_topics.html:15
-msgid "All topics created by"
-msgstr ""
-
-#: pybb/templates/pybb/users.html:8
-msgid "Users"
-msgstr ""
-
-#: pybb/templates/pybb/users.html:12
-msgid "Search"
-msgstr ""
-
-#: pybb/templates/pybb/users.html:24
-msgid "'Users'"
-msgstr ""
-
-#: pybb/templates/pybb/mail_templates/subscription_email_body.html:3
-msgid "replied in topic to which you are subscribed."
-msgstr ""
-
-#: pybb/templates/pybb/mail_templates/subscription_email_body.html:4
-msgid "Link to post:"
-msgstr ""
-
-#: pybb/templates/pybb/mail_templates/subscription_email_body.html:5
-msgid "Link to topic:"
-msgstr ""
-
-#: pybb/templates/pybb/mail_templates/subscription_email_body.html:8
-msgid ""
-"If you don't want to recive notifications on new messages in this topic "
-"visit following link:"
-msgstr ""
-
-#: pybb/templates/pybb/mail_templates/subscription_email_subject.html:2
-msgid "New answer in topic that you subscribed."
-msgstr ""
-
-#: pybb/templatetags/pybb_tags.py:61
-msgid "seconds ago,seconds ago,seconds ago"
-msgstr ""
-
-#: pybb/templatetags/pybb_tags.py:64
-msgid "seconds ago"
-msgstr ""
-
-#: pybb/templatetags/pybb_tags.py:70
-msgid "minutes ago,minutes ago,minutes ago"
-msgstr ""
-
-#: pybb/templatetags/pybb_tags.py:73
-msgid "minutes ago"
-msgstr ""
-
-#: pybb/templatetags/pybb_tags.py:83
-#, python-format
-msgid "today, %s"
-msgstr ""
-
-#: pybb/templatetags/pybb_tags.py:85
-#, python-format
-msgid "yesterday, %s"
-msgstr ""
-
diff --git a/edumed/locale-contrib/pl/LC_MESSAGES/django.mo b/edumed/locale-contrib/pl/LC_MESSAGES/django.mo
deleted file mode 100644 (file)
index dce9c5a..0000000
Binary files a/edumed/locale-contrib/pl/LC_MESSAGES/django.mo and /dev/null differ
diff --git a/edumed/locale-contrib/pl/LC_MESSAGES/django.po b/edumed/locale-contrib/pl/LC_MESSAGES/django.po
deleted file mode 100644 (file)
index f2768dd..0000000
+++ /dev/null
@@ -1,677 +0,0 @@
-# Polish translations for PROJECT.
-# Copyright (C) 2013 ORGANIZATION
-# This file is distributed under the same license as the PROJECT project.
-# FIRST AUTHOR <EMAIL@ADDRESS>, 2013.
-#
-msgid ""
-msgstr ""
-"Project-Id-Version: PROJECT VERSION\n"
-"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
-"POT-Creation-Date: 2013-08-09 11:40+0200\n"
-"PO-Revision-Date: 2013-08-09 12:17+0100\n"
-"Last-Translator: Radek Czajka <radoslaw.czajka@nowoczesnapolska.org.pl>\n"
-"Language-Team: pl <LL@li.org>\n"
-"Plural-Forms: nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 "
-"|| n%100>=20) ? 1 : 2);\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=utf-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"Generated-By: Babel 1.3\n"
-"X-Generator: Poedit 1.5.4\n"
-
-#: pybb/admin.py:40 pybb/admin.py:66 pybb/admin.py:94 pybb/admin.py:116
-msgid "Additional options"
-msgstr ""
-
-#: pybb/admin.py:99 pybb/models.py:254
-msgid "Message"
-msgstr ""
-
-#: pybb/admin.py:130
-msgid "View post"
-msgstr ""
-
-#: pybb/admin.py:135
-msgid "Edit post"
-msgstr ""
-
-#: pybb/feeds.py:25 pybb/feeds.py:26 pybb/templates/pybb/base.html:12
-msgid "Latest posts on forum"
-msgstr ""
-
-#: pybb/feeds.py:35 pybb/feeds.py:36 pybb/templates/pybb/base.html:13
-msgid "Latest topics on forum"
-msgstr ""
-
-#: pybb/forms.py:27
-msgid "Attachment is too big"
-msgstr ""
-
-#: pybb/forms.py:47
-#, python-format
-msgid "You cant add more than %s answers for poll"
-msgstr ""
-
-#: pybb/forms.py:49
-msgid "Add two or more answers for this poll"
-msgstr ""
-
-#: pybb/forms.py:109
-msgid "Polls question is required when adding a poll"
-msgstr ""
-
-#: pybb/forms.py:192
-#, python-format
-msgid "Avatar is too large, max size: %s bytes"
-msgstr ""
-
-#: pybb/models.py:68 pybb/models.py:99
-msgid "Name"
-msgstr ""
-
-#: pybb/models.py:69 pybb/models.py:100
-msgid "Position"
-msgstr ""
-
-#: pybb/models.py:70 pybb/models.py:106 pybb/templates/pybb/category.html:5
-#: pybb/templates/pybb/category.html:28
-msgid "Hidden"
-msgstr ""
-
-#: pybb/models.py:71
-msgid "If checked, this category will be visible only for staff"
-msgstr ""
-
-#: pybb/models.py:76 pybb/models.py:98
-msgid "Category"
-msgstr ""
-
-#: pybb/models.py:77
-msgid "Categories"
-msgstr ""
-
-#: pybb/models.py:101
-msgid "Description"
-msgstr ""
-
-#: pybb/models.py:102
-msgid "Moderators"
-msgstr ""
-
-#: pybb/models.py:103 pybb/models.py:165 pybb/models.py:270
-msgid "Updated"
-msgstr ""
-
-#: pybb/models.py:104 pybb/models.py:172 pybb/models.py:357
-msgid "Post count"
-msgstr ""
-
-#: pybb/models.py:105
-msgid "Topic count"
-msgstr ""
-
-#: pybb/models.py:108
-msgid "Headline"
-msgstr ""
-
-#: pybb/models.py:112 pybb/models.py:162 pybb/templates/pybb/category.html:10
-msgid "Forum"
-msgstr ""
-
-#: pybb/models.py:113
-msgid "Forums"
-msgstr ""
-
-#: pybb/models.py:157
-msgid "None"
-msgstr ""
-
-#: pybb/models.py:158
-msgid "Single answer"
-msgstr ""
-
-#: pybb/models.py:159
-msgid "Multiple answers"
-msgstr ""
-
-#: pybb/models.py:163
-msgid "Subject"
-msgstr ""
-
-#: pybb/models.py:164 pybb/models.py:269
-msgid "Created"
-msgstr ""
-
-#: pybb/models.py:166 pybb/models.py:268 pybb/models.py:381 pybb/models.py:512
-#: pybb/templates/pybb/mail_templates/subscription_email_body.html:3
-msgid "User"
-msgstr ""
-
-#: pybb/models.py:167
-msgid "Views count"
-msgstr ""
-
-#: pybb/models.py:168 pybb/templates/pybb/topic_list.html:27
-msgid "Sticky"
-msgstr ""
-
-#: pybb/models.py:169 pybb/templates/pybb/topic_list.html:28
-msgid "Closed"
-msgstr ""
-
-#: pybb/models.py:170 pybb/templates/pybb/topic.html:92
-msgid "Subscribers"
-msgstr ""
-
-#: pybb/models.py:174 pybb/models.py:272
-msgid "On moderation"
-msgstr ""
-
-#: pybb/models.py:175
-msgid "Poll type"
-msgstr ""
-
-#: pybb/models.py:176
-msgid "Poll question"
-msgstr ""
-
-#: pybb/models.py:180 pybb/models.py:267 pybb/models.py:489
-#: pybb/templates/pybb/topic_list.html:7
-msgid "Topic"
-msgstr ""
-
-#: pybb/models.py:181 pybb/templates/pybb/category.html:13
-msgid "Topics"
-msgstr ""
-
-#: pybb/models.py:255
-msgid "HTML version"
-msgstr ""
-
-#: pybb/models.py:256
-msgid "Text version"
-msgstr ""
-
-#: pybb/models.py:271
-msgid "User IP"
-msgstr ""
-
-#: pybb/models.py:276 pybb/models.py:397
-msgid "Post"
-msgstr ""
-
-#: pybb/models.py:277 pybb/templates/pybb/category.html:16
-#: pybb/templates/pybb/topic_list.html:10
-msgid "Posts"
-msgstr ""
-
-#: pybb/models.py:346
-msgid "Signature"
-msgstr "Podpis"
-
-#: pybb/models.py:348
-msgid "Signature HTML Version"
-msgstr ""
-
-#: pybb/models.py:350
-msgid "Time zone"
-msgstr ""
-
-#: pybb/models.py:352
-msgid "Language"
-msgstr ""
-
-#: pybb/models.py:355
-msgid "Show signatures"
-msgstr ""
-
-#: pybb/models.py:358
-msgid "Avatar"
-msgstr ""
-
-#: pybb/models.py:360
-msgid "Automatically subscribe"
-msgstr ""
-
-#: pybb/models.py:361
-msgid "Automatically subscribe to topics that you answer"
-msgstr ""
-
-#: pybb/models.py:384
-msgid "Profile"
-msgstr ""
-
-#: pybb/models.py:385
-msgid "Profiles"
-msgstr ""
-
-#: pybb/models.py:394 pybb/templates/pybb/post_template.html:73
-msgid "Attachment"
-msgstr ""
-
-#: pybb/models.py:395
-msgid "Attachments"
-msgstr ""
-
-#: pybb/models.py:398
-msgid "Size"
-msgstr ""
-
-#: pybb/models.py:399
-msgid "File"
-msgstr ""
-
-#: pybb/models.py:447
-msgid "Topic read tracker"
-msgstr ""
-
-#: pybb/models.py:448
-msgid "Topic read trackers"
-msgstr ""
-
-#: pybb/models.py:483
-msgid "Forum read tracker"
-msgstr ""
-
-#: pybb/models.py:484
-msgid "Forum read trackers"
-msgstr ""
-
-#: pybb/models.py:490
-msgid "Text"
-msgstr ""
-
-#: pybb/models.py:493 pybb/models.py:511
-msgid "Poll answer"
-msgstr ""
-
-#: pybb/models.py:494
-msgid "Polls answers"
-msgstr ""
-
-#: pybb/models.py:516
-msgid "Poll answer user"
-msgstr ""
-
-#: pybb/models.py:517
-msgid "Polls answers users"
-msgstr ""
-
-#: pybb/util.py:58
-msgid "Can't get profile for anonymous user"
-msgstr ""
-
-#: pybb/views.py:648
-msgid "All forums marked as read"
-msgstr ""
-
-#: pybb/views.py:668
-msgid "User successfuly blocked"
-msgstr ""
-
-#: pybb/templates/pybb/_button_new_topic.html:2
-#: pybb/templates/pybb/add_post.html:24
-msgid "New topic"
-msgstr ""
-
-#: pybb/templates/pybb/_button_save.html:1
-msgid "Save"
-msgstr ""
-
-#: pybb/templates/pybb/_button_submit.html:1
-msgid "Submit"
-msgstr ""
-
-#: pybb/templates/pybb/_markitup.html:15
-msgid "Bold"
-msgstr "Pogrubienie"
-
-#: pybb/templates/pybb/_markitup.html:16
-msgid "Italic"
-msgstr "Kursywa"
-
-#: pybb/templates/pybb/_markitup.html:17
-msgid "Underline"
-msgstr "Podkreślenie"
-
-#: pybb/templates/pybb/_markitup.html:18
-msgid "Stroke"
-msgstr "Przekreślenie"
-
-#: pybb/templates/pybb/_markitup.html:20
-msgid "Picture"
-msgstr "Obrazek"
-
-#: pybb/templates/pybb/_markitup.html:21
-msgid "Link"
-msgstr ""
-
-#: pybb/templates/pybb/_markitup.html:23
-msgid "Bulleted list"
-msgstr "Lista wypunktowana"
-
-#: pybb/templates/pybb/_markitup.html:24
-msgid "Numeric list"
-msgstr "Lista numerowana"
-
-#: pybb/templates/pybb/_markitup.html:25
-msgid "List item"
-msgstr "Element listy"
-
-#: pybb/templates/pybb/_markitup.html:27
-msgid "Quotes"
-msgstr "Cytat"
-
-#: pybb/templates/pybb/_markitup.html:28
-msgid "Code"
-msgstr "Kod"
-
-#: pybb/templates/pybb/_markitup.html:30
-msgid "Clean"
-msgstr ""
-
-#: pybb/templates/pybb/_markitup.html:31
-msgid "Preview"
-msgstr "Podgląd"
-
-#: pybb/templates/pybb/_need_to_login_message.html:3
-msgid "Register"
-msgstr ""
-
-#: pybb/templates/pybb/_need_to_login_message.html:3
-msgid "or"
-msgstr ""
-
-#: pybb/templates/pybb/_need_to_login_message.html:3
-msgid "login"
-msgstr ""
-
-#: pybb/templates/pybb/_need_to_login_message.html:3
-msgid "to create to post a reply"
-msgstr ""
-
-#: pybb/templates/pybb/add_post.html:24
-msgid "New reply"
-msgstr ""
-
-#: pybb/templates/pybb/attachments_formset.html:4
-msgid "Add attachments"
-msgstr ""
-
-#: pybb/templates/pybb/attachments_formset.html:10
-#: pybb/templates/pybb/edit_profile.html:27
-msgid "delete"
-msgstr ""
-
-#: pybb/templates/pybb/breadcrumb.html:5
-msgid "Home"
-msgstr ""
-
-#: pybb/templates/pybb/category.html:19
-msgid "Last posts"
-msgstr ""
-
-#: pybb/templates/pybb/category.html:44
-msgid "No forums created"
-msgstr ""
-
-#: pybb/templates/pybb/category.html:45
-msgid "Add forum now"
-msgstr ""
-
-#: pybb/templates/pybb/delete_post.html:5
-msgid "Are you sure you want to delete this message?"
-msgstr ""
-
-#: pybb/templates/pybb/delete_post.html:12
-msgid "No, take me back"
-msgstr ""
-
-#: pybb/templates/pybb/delete_post.html:13
-msgid "Yes, I am sure"
-msgstr ""
-
-#: pybb/templates/pybb/edit_post.html:4 pybb/templates/pybb/edit_post.html:13
-msgid "Editing the post"
-msgstr ""
-
-#: pybb/templates/pybb/edit_profile.html:7
-#: pybb/templates/pybb/edit_profile.html:10
-#: pybb/templates/pybb/edit_profile.html:15
-msgid "Profile editing"
-msgstr ""
-
-#: pybb/templates/pybb/edit_profile.html:20
-msgid "Subscriptions on topics"
-msgstr ""
-
-#: pybb/templates/pybb/index.html:19
-msgid "Forum categories are not created"
-msgstr ""
-
-#: pybb/templates/pybb/index.html:20
-msgid "Add a category now"
-msgstr ""
-
-#: pybb/templates/pybb/index.html:25 pybb/templates/pybb/latest_topics.html:7
-#: pybb/templates/pybb/latest_topics.html:17
-msgid "Last updates in topics"
-msgstr "Ostatnio modyfikowane tematy"
-
-#: pybb/templates/pybb/index.html:28
-msgid "Mark all forums as read"
-msgstr ""
-
-#: pybb/templates/pybb/latest_topics.html:10
-msgid "\"Last updates in topics\""
-msgstr ""
-
-#: pybb/templates/pybb/latest_topics.html:33
-msgid "Mark all topics as read"
-msgstr "Oznacz wszystkie tematy jako przeczytane"
-
-#: pybb/templates/pybb/pagination.html:7
-msgid "previous page"
-msgstr ""
-
-#: pybb/templates/pybb/pagination.html:21
-msgid "next page"
-msgstr ""
-
-#: pybb/templates/pybb/poll.html:5
-msgid "Poll"
-msgstr ""
-
-#: pybb/templates/pybb/poll.html:37
-msgid "'Cancel my poll vote'"
-msgstr "Anuluj mój głos w ankiecie"
-
-#: pybb/templates/pybb/poll_edit_form.html:7
-msgid "Poll answers"
-msgstr ""
-
-#: pybb/templates/pybb/poll_edit_form.html:20
-msgid "remove answer"
-msgstr ""
-
-#: pybb/templates/pybb/poll_edit_form.html:21
-msgid "add answer"
-msgstr ""
-
-#: pybb/templates/pybb/post_template.html:25
-msgid "Rank"
-msgstr ""
-
-#: pybb/templates/pybb/post_template.html:38 pybb/templates/pybb/user.html:41
-msgid "Edit"
-msgstr ""
-
-#: pybb/templates/pybb/post_template.html:42
-msgid "Delete post?"
-msgstr ""
-
-#: pybb/templates/pybb/post_template.html:43
-msgid "Delete"
-msgstr ""
-
-#: pybb/templates/pybb/post_template.html:45
-msgid "Approve post"
-msgstr ""
-
-#: pybb/templates/pybb/post_template.html:50 pybb/templates/pybb/topic.html:63
-msgid "Admin"
-msgstr ""
-
-#: pybb/templates/pybb/post_template.html:66
-msgid "Edited"
-msgstr ""
-
-#: pybb/templates/pybb/post_template.html:78
-msgid "quote"
-msgstr ""
-
-#: pybb/templates/pybb/topic.html:24 pybb/templates/pybb/topic.html:44
-#: pybb/templates/pybb/user_posts.html:8
-msgid "'Posts'"
-msgstr "'Posty'"
-
-#: pybb/templates/pybb/topic.html:52
-msgid "Unstick topic"
-msgstr ""
-
-#: pybb/templates/pybb/topic.html:54
-msgid "Stick topic"
-msgstr ""
-
-#: pybb/templates/pybb/topic.html:58
-msgid "Open topic"
-msgstr ""
-
-#: pybb/templates/pybb/topic.html:60
-msgid "Close topic"
-msgstr ""
-
-#: pybb/templates/pybb/topic.html:66
-msgid "Merge topics"
-msgstr "Połącz wątki"
-
-#: pybb/templates/pybb/topic.html:71
-msgid "Unsubscribe"
-msgstr ""
-
-#: pybb/templates/pybb/topic.html:73
-msgid "Subscribe"
-msgstr ""
-
-#: pybb/templates/pybb/topic_list.html:13
-msgid "Views"
-msgstr ""
-
-#: pybb/templates/pybb/topic_list.html:16
-msgid "Last post"
-msgstr ""
-
-#: pybb/templates/pybb/topic_list.html:26
-msgid "Go to first unread post"
-msgstr "Zobacz pierwszy nieprzeczytany post"
-
-#: pybb/templates/pybb/topic_list.html:32
-msgid "pages"
-msgstr ""
-
-#: pybb/templates/pybb/user.html:15
-msgid "Statistics"
-msgstr ""
-
-#: pybb/templates/pybb/user.html:18
-msgid "Number of topics"
-msgstr ""
-
-#: pybb/templates/pybb/user.html:24
-msgid "Number of posts"
-msgstr ""
-
-#: pybb/templates/pybb/user.html:28
-msgid "Date of registration"
-msgstr ""
-
-#: pybb/templates/pybb/user.html:35
-msgid "Block"
-msgstr ""
-
-#: pybb/templates/pybb/user.html:36
-msgid "Block and delete all messages"
-msgstr "Zablokuj i usuń wszystkie posty"
-
-#: pybb/templates/pybb/user_posts.html:13
-msgid "All posts created by"
-msgstr "Wszystkie posty utworzone przez"
-
-#: pybb/templates/pybb/user_topics.html:8
-msgid "'Topics'"
-msgstr "'Tematy'"
-
-#: pybb/templates/pybb/user_topics.html:11
-#: pybb/templates/pybb/user_topics.html:15
-msgid "All topics created by"
-msgstr ""
-
-#: pybb/templates/pybb/users.html:8
-msgid "Users"
-msgstr ""
-
-#: pybb/templates/pybb/users.html:12
-msgid "Search"
-msgstr ""
-
-#: pybb/templates/pybb/users.html:24
-msgid "'Users'"
-msgstr "'Użytkownicy'"
-
-#: pybb/templates/pybb/mail_templates/subscription_email_body.html:3
-msgid "replied in topic to which you are subscribed."
-msgstr ""
-
-#: pybb/templates/pybb/mail_templates/subscription_email_body.html:4
-msgid "Link to post:"
-msgstr ""
-
-#: pybb/templates/pybb/mail_templates/subscription_email_body.html:5
-msgid "Link to topic:"
-msgstr ""
-
-#: pybb/templates/pybb/mail_templates/subscription_email_body.html:8
-msgid ""
-"If you don't want to recive notifications on new messages in this topic "
-"visit following link:"
-msgstr ""
-
-#: pybb/templates/pybb/mail_templates/subscription_email_subject.html:2
-msgid "New answer in topic that you subscribed."
-msgstr ""
-
-#: pybb/templatetags/pybb_tags.py:61
-msgid "seconds ago,seconds ago,seconds ago"
-msgstr ""
-
-#: pybb/templatetags/pybb_tags.py:64
-msgid "seconds ago"
-msgstr ""
-
-#: pybb/templatetags/pybb_tags.py:70
-msgid "minutes ago,minutes ago,minutes ago"
-msgstr ""
-
-#: pybb/templatetags/pybb_tags.py:73
-msgid "minutes ago"
-msgstr ""
-
-#: pybb/templatetags/pybb_tags.py:83
-#, python-format
-msgid "today, %s"
-msgstr ""
-
-#: pybb/templatetags/pybb_tags.py:85
-#, python-format
-msgid "yesterday, %s"
-msgstr ""
diff --git a/edumed/locale/pl/LC_MESSAGES/django.mo b/edumed/locale/pl/LC_MESSAGES/django.mo
deleted file mode 100644 (file)
index 89f7535..0000000
Binary files a/edumed/locale/pl/LC_MESSAGES/django.mo and /dev/null differ
diff --git a/edumed/locale/pl/LC_MESSAGES/django.po b/edumed/locale/pl/LC_MESSAGES/django.po
deleted file mode 100644 (file)
index c35be11..0000000
+++ /dev/null
@@ -1,109 +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: 2013-11-05 10:12+0100\n"
-"PO-Revision-Date: 2012-11-19 15:58+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"
-
-#: contact_forms.py:131
-msgid "extended"
-msgstr "rozszerzony"
-
-#: contact_forms.py:160
-msgid ""
-"Share your thoughts on the \"Media and information literacy competencies "
-"catalogue\""
-msgstr " Podziel się uwagami na temat Katalogu Kompetencji "
-
-#: contact_forms.py:161
-msgid "Submit"
-msgstr "Zgłoś"
-
-#: contact_forms.py:165
-msgid "Name and Surname"
-msgstr "Imię i nazwisko"
-
-#: contact_forms.py:166
-msgid "E-mail"
-msgstr "Adres e-mail"
-
-#: contact_forms.py:168
-msgid "Institution"
-msgstr "Instytucja"
-
-#: contact_forms.py:171
-msgid "What do you think about the proposed educational stages classification?"
-msgstr "Co sądzisz o zaproponowanym podziale na etapy edukacyjne?"
-
-#: contact_forms.py:178
-msgid "What do you think about the proposed thematic fields?"
-msgstr "Co sądzisz o zaproponowanym podziale na obszary tematyczne?"
-
-#: contact_forms.py:185
-msgid ""
-"What important areas of media and information literacy have been left out?"
-msgstr ""
-"Jakie ważne obszary edukacji medialnej i informacyjnej zostały Twoim zdaniem "
-"niewystarczająco pogłębione lub pominięto je w ogóle?"
-
-#: contact_forms.py:192
-msgid "Other suggestions and comments"
-msgstr "Inne uwagi i sugestie"
-
-#: forms.py:11
-msgid "Signature"
-msgstr ""
-
-#: templates/404.html:4 templates/404.html.py:8 templates/404_mil.html:4
-#: templates/404_mil.html.py:8
-msgid "Page not found"
-msgstr "Strona nie znaleziona"
-
-#: templates/404.html:11 templates/404_mil.html:11
-msgid "The page you were looking for doesn't exist."
-msgstr "Strona której szukasz nie została znaleziona."
-
-#: templates/base_forum.html:7
-msgid "Forum search"
-msgstr "Szukaj na forum"
-
-#: templates/base_mil.html:9
-msgid "About Catalogue"
-msgstr "O katalogu"
-
-#: templates/base_mil.html:10
-msgid "Competencies"
-msgstr "Kompetencje"
-
-#: templates/base_mil.html:11
-msgid "Take Part"
-msgstr "Weź udział"
-
-#: templates/base_mil.html:15
-msgid "Contact"
-msgstr "Kontakt"
-
-#: templates/pybb/_need_to_login_message.html:2
-msgid "Login"
-msgstr ""
-
-#: templates/pybb/_need_to_login_message.html:2
-msgid "register"
-msgstr ""
-
-#: templates/pybb/_need_to_login_message.html:2
-msgid "to create to post a reply"
-msgstr ""
diff --git a/edumed/milurls.py b/edumed/milurls.py
deleted file mode 100644 (file)
index dea2558..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-# -*- coding: utf-8 -*-
-from django.conf.urls import include, url, patterns
-from django.conf import settings
-
-from fnpdjango.utils.urls import i18n_patterns
-from .views import mil_home_view, mil_contact_view, mil_knowledge_base_view
-
-
-urlpatterns = i18n_patterns(
-    '',
-    url(r'^$', mil_home_view, name="mil_home"),
-    url(r'^kompetencje/', include('curriculum.urls')),
-    url(r'^wez-udzial/', include('comment.urls')),
-    url(r'^zglos/', include('contact.urls')),
-    url(r'^kontakt/$', mil_contact_view, name='mil_contact'),
-    url(r'^bazawiedzy/(?P<url>.*)$', mil_knowledge_base_view,
-        name="knowledge_base"),
-)
-
-handler404 = 'edumed.views.mil_404_view'
-
-if settings.DEBUG:
-    urlpatterns += patterns(
-        '',
-        url(r'^media/(?P<path>.*)$', 'django.views.static.serve', {
-            'document_root': settings.MEDIA_ROOT,
-        }),
-    )
diff --git a/edumed/settings/__init__.py b/edumed/settings/__init__.py
deleted file mode 100644 (file)
index 4a75df0..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-# -*- coding: utf-8 -*-
-
-from .paths import *
-from .basic import *
-from .apps import *
-from .locale import *
-from .search import *
-from .auth import *
-from .cache import *
-from .context import *
-from .logging import *
-from .middleware import *
-from .contrib import *
-from .static import *
-from .custom import *
-
-# Load localsettings, if they exist
-try:
-    from edumed.localsettings import *
-except ImportError:
-    pass
\ No newline at end of file
diff --git a/edumed/settings/apps.py b/edumed/settings/apps.py
deleted file mode 100644 (file)
index 04835b5..0000000
+++ /dev/null
@@ -1,42 +0,0 @@
-# -*- coding: utf-8 -*-
-
-INSTALLED_APPS = (
-    'edumed',
-    'curriculum',
-    'catalogue',
-    'comment',
-    'wtem',
-    'publishers',
-    'api',
-
-    'fnpdjango',
-    'south',
-    'pipeline',
-    'django_extensions',
-    # Disable, if not using Piwik.
-    'piwik',
-    # Disable, if not using CAS.
-    'honeypot',
-    'django_cas',
-    'sponsors',
-    'haystack',
-    'chunks',
-    'contact',
-    'forum',
-    'pybb',
-    'django_libravatar',
-    'sorl.thumbnail',
-    'subdomains',
-    'piston',
-
-    'django.contrib.auth',
-    'django.contrib.contenttypes',
-    'django.contrib.sessions',
-    'django.contrib.sites',
-    'django.contrib.messages',
-    'django.contrib.staticfiles',
-    'django.contrib.admin',
-    'django.contrib.admindocs',
-    'django.contrib.flatpages',
-    'django.contrib.humanize'
-)
diff --git a/edumed/settings/auth.py b/edumed/settings/auth.py
deleted file mode 100644 (file)
index 35c74c4..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-# -*- coding: utf-8 -*-
-from .apps import INSTALLED_APPS
-
-if 'django_cas' in INSTALLED_APPS:
-    AUTHENTICATION_BACKENDS = (
-        'django.contrib.auth.backends.ModelBackend',
-        'fnpdjango.auth_backends.AttrCASBackend',
-    )
diff --git a/edumed/settings/basic.py b/edumed/settings/basic.py
deleted file mode 100644 (file)
index 3e553b3..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-# -*- coding: utf-8 -*-
-import os.path
-
-from .paths import PROJECT_DIR
-
-DEBUG = False
-TEMPLATE_DEBUG = DEBUG
-
-DATABASES = {
-    'default': {
-        'ENGINE': 'django.db.backends.sqlite3',  # Add 'postgresql_psycopg2', 'mysql', 'sqlite3' or 'oracle'.
-        'NAME': os.path.join(PROJECT_DIR, 'dev.db'),                      # 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.
-        'PORT': '',                      # Set to empty string for default. Not used with sqlite3.
-    }
-}
-
-SITE_ID = 1
-
-# List of callables that know how to import templates from various sources.
-TEMPLATE_LOADERS = (
-    'django.template.loaders.filesystem.Loader',
-    'django.template.loaders.app_directories.Loader',
-    # 'django.template.loaders.eggs.Loader',
-)
-
-ROOT_URLCONF = 'edumed.urls'
-
-SUBDOMAIN_URLCONFS = {
-    None: 'edumed.urls',
-    'katalog': 'edumed.milurls',
-}
-
-# Python dotted path to the WSGI application used by Django's runserver.
-WSGI_APPLICATION = 'edumed.wsgi.application'
-
-TEMPLATE_DIRS = (
-    # Put strings here, like "/home/html/django_templates" or "C:/www/django/templates".
-    # Always use forward slashes, even on Windows.
-    # Don't forget to use absolute paths, not relative paths.
-)
diff --git a/edumed/settings/cache.py b/edumed/settings/cache.py
deleted file mode 100644 (file)
index 3079b6c..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-# -*- coding: utf-8 -*-
-
-CACHES = {
-    'default': {
-        'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache',
-        'LOCATION': '127.0.0.1:11211',
-        'KEY_PREFIX': 'edumed',
-    }
-}
-
-CACHE_MIDDLEWARE_ANONYMOUS_ONLY = True
diff --git a/edumed/settings/context.py b/edumed/settings/context.py
deleted file mode 100644 (file)
index bff5838..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-# -*- coding: utf-8 -*-
-from edumed.utils import process_app_deps
-
-TEMPLATE_CONTEXT_PROCESSORS = process_app_deps((
-    ("django.contrib.auth.context_processors.auth", "django.contrib.auth"),
-    "django.core.context_processors.debug",
-    "django.core.context_processors.i18n",
-    "django.core.context_processors.media",
-    "django.core.context_processors.static",
-    "django.core.context_processors.tz",
-    ("django.contrib.messages.context_processors.messages", 'django.contrib.messages'),
-    "django.core.context_processors.request",
-    'pybb.context_processors.processor',
-    'edumed.context_processors.base_template',
-))
diff --git a/edumed/settings/contrib.py b/edumed/settings/contrib.py
deleted file mode 100644 (file)
index d7ea957..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-# -*- coding: utf-8 -*-
-
-CAS_SERVER_URL = 'http://logowanie.nowoczesnapolska.org.pl/cas/'
-CAS_VERSION = '3'
-
-SPONSORS_THUMB_WIDTH = 100
-SPONSORS_THUMB_HEIGHT = 56
-
-PYBB_TEMPLATE = "base_forum.html"
-PYBB_SMILES = {}
-PYBB_ENABLE_ANONYMOUS_POST = False
-
-PYBB_DEFAULT_TITLE = u'Forum'
-PYBB_DEFAULT_TIME_ZONE = 1
-PYBB_PERMISSION_HANDLER = 'edumed.forum.ForumPermissionHandler'
-
-THUMBNAIL_ENGINE = 'sorl.thumbnail.engines.convert_engine.Engine'
-THUMBNAIL_CONVERT = 'convert -density 300 -background white -alpha off'
diff --git a/edumed/settings/custom.py b/edumed/settings/custom.py
deleted file mode 100644 (file)
index a2fc281..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-# -*- coding: utf-8 -*-
-
-CONTACT_FORMS_MODULE = 'edumed.contact_forms'
diff --git a/edumed/settings/locale.py b/edumed/settings/locale.py
deleted file mode 100644 (file)
index cfe4cc1..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-# -*- coding: utf-8 -*-
-import os.path
-
-from .paths import PROJECT_DIR
-
-LANGUAGES = (
-    ('pl', u'polski'),
-    ('en', u'English'),
-)
-
-# Local time zone for this installation. Choices can be found here:
-# http://en.wikipedia.org/wiki/List_of_tz_zones_by_name
-# although not all choices may be available on all operating systems.
-# On Unix systems, a value of None will cause Django to use the same
-# timezone as the operating system.
-# If running in a Windows environment this must be set to the same as your
-# system time zone.
-TIME_ZONE = None
-
-# Language code for this installation. All choices can be found here:
-# http://www.i18nguy.com/unicode/language-identifiers.html
-LANGUAGE_CODE = 'pl'
-
-# If you set this to False, Django will make some optimizations so as not
-# to load the internationalization machinery.
-USE_I18N = True
-
-# If you set this to False, Django will not format dates, numbers and
-# calendars according to the current locale.
-USE_L10N = True
-
-# If you set this to False, Django will not use timezone-aware datetimes.
-USE_TZ = True
-
-CONTRIB_LOCALE_APPS = (
-    'pybb',
-)
-LOCALE_PATHS = (
-    os.path.join(PROJECT_DIR, 'edumed/locale-contrib'),
-)
diff --git a/edumed/settings/logging.py b/edumed/settings/logging.py
deleted file mode 100644 (file)
index ea3ad61..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-# -*- coding: utf-8 -*-
-# A sample logging configuration. The only tangible logging
-# performed by this configuration is to send an email to
-# the site admins on every HTTP 500 error when DEBUG=False.
-# See http://docs.djangoproject.com/en/dev/topics/logging for
-# more details on how to customize your logging configuration.
-LOGGING = {
-    'version': 1,
-    'disable_existing_loggers': False,
-    'filters': {
-        'require_debug_false': {
-            '()': 'django.utils.log.RequireDebugFalse'
-        }
-    },
-    'handlers': {
-        'mail_admins': {
-            'level': 'ERROR',
-            'filters': ['require_debug_false'],
-            'class': 'django.utils.log.AdminEmailHandler'
-        }
-    },
-    'loggers': {
-        'django.request': {
-            'handlers': ['mail_admins'],
-            'level': 'ERROR',
-            'propagate': True,
-        },
-    }
-}
diff --git a/edumed/settings/middleware.py b/edumed/settings/middleware.py
deleted file mode 100644 (file)
index 3dc3278..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-# -*- coding: utf-8 -*-
-from edumed.utils import process_app_deps
-
-MIDDLEWARE_CLASSES = process_app_deps((
-    'django.middleware.cache.UpdateCacheMiddleware',
-    ('django.contrib.sessions.middleware.SessionMiddleware', 'django.contrib.sessions'),
-    # 'django.middleware.locale.LocaleMiddleware',
-    'subdomains.middleware.SubdomainURLRoutingMiddleware',
-    'fnpdjango.middleware.URLLocaleMiddleware',
-
-    'django.middleware.common.CommonMiddleware',
-    'django.middleware.csrf.CsrfViewMiddleware',
-    ('django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.auth'),
-    ('django_cas.middleware.CASMiddleware', 'django_cas'),
-    ('django.contrib.messages.middleware.MessageMiddleware', 'django.contrib.messages'),
-    # Uncomment the next line for simple clickjacking protection:
-    # 'django.middleware.clickjacking.XFrameOptionsMiddleware',
-    ('pagination.middleware.PaginationMiddleware', 'pagination'),
-    'django.middleware.cache.FetchFromCacheMiddleware',
-    'fnpdjango.middleware.SetRemoteAddrFromXRealIP',
-    'pybb.middleware.PybbMiddleware',
-    'forum.middleware.ForumMiddleware',
-    'wtem.middleware.ThreadLocalMiddleware'
-))
diff --git a/edumed/settings/paths.py b/edumed/settings/paths.py
deleted file mode 100644 (file)
index 55d7b9e..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-# -*- coding: utf-8 -*-
-import os.path
-
-PROJECT_DIR = os.path.dirname(os.path.abspath(os.path.dirname(__file__)))
diff --git a/edumed/settings/search.py b/edumed/settings/search.py
deleted file mode 100644 (file)
index f54983b..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-# -*- coding: utf-8 -*-
-
-HAYSTACK_CONNECTIONS = {
-    'default': {
-        'ENGINE': 'haystack.backends.solr_backend.SolrEngine',
-        'URL': 'http://127.0.0.1:8983/solr/edumed'
-    },
-}
diff --git a/edumed/settings/static.py b/edumed/settings/static.py
deleted file mode 100644 (file)
index a2f2c05..0000000
+++ /dev/null
@@ -1,73 +0,0 @@
-# -*- coding: utf-8 -*-
-import os.path
-
-from .paths import PROJECT_DIR
-
-MEDIA_ROOT = os.path.join(PROJECT_DIR, 'media/')
-MEDIA_URL = '/media/'
-STATIC_ROOT = os.path.join(PROJECT_DIR, 'static/')
-STATIC_URL = '/static/'
-
-STATICFILES_FINDERS = (
-    'django.contrib.staticfiles.finders.FileSystemFinder',
-    'django.contrib.staticfiles.finders.AppDirectoriesFinder',
-    # 'django.contrib.staticfiles.finders.DefaultStorageFinder',
-)
-
-STATICFILES_STORAGE = 'fnpdjango.utils.pipeline_storage.GzipPipelineCachedStorage'
-PIPELINE_CSS_COMPRESSOR = None
-PIPELINE_JS_COMPRESSOR = None
-PIPELINE_CSS = {
-    'base': {
-        'source_filenames': (
-          'css/base.scss',
-          'css/main.scss',
-          'css/form.scss',
-          'catalogue/css/carousel.scss',
-          'catalogue/css/layout.scss',
-          'catalogue/css/lesson.scss',
-          'catalogue/css/exercise.scss',
-          'catalogue/css/section_list.scss',
-          'curriculum/curriculum.scss',
-          'jquery/colorbox/colorbox.css',
-          'fnpdjango/annoy/annoy.css',
-
-          'css/forum.scss',
-          'css/mil.scss'
-        ),
-        'output_filename': 'compressed/base.css',
-    },
-}
-PIPELINE_JS = {
-    'base': {
-        'source_filenames': (
-            'catalogue/js/jquery-ui-1.10.0.custom.js',
-            'catalogue/js/jquery.cycle.all.js',
-            'jquery/colorbox/jquery.colorbox-min.js',
-            'jquery/colorbox/jquery.colorbox-pl.js',
-            'catalogue/js/carousel.js',
-            'catalogue/js/edumed.js',
-            'catalogue/js/lesson.js',
-            'catalogue/js/lesson-list.js',
-            'sponsors/js/sponsors.js',
-            'curriculum/curriculum.js',
-            'js/formset.js',
-            'pybb/js/pybbjs.js',
-            'fnpdjango/annoy/annoy.js',
-        ),
-        'output_filename': 'compressed/base.js',
-    },
-    'wtem': {
-        'source_filenames': (
-            'catalogue/js/jquery-ui-1.10.0.custom.js',
-            'wtem/edumed.js',
-            'wtem/wtem.js',
-            'wtem/json2.js'
-        ),
-        'output_filename': 'compressed/wtem.js'
-    },
-}
-
-PIPELINE_COMPILERS = (
-  'pipeline.compilers.sass.SASSCompiler',
-)
diff --git a/edumed/static/css/_mixins.scss b/edumed/static/css/_mixins.scss
deleted file mode 100644 (file)
index 6b9499c..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-@import "vars";
-
-@mixin base-font {
-    font-family: Dosis;
-    background: white;
-    color: $ciemny;
-}
\ No newline at end of file
diff --git a/edumed/static/css/_vars.scss b/edumed/static/css/_vars.scss
deleted file mode 100644 (file)
index a502ca4..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-$px: .0625em;
-$oranji: #ed7831;
-$ciemny: #363a3e;
-$zielony: #16a487;
\ No newline at end of file
diff --git a/edumed/static/css/base.css b/edumed/static/css/base.css
deleted file mode 100644 (file)
index 5ab583d..0000000
+++ /dev/null
@@ -1,250 +0,0 @@
-@charset "UTF-8";
-@import url(//fonts.googleapis.com/css?family=Dosis:400,700&subset=latin,latin-ext);
-a {
-  text-decoration: none;
-  color: #ed7831; }
-  a img {
-    border: 0;
-    padding: 0; }
-
-body {
-  font-family: Dosis;
-  background: white;
-  color: #363a3e;
-  margin: 0; }
-
-.clr {
-  clear: both; }
-
-#banners {
-  margin: 0 auto;
-  width: 58.75em; }
-  #banners > a {
-    display: block;
-    width: 100%; }
-  #banners img {
-    display: block;
-    margin: 0 auto;
-    width: 100%; }
-
-#header-wrapper {
-  background-image: url(../img/header-bar.png);
-  background-repeat: repeat-x;
-  background-position: 0 100%; }
-
-header.main {
-  margin: 0 auto 1.4375em;
-  width: 58.75em;
-  padding: 1.8125em 0.625em 0; }
-  header.main #logo {
-    float: left;
-    margin-bottom: 1.25em; }
-    header.main #logo img {
-      vertical-align: middle; }
-  header.main #organizer {
-    float: right;
-    font-size: .75em;
-    color: #777; }
-    header.main #organizer img {
-      margin-top: .5em; }
-  header.main nav ul {
-    padding: 0;
-    position: absolute;
-    left: 15em; }
-  header.main nav li {
-    list-style: none;
-    display: inline-block;
-    text-transform: uppercase;
-    margin: 0 .5em;
-    text-align: center;
-    /*position:relative;*/ }
-  header.main nav a {
-    color: #363a3e;
-    display: block;
-    vertical-align: bottom;
-    font-size: .85em; }
-  header.main nav a:hover {
-    color: #ed7831; }
-  header.main nav a:before {
-    content: " ";
-    display: block;
-    margin-bottom: .8em;
-    width: 2.75em;
-    height: 2.125em;
-    text-align: center;
-    margin: auto;
-    margin-bottom: .8em; }
-  header.main nav .menu-lekcje:before {
-    background: url(../img/menu/lekcje.png) no-repeat 0 0;
-    background-size: 100%; }
-  header.main nav .menu-kompetencje:before {
-    background: url(../img/menu/kompetencje.png) no-repeat 0 0;
-    background-size: 100%; }
-  header.main nav .menu-olimpiada:before {
-    background: url(../img/menu/olimpiada.png) no-repeat 0 0;
-    background-size: 100%; }
-  header.main nav .menu-trener:before {
-    background: url(../img/menu/dla-trenera.png) no-repeat 0 0;
-    background-size: 100%; }
-  header.main nav .menu-kurs:before {
-    background: url(../img/menu/dla-ucznia.png) no-repeat 0 0;
-    background-size: 100%; }
-  header.main nav .menu-o-nas:before {
-    background: url(../img/menu/o-nas.png) no-repeat 0 0;
-    background-size: 100%; }
-  header.main nav .menu-lekcje:hover:before {
-    background: url(../img/menu/lekcje_active.png) no-repeat 0 0;
-    background-size: 100%; }
-  header.main nav .menu-kompetencje:hover:before {
-    background: url(../img/menu/kompetencje_active.png) no-repeat 0 0;
-    background-size: 100%; }
-  header.main nav .menu-olimpiada:hover:before {
-    background: url(../img/menu/olimpiada_active.png) no-repeat 0 0;
-    background-size: 100%; }
-  header.main nav .menu-trener:hover:before {
-    background: url(../img/menu/dla-trenera_active.png) no-repeat 0 0;
-    background-size: 100%; }
-  header.main nav .menu-kurs:hover:before {
-    background: url(../img/menu/dla-ucznia_active.png) no-repeat 0 0;
-    background-size: 100%; }
-  header.main nav .menu-o-nas:hover:before {
-    background: url(../img/menu/o-nas_active.png) no-repeat 0 0;
-    background-size: 100%; }
-  header.main nav .menu-oc-program:before {
-    background: url(../img/menu/olimpiada/program.png) no-repeat 0 0;
-    background-size: 100%; }
-  header.main nav .menu-oc-harmonogram:before {
-    background: url(../img/menu/olimpiada/harmonogram.png) no-repeat 0 0;
-    background-size: 100%; }
-  header.main nav .menu-oc-regulamin:before {
-    background: url(../img/menu/olimpiada/regulamin.png) no-repeat 0 0;
-    background-size: 100%; }
-  header.main nav .menu-oc-literatura:before {
-    background: url(../img/menu/olimpiada/literatura.png) no-repeat 0 0;
-    background-size: 100%; }
-  header.main nav .menu-oc-komitet:before {
-    background: url(../img/menu/olimpiada/komitet.png) no-repeat 0 0;
-    background-size: 100%; }
-  header.main nav .menu-oc-kontakt:before {
-    background: url(../img/menu/olimpiada/kontakt.png) no-repeat 0 0;
-    background-size: 100%; }
-  header.main nav .menu-oc-program:hover:before {
-    background: url(../img/menu/olimpiada/program_active.png) no-repeat 0 0;
-    background-size: 100%; }
-  header.main nav .menu-oc-harmonogram:hover:before {
-    background: url(../img/menu/olimpiada/harmonogram_active.png) no-repeat 0 0;
-    background-size: 100%; }
-  header.main nav .menu-oc-regulamin:hover:before {
-    background: url(../img/menu/olimpiada/regulamin_active.png) no-repeat 0 0;
-    background-size: 100%; }
-  header.main nav .menu-oc-literatura:hover:before {
-    background: url(../img/menu/olimpiada/literatura_active.png) no-repeat 0 0;
-    background-size: 100%; }
-  header.main nav .menu-oc-komitet:hover:before {
-    background: url(../img/menu/olimpiada/komitet_active.png) no-repeat 0 0;
-    background-size: 100%; }
-  header.main nav .menu-oc-kontakt:hover:before {
-    background: url(../img/menu/olimpiada/kontakt_active.png) no-repeat 0 0;
-    background-size: 100%; }
-  header.main #tagline {
-    clear: both;
-    float: left;
-    background-color: white;
-    /* Extend padded background .*/
-    padding: 0 0.625em;
-    margin-left: -0.625em;
-    font-size: .9em;
-    color: #363a3e; }
-  header.main #search {
-    float: right;
-    background-color: white;
-    /* Extend padded background .*/
-    padding: 2px 0.625em 0;
-    margin-right: -0.625em; }
-
-#content {
-  width: 58.75em;
-  padding: 0 0.625em;
-  margin: auto;
-  position: relative; }
-
-footer.main {
-  clear: both;
-  border-top: 1px solid #c9ccce;
-  width: 58.75em;
-  padding: 0.2em 0.625em;
-  margin: 2.5em auto 1em auto;
-  color: #9a9c9e; }
-  footer.main p {
-    font-size: .75em; }
-  footer.main .footer-item {
-    float: left;
-    margin-right: 1.25em;
-    width: 13.75em; }
-  footer.main .sponsors-column {
-    float: left;
-    margin-left: 1.25em;
-    width: 6.25em; }
-    footer.main .sponsors-column p {
-      font-size: .75em; }
-  footer.main .footer-extra p {
-    margin-top: 0; }
-
-#search {
-  font-size: .8em; }
-  #search input, #search button {
-    font-family: Dosis;
-    font-size: .9em;
-    vertical-align: bottom;
-    border: 1px solid #c9ccce;
-    padding: 0;
-    margin: 0;
-    line-height: .9em; }
-  #search input {
-    border-right-width: 0;
-    height: 16px;
-    width: 16em;
-    padding-left: 1.3em; }
-  #search button {
-    height: 18px;
-    width: 1.8em; }
-    #search button span {
-      position: relative;
-      top: -1px; }
-  #search input::-webkit-input-placeholder {
-    text-transform: uppercase; }
-  #search input:-moz-placeholder {
-    text-transform: uppercase; }
-  #search input::-moz-placeholder {
-    text-transform: uppercase; }
-  #search input::-ms-placeholder {
-    text-transform: uppercase; }
-
-.link-list {
-  list-style: none;
-  padding: 0; }
-  .link-list li {
-    margin-bottom: .5em; }
-  .link-list a:before {
-    content: "→";
-    margin-right: .5em; }
-  .link-list a {
-    color: #363a3e; }
-  .link-list a:hover {
-    color: #ed7831; }
-
-.link-list-colored a {
-  color: #ed7831; }
-
-.plain {
-  margin: 0;
-  padding: 0;
-  list-style: none; }
-  .plain li {
-    margin: 1em 0; }
-
-.flatpage img {
-  border: 0.3125em solid #eee;
-  margin: 1.3em; }
-
-/*# sourceMappingURL=base.css.map */
diff --git a/edumed/static/css/base.scss b/edumed/static/css/base.scss
deleted file mode 100644 (file)
index b87a3e8..0000000
+++ /dev/null
@@ -1,280 +0,0 @@
-@import url(//fonts.googleapis.com/css?family=Dosis:400,700&subset=latin,latin-ext);
-
-@import "vars";
-@import "mixins";
-
-
-a {
-    text-decoration: none;
-    color: $oranji;
-    img {
-        border: 0;
-        padding: 0;
-    }
-}
-
-body {
-    @include base-font;
-    margin: 0;
-}
-.clr {
-    clear: both;
-}
-
-#banners {
-    margin: 0 auto;
-    width: 58.75em;
-
-    > a {
-        display: block;
-        width: 100%;
-    }
-
-    img {
-        display: block;
-        margin: 0 auto;
-        width: 100%;
-    }
-}
-#header-wrapper {
-    background-image: url(../img/header-bar.png);
-    background-repeat: repeat-x;
-    background-position: 0 100%;
-}
-header.main {
-    margin: 0 auto 23*$px;
-    width: 940*$px;
-    padding: 29*$px 10*$px 0;
-
-    #header-top {
-    }
-
-    #logo {
-        float: left;
-        margin-bottom: 20*$px;
-        img {
-            vertical-align: middle;
-        }
-    }
-    #organizer {
-        float: right;
-        font-size: .75em;
-        color: #777;
-        
-        img {
-            margin-top: .5em;
-        }
-    }
-
-
-
-    nav {
-        ul {
-            padding: 0;
-            position: absolute;
-            left: 15em;
-        }
-        li {
-            list-style: none;
-            display: inline-block;
-            text-transform: uppercase;
-            margin: 0 .5em;
-            text-align: center;
-            /*position:relative;*/
-        }
-        a {
-            color: $ciemny;
-            display: block;
-            vertical-align: bottom;
-            font-size: .85em;
-        }
-        a:hover {
-            color: $oranji;
-        }
-
-        a:before {
-            content: " ";
-            display: block;
-            margin-bottom: .8em;
-            width: 44*$px;
-            height: 34*$px;
-            text-align:center;
-            margin: auto;
-            margin-bottom: .8em;
-        }
-        .menu-lekcje:before { background: url(../img/menu/lekcje.png) no-repeat 0 0; background-size: 100%;}
-        .menu-kompetencje:before { background: url(../img/menu/kompetencje.png) no-repeat 0 0; background-size: 100%;}
-        .menu-olimpiada:before { background: url(../img/menu/olimpiada.png) no-repeat 0 0; background-size: 100%;}
-        .menu-trener:before { background: url(../img/menu/dla-trenera.png) no-repeat 0 0; background-size: 100%;}
-        .menu-kurs:before { background: url(../img/menu/dla-ucznia.png) no-repeat 0 0; background-size: 100%;}
-        .menu-o-nas:before { background: url(../img/menu/o-nas.png) no-repeat 0 0; background-size: 100%;}
-
-        .menu-lekcje:hover:before { background: url(../img/menu/lekcje_active.png) no-repeat 0 0; background-size: 100%;}
-        .menu-kompetencje:hover:before { background: url(../img/menu/kompetencje_active.png) no-repeat 0 0; background-size: 100%;}
-        .menu-olimpiada:hover:before { background: url(../img/menu/olimpiada_active.png) no-repeat 0 0; background-size: 100%;}
-        .menu-trener:hover:before { background: url(../img/menu/dla-trenera_active.png) no-repeat 0 0; background-size: 100%;}
-        .menu-kurs:hover:before { background: url(../img/menu/dla-ucznia_active.png) no-repeat 0 0; background-size: 100%;}
-        .menu-o-nas:hover:before { background: url(../img/menu/o-nas_active.png) no-repeat 0 0; background-size: 100%;}
-
-        .menu-oc-program:before { background: url(../img/menu/olimpiada/program.png) no-repeat 0 0; background-size: 100%;}
-        .menu-oc-harmonogram:before { background: url(../img/menu/olimpiada/harmonogram.png) no-repeat 0 0; background-size: 100%;}
-        .menu-oc-regulamin:before { background: url(../img/menu/olimpiada/regulamin.png) no-repeat 0 0; background-size: 100%;}
-        .menu-oc-literatura:before { background: url(../img/menu/olimpiada/literatura.png) no-repeat 0 0; background-size: 100%;}
-        .menu-oc-komitet:before { background: url(../img/menu/olimpiada/komitet.png) no-repeat 0 0; background-size: 100%;}
-        .menu-oc-kontakt:before { background: url(../img/menu/olimpiada/kontakt.png) no-repeat 0 0; background-size: 100%;}
-        .menu-oc-program:hover:before {
-            background: url(../img/menu/olimpiada/program_active.png) no-repeat 0 0; background-size: 100%;}
-        .menu-oc-harmonogram:hover:before {
-            background: url(../img/menu/olimpiada/harmonogram_active.png) no-repeat 0 0; background-size: 100%;}
-        .menu-oc-regulamin:hover:before {
-            background: url(../img/menu/olimpiada/regulamin_active.png) no-repeat 0 0; background-size: 100%;}
-        .menu-oc-literatura:hover:before {
-            background: url(../img/menu/olimpiada/literatura_active.png) no-repeat 0 0; background-size: 100%;}
-        .menu-oc-komitet:hover:before {
-            background: url(../img/menu/olimpiada/komitet_active.png) no-repeat 0 0; background-size: 100%;}
-        .menu-oc-kontakt:hover:before {
-            background: url(../img/menu/olimpiada/kontakt_active.png) no-repeat 0 0; background-size: 100%;}
-    }
-
-    #tagline {
-        clear: both;
-        float: left;
-        background-color: white;
-        /* Extend padded background .*/
-        padding: 0 10*$px;
-        margin-left: -10*$px;
-        font-size: .9em;
-        color: $ciemny;
-    }
-    #search {
-        float: right;
-        background-color: white;
-        /* Extend padded background .*/
-        padding: 2px 10*$px 0;
-        margin-right: -10*$px;
-    }
-}
-
-
-#content {
-    width: 940 * $px;
-    padding: 0 10 * $px;
-    margin: auto;
-    position: relative;
-}
-
-
-footer.main {
-    clear: both;
-    border-top: 1px solid #c9ccce;
-    width: 940 * $px;
-    padding: .2em 10 * $px;
-    margin: 40*$px auto 1em auto;
-    color: #9a9c9e;
-
-    p {
-        font-size: .75em;
-    }
-    .footer-item {
-        float: left;
-        margin-right: 20 * $px;
-        width: 220 * $px;
-    }
-    .sponsors-column {
-        float: left;
-        margin-left: 20 * $px;
-        width: 100 * $px;
-        p {
-            font-size: .75em;
-        }
-    }
-    .footer-extra p {
-        margin-top: 0;
-    }
-}
-
-
-#search {
-    font-size: .8em;
-
-    input, button {
-        font-family: Dosis;
-        font-size: .9em;
-        vertical-align:bottom;
-        border: 1px solid #c9ccce;
-        padding: 0;
-        margin: 0;
-        line-height: .9em;
-    }
-    input {
-        border-right-width: 0;
-        height: 16px;
-        width: 16em;
-        padding-left: 1.3em;
-    }
-    button {
-        height: 18px;
-        width: 1.8em;
-        span {
-            position:relative;
-            top: -1px;
-        }
-    }
-
-    input::-webkit-input-placeholder {
-        text-transform: uppercase;
-    }
-    input:-moz-placeholder {
-        text-transform: uppercase;
-    }
-    input::-moz-placeholder {
-        text-transform: uppercase;
-    }
-    input::-ms-placeholder {
-        text-transform: uppercase;
-    }
-
-}
-
-
-.link-list {
-    list-style: none;
-    padding: 0;
-
-    li {
-        margin-bottom: .5em;
-    }
-
-    a:before {
-        content: "→";
-        margin-right: .5em;
-    }
-    a {
-        color: $ciemny;
-    }
-    a:hover {
-        color: $oranji;
-    }
-}
-.link-list-colored {
-    a {
-        color: $oranji;
-    }
-}
-
-
-.plain {
-    margin: 0;
-    padding: 0;
-    list-style: none;
-    li {
-        margin: 1em 0;
-    }
-}
-
-.flatpage {
-    img {
-        border: 5*$px solid #eee;
-        margin: 1.3em;
-    }
-}
diff --git a/edumed/static/css/form.css b/edumed/static/css/form.css
deleted file mode 100644 (file)
index 5699dd6..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-.submit-form th, .submit-form td {
-  padding: .3em;
-  vertical-align: top;
-  text-align: left; }
-.submit-form ul {
-  padding: 0;
-  list-style: none;
-  margin: 0; }
-.submit-form th {
-  min-width: 4em;
-  max-width: 16em;
-  font-weight: normal; }
-.submit-form .required th label:before, .submit-form .required > label:before {
-  content: "* ";
-  color: red; }
-.submit-form p.required {
-  font-weight: bold; }
-.submit-form .errorlist {
-  padding: 0 0 0 1em;
-  margin: 0;
-  color: red; }
-.submit-form .form-footer {
-  font-size: smaller; }
-
-/*# sourceMappingURL=form.css.map */
diff --git a/edumed/static/css/form.scss b/edumed/static/css/form.scss
deleted file mode 100755 (executable)
index 90ad634..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-.submit-form {
-    th, td {
-        padding: .3em;
-        vertical-align: top;
-        text-align: left;
-    }
-    ul {
-        padding: 0;
-        list-style: none;
-        margin: 0;
-    }
-    th {
-        min-width: 4em;
-        max-width: 16em;
-        font-weight: normal;
-    }
-    .required th label:before, .required>label:before {
-        content: "* ";
-        color: red;
-    }
-    p.required {
-        font-weight: bold;
-    }
-    .errorlist {
-        padding: 0 0 0 1em;
-        margin: 0;
-        color: red;
-    }
-    .form-footer {
-        font-size: smaller;
-    }
-}
diff --git a/edumed/static/css/forum.css b/edumed/static/css/forum.css
deleted file mode 100644 (file)
index 1c0b056..0000000
+++ /dev/null
@@ -1,89 +0,0 @@
-ul.breadcrumb {
-  margin: 0;
-  padding: 0;
-  list-style: none; }
-  ul.breadcrumb li {
-    display: inline; }
-
-.forum-body {
-  position: relative;
-  /* --- Unread --- */
-  /* --- Moderation --- */
-  /* --- Mini pagination --- */ }
-  .forum-body .search-result em {
-    background-color: yellow; }
-  .forum-body .pagination ul {
-    margin: 0;
-    padding: 0;
-    list-style: none; }
-    .forum-body .pagination ul li {
-      display: inline-block; }
-      .forum-body .pagination ul li a {
-        display: block;
-        padding: .5em; }
-    .forum-body .pagination ul .disabled a {
-      color: black; }
-  .forum-body .table {
-    width: 100%;
-    margin: 1em 0; }
-  .forum-body .forum-description {
-    margin: 5px; }
-  .forum-body .forum-row, .forum-body .topic-row {
-    width: 100%; }
-  .forum-body .forum-name, .forum-body .topic-name {
-    width: 40%;
-    text-align: left; }
-  .forum-body .forum-topic-count, .forum-body .forum-post-count, .forum-body .topic-post-count, .forum-body .topic-view-count {
-    width: 10%;
-    text-align: center; }
-  .forum-body .forum-last-post, .forum-body .topic-last-post {
-    width: 32%;
-    text-align: center; }
-  .forum-body .first-unread-post-link, .forum-body .first-unread-post-link:hover {
-    text-decoration: none; }
-  .forum-body .post:nth-child(4n+4) {
-    background-color: #eaeaea; }
-  .forum-body .post-header {
-    padding: 3px 0 3px 20px; }
-    .forum-body .post-header th {
-      text-align: left; }
-  .forum-body .post-info {
-    width: 200px;
-    padding: 10px; }
-    .forum-body .post-info .post-author {
-      padding: 5px 0; }
-  .forum-body .post-content {
-    vertical-align: top;
-    padding: 10px; }
-  .forum-body .post-signature {
-    color: #CCC;
-    margin-top: 15px;
-    border-top: 1px dotted #cccccc;
-    display: block; }
-  .forum-body .post-related {
-    margin-top: 20px; }
-  .forum-body .forum-headline {
-    margin-top: 10px; }
-  .forum-body .attachments-form {
-    padding-bottom: 15px; }
-  .forum-body .attachment-link {
-    border-bottom: 1px dotted; }
-  .forum-body .state-indicator {
-    display: block;
-    float: left;
-    height: 10px;
-    width: 10px;
-    margin: 3px 5px; }
-  .forum-body .topic-unread a, .forum-body .forum-unread a {
-    font-weight: bold; }
-  .forum-body .on-moderation {
-    background: #ffcccc; }
-  .forum-body .mini-pagination {
-    padding: 3px 0 3px 10px; }
-  .forum-body .post-form input, .forum-body .post-form textarea {
-    font-family: Dosis;
-    background: white;
-    color: #363a3e;
-    font-size: 1.6em; }
-  .forum-body .post-form #id_name {
-    width: 698px; }
diff --git a/edumed/static/css/forum.scss b/edumed/static/css/forum.scss
deleted file mode 100755 (executable)
index e1a3d58..0000000
+++ /dev/null
@@ -1,180 +0,0 @@
-@import "mixins";
-
-
-ul.breadcrumb {
-    margin: 0;
-    padding: 0;
-    list-style: none;
-    li {
-        display: inline;
-    }
-}
-
-
-
-.forum-body {
-
-    position: relative;
-
-    .search-result {
-        em {
-            background-color: yellow;
-        }
-    }
-
-    .pagination {
-        ul {
-            margin: 0;
-            padding: 0;
-            list-style: none;
-
-            li {
-                display: inline-block;
-                a {
-                    display: block;
-                    padding: .5em;
-                }
-            }
-
-            .disabled {
-                a {
-                    color: black;
-                }
-            }
-        }
-    }
-
-    .table {
-        width: 100%;
-        margin: 1em 0;
-    }
-
-    .forum-description {
-        margin: 5px;
-    }
-
-    .forum-row, .topic-row {
-        width: 100%;
-    }
-
-    .forum-name, .topic-name {
-        width: 40%;
-        text-align: left;
-    }
-
-    .forum-topic-count, .forum-post-count, .topic-post-count, .topic-view-count {
-        width: 10%;
-        text-align: center;
-    }
-
-    .forum-last-post, .topic-last-post {
-        width: 32%;
-        text-align: center;
-    }
-
-    .first-unread-post-link, .first-unread-post-link:hover {
-        text-decoration: none;
-    }
-
-
-
-    .post:nth-child(4n+4) {
-        background-color: lighten(#D0D0D0 , 10%);
-    }
-
-    .post-header {
-       padding: 3px 0 3px 20px;
-       th {
-            text-align: left;
-       }
-    }
-
-    .post-info {
-        width: 200px;
-        padding: 10px;
-
-        .avatar {
-
-        }
-
-        .post-author {
-            padding: 5px 0;
-        }
-
-        .post-extra-info {
-        }
-
-        .post-controls {
-        }
-    }
-
-    .post-content {
-        vertical-align: top;
-        padding: 10px;
-    }
-
-    .post-signature {
-        color: #CCC;
-        margin-top: 15px;
-        border-top: 1px dotted #CCC;
-        display: block;
-    }
-
-    .post-related {
-        margin-top: 20px;
-    }
-
-
-
-
-    .forum-headline {
-        margin-top: 10px;
-    }
-
-    .attachments-form {
-        padding-bottom: 15px;
-    }
-
-    .attachment-link {
-        border-bottom: 1px dotted;
-    }
-
-    /* --- Unread --- */
-
-    .state-indicator {
-        display: block;
-        float: left;
-        height: 10px;
-        width: 10px;
-        margin: 3px 5px;
-    }
-
-    .topic-unread, .forum-unread {
-        a {
-            font-weight: bold;
-        }
-        .state-indicator {
-        }
-    }
-
-    /* --- Moderation --- */
-    .on-moderation {
-        background: #ffcccc;
-    }
-
-    /* --- Mini pagination --- */
-    .mini-pagination {
-        padding: 3px 0 3px 10px;
-    }
-
-
-    .post-form {
-        input, textarea {
-            @include base-font;
-            font-size: 1.6em;
-        }
-        #id_name {
-            width: 698px;
-        }
-    }
-}
diff --git a/edumed/static/css/main.css b/edumed/static/css/main.css
deleted file mode 100644 (file)
index 98dadef..0000000
+++ /dev/null
@@ -1,168 +0,0 @@
-#main-promobox {
-  float: right;
-  width: 12.5em;
-  height: 11.6875em; }
-  #main-promobox a {
-    background: #16a487;
-    padding: 1em 0.625em;
-    border-radius: 0.9375em;
-    display: block;
-    margin-bottom: 1em;
-    width: 11.25em;
-    float: left; }
-    #main-promobox a:last-of-type {
-      margin-bottom: 0; }
-  #main-promobox h1 {
-    background: #16a487;
-    padding: 1em 0.625em;
-    border-radius: 0.9375em;
-    color: white;
-    margin: 0;
-    text-transform: uppercase;
-    font-size: .9em;
-    width: 12.625em;
-    float: left;
-    padding-top: 1.25em;
-    padding-bottom: 1.25em;
-    border-bottom-right-radius: 0;
-    border-bottom-left-radius: 0; }
-  #main-promobox h1:before {
-    content: url(/static/img/icons/announce_white.png);
-    margin-right: 1.2em;
-    vertical-align: top; }
-  #main-promobox h2 {
-    color: white;
-    font-size: .9em;
-    /*margin: 1.1em 0 0 0;*/
-    margin: 0;
-    font-weight: normal;
-    text-transform: uppercase; }
-  #main-promobox p {
-    color: #363a3e;
-    font-size: .8em;
-    line-height: 1.15em;
-    margin: .3em 0; }
-
-#main-sections {
-  clear: both;
-  float: left;
-  margin-top: 1.2em;
-  width: 43.75em; }
-  #main-sections h1 {
-    font-size: .9em;
-    margin: 0 0 0 1.25em;
-    text-transform: uppercase; }
-  #main-sections ul {
-    margin: -0.1875em 0 0 -1.25em;
-    padding: 0;
-    list-style: none; }
-    #main-sections ul li {
-      margin-top: 1.25em;
-      margin-left: 1.25em;
-      float: left;
-      height: 5.625em;
-      border-radius: 0.9375em; }
-      #main-sections ul li a {
-        color: white;
-        text-transform: uppercase;
-        height: 5em;
-        display: table;
-        padding: 5px; }
-        #main-sections ul li a .in-box {
-          font-size: .9em;
-          height: 100%;
-          width: 100%;
-          display: table-cell;
-          vertical-align: middle;
-          border: 1px solid transparent;
-          border-radius: 0.625em;
-          padding: 0 1em; }
-          #main-sections ul li a .in-box .name {
-            display: block;
-            font-size: 1.5em;
-            line-height: 1em;
-            margin-bottom: .2em; }
-      #main-sections ul li a:hover .in-box {
-        border: 1px solid white; }
-    #main-sections ul .box1 {
-      background-color: #adaeaf; }
-    #main-sections ul .box2 {
-      background-color: #f8b323; }
-    #main-sections ul .box3 {
-      background-color: #16a487; }
-    #main-sections ul .box4 {
-      background-color: #5e6165; }
-    #main-sections ul .box5 {
-      background-color: #f8b323; }
-    #main-sections ul .box6 {
-      background-color: #363a3e; }
-    #main-sections ul .box7 {
-      background-color: #adaeaf; }
-    #main-sections ul .box8 {
-      background-color: #ed7831; }
-
-#main-howto {
-  float: right;
-  margin-top: 1.2em;
-  width: 13.75em; }
-  #main-howto h1 {
-    font-size: .9em;
-    margin: 0 0 0 1.4em;
-    text-transform: uppercase; }
-  #main-howto ul {
-    margin: 1.0625em 0 1.0625em 1.4em; }
-    #main-howto ul li {
-      font-size: .9em;
-      text-transform: uppercase;
-      line-height: 1.25em; }
-    #main-howto ul a:before {
-      height: 1.25em; }
-    #main-howto ul .knowledge:before {
-      content: url(/static/img/icons/knowledge_dark.png); }
-    #main-howto ul .activity:before {
-      content: url(/static/img/icons/activity_dark.png); }
-    #main-howto ul .lesson-plan:before {
-      content: url(/static/img/icons/lesson-plan_dark.png); }
-    #main-howto ul .reference:before {
-      content: url(/static/img/icons/reference_dark.png); }
-    #main-howto ul .knowledge:hover:before {
-      content: url(/static/img/icons/knowledge_orange.png); }
-    #main-howto ul .activity:hover:before {
-      content: url(/static/img/icons/activity_orange.png); }
-    #main-howto ul .lesson-plan:hover:before {
-      content: url(/static/img/icons/lesson-plan_orange.png); }
-    #main-howto ul .reference:hover:before {
-      content: url(/static/img/icons/reference_orange.png); }
-  #main-howto p {
-    margin: 0 0 1.875em 1.4em; }
-  #main-howto .side-banner img {
-    display: block;
-    width: 100%;
-    margin-bottom: 0.2em; }
-
-#main-chosen {
-  clear: left;
-  float: left;
-  margin-top: 2em; }
-  #main-chosen h1 {
-    font-size: .9em;
-    margin: 0 0 1em 1.25em;
-    text-transform: uppercase; }
-  #main-chosen .levelth {
-    margin-left: 1.25em; }
-
-#main-tools {
-  clear: both; }
-  #main-tools .main-tools-box {
-    float: left;
-    margin-top: 1.5em;
-    margin-right: 1.25em;
-    width: 17.5em; }
-    #main-tools .main-tools-box h1 {
-      margin: 0;
-      font-size: .9em;
-      text-transform: uppercase; }
-    #main-tools .main-tools-box ul, #main-tools .main-tools-box ol {
-      margin: 1.1em 0 0 0;
-      font-size: .9em;
-      line-height: 1.15em; }
diff --git a/edumed/static/css/main.scss b/edumed/static/css/main.scss
deleted file mode 100755 (executable)
index 8d21b1d..0000000
+++ /dev/null
@@ -1,241 +0,0 @@
-$px: .0625em;
-
-$horiz_padding: 10*$px;
-$width_offset: 20*$px;
-
-@mixin main-promobox-shape() {
-  background: #16a487;
-  padding: 1em $horiz_padding;
-  border-radius: 15*$px;
-}
-
-#main-promobox {
-  float: right;
-
-  width: 220*$px - $width_offset;
-  height: 235*$px - 2 * 1.5em;
-
-  a {
-    @include main-promobox-shape();
-
-    display: block;
-    margin-bottom: 1em;
-    width: 220*$px - $width_offset - 2*$horiz_padding;
-    float: left;
-
-    &:last-of-type {
-      margin-bottom: 0;
-    }
-  }
-  h1 {
-    @include main-promobox-shape();
-
-    color: white;
-    margin: 0;
-    text-transform: uppercase;
-    font-size: .9em;
-    width: 222*$px - 2 * $horiz_padding;
-    float: left;
-    padding-top: 1.25em;
-    padding-bottom: 1.25em;
-    border-bottom-right-radius: 0;
-    border-bottom-left-radius: 0;
-  }
-  h1:before {
-    content: url(/static/img/icons/announce_white.png);
-    margin-right: 1.2em;
-    vertical-align: top;
-  }
-  h2 {
-    color: white;
-    font-size: .9em;
-    /*margin: 1.1em 0 0 0;*/
-    margin: 0;
-    font-weight: normal;
-    text-transform: uppercase;
-  }
-  p {
-    color: #363a3e;
-    font-size: .8em;
-    line-height: 1.15em;
-    margin: .3em 0;
-  }
-}
-
-#main-sections {
-  clear: both;
-  float: left;
-  margin-top: 1.2em;
-  width: 700*$px;
-
-  h1 {
-    font-size: .9em;
-    margin: 0 0 0 20*$px;
-    text-transform: uppercase;
-  }
-
-  ul {
-    margin: -3*$px 0 0 -20*$px;
-    padding: 0;
-    list-style: none;
-
-    li {
-      margin-top: 20*$px;
-      margin-left: 20*$px;
-      float: left;
-      height: 90*$px;
-      border-radius: 15*$px;
-
-      a {
-        color: white;
-        text-transform: uppercase;
-        height: 80*$px;
-        display: table;
-        padding: 5px;
-
-        .in-box {
-          font-size: .9em;
-          height: 100%;
-          width: 100%;
-          display: table-cell;
-          vertical-align: middle;
-          border: 1px solid transparent;
-          border-radius: 10*$px;
-          padding: 0 16*$px;
-
-          .name {
-            display: block;
-            font-size: 1.5em;
-            line-height: 1em;
-            margin-bottom: .2em;
-          }
-        }
-      }
-      a:hover .in-box {
-        border: 1px solid white;
-      }
-    }
-    .box1 {
-      background-color: #adaeaf;
-    }
-    .box2 {
-      background-color: #f8b323;
-    }
-    .box3 {
-      background-color: #16a487;
-    }
-    .box4 {
-      background-color: #5e6165;
-    }
-    // .box5 {background-color: #16a487;}
-    .box5 {
-      background-color: #f8b323;
-    }
-    .box6 {
-      background-color: #363a3e;
-    }
-    .box7 {
-      background-color: #adaeaf;
-    }
-    .box8 {
-      background-color: #ed7831;
-    }
-  }
-}
-
-#main-howto {
-  float: right;
-  margin-top: 1.2em;
-  width: 220*$px;
-
-  h1 {
-    font-size: .9em;
-    margin: 0 0 0 1.4em;
-    text-transform: uppercase;
-  }
-
-  ul {
-    margin: 17*$px 0 17*$px 1.4em;
-
-    li {
-      font-size: .9em;
-      text-transform: uppercase;
-      line-height: 1.25em;
-    }
-    a:before {
-      height: 20*$px;
-    }
-
-    .knowledge:before {
-      content: url(/static/img/icons/knowledge_dark.png);
-    }
-    .activity:before {
-      content: url(/static/img/icons/activity_dark.png);
-    }
-    .lesson-plan:before {
-      content: url(/static/img/icons/lesson-plan_dark.png);
-    }
-    .reference:before {
-      content: url(/static/img/icons/reference_dark.png);
-    }
-    .knowledge:hover:before {
-      content: url(/static/img/icons/knowledge_orange.png);
-    }
-    .activity:hover:before {
-      content: url(/static/img/icons/activity_orange.png);
-    }
-    .lesson-plan:hover:before {
-      content: url(/static/img/icons/lesson-plan_orange.png);
-    }
-    .reference:hover:before {
-      content: url(/static/img/icons/reference_orange.png);
-    }
-
-  }
-  p {
-    margin: 0 0 30*$px 1.4em;
-  }
-  .side-banner img {
-    display: block;
-    width: 100%;
-    margin-bottom: 0.2em;
-  }
-}
-
-#main-chosen {
-  clear: left;
-  float: left;
-  margin-top: 2em;
-
-  h1 {
-    font-size: .9em;
-    margin: 0 0 1em 20*$px;
-    text-transform: uppercase;
-  }
-
-  .levelth {
-    margin-left: 20*$px;
-  }
-}
-
-#main-tools {
-  clear: both;
-  .main-tools-box {
-    float: left;
-    margin-top: 1.5em;
-    margin-right: 20*$px;
-    width: 280*$px;
-
-    h1 {
-      margin: 0;
-      font-size: .9em;
-      text-transform: uppercase;
-    }
-
-    ul, ol {
-      margin: 1.1em 0 0 0;
-      font-size: .9em;
-      line-height: 1.15em;
-    }
-  }
-}
diff --git a/edumed/static/css/mil.css b/edumed/static/css/mil.css
deleted file mode 100644 (file)
index 3d9bbbe..0000000
+++ /dev/null
@@ -1,47 +0,0 @@
-header.header-mil {
-  background-color: #f47b3b; }
-  header.header-mil #organizer {
-    color: white;
-    float: none;
-    position: absolute;
-    top: 10px;
-    right: 12px; }
-  header.header-mil nav ul {
-    margin-top: 0; }
-    header.header-mil nav ul li {
-      vertical-align: text-bottom; }
-  header.header-mil nav a, header.header-mil nav a:hover {
-    color: white; }
-  header.header-mil nav a:before {
-    content: " ";
-    display: block;
-    margin-bottom: .8em;
-    width: 5.5em;
-    height: 4.25em;
-    text-align: center;
-    margin: auto;
-    margin-bottom: .8em; }
-  header.header-mil nav .menu-consultations:before {
-    background: url(../img/menu/mil/consultations.png) no-repeat 0 0;
-    background-size: 100%; }
-  header.header-mil nav .menu-takepart:before {
-    background: url(../img/menu/mil/takepart.png) no-repeat 0 0;
-    background-size: 100%; }
-  header.header-mil nav .menu-knowledgebase:before {
-    background: url(../img/menu/mil/knowledgebase.png) no-repeat 0 0;
-    background-size: 100%; }
-  header.header-mil nav .menu-kompetencje:before, header.header-mil nav .menu-kontakt:before {
-    width: 3.625em;
-    height: 2.8125em; }
-  header.header-mil nav .menu-kompetencje:before, header.header-mil nav .menu-kompetencje:hover:before {
-    background: url(../img/menu/mil/catalog.png) no-repeat 0 0;
-    background-size: 100%; }
-  header.header-mil nav .menu-kontakt:before, header.header-mil nav .menu-kontakt:hover:before {
-    background: url(../img/menu/mil/contact.png) no-repeat 0 0;
-    background-size: 100%; }
-  header.header-mil nav .lang-switcher-en:before {
-    background: url(../img/menu/mil/lang_en.png) no-repeat 0 0;
-    background-size: 100%; }
-  header.header-mil nav .lang-switcher-pl:before {
-    background: url(../img/menu/mil/lang_pl.png) no-repeat 0 0;
-    background-size: 100%; }
diff --git a/edumed/static/css/mil.scss b/edumed/static/css/mil.scss
deleted file mode 100644 (file)
index be3f0aa..0000000
+++ /dev/null
@@ -1,57 +0,0 @@
-@import "vars";
-
-header.header-mil {
-    
-    background-color: #f47b3b;
-
-    #organizer {
-        color: white;
-        float: none;
-        position: absolute;
-        top: 10px;
-        right:12px;
-    }
-    
-    nav {
-        ul {
-            margin-top: 0;
-            li {
-                vertical-align: text-bottom;
-            }
-        }
-
-        a,a:hover {
-            color: white;
-        }
-
-        a:before {
-            content: " ";
-            display: block;
-            margin-bottom: .8em;
-            width: 88*$px;
-            height: 68*$px;
-            text-align:center;
-            margin: auto;
-            margin-bottom: .8em;
-        }
-
-        .menu-consultations:before { background: url(../img/menu/mil/consultations.png) no-repeat 0 0; background-size: 100%;}
-        .menu-takepart:before { background: url(../img/menu/mil/takepart.png) no-repeat 0 0; background-size: 100%;}
-        .menu-knowledgebase:before { background: url(../img/menu/mil/knowledgebase.png) no-repeat 0 0; background-size: 100%;}
-
-        .menu-kompetencje:before, .menu-kontakt:before {
-            width: 58*$px;
-            height: 45*$px;
-        }
-
-        .menu-kompetencje:before, .menu-kompetencje:hover:before {
-            background: url(../img/menu/mil/catalog.png) no-repeat 0 0; background-size: 100%;
-        }
-        .menu-kontakt:before, .menu-kontakt:hover:before {
-            background: url(../img/menu/mil/contact.png) no-repeat 0 0; background-size: 100%;
-        }
-
-        .lang-switcher-en:before { background: url(../img/menu/mil/lang_en.png) no-repeat 0 0; background-size: 100%;}
-        .lang-switcher-pl:before { background: url(../img/menu/mil/lang_pl.png) no-repeat 0 0; background-size: 100%;}
-    }
-}
\ No newline at end of file
diff --git a/edumed/static/css/promobox.css b/edumed/static/css/promobox.css
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/edumed/static/css/promobox.scss b/edumed/static/css/promobox.scss
deleted file mode 100755 (executable)
index f90b03f..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-/*TODO: delete cause is not used*/
-
-#main-promobox {
-    h1 {
-        color: white;
-        margin: 0;
-      background: red;
-    }
-}
\ No newline at end of file
diff --git a/edumed/static/img/banners/440px_Forum.jpg b/edumed/static/img/banners/440px_Forum.jpg
deleted file mode 100644 (file)
index b847807..0000000
Binary files a/edumed/static/img/banners/440px_Forum.jpg and /dev/null differ
diff --git a/edumed/static/img/banners/440px_Salon-1.jpg b/edumed/static/img/banners/440px_Salon-1.jpg
deleted file mode 100644 (file)
index 47ee486..0000000
Binary files a/edumed/static/img/banners/440px_Salon-1.jpg and /dev/null differ
diff --git a/edumed/static/img/banners/960x150_edukacjaMedialna.jpg b/edumed/static/img/banners/960x150_edukacjaMedialna.jpg
deleted file mode 100644 (file)
index c3a9819..0000000
Binary files a/edumed/static/img/banners/960x150_edukacjaMedialna.jpg and /dev/null differ
diff --git a/edumed/static/img/banners/OC_collegium_web_970x250.jpg b/edumed/static/img/banners/OC_collegium_web_970x250.jpg
deleted file mode 100644 (file)
index c13cb82..0000000
Binary files a/edumed/static/img/banners/OC_collegium_web_970x250.jpg and /dev/null differ
diff --git a/edumed/static/img/banners/oc-banner.png b/edumed/static/img/banners/oc-banner.png
deleted file mode 100644 (file)
index 279f1a5..0000000
Binary files a/edumed/static/img/banners/oc-banner.png and /dev/null differ
diff --git a/edumed/static/img/favicon.png b/edumed/static/img/favicon.png
deleted file mode 100644 (file)
index 61e13ab..0000000
Binary files a/edumed/static/img/favicon.png and /dev/null differ
diff --git a/edumed/static/img/header-bar.png b/edumed/static/img/header-bar.png
deleted file mode 100644 (file)
index 9bef386..0000000
Binary files a/edumed/static/img/header-bar.png and /dev/null differ
diff --git a/edumed/static/img/icons/activity-kind.png b/edumed/static/img/icons/activity-kind.png
deleted file mode 100644 (file)
index d8b7dd7..0000000
Binary files a/edumed/static/img/icons/activity-kind.png and /dev/null differ
diff --git a/edumed/static/img/icons/activity-time.png b/edumed/static/img/icons/activity-time.png
deleted file mode 100644 (file)
index 1de3451..0000000
Binary files a/edumed/static/img/icons/activity-time.png and /dev/null differ
diff --git a/edumed/static/img/icons/activity-tools.png b/edumed/static/img/icons/activity-tools.png
deleted file mode 100644 (file)
index b468872..0000000
Binary files a/edumed/static/img/icons/activity-tools.png and /dev/null differ
diff --git a/edumed/static/img/icons/activity_dark.png b/edumed/static/img/icons/activity_dark.png
deleted file mode 100644 (file)
index a2cbaba..0000000
Binary files a/edumed/static/img/icons/activity_dark.png and /dev/null differ
diff --git a/edumed/static/img/icons/activity_orange.png b/edumed/static/img/icons/activity_orange.png
deleted file mode 100644 (file)
index 2a9f829..0000000
Binary files a/edumed/static/img/icons/activity_orange.png and /dev/null differ
diff --git a/edumed/static/img/icons/activity_white.png b/edumed/static/img/icons/activity_white.png
deleted file mode 100644 (file)
index a8550f0..0000000
Binary files a/edumed/static/img/icons/activity_white.png and /dev/null differ
diff --git a/edumed/static/img/icons/announce_dark.png b/edumed/static/img/icons/announce_dark.png
deleted file mode 100644 (file)
index 485c358..0000000
Binary files a/edumed/static/img/icons/announce_dark.png and /dev/null differ
diff --git a/edumed/static/img/icons/announce_orange.png b/edumed/static/img/icons/announce_orange.png
deleted file mode 100644 (file)
index 1f1eb01..0000000
Binary files a/edumed/static/img/icons/announce_orange.png and /dev/null differ
diff --git a/edumed/static/img/icons/announce_white.png b/edumed/static/img/icons/announce_white.png
deleted file mode 100644 (file)
index 0142525..0000000
Binary files a/edumed/static/img/icons/announce_white.png and /dev/null differ
diff --git a/edumed/static/img/icons/internet_black.png b/edumed/static/img/icons/internet_black.png
deleted file mode 100644 (file)
index 538e60b..0000000
Binary files a/edumed/static/img/icons/internet_black.png and /dev/null differ
diff --git a/edumed/static/img/icons/knowledge_dark.png b/edumed/static/img/icons/knowledge_dark.png
deleted file mode 100644 (file)
index 3cfdd36..0000000
Binary files a/edumed/static/img/icons/knowledge_dark.png and /dev/null differ
diff --git a/edumed/static/img/icons/knowledge_orange.png b/edumed/static/img/icons/knowledge_orange.png
deleted file mode 100644 (file)
index 129689f..0000000
Binary files a/edumed/static/img/icons/knowledge_orange.png and /dev/null differ
diff --git a/edumed/static/img/icons/knowledge_white.png b/edumed/static/img/icons/knowledge_white.png
deleted file mode 100644 (file)
index 62d9b8b..0000000
Binary files a/edumed/static/img/icons/knowledge_white.png and /dev/null differ
diff --git a/edumed/static/img/icons/lesson-plan_dark.png b/edumed/static/img/icons/lesson-plan_dark.png
deleted file mode 100644 (file)
index 07ce96b..0000000
Binary files a/edumed/static/img/icons/lesson-plan_dark.png and /dev/null differ
diff --git a/edumed/static/img/icons/lesson-plan_orange.png b/edumed/static/img/icons/lesson-plan_orange.png
deleted file mode 100644 (file)
index 1402d17..0000000
Binary files a/edumed/static/img/icons/lesson-plan_orange.png and /dev/null differ
diff --git a/edumed/static/img/icons/lesson-plan_white.png b/edumed/static/img/icons/lesson-plan_white.png
deleted file mode 100644 (file)
index 63a516b..0000000
Binary files a/edumed/static/img/icons/lesson-plan_white.png and /dev/null differ
diff --git a/edumed/static/img/icons/nointernet_black.png b/edumed/static/img/icons/nointernet_black.png
deleted file mode 100644 (file)
index 9977783..0000000
Binary files a/edumed/static/img/icons/nointernet_black.png and /dev/null differ
diff --git a/edumed/static/img/icons/reference_dark.png b/edumed/static/img/icons/reference_dark.png
deleted file mode 100644 (file)
index 6df814c..0000000
Binary files a/edumed/static/img/icons/reference_dark.png and /dev/null differ
diff --git a/edumed/static/img/icons/reference_orange.png b/edumed/static/img/icons/reference_orange.png
deleted file mode 100644 (file)
index f087312..0000000
Binary files a/edumed/static/img/icons/reference_orange.png and /dev/null differ
diff --git a/edumed/static/img/icons/reference_white.png b/edumed/static/img/icons/reference_white.png
deleted file mode 100644 (file)
index 6487417..0000000
Binary files a/edumed/static/img/icons/reference_white.png and /dev/null differ
diff --git a/edumed/static/img/icons/time_dark.png b/edumed/static/img/icons/time_dark.png
deleted file mode 100644 (file)
index 157b759..0000000
Binary files a/edumed/static/img/icons/time_dark.png and /dev/null differ
diff --git a/edumed/static/img/icons/time_orange.png b/edumed/static/img/icons/time_orange.png
deleted file mode 100644 (file)
index 80ee73a..0000000
Binary files a/edumed/static/img/icons/time_orange.png and /dev/null differ
diff --git a/edumed/static/img/icons/time_white.png b/edumed/static/img/icons/time_white.png
deleted file mode 100644 (file)
index ab4ec8f..0000000
Binary files a/edumed/static/img/icons/time_white.png and /dev/null differ
diff --git a/edumed/static/img/logo-mil.png b/edumed/static/img/logo-mil.png
deleted file mode 100644 (file)
index 1f1d780..0000000
Binary files a/edumed/static/img/logo-mil.png and /dev/null differ
diff --git a/edumed/static/img/logo-oc.png b/edumed/static/img/logo-oc.png
deleted file mode 100644 (file)
index 23f488f..0000000
Binary files a/edumed/static/img/logo-oc.png and /dev/null differ
diff --git a/edumed/static/img/logo.png b/edumed/static/img/logo.png
deleted file mode 100644 (file)
index eab7eed..0000000
Binary files a/edumed/static/img/logo.png and /dev/null differ
diff --git a/edumed/static/img/logo_fnp.png b/edumed/static/img/logo_fnp.png
deleted file mode 100644 (file)
index 768436a..0000000
Binary files a/edumed/static/img/logo_fnp.png and /dev/null differ
diff --git a/edumed/static/img/logo_fnp_white.png b/edumed/static/img/logo_fnp_white.png
deleted file mode 100644 (file)
index f189ca7..0000000
Binary files a/edumed/static/img/logo_fnp_white.png and /dev/null differ
diff --git a/edumed/static/img/menu/dla-trenera.png b/edumed/static/img/menu/dla-trenera.png
deleted file mode 100644 (file)
index f8923c7..0000000
Binary files a/edumed/static/img/menu/dla-trenera.png and /dev/null differ
diff --git a/edumed/static/img/menu/dla-trenera_active.png b/edumed/static/img/menu/dla-trenera_active.png
deleted file mode 100644 (file)
index 69647a6..0000000
Binary files a/edumed/static/img/menu/dla-trenera_active.png and /dev/null differ
diff --git a/edumed/static/img/menu/dla-ucznia.png b/edumed/static/img/menu/dla-ucznia.png
deleted file mode 100644 (file)
index f0f2bcc..0000000
Binary files a/edumed/static/img/menu/dla-ucznia.png and /dev/null differ
diff --git a/edumed/static/img/menu/dla-ucznia_active.png b/edumed/static/img/menu/dla-ucznia_active.png
deleted file mode 100644 (file)
index 07c2101..0000000
Binary files a/edumed/static/img/menu/dla-ucznia_active.png and /dev/null differ
diff --git a/edumed/static/img/menu/kompetencje.png b/edumed/static/img/menu/kompetencje.png
deleted file mode 100644 (file)
index ffc375e..0000000
Binary files a/edumed/static/img/menu/kompetencje.png and /dev/null differ
diff --git a/edumed/static/img/menu/kompetencje_active.png b/edumed/static/img/menu/kompetencje_active.png
deleted file mode 100644 (file)
index 95385d8..0000000
Binary files a/edumed/static/img/menu/kompetencje_active.png and /dev/null differ
diff --git a/edumed/static/img/menu/lekcje.png b/edumed/static/img/menu/lekcje.png
deleted file mode 100644 (file)
index 8635757..0000000
Binary files a/edumed/static/img/menu/lekcje.png and /dev/null differ
diff --git a/edumed/static/img/menu/lekcje_active.png b/edumed/static/img/menu/lekcje_active.png
deleted file mode 100644 (file)
index e5f9983..0000000
Binary files a/edumed/static/img/menu/lekcje_active.png and /dev/null differ
diff --git a/edumed/static/img/menu/mil/catalog.png b/edumed/static/img/menu/mil/catalog.png
deleted file mode 100644 (file)
index f0cc3c7..0000000
Binary files a/edumed/static/img/menu/mil/catalog.png and /dev/null differ
diff --git a/edumed/static/img/menu/mil/consultations.png b/edumed/static/img/menu/mil/consultations.png
deleted file mode 100644 (file)
index e050b98..0000000
Binary files a/edumed/static/img/menu/mil/consultations.png and /dev/null differ
diff --git a/edumed/static/img/menu/mil/contact.png b/edumed/static/img/menu/mil/contact.png
deleted file mode 100644 (file)
index 7466951..0000000
Binary files a/edumed/static/img/menu/mil/contact.png and /dev/null differ
diff --git a/edumed/static/img/menu/mil/knowledgebase.png b/edumed/static/img/menu/mil/knowledgebase.png
deleted file mode 100644 (file)
index 6bd0372..0000000
Binary files a/edumed/static/img/menu/mil/knowledgebase.png and /dev/null differ
diff --git a/edumed/static/img/menu/mil/lang_en.png b/edumed/static/img/menu/mil/lang_en.png
deleted file mode 100644 (file)
index ed9aa77..0000000
Binary files a/edumed/static/img/menu/mil/lang_en.png and /dev/null differ
diff --git a/edumed/static/img/menu/mil/lang_pl.png b/edumed/static/img/menu/mil/lang_pl.png
deleted file mode 100644 (file)
index 1c48db6..0000000
Binary files a/edumed/static/img/menu/mil/lang_pl.png and /dev/null differ
diff --git a/edumed/static/img/menu/mil/takepart.png b/edumed/static/img/menu/mil/takepart.png
deleted file mode 100644 (file)
index 28a6839..0000000
Binary files a/edumed/static/img/menu/mil/takepart.png and /dev/null differ
diff --git a/edumed/static/img/menu/o-nas.png b/edumed/static/img/menu/o-nas.png
deleted file mode 100644 (file)
index 6815fca..0000000
Binary files a/edumed/static/img/menu/o-nas.png and /dev/null differ
diff --git a/edumed/static/img/menu/o-nas_active.png b/edumed/static/img/menu/o-nas_active.png
deleted file mode 100644 (file)
index 4e8151b..0000000
Binary files a/edumed/static/img/menu/o-nas_active.png and /dev/null differ
diff --git a/edumed/static/img/menu/old/katalog.png b/edumed/static/img/menu/old/katalog.png
deleted file mode 100644 (file)
index 106bdae..0000000
Binary files a/edumed/static/img/menu/old/katalog.png and /dev/null differ
diff --git a/edumed/static/img/menu/old/katalog_active.png b/edumed/static/img/menu/old/katalog_active.png
deleted file mode 100644 (file)
index 5485b5e..0000000
Binary files a/edumed/static/img/menu/old/katalog_active.png and /dev/null differ
diff --git a/edumed/static/img/menu/old/kontakt.png b/edumed/static/img/menu/old/kontakt.png
deleted file mode 100644 (file)
index 291865d..0000000
Binary files a/edumed/static/img/menu/old/kontakt.png and /dev/null differ
diff --git a/edumed/static/img/menu/old/kontakt_active.png b/edumed/static/img/menu/old/kontakt_active.png
deleted file mode 100644 (file)
index 892da3c..0000000
Binary files a/edumed/static/img/menu/old/kontakt_active.png and /dev/null differ
diff --git a/edumed/static/img/menu/old/lekcje.png b/edumed/static/img/menu/old/lekcje.png
deleted file mode 100644 (file)
index 9989280..0000000
Binary files a/edumed/static/img/menu/old/lekcje.png and /dev/null differ
diff --git a/edumed/static/img/menu/old/lekcje_active.png b/edumed/static/img/menu/old/lekcje_active.png
deleted file mode 100644 (file)
index 47ed591..0000000
Binary files a/edumed/static/img/menu/old/lekcje_active.png and /dev/null differ
diff --git a/edumed/static/img/menu/old/o-nas.png b/edumed/static/img/menu/old/o-nas.png
deleted file mode 100644 (file)
index 00dab37..0000000
Binary files a/edumed/static/img/menu/old/o-nas.png and /dev/null differ
diff --git a/edumed/static/img/menu/old/o-nas_active.png b/edumed/static/img/menu/old/o-nas_active.png
deleted file mode 100644 (file)
index 1fc61e9..0000000
Binary files a/edumed/static/img/menu/old/o-nas_active.png and /dev/null differ
diff --git a/edumed/static/img/menu/old/szkolenia.png b/edumed/static/img/menu/old/szkolenia.png
deleted file mode 100644 (file)
index 97f8362..0000000
Binary files a/edumed/static/img/menu/old/szkolenia.png and /dev/null differ
diff --git a/edumed/static/img/menu/old/szkolenia_active.png b/edumed/static/img/menu/old/szkolenia_active.png
deleted file mode 100644 (file)
index 271eb8a..0000000
Binary files a/edumed/static/img/menu/old/szkolenia_active.png and /dev/null differ
diff --git a/edumed/static/img/menu/old/wesprzyj.png b/edumed/static/img/menu/old/wesprzyj.png
deleted file mode 100644 (file)
index 5182a12..0000000
Binary files a/edumed/static/img/menu/old/wesprzyj.png and /dev/null differ
diff --git a/edumed/static/img/menu/old/wesprzyj_active.png b/edumed/static/img/menu/old/wesprzyj_active.png
deleted file mode 100644 (file)
index 0402b9f..0000000
Binary files a/edumed/static/img/menu/old/wesprzyj_active.png and /dev/null differ
diff --git a/edumed/static/img/menu/old/wspolpraca.png b/edumed/static/img/menu/old/wspolpraca.png
deleted file mode 100644 (file)
index af1aa43..0000000
Binary files a/edumed/static/img/menu/old/wspolpraca.png and /dev/null differ
diff --git a/edumed/static/img/menu/old/wspolpraca_active.png b/edumed/static/img/menu/old/wspolpraca_active.png
deleted file mode 100644 (file)
index e849d30..0000000
Binary files a/edumed/static/img/menu/old/wspolpraca_active.png and /dev/null differ
diff --git a/edumed/static/img/menu/olimpiada.png b/edumed/static/img/menu/olimpiada.png
deleted file mode 100644 (file)
index 5194407..0000000
Binary files a/edumed/static/img/menu/olimpiada.png and /dev/null differ
diff --git a/edumed/static/img/menu/olimpiada/harmonogram.png b/edumed/static/img/menu/olimpiada/harmonogram.png
deleted file mode 100644 (file)
index 06e9c92..0000000
Binary files a/edumed/static/img/menu/olimpiada/harmonogram.png and /dev/null differ
diff --git a/edumed/static/img/menu/olimpiada/harmonogram_active.png b/edumed/static/img/menu/olimpiada/harmonogram_active.png
deleted file mode 100644 (file)
index 68c9721..0000000
Binary files a/edumed/static/img/menu/olimpiada/harmonogram_active.png and /dev/null differ
diff --git a/edumed/static/img/menu/olimpiada/komitet.png b/edumed/static/img/menu/olimpiada/komitet.png
deleted file mode 100644 (file)
index 2837890..0000000
Binary files a/edumed/static/img/menu/olimpiada/komitet.png and /dev/null differ
diff --git a/edumed/static/img/menu/olimpiada/komitet_active.png b/edumed/static/img/menu/olimpiada/komitet_active.png
deleted file mode 100644 (file)
index b70ad4c..0000000
Binary files a/edumed/static/img/menu/olimpiada/komitet_active.png and /dev/null differ
diff --git a/edumed/static/img/menu/olimpiada/kontakt.png b/edumed/static/img/menu/olimpiada/kontakt.png
deleted file mode 100644 (file)
index e94d178..0000000
Binary files a/edumed/static/img/menu/olimpiada/kontakt.png and /dev/null differ
diff --git a/edumed/static/img/menu/olimpiada/kontakt_active.png b/edumed/static/img/menu/olimpiada/kontakt_active.png
deleted file mode 100644 (file)
index 58e597a..0000000
Binary files a/edumed/static/img/menu/olimpiada/kontakt_active.png and /dev/null differ
diff --git a/edumed/static/img/menu/olimpiada/literatura.png b/edumed/static/img/menu/olimpiada/literatura.png
deleted file mode 100644 (file)
index f252351..0000000
Binary files a/edumed/static/img/menu/olimpiada/literatura.png and /dev/null differ
diff --git a/edumed/static/img/menu/olimpiada/literatura_active.png b/edumed/static/img/menu/olimpiada/literatura_active.png
deleted file mode 100644 (file)
index 98719ac..0000000
Binary files a/edumed/static/img/menu/olimpiada/literatura_active.png and /dev/null differ
diff --git a/edumed/static/img/menu/olimpiada/program.png b/edumed/static/img/menu/olimpiada/program.png
deleted file mode 100644 (file)
index 56760e1..0000000
Binary files a/edumed/static/img/menu/olimpiada/program.png and /dev/null differ
diff --git a/edumed/static/img/menu/olimpiada/program_active.png b/edumed/static/img/menu/olimpiada/program_active.png
deleted file mode 100644 (file)
index 9b6ec98..0000000
Binary files a/edumed/static/img/menu/olimpiada/program_active.png and /dev/null differ
diff --git a/edumed/static/img/menu/olimpiada/regulamin.png b/edumed/static/img/menu/olimpiada/regulamin.png
deleted file mode 100644 (file)
index 449ac1c..0000000
Binary files a/edumed/static/img/menu/olimpiada/regulamin.png and /dev/null differ
diff --git a/edumed/static/img/menu/olimpiada/regulamin_active.png b/edumed/static/img/menu/olimpiada/regulamin_active.png
deleted file mode 100644 (file)
index 1a1516b..0000000
Binary files a/edumed/static/img/menu/olimpiada/regulamin_active.png and /dev/null differ
diff --git a/edumed/static/img/menu/olimpiada/svg/harmonogram.svg b/edumed/static/img/menu/olimpiada/svg/harmonogram.svg
deleted file mode 100644 (file)
index 64a3a3e..0000000
+++ /dev/null
@@ -1,145 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
-
-<svg
-   xmlns:dc="http://purl.org/dc/elements/1.1/"
-   xmlns:cc="http://creativecommons.org/ns#"
-   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
-   xmlns:svg="http://www.w3.org/2000/svg"
-   xmlns="http://www.w3.org/2000/svg"
-   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
-   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
-   version="1.1"
-   id="Capa_1"
-   x="0px"
-   y="0px"
-   viewBox="0 0 58 58"
-   style="enable-background:new 0 0 58 58;"
-   xml:space="preserve"
-   inkscape:version="0.48.4 r9939"
-   width="100%"
-   height="100%"
-   sodipodi:docname="harmonogram.svg"><metadata
-     id="metadata93"><rdf:RDF><cc:Work
-         rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
-           rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs
-     id="defs91" /><sodipodi:namedview
-     pagecolor="#ffffff"
-     bordercolor="#666666"
-     borderopacity="1"
-     objecttolerance="10"
-     gridtolerance="10"
-     guidetolerance="10"
-     inkscape:pageopacity="0"
-     inkscape:pageshadow="2"
-     inkscape:window-width="1366"
-     inkscape:window-height="692"
-     id="namedview89"
-     showgrid="false"
-     inkscape:zoom="5.7543862"
-     inkscape:cx="29"
-     inkscape:cy="29"
-     inkscape:window-x="0"
-     inkscape:window-y="24"
-     inkscape:window-maximized="1"
-     inkscape:current-layer="Capa_1" /><g
-     id="g3889"><path
-       style="fill:#96928b;fill-opacity:1"
-       d="M 42.899,4.5 C 42.434,2.221 40.415,0.5 38,0.5 c -0.553,0 -1,0.447 -1,1 0,0.553 0.447,1 1,1 1.654,0 3,1.346 3,3 0,1.654 -1.346,3 -3,3 -0.553,0 -1,0.447 -1,1 0,0.553 0.447,1 1,1 2.414,0 4.434,-1.721 4.899,-4 H 56 v 9 H 2 v -9 h 14 3 c 0.553,0 1,-0.447 1,-1 0,-0.553 -0.447,-1 -1,-1 h -1.816 c 0.414,-1.162 1.514,-2 2.816,-2 1.654,0 3,1.346 3,3 0,1.654 -1.346,3 -3,3 -0.553,0 -1,0.447 -1,1 0,0.553 0.447,1 1,1 2.757,0 5,-2.243 5,-5 0,-2.757 -2.243,-5 -5,-5 -2.414,0 -4.434,1.721 -4.899,4 H 0 v 13 40 h 58 v -40 -13 H 42.899 z M 56,55.5 H 2 v -38 h 54 v 38 z"
-       id="path5"
-       inkscape:connector-curvature="0" /><path
-       style="fill:#96928b;fill-opacity:1"
-       d="m 26,2.5 c 1.654,0 3,1.346 3,3 0,1.654 -1.346,3 -3,3 -0.553,0 -1,0.447 -1,1 0,0.553 0.447,1 1,1 2.757,0 5,-2.243 5,-5 0,-2.757 -2.243,-5 -5,-5 -0.553,0 -1,0.447 -1,1 0,0.553 0.447,1 1,1 z"
-       id="path7"
-       inkscape:connector-curvature="0" /><path
-       style="fill:#96928b;fill-opacity:1"
-       d="m 32,2.5 c 1.654,0 3,1.346 3,3 0,1.654 -1.346,3 -3,3 -0.553,0 -1,0.447 -1,1 0,0.553 0.447,1 1,1 2.757,0 5,-2.243 5,-5 0,-2.757 -2.243,-5 -5,-5 -0.553,0 -1,0.447 -1,1 0,0.553 0.447,1 1,1 z"
-       id="path9"
-       inkscape:connector-curvature="0" /><path
-       id="circle11"
-       d="m 23,24.5 c 0,0.552285 -0.447715,1 -1,1 -0.552285,0 -1,-0.447715 -1,-1 0,-0.552285 0.447715,-1 1,-1 0.552285,0 1,0.447715 1,1 z"
-       style="fill:#96928b;fill-opacity:1" /><path
-       id="circle13"
-       d="m 30,24.5 c 0,0.552285 -0.447715,1 -1,1 -0.552285,0 -1,-0.447715 -1,-1 0,-0.552285 0.447715,-1 1,-1 0.552285,0 1,0.447715 1,1 z"
-       style="fill:#96928b;fill-opacity:1" /><path
-       id="circle15"
-       d="m 37,24.5 c 0,0.552285 -0.447715,1 -1,1 -0.552285,0 -1,-0.447715 -1,-1 0,-0.552285 0.447715,-1 1,-1 0.552285,0 1,0.447715 1,1 z"
-       style="fill:#96928b;fill-opacity:1" /><path
-       id="circle17"
-       d="m 44,24.5 c 0,0.552285 -0.447715,1 -1,1 -0.552285,0 -1,-0.447715 -1,-1 0,-0.552285 0.447715,-1 1,-1 0.552285,0 1,0.447715 1,1 z"
-       style="fill:#96928b;fill-opacity:1" /><path
-       id="circle19"
-       d="m 51,24.5 c 0,0.552285 -0.447715,1 -1,1 -0.552285,0 -1,-0.447715 -1,-1 0,-0.552285 0.447715,-1 1,-1 0.552285,0 1,0.447715 1,1 z"
-       style="fill:#96928b;fill-opacity:1" /><path
-       id="circle21"
-       d="m 9,32.5 c 0,0.552285 -0.4477153,1 -1,1 -0.5522847,0 -1,-0.447715 -1,-1 0,-0.552285 0.4477153,-1 1,-1 0.5522847,0 1,0.447715 1,1 z"
-       style="fill:#96928b;fill-opacity:1" /><path
-       id="circle23"
-       d="m 16,32.5 c 0,0.552285 -0.447715,1 -1,1 -0.552285,0 -1,-0.447715 -1,-1 0,-0.552285 0.447715,-1 1,-1 0.552285,0 1,0.447715 1,1 z"
-       style="fill:#96928b;fill-opacity:1" /><path
-       id="circle25"
-       d="m 23,32.5 c 0,0.552285 -0.447715,1 -1,1 -0.552285,0 -1,-0.447715 -1,-1 0,-0.552285 0.447715,-1 1,-1 0.552285,0 1,0.447715 1,1 z"
-       style="fill:#96928b;fill-opacity:1" /><path
-       id="circle27"
-       d="m 30,32.5 c 0,0.552285 -0.447715,1 -1,1 -0.552285,0 -1,-0.447715 -1,-1 0,-0.552285 0.447715,-1 1,-1 0.552285,0 1,0.447715 1,1 z"
-       style="fill:#96928b;fill-opacity:1" /><path
-       id="circle29"
-       d="m 37,32.5 c 0,0.552285 -0.447715,1 -1,1 -0.552285,0 -1,-0.447715 -1,-1 0,-0.552285 0.447715,-1 1,-1 0.552285,0 1,0.447715 1,1 z"
-       style="fill:#96928b;fill-opacity:1" /><path
-       id="circle31"
-       d="m 44,32.5 c 0,0.552285 -0.447715,1 -1,1 -0.552285,0 -1,-0.447715 -1,-1 0,-0.552285 0.447715,-1 1,-1 0.552285,0 1,0.447715 1,1 z"
-       style="fill:#96928b;fill-opacity:1" /><path
-       id="circle33"
-       d="m 51,32.5 c 0,0.552285 -0.447715,1 -1,1 -0.552285,0 -1,-0.447715 -1,-1 0,-0.552285 0.447715,-1 1,-1 0.552285,0 1,0.447715 1,1 z"
-       style="fill:#96928b;fill-opacity:1" /><path
-       id="circle35"
-       d="m 9,39.5 c 0,0.552285 -0.4477153,1 -1,1 -0.5522847,0 -1,-0.447715 -1,-1 0,-0.552285 0.4477153,-1 1,-1 0.5522847,0 1,0.447715 1,1 z"
-       style="fill:#96928b;fill-opacity:1" /><path
-       id="circle37"
-       d="m 16,39.5 c 0,0.552285 -0.447715,1 -1,1 -0.552285,0 -1,-0.447715 -1,-1 0,-0.552285 0.447715,-1 1,-1 0.552285,0 1,0.447715 1,1 z"
-       style="fill:#96928b;fill-opacity:1" /><path
-       id="circle39"
-       d="m 23,39.5 c 0,0.552285 -0.447715,1 -1,1 -0.552285,0 -1,-0.447715 -1,-1 0,-0.552285 0.447715,-1 1,-1 0.552285,0 1,0.447715 1,1 z"
-       style="fill:#96928b;fill-opacity:1" /><path
-       id="circle41"
-       d="m 30,39.5 c 0,0.552285 -0.447715,1 -1,1 -0.552285,0 -1,-0.447715 -1,-1 0,-0.552285 0.447715,-1 1,-1 0.552285,0 1,0.447715 1,1 z"
-       style="fill:#96928b;fill-opacity:1" /><path
-       id="circle43"
-       d="m 37,39.5 c 0,0.552285 -0.447715,1 -1,1 -0.552285,0 -1,-0.447715 -1,-1 0,-0.552285 0.447715,-1 1,-1 0.552285,0 1,0.447715 1,1 z"
-       style="fill:#96928b;fill-opacity:1" /><path
-       id="circle45"
-       d="m 44,39.5 c 0,0.552285 -0.447715,1 -1,1 -0.552285,0 -1,-0.447715 -1,-1 0,-0.552285 0.447715,-1 1,-1 0.552285,0 1,0.447715 1,1 z"
-       style="fill:#96928b;fill-opacity:1" /><path
-       id="circle47"
-       d="m 51,39.5 c 0,0.552285 -0.447715,1 -1,1 -0.552285,0 -1,-0.447715 -1,-1 0,-0.552285 0.447715,-1 1,-1 0.552285,0 1,0.447715 1,1 z"
-       style="fill:#96928b;fill-opacity:1" /><path
-       id="circle49"
-       d="m 9,47.5 c 0,0.552285 -0.4477153,1 -1,1 -0.5522847,0 -1,-0.447715 -1,-1 0,-0.552285 0.4477153,-1 1,-1 0.5522847,0 1,0.447715 1,1 z"
-       style="fill:#96928b;fill-opacity:1" /><path
-       id="circle51"
-       d="m 16,47.5 c 0,0.552285 -0.447715,1 -1,1 -0.552285,0 -1,-0.447715 -1,-1 0,-0.552285 0.447715,-1 1,-1 0.552285,0 1,0.447715 1,1 z"
-       style="fill:#96928b;fill-opacity:1" /><path
-       id="circle53"
-       d="m 23,47.5 c 0,0.552285 -0.447715,1 -1,1 -0.552285,0 -1,-0.447715 -1,-1 0,-0.552285 0.447715,-1 1,-1 0.552285,0 1,0.447715 1,1 z"
-       style="fill:#96928b;fill-opacity:1" /><path
-       id="circle55"
-       d="m 30,47.5 c 0,0.552285 -0.447715,1 -1,1 -0.552285,0 -1,-0.447715 -1,-1 0,-0.552285 0.447715,-1 1,-1 0.552285,0 1,0.447715 1,1 z"
-       style="fill:#96928b;fill-opacity:1" /><path
-       id="circle57"
-       d="m 37,47.5 c 0,0.552285 -0.447715,1 -1,1 -0.552285,0 -1,-0.447715 -1,-1 0,-0.552285 0.447715,-1 1,-1 0.552285,0 1,0.447715 1,1 z"
-       style="fill:#96928b;fill-opacity:1" /></g><g
-     id="g59" /><g
-     id="g61" /><g
-     id="g63" /><g
-     id="g65" /><g
-     id="g67" /><g
-     id="g69" /><g
-     id="g71" /><g
-     id="g73" /><g
-     id="g75" /><g
-     id="g77" /><g
-     id="g79" /><g
-     id="g81" /><g
-     id="g83" /><g
-     id="g85" /><g
-     id="g87" /></svg>
\ No newline at end of file
diff --git a/edumed/static/img/menu/olimpiada/svg/harmonogram_active.svg b/edumed/static/img/menu/olimpiada/svg/harmonogram_active.svg
deleted file mode 100644 (file)
index f690251..0000000
+++ /dev/null
@@ -1,146 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
-
-<svg
-   xmlns:dc="http://purl.org/dc/elements/1.1/"
-   xmlns:cc="http://creativecommons.org/ns#"
-   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
-   xmlns:svg="http://www.w3.org/2000/svg"
-   xmlns="http://www.w3.org/2000/svg"
-   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
-   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
-   version="1.1"
-   id="Capa_1"
-   x="0px"
-   y="0px"
-   viewBox="0 0 58 58"
-   style="enable-background:new 0 0 58 58;"
-   xml:space="preserve"
-   inkscape:version="0.48.4 r9939"
-   width="100%"
-   height="100%"
-   sodipodi:docname="harmonogram.svg"><metadata
-     id="metadata93"><rdf:RDF><cc:Work
-         rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
-           rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
-     id="defs91" /><sodipodi:namedview
-     pagecolor="#ffffff"
-     bordercolor="#666666"
-     borderopacity="1"
-     objecttolerance="10"
-     gridtolerance="10"
-     guidetolerance="10"
-     inkscape:pageopacity="0"
-     inkscape:pageshadow="2"
-     inkscape:window-width="1366"
-     inkscape:window-height="692"
-     id="namedview89"
-     showgrid="false"
-     inkscape:zoom="5.7543862"
-     inkscape:cx="29"
-     inkscape:cy="29"
-     inkscape:window-x="0"
-     inkscape:window-y="24"
-     inkscape:window-maximized="1"
-     inkscape:current-layer="Capa_1" /><g
-     id="g3889"
-     style="fill:#ed7831;fill-opacity:1"><path
-       style="fill:#ed7831;fill-opacity:1"
-       d="M 42.899,4.5 C 42.434,2.221 40.415,0.5 38,0.5 c -0.553,0 -1,0.447 -1,1 0,0.553 0.447,1 1,1 1.654,0 3,1.346 3,3 0,1.654 -1.346,3 -3,3 -0.553,0 -1,0.447 -1,1 0,0.553 0.447,1 1,1 2.414,0 4.434,-1.721 4.899,-4 H 56 v 9 H 2 v -9 h 14 3 c 0.553,0 1,-0.447 1,-1 0,-0.553 -0.447,-1 -1,-1 h -1.816 c 0.414,-1.162 1.514,-2 2.816,-2 1.654,0 3,1.346 3,3 0,1.654 -1.346,3 -3,3 -0.553,0 -1,0.447 -1,1 0,0.553 0.447,1 1,1 2.757,0 5,-2.243 5,-5 0,-2.757 -2.243,-5 -5,-5 -2.414,0 -4.434,1.721 -4.899,4 H 0 v 13 40 h 58 v -40 -13 H 42.899 z M 56,55.5 H 2 v -38 h 54 v 38 z"
-       id="path5"
-       inkscape:connector-curvature="0" /><path
-       style="fill:#ed7831;fill-opacity:1"
-       d="m 26,2.5 c 1.654,0 3,1.346 3,3 0,1.654 -1.346,3 -3,3 -0.553,0 -1,0.447 -1,1 0,0.553 0.447,1 1,1 2.757,0 5,-2.243 5,-5 0,-2.757 -2.243,-5 -5,-5 -0.553,0 -1,0.447 -1,1 0,0.553 0.447,1 1,1 z"
-       id="path7"
-       inkscape:connector-curvature="0" /><path
-       style="fill:#ed7831;fill-opacity:1"
-       d="m 32,2.5 c 1.654,0 3,1.346 3,3 0,1.654 -1.346,3 -3,3 -0.553,0 -1,0.447 -1,1 0,0.553 0.447,1 1,1 2.757,0 5,-2.243 5,-5 0,-2.757 -2.243,-5 -5,-5 -0.553,0 -1,0.447 -1,1 0,0.553 0.447,1 1,1 z"
-       id="path9"
-       inkscape:connector-curvature="0" /><path
-       id="circle11"
-       d="m 23,24.5 c 0,0.552285 -0.447715,1 -1,1 -0.552285,0 -1,-0.447715 -1,-1 0,-0.552285 0.447715,-1 1,-1 0.552285,0 1,0.447715 1,1 z"
-       style="fill:#ed7831;fill-opacity:1" /><path
-       id="circle13"
-       d="m 30,24.5 c 0,0.552285 -0.447715,1 -1,1 -0.552285,0 -1,-0.447715 -1,-1 0,-0.552285 0.447715,-1 1,-1 0.552285,0 1,0.447715 1,1 z"
-       style="fill:#ed7831;fill-opacity:1" /><path
-       id="circle15"
-       d="m 37,24.5 c 0,0.552285 -0.447715,1 -1,1 -0.552285,0 -1,-0.447715 -1,-1 0,-0.552285 0.447715,-1 1,-1 0.552285,0 1,0.447715 1,1 z"
-       style="fill:#ed7831;fill-opacity:1" /><path
-       id="circle17"
-       d="m 44,24.5 c 0,0.552285 -0.447715,1 -1,1 -0.552285,0 -1,-0.447715 -1,-1 0,-0.552285 0.447715,-1 1,-1 0.552285,0 1,0.447715 1,1 z"
-       style="fill:#ed7831;fill-opacity:1" /><path
-       id="circle19"
-       d="m 51,24.5 c 0,0.552285 -0.447715,1 -1,1 -0.552285,0 -1,-0.447715 -1,-1 0,-0.552285 0.447715,-1 1,-1 0.552285,0 1,0.447715 1,1 z"
-       style="fill:#ed7831;fill-opacity:1" /><path
-       id="circle21"
-       d="m 9,32.5 c 0,0.552285 -0.4477153,1 -1,1 -0.5522847,0 -1,-0.447715 -1,-1 0,-0.552285 0.4477153,-1 1,-1 0.5522847,0 1,0.447715 1,1 z"
-       style="fill:#ed7831;fill-opacity:1" /><path
-       id="circle23"
-       d="m 16,32.5 c 0,0.552285 -0.447715,1 -1,1 -0.552285,0 -1,-0.447715 -1,-1 0,-0.552285 0.447715,-1 1,-1 0.552285,0 1,0.447715 1,1 z"
-       style="fill:#ed7831;fill-opacity:1" /><path
-       id="circle25"
-       d="m 23,32.5 c 0,0.552285 -0.447715,1 -1,1 -0.552285,0 -1,-0.447715 -1,-1 0,-0.552285 0.447715,-1 1,-1 0.552285,0 1,0.447715 1,1 z"
-       style="fill:#ed7831;fill-opacity:1" /><path
-       id="circle27"
-       d="m 30,32.5 c 0,0.552285 -0.447715,1 -1,1 -0.552285,0 -1,-0.447715 -1,-1 0,-0.552285 0.447715,-1 1,-1 0.552285,0 1,0.447715 1,1 z"
-       style="fill:#ed7831;fill-opacity:1" /><path
-       id="circle29"
-       d="m 37,32.5 c 0,0.552285 -0.447715,1 -1,1 -0.552285,0 -1,-0.447715 -1,-1 0,-0.552285 0.447715,-1 1,-1 0.552285,0 1,0.447715 1,1 z"
-       style="fill:#ed7831;fill-opacity:1" /><path
-       id="circle31"
-       d="m 44,32.5 c 0,0.552285 -0.447715,1 -1,1 -0.552285,0 -1,-0.447715 -1,-1 0,-0.552285 0.447715,-1 1,-1 0.552285,0 1,0.447715 1,1 z"
-       style="fill:#ed7831;fill-opacity:1" /><path
-       id="circle33"
-       d="m 51,32.5 c 0,0.552285 -0.447715,1 -1,1 -0.552285,0 -1,-0.447715 -1,-1 0,-0.552285 0.447715,-1 1,-1 0.552285,0 1,0.447715 1,1 z"
-       style="fill:#ed7831;fill-opacity:1" /><path
-       id="circle35"
-       d="m 9,39.5 c 0,0.552285 -0.4477153,1 -1,1 -0.5522847,0 -1,-0.447715 -1,-1 0,-0.552285 0.4477153,-1 1,-1 0.5522847,0 1,0.447715 1,1 z"
-       style="fill:#ed7831;fill-opacity:1" /><path
-       id="circle37"
-       d="m 16,39.5 c 0,0.552285 -0.447715,1 -1,1 -0.552285,0 -1,-0.447715 -1,-1 0,-0.552285 0.447715,-1 1,-1 0.552285,0 1,0.447715 1,1 z"
-       style="fill:#ed7831;fill-opacity:1" /><path
-       id="circle39"
-       d="m 23,39.5 c 0,0.552285 -0.447715,1 -1,1 -0.552285,0 -1,-0.447715 -1,-1 0,-0.552285 0.447715,-1 1,-1 0.552285,0 1,0.447715 1,1 z"
-       style="fill:#ed7831;fill-opacity:1" /><path
-       id="circle41"
-       d="m 30,39.5 c 0,0.552285 -0.447715,1 -1,1 -0.552285,0 -1,-0.447715 -1,-1 0,-0.552285 0.447715,-1 1,-1 0.552285,0 1,0.447715 1,1 z"
-       style="fill:#ed7831;fill-opacity:1" /><path
-       id="circle43"
-       d="m 37,39.5 c 0,0.552285 -0.447715,1 -1,1 -0.552285,0 -1,-0.447715 -1,-1 0,-0.552285 0.447715,-1 1,-1 0.552285,0 1,0.447715 1,1 z"
-       style="fill:#ed7831;fill-opacity:1" /><path
-       id="circle45"
-       d="m 44,39.5 c 0,0.552285 -0.447715,1 -1,1 -0.552285,0 -1,-0.447715 -1,-1 0,-0.552285 0.447715,-1 1,-1 0.552285,0 1,0.447715 1,1 z"
-       style="fill:#ed7831;fill-opacity:1" /><path
-       id="circle47"
-       d="m 51,39.5 c 0,0.552285 -0.447715,1 -1,1 -0.552285,0 -1,-0.447715 -1,-1 0,-0.552285 0.447715,-1 1,-1 0.552285,0 1,0.447715 1,1 z"
-       style="fill:#ed7831;fill-opacity:1" /><path
-       id="circle49"
-       d="m 9,47.5 c 0,0.552285 -0.4477153,1 -1,1 -0.5522847,0 -1,-0.447715 -1,-1 0,-0.552285 0.4477153,-1 1,-1 0.5522847,0 1,0.447715 1,1 z"
-       style="fill:#ed7831;fill-opacity:1" /><path
-       id="circle51"
-       d="m 16,47.5 c 0,0.552285 -0.447715,1 -1,1 -0.552285,0 -1,-0.447715 -1,-1 0,-0.552285 0.447715,-1 1,-1 0.552285,0 1,0.447715 1,1 z"
-       style="fill:#ed7831;fill-opacity:1" /><path
-       id="circle53"
-       d="m 23,47.5 c 0,0.552285 -0.447715,1 -1,1 -0.552285,0 -1,-0.447715 -1,-1 0,-0.552285 0.447715,-1 1,-1 0.552285,0 1,0.447715 1,1 z"
-       style="fill:#ed7831;fill-opacity:1" /><path
-       id="circle55"
-       d="m 30,47.5 c 0,0.552285 -0.447715,1 -1,1 -0.552285,0 -1,-0.447715 -1,-1 0,-0.552285 0.447715,-1 1,-1 0.552285,0 1,0.447715 1,1 z"
-       style="fill:#ed7831;fill-opacity:1" /><path
-       id="circle57"
-       d="m 37,47.5 c 0,0.552285 -0.447715,1 -1,1 -0.552285,0 -1,-0.447715 -1,-1 0,-0.552285 0.447715,-1 1,-1 0.552285,0 1,0.447715 1,1 z"
-       style="fill:#ed7831;fill-opacity:1" /></g><g
-     id="g59" /><g
-     id="g61" /><g
-     id="g63" /><g
-     id="g65" /><g
-     id="g67" /><g
-     id="g69" /><g
-     id="g71" /><g
-     id="g73" /><g
-     id="g75" /><g
-     id="g77" /><g
-     id="g79" /><g
-     id="g81" /><g
-     id="g83" /><g
-     id="g85" /><g
-     id="g87" /></svg>
\ No newline at end of file
diff --git a/edumed/static/img/menu/olimpiada/svg/komitet.svg b/edumed/static/img/menu/olimpiada/svg/komitet.svg
deleted file mode 100644 (file)
index d04c979..0000000
+++ /dev/null
@@ -1,63 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
-
-<svg
-   xmlns:dc="http://purl.org/dc/elements/1.1/"
-   xmlns:cc="http://creativecommons.org/ns#"
-   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
-   xmlns:svg="http://www.w3.org/2000/svg"
-   xmlns="http://www.w3.org/2000/svg"
-   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
-   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
-   version="1.1"
-   id="Capa_1"
-   x="0px"
-   y="0px"
-   viewBox="0 0 60 60"
-   style="enable-background:new 0 0 60 60;"
-   xml:space="preserve"
-   inkscape:version="0.48.4 r9939"
-   width="100%"
-   height="100%"
-   sodipodi:docname="komitet.svg"><metadata
-     id="metadata39"><rdf:RDF><cc:Work
-         rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
-           rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs
-     id="defs37" /><sodipodi:namedview
-     pagecolor="#ffffff"
-     bordercolor="#666666"
-     borderopacity="1"
-     objecttolerance="10"
-     gridtolerance="10"
-     guidetolerance="10"
-     inkscape:pageopacity="0"
-     inkscape:pageshadow="2"
-     inkscape:window-width="1366"
-     inkscape:window-height="692"
-     id="namedview35"
-     showgrid="false"
-     inkscape:zoom="3.9333333"
-     inkscape:cx="-16.779661"
-     inkscape:cy="30"
-     inkscape:window-x="0"
-     inkscape:window-y="24"
-     inkscape:window-maximized="1"
-     inkscape:current-layer="Capa_1" /><path
-     d="M55.517,46.55l-9.773-4.233c-0.23-0.115-0.485-0.396-0.704-0.771l6.525-0.005c0.114,0.011,2.804,0.257,4.961-0.67  c0.817-0.352,1.425-1.047,1.669-1.907c0.246-0.868,0.09-1.787-0.426-2.523c-1.865-2.654-6.218-9.589-6.354-16.623  c-0.003-0.121-0.397-12.083-12.21-12.18c-1.739,0.014-3.347,0.309-4.81,0.853c-0.319-0.813-0.789-1.661-1.488-2.459  C30.854,3.688,27.521,2.5,23,2.5s-7.854,1.188-9.908,3.53c-2.368,2.701-2.148,5.976-2.092,6.525v5.319c-0.64,0.729-1,1.662-1,2.625  v4c0,1.217,0.553,2.352,1.497,3.109c0.916,3.627,2.833,6.36,3.503,7.237v3.309c0,0.968-0.528,1.856-1.377,2.32l-8.921,4.866  C1.801,46.924,0,49.958,0,53.262V57.5h44h2h14v-3.697C60,50.711,58.282,47.933,55.517,46.55z M44,55.5H2v-2.238  c0-2.571,1.402-4.934,3.659-6.164l8.921-4.866C16.073,41.417,17,39.854,17,38.155v-4.019l-0.233-0.278  c-0.024-0.029-2.475-2.994-3.41-7.065l-0.091-0.396l-0.341-0.22C12.346,25.803,12,25.176,12,24.5v-4c0-0.561,0.238-1.084,0.67-1.475  L13,18.728V12.5l-0.009-0.131c-0.003-0.027-0.343-2.799,1.605-5.021C16.253,5.458,19.081,4.5,23,4.5  c3.905,0,6.727,0.951,8.386,2.828c0.825,0.932,1.24,1.973,1.447,2.867c0.016,0.07,0.031,0.139,0.045,0.208  c0.014,0.071,0.029,0.142,0.04,0.21c0.013,0.078,0.024,0.152,0.035,0.226c0.008,0.053,0.016,0.107,0.022,0.158  c0.015,0.124,0.027,0.244,0.035,0.355c0.001,0.009,0.001,0.017,0.001,0.026c0.007,0.108,0.012,0.21,0.015,0.303  c0,0.018,0,0.033,0.001,0.051c0.002,0.083,0.002,0.162,0.001,0.231c0,0.01,0,0.02,0,0.03c-0.004,0.235-0.02,0.375-0.02,0.378  L33,18.728l0.33,0.298C33.762,19.416,34,19.939,34,20.5v4c0,0.873-0.572,1.637-1.422,1.899l-0.498,0.153l-0.16,0.495  c-0.669,2.081-1.622,4.003-2.834,5.713c-0.297,0.421-0.586,0.794-0.837,1.079L28,34.123v4.125c0,0.253,0.025,0.501,0.064,0.745  c0.008,0.052,0.022,0.102,0.032,0.154c0.039,0.201,0.091,0.398,0.155,0.59c0.015,0.045,0.031,0.088,0.048,0.133  c0.078,0.209,0.169,0.411,0.275,0.605c0.012,0.022,0.023,0.045,0.035,0.067c0.145,0.256,0.312,0.499,0.504,0.723l0.228,0.281h0.039  c0.343,0.338,0.737,0.632,1.185,0.856l9.553,4.776C42.513,48.374,44,50.78,44,53.457V55.5z M58,55.5H46v-2.043  c0-3.439-1.911-6.53-4.986-8.068l-6.858-3.43c0.169-0.386,0.191-0.828,0.043-1.254c-0.245-0.705-0.885-1.16-1.63-1.16h-2.217  c-0.046-0.081-0.076-0.17-0.113-0.256c-0.05-0.115-0.109-0.228-0.142-0.349C30.036,38.718,30,38.486,30,38.248v-3.381  c0.229-0.28,0.47-0.599,0.719-0.951c1.239-1.75,2.232-3.698,2.954-5.799C35.084,27.47,36,26.075,36,24.5v-4  c0-0.963-0.36-1.896-1-2.625v-5.319c0.026-0.25,0.082-1.069-0.084-2.139c1.288-0.506,2.731-0.767,4.29-0.78  c9.841,0.081,10.2,9.811,10.21,10.221c0.147,7.583,4.746,14.927,6.717,17.732c0.169,0.24,0.22,0.542,0.139,0.827  c-0.046,0.164-0.178,0.462-0.535,0.615c-1.68,0.723-3.959,0.518-4.076,0.513h-6.883c-0.643,0-1.229,0.327-1.568,0.874  c-0.338,0.545-0.37,1.211-0.086,1.783c0.313,0.631,0.866,1.474,1.775,1.927l9.747,4.222C56.715,49.396,58,51.482,58,53.803V55.5z"
-     id="path3"
-     style="fill:#96928b;fill-opacity:1" /><g
-     id="g5" /><g
-     id="g7" /><g
-     id="g9" /><g
-     id="g11" /><g
-     id="g13" /><g
-     id="g15" /><g
-     id="g17" /><g
-     id="g19" /><g
-     id="g21" /><g
-     id="g23" /><g
-     id="g25" /><g
-     id="g27" /><g
-     id="g29" /><g
-     id="g31" /><g
-     id="g33" /></svg>
\ No newline at end of file
diff --git a/edumed/static/img/menu/olimpiada/svg/komitet_active.svg b/edumed/static/img/menu/olimpiada/svg/komitet_active.svg
deleted file mode 100644 (file)
index 9202ac9..0000000
+++ /dev/null
@@ -1,63 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
-
-<svg
-   xmlns:dc="http://purl.org/dc/elements/1.1/"
-   xmlns:cc="http://creativecommons.org/ns#"
-   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
-   xmlns:svg="http://www.w3.org/2000/svg"
-   xmlns="http://www.w3.org/2000/svg"
-   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
-   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
-   version="1.1"
-   id="Capa_1"
-   x="0px"
-   y="0px"
-   viewBox="0 0 60 60"
-   style="enable-background:new 0 0 60 60;"
-   xml:space="preserve"
-   inkscape:version="0.48.4 r9939"
-   width="100%"
-   height="100%"
-   sodipodi:docname="komitet.svg"><metadata
-     id="metadata39"><rdf:RDF><cc:Work
-         rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
-           rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
-     id="defs37" /><sodipodi:namedview
-     pagecolor="#ffffff"
-     bordercolor="#666666"
-     borderopacity="1"
-     objecttolerance="10"
-     gridtolerance="10"
-     guidetolerance="10"
-     inkscape:pageopacity="0"
-     inkscape:pageshadow="2"
-     inkscape:window-width="1366"
-     inkscape:window-height="692"
-     id="namedview35"
-     showgrid="false"
-     inkscape:zoom="3.9333333"
-     inkscape:cx="-16.779661"
-     inkscape:cy="30"
-     inkscape:window-x="0"
-     inkscape:window-y="24"
-     inkscape:window-maximized="1"
-     inkscape:current-layer="Capa_1" /><path
-     d="M55.517,46.55l-9.773-4.233c-0.23-0.115-0.485-0.396-0.704-0.771l6.525-0.005c0.114,0.011,2.804,0.257,4.961-0.67  c0.817-0.352,1.425-1.047,1.669-1.907c0.246-0.868,0.09-1.787-0.426-2.523c-1.865-2.654-6.218-9.589-6.354-16.623  c-0.003-0.121-0.397-12.083-12.21-12.18c-1.739,0.014-3.347,0.309-4.81,0.853c-0.319-0.813-0.789-1.661-1.488-2.459  C30.854,3.688,27.521,2.5,23,2.5s-7.854,1.188-9.908,3.53c-2.368,2.701-2.148,5.976-2.092,6.525v5.319c-0.64,0.729-1,1.662-1,2.625  v4c0,1.217,0.553,2.352,1.497,3.109c0.916,3.627,2.833,6.36,3.503,7.237v3.309c0,0.968-0.528,1.856-1.377,2.32l-8.921,4.866  C1.801,46.924,0,49.958,0,53.262V57.5h44h2h14v-3.697C60,50.711,58.282,47.933,55.517,46.55z M44,55.5H2v-2.238  c0-2.571,1.402-4.934,3.659-6.164l8.921-4.866C16.073,41.417,17,39.854,17,38.155v-4.019l-0.233-0.278  c-0.024-0.029-2.475-2.994-3.41-7.065l-0.091-0.396l-0.341-0.22C12.346,25.803,12,25.176,12,24.5v-4c0-0.561,0.238-1.084,0.67-1.475  L13,18.728V12.5l-0.009-0.131c-0.003-0.027-0.343-2.799,1.605-5.021C16.253,5.458,19.081,4.5,23,4.5  c3.905,0,6.727,0.951,8.386,2.828c0.825,0.932,1.24,1.973,1.447,2.867c0.016,0.07,0.031,0.139,0.045,0.208  c0.014,0.071,0.029,0.142,0.04,0.21c0.013,0.078,0.024,0.152,0.035,0.226c0.008,0.053,0.016,0.107,0.022,0.158  c0.015,0.124,0.027,0.244,0.035,0.355c0.001,0.009,0.001,0.017,0.001,0.026c0.007,0.108,0.012,0.21,0.015,0.303  c0,0.018,0,0.033,0.001,0.051c0.002,0.083,0.002,0.162,0.001,0.231c0,0.01,0,0.02,0,0.03c-0.004,0.235-0.02,0.375-0.02,0.378  L33,18.728l0.33,0.298C33.762,19.416,34,19.939,34,20.5v4c0,0.873-0.572,1.637-1.422,1.899l-0.498,0.153l-0.16,0.495  c-0.669,2.081-1.622,4.003-2.834,5.713c-0.297,0.421-0.586,0.794-0.837,1.079L28,34.123v4.125c0,0.253,0.025,0.501,0.064,0.745  c0.008,0.052,0.022,0.102,0.032,0.154c0.039,0.201,0.091,0.398,0.155,0.59c0.015,0.045,0.031,0.088,0.048,0.133  c0.078,0.209,0.169,0.411,0.275,0.605c0.012,0.022,0.023,0.045,0.035,0.067c0.145,0.256,0.312,0.499,0.504,0.723l0.228,0.281h0.039  c0.343,0.338,0.737,0.632,1.185,0.856l9.553,4.776C42.513,48.374,44,50.78,44,53.457V55.5z M58,55.5H46v-2.043  c0-3.439-1.911-6.53-4.986-8.068l-6.858-3.43c0.169-0.386,0.191-0.828,0.043-1.254c-0.245-0.705-0.885-1.16-1.63-1.16h-2.217  c-0.046-0.081-0.076-0.17-0.113-0.256c-0.05-0.115-0.109-0.228-0.142-0.349C30.036,38.718,30,38.486,30,38.248v-3.381  c0.229-0.28,0.47-0.599,0.719-0.951c1.239-1.75,2.232-3.698,2.954-5.799C35.084,27.47,36,26.075,36,24.5v-4  c0-0.963-0.36-1.896-1-2.625v-5.319c0.026-0.25,0.082-1.069-0.084-2.139c1.288-0.506,2.731-0.767,4.29-0.78  c9.841,0.081,10.2,9.811,10.21,10.221c0.147,7.583,4.746,14.927,6.717,17.732c0.169,0.24,0.22,0.542,0.139,0.827  c-0.046,0.164-0.178,0.462-0.535,0.615c-1.68,0.723-3.959,0.518-4.076,0.513h-6.883c-0.643,0-1.229,0.327-1.568,0.874  c-0.338,0.545-0.37,1.211-0.086,1.783c0.313,0.631,0.866,1.474,1.775,1.927l9.747,4.222C56.715,49.396,58,51.482,58,53.803V55.5z"
-     id="path3"
-     style="fill:#ed7831;fill-opacity:1;" /><g
-     id="g5" /><g
-     id="g7" /><g
-     id="g9" /><g
-     id="g11" /><g
-     id="g13" /><g
-     id="g15" /><g
-     id="g17" /><g
-     id="g19" /><g
-     id="g21" /><g
-     id="g23" /><g
-     id="g25" /><g
-     id="g27" /><g
-     id="g29" /><g
-     id="g31" /><g
-     id="g33" /></svg>
\ No newline at end of file
diff --git a/edumed/static/img/menu/olimpiada/svg/kontakt.svg b/edumed/static/img/menu/olimpiada/svg/kontakt.svg
deleted file mode 100644 (file)
index 1e9339f..0000000
+++ /dev/null
@@ -1,74 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
-
-<svg
-   xmlns:dc="http://purl.org/dc/elements/1.1/"
-   xmlns:cc="http://creativecommons.org/ns#"
-   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
-   xmlns:svg="http://www.w3.org/2000/svg"
-   xmlns="http://www.w3.org/2000/svg"
-   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
-   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
-   version="1.1"
-   id="Capa_1"
-   x="0px"
-   y="0px"
-   viewBox="0 0 59.999 59.999"
-   style="enable-background:new 0 0 59.999 59.999;"
-   xml:space="preserve"
-   inkscape:version="0.48.4 r9939"
-   width="100%"
-   height="100%"
-   sodipodi:docname="kontakt.svg"><metadata
-     id="metadata47"><rdf:RDF><cc:Work
-         rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
-           rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs
-     id="defs45" /><sodipodi:namedview
-     pagecolor="#ffffff"
-     bordercolor="#666666"
-     borderopacity="1"
-     objecttolerance="10"
-     gridtolerance="10"
-     guidetolerance="10"
-     inkscape:pageopacity="0"
-     inkscape:pageshadow="2"
-     inkscape:window-width="769"
-     inkscape:window-height="480"
-     id="namedview43"
-     showgrid="false"
-     inkscape:zoom="3.9333989"
-     inkscape:cx="29.9995"
-     inkscape:cy="29.9995"
-     inkscape:window-x="0"
-     inkscape:window-y="24"
-     inkscape:window-maximized="0"
-     inkscape:current-layer="Capa_1" /><g
-     id="g3"
-     style="fill:#96928b;fill-opacity:1"><path
-       d="M36.176,49.999c-1.93,0-3.5,1.57-3.5,3.5s1.57,3.5,3.5,3.5s3.5-1.57,3.5-3.5S38.105,49.999,36.176,49.999z M36.176,54.999   c-0.827,0-1.5-0.673-1.5-1.5s0.673-1.5,1.5-1.5s1.5,0.673,1.5,1.5S37.003,54.999,36.176,54.999z"
-       id="path5"
-       style="fill:#96928b;fill-opacity:1" /><path
-       d="M40.676,36.999c2.206,0,4-1.794,4-4s-1.794-4-4-4s-4,1.794-4,4S38.469,36.999,40.676,36.999z M40.676,30.999   c1.103,0,2,0.897,2,2s-0.897,2-2,2s-2-0.897-2-2S39.573,30.999,40.676,30.999z"
-       id="path7"
-       style="fill:#96928b;fill-opacity:1" /><path
-       d="M16.676,11.999c0.256,0,0.512-0.098,0.707-0.293l2-2c0.391-0.391,0.391-1.023,0-1.414s-1.023-0.391-1.414,0l-2,2   c-0.391,0.391-0.391,1.023,0,1.414C16.164,11.901,16.42,11.999,16.676,11.999z"
-       id="path9"
-       style="fill:#96928b;fill-opacity:1" /><path
-       d="M52.676,29.747c0-0.88-0.343-1.707-0.965-2.329l-0.557-0.557c0.949-0.84,1.521-2.055,1.521-3.362   c0-2.481-2.019-4.5-4.5-4.5c-0.182,0-0.362,0.018-0.54,0.04c0.022-0.179,0.04-0.357,0.04-0.54c0-2.481-2.019-4.5-4.5-4.5   c-0.182,0-0.362,0.018-0.54,0.04c0.022-0.179,0.04-0.357,0.04-0.54c0-2.481-2.019-4.5-4.5-4.5c-0.182,0-0.362,0.018-0.54,0.04   c0.022-0.179,0.04-0.357,0.04-0.54c0-2.481-2.019-4.5-4.5-4.5c-1.308,0-2.522,0.573-3.362,1.521l-0.794-0.794l-3.763-3.763   c-1.285-1.285-3.375-1.285-4.658,0L8.286,13.275c-1.283,1.285-1.283,3.374,0,4.659l3.763,3.763l4.91,4.91   c-1.356,0.776-2.283,2.221-2.283,3.892c0,1.563,0.803,2.941,2.017,3.748c0.061,0.081,0.132,0.161,0.227,0.242l10.756,10.715v1.796   h-2v13h18h8v-13h-2V43.97c1.913-1.621,3-3.952,3-6.471c0-1.74-0.543-3.43-1.536-4.852l0.571-0.571   C52.333,31.454,52.676,30.627,52.676,29.747z M50.676,23.499c0,0.768-0.354,1.479-0.937,1.947l-3.511-3.511   c0.468-0.583,1.18-0.937,1.947-0.937C49.554,20.999,50.676,22.12,50.676,23.499z M45.676,18.499c0,0.768-0.354,1.479-0.937,1.947   l-3.511-3.511c0.468-0.583,1.18-0.937,1.947-0.937C44.554,15.999,45.676,17.12,45.676,18.499z M40.676,13.499   c0,0.768-0.354,1.479-0.937,1.947l-3.511-3.511c0.468-0.583,1.18-0.937,1.947-0.937C39.554,10.999,40.676,12.12,40.676,13.499z    M33.176,5.999c1.379,0,2.5,1.121,2.5,2.5c0,0.768-0.354,1.479-0.937,1.947l-3.511-3.511C31.696,6.353,32.408,5.999,33.176,5.999z    M9.7,16.521c-0.504-0.505-0.504-1.326,0-1.831L22.012,2.378c0.125-0.125,0.271-0.219,0.426-0.282   c0.07-0.029,0.149-0.028,0.223-0.044c0.178-0.038,0.354-0.038,0.532,0c0.074,0.016,0.153,0.015,0.223,0.044   c0.155,0.063,0.3,0.157,0.426,0.282l2.349,2.349L12.049,18.869L9.7,16.521z M27.605,6.141l1.178,1.178l5,5l0.573,0.573l4.427,4.427   l0.573,0.573l4.427,4.427l0.573,0.573l5,5l0.94,0.94c0.505,0.505,0.505,1.325,0,1.83L49.859,31.1l0,0L37.985,42.975   c-0.503,0.504-1.326,0.506-1.831,0l-7.975-7.976h0.996c2.481,0,4.5-2.019,4.5-4.5s-2.019-4.5-4.5-4.5h-9.997l-5.716-5.716   L27.605,6.141z M18.636,28.061l0.415-0.047c0.041-0.006,0.082-0.015,0.124-0.015h10c1.379,0,2.5,1.121,2.5,2.5s-1.121,2.5-2.5,2.5   h-2.996h-2.828h-4.176c-1.379,0-2.5-1.121-2.5-2.5C16.676,29.306,17.517,28.309,18.636,28.061z M27.676,57.999v-9h8.426   c3.073,0,5.574,2.501,5.574,5.574v3.426H27.676z M49.676,57.999h-6v-3.426c0-2.206-0.954-4.188-2.464-5.574h8.464V57.999z    M49.701,34.087c0.634,1.021,0.975,2.202,0.975,3.412c0,2.055-0.948,3.946-2.602,5.191l-0.398,0.3v4.009H36.101h-6.426v-2.718   l-0.353-0.299c-0.045-0.039-0.093-0.075-0.18-0.14l-8.877-8.844h5.085l9.389,9.39c0.643,0.642,1.486,0.963,2.329,0.963   c0.844,0,1.688-0.321,2.33-0.963L49.701,34.087z"
-       id="path11"
-       style="fill:#96928b;fill-opacity:1" /></g><g
-     id="g13" /><g
-     id="g15" /><g
-     id="g17" /><g
-     id="g19" /><g
-     id="g21" /><g
-     id="g23" /><g
-     id="g25" /><g
-     id="g27" /><g
-     id="g29" /><g
-     id="g31" /><g
-     id="g33" /><g
-     id="g35" /><g
-     id="g37" /><g
-     id="g39" /><g
-     id="g41" /></svg>
\ No newline at end of file
diff --git a/edumed/static/img/menu/olimpiada/svg/kontakt_active.svg b/edumed/static/img/menu/olimpiada/svg/kontakt_active.svg
deleted file mode 100644 (file)
index 940e21e..0000000
+++ /dev/null
@@ -1,74 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
-
-<svg
-   xmlns:dc="http://purl.org/dc/elements/1.1/"
-   xmlns:cc="http://creativecommons.org/ns#"
-   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
-   xmlns:svg="http://www.w3.org/2000/svg"
-   xmlns="http://www.w3.org/2000/svg"
-   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
-   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
-   version="1.1"
-   id="Capa_1"
-   x="0px"
-   y="0px"
-   viewBox="0 0 59.999 59.999"
-   style="enable-background:new 0 0 59.999 59.999;"
-   xml:space="preserve"
-   inkscape:version="0.48.4 r9939"
-   width="100%"
-   height="100%"
-   sodipodi:docname="kontakt.svg"><metadata
-     id="metadata47"><rdf:RDF><cc:Work
-         rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
-           rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
-     id="defs45" /><sodipodi:namedview
-     pagecolor="#ffffff"
-     bordercolor="#666666"
-     borderopacity="1"
-     objecttolerance="10"
-     gridtolerance="10"
-     guidetolerance="10"
-     inkscape:pageopacity="0"
-     inkscape:pageshadow="2"
-     inkscape:window-width="769"
-     inkscape:window-height="480"
-     id="namedview43"
-     showgrid="false"
-     inkscape:zoom="3.9333989"
-     inkscape:cx="29.9995"
-     inkscape:cy="29.9995"
-     inkscape:window-x="0"
-     inkscape:window-y="24"
-     inkscape:window-maximized="0"
-     inkscape:current-layer="Capa_1" /><g
-     id="g3"
-     style="fill:#ed7831;fill-opacity:1"><path
-       d="M36.176,49.999c-1.93,0-3.5,1.57-3.5,3.5s1.57,3.5,3.5,3.5s3.5-1.57,3.5-3.5S38.105,49.999,36.176,49.999z M36.176,54.999   c-0.827,0-1.5-0.673-1.5-1.5s0.673-1.5,1.5-1.5s1.5,0.673,1.5,1.5S37.003,54.999,36.176,54.999z"
-       id="path5"
-       style="fill:#ed7831;fill-opacity:1" /><path
-       d="M40.676,36.999c2.206,0,4-1.794,4-4s-1.794-4-4-4s-4,1.794-4,4S38.469,36.999,40.676,36.999z M40.676,30.999   c1.103,0,2,0.897,2,2s-0.897,2-2,2s-2-0.897-2-2S39.573,30.999,40.676,30.999z"
-       id="path7"
-       style="fill:#ed7831;fill-opacity:1" /><path
-       d="M16.676,11.999c0.256,0,0.512-0.098,0.707-0.293l2-2c0.391-0.391,0.391-1.023,0-1.414s-1.023-0.391-1.414,0l-2,2   c-0.391,0.391-0.391,1.023,0,1.414C16.164,11.901,16.42,11.999,16.676,11.999z"
-       id="path9"
-       style="fill:#ed7831;fill-opacity:1" /><path
-       d="M52.676,29.747c0-0.88-0.343-1.707-0.965-2.329l-0.557-0.557c0.949-0.84,1.521-2.055,1.521-3.362   c0-2.481-2.019-4.5-4.5-4.5c-0.182,0-0.362,0.018-0.54,0.04c0.022-0.179,0.04-0.357,0.04-0.54c0-2.481-2.019-4.5-4.5-4.5   c-0.182,0-0.362,0.018-0.54,0.04c0.022-0.179,0.04-0.357,0.04-0.54c0-2.481-2.019-4.5-4.5-4.5c-0.182,0-0.362,0.018-0.54,0.04   c0.022-0.179,0.04-0.357,0.04-0.54c0-2.481-2.019-4.5-4.5-4.5c-1.308,0-2.522,0.573-3.362,1.521l-0.794-0.794l-3.763-3.763   c-1.285-1.285-3.375-1.285-4.658,0L8.286,13.275c-1.283,1.285-1.283,3.374,0,4.659l3.763,3.763l4.91,4.91   c-1.356,0.776-2.283,2.221-2.283,3.892c0,1.563,0.803,2.941,2.017,3.748c0.061,0.081,0.132,0.161,0.227,0.242l10.756,10.715v1.796   h-2v13h18h8v-13h-2V43.97c1.913-1.621,3-3.952,3-6.471c0-1.74-0.543-3.43-1.536-4.852l0.571-0.571   C52.333,31.454,52.676,30.627,52.676,29.747z M50.676,23.499c0,0.768-0.354,1.479-0.937,1.947l-3.511-3.511   c0.468-0.583,1.18-0.937,1.947-0.937C49.554,20.999,50.676,22.12,50.676,23.499z M45.676,18.499c0,0.768-0.354,1.479-0.937,1.947   l-3.511-3.511c0.468-0.583,1.18-0.937,1.947-0.937C44.554,15.999,45.676,17.12,45.676,18.499z M40.676,13.499   c0,0.768-0.354,1.479-0.937,1.947l-3.511-3.511c0.468-0.583,1.18-0.937,1.947-0.937C39.554,10.999,40.676,12.12,40.676,13.499z    M33.176,5.999c1.379,0,2.5,1.121,2.5,2.5c0,0.768-0.354,1.479-0.937,1.947l-3.511-3.511C31.696,6.353,32.408,5.999,33.176,5.999z    M9.7,16.521c-0.504-0.505-0.504-1.326,0-1.831L22.012,2.378c0.125-0.125,0.271-0.219,0.426-0.282   c0.07-0.029,0.149-0.028,0.223-0.044c0.178-0.038,0.354-0.038,0.532,0c0.074,0.016,0.153,0.015,0.223,0.044   c0.155,0.063,0.3,0.157,0.426,0.282l2.349,2.349L12.049,18.869L9.7,16.521z M27.605,6.141l1.178,1.178l5,5l0.573,0.573l4.427,4.427   l0.573,0.573l4.427,4.427l0.573,0.573l5,5l0.94,0.94c0.505,0.505,0.505,1.325,0,1.83L49.859,31.1l0,0L37.985,42.975   c-0.503,0.504-1.326,0.506-1.831,0l-7.975-7.976h0.996c2.481,0,4.5-2.019,4.5-4.5s-2.019-4.5-4.5-4.5h-9.997l-5.716-5.716   L27.605,6.141z M18.636,28.061l0.415-0.047c0.041-0.006,0.082-0.015,0.124-0.015h10c1.379,0,2.5,1.121,2.5,2.5s-1.121,2.5-2.5,2.5   h-2.996h-2.828h-4.176c-1.379,0-2.5-1.121-2.5-2.5C16.676,29.306,17.517,28.309,18.636,28.061z M27.676,57.999v-9h8.426   c3.073,0,5.574,2.501,5.574,5.574v3.426H27.676z M49.676,57.999h-6v-3.426c0-2.206-0.954-4.188-2.464-5.574h8.464V57.999z    M49.701,34.087c0.634,1.021,0.975,2.202,0.975,3.412c0,2.055-0.948,3.946-2.602,5.191l-0.398,0.3v4.009H36.101h-6.426v-2.718   l-0.353-0.299c-0.045-0.039-0.093-0.075-0.18-0.14l-8.877-8.844h5.085l9.389,9.39c0.643,0.642,1.486,0.963,2.329,0.963   c0.844,0,1.688-0.321,2.33-0.963L49.701,34.087z"
-       id="path11"
-       style="fill:#ed7831;fill-opacity:1" /></g><g
-     id="g13" /><g
-     id="g15" /><g
-     id="g17" /><g
-     id="g19" /><g
-     id="g21" /><g
-     id="g23" /><g
-     id="g25" /><g
-     id="g27" /><g
-     id="g29" /><g
-     id="g31" /><g
-     id="g33" /><g
-     id="g35" /><g
-     id="g37" /><g
-     id="g39" /><g
-     id="g41" /></svg>
\ No newline at end of file
diff --git a/edumed/static/img/menu/olimpiada/svg/literatura.svg b/edumed/static/img/menu/olimpiada/svg/literatura.svg
deleted file mode 100644 (file)
index a004d7e..0000000
+++ /dev/null
@@ -1,63 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
-
-<svg
-   xmlns:dc="http://purl.org/dc/elements/1.1/"
-   xmlns:cc="http://creativecommons.org/ns#"
-   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
-   xmlns:svg="http://www.w3.org/2000/svg"
-   xmlns="http://www.w3.org/2000/svg"
-   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
-   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
-   version="1.1"
-   id="Capa_1"
-   x="0px"
-   y="0px"
-   viewBox="0 0 60 60"
-   style="enable-background:new 0 0 60 60;"
-   xml:space="preserve"
-   inkscape:version="0.48.4 r9939"
-   width="100%"
-   height="100%"
-   sodipodi:docname="literatura.svg"><metadata
-     id="metadata39"><rdf:RDF><cc:Work
-         rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
-           rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs
-     id="defs37" /><sodipodi:namedview
-     pagecolor="#ffffff"
-     bordercolor="#666666"
-     borderopacity="1"
-     objecttolerance="10"
-     gridtolerance="10"
-     guidetolerance="10"
-     inkscape:pageopacity="0"
-     inkscape:pageshadow="2"
-     inkscape:window-width="769"
-     inkscape:window-height="480"
-     id="namedview35"
-     showgrid="false"
-     inkscape:zoom="3.9333333"
-     inkscape:cx="30"
-     inkscape:cy="30"
-     inkscape:window-x="0"
-     inkscape:window-y="24"
-     inkscape:window-maximized="0"
-     inkscape:current-layer="Capa_1" /><path
-     d="M13,0c-1.547,0-3.033,0.662-4.078,1.817C7.895,2.954,7.389,4.476,7.525,6H7.5v48.958C7.5,57.738,9.762,60,12.542,60H52.5V11  V9V0H13z M9.5,54.958V9.998c0.836,0.629,1.875,1.002,3,1.002v46.996C10.842,57.973,9.5,56.621,9.5,54.958z M50.5,58h-36V11h3v25.201  c0,0.682,0.441,1.262,1.099,1.444c0.137,0.037,0.273,0.056,0.408,0.056c0.015,0,0.029-0.005,0.044-0.006  c0.045-0.001,0.088-0.012,0.133-0.017c0.103-0.012,0.202-0.033,0.299-0.066c0.048-0.016,0.093-0.035,0.138-0.056  c0.094-0.043,0.18-0.097,0.263-0.159c0.036-0.027,0.073-0.05,0.106-0.08c0.111-0.099,0.212-0.211,0.292-0.346l4.217-7.028  l4.217,7.029c0.327,0.545,0.939,0.801,1.55,0.687c0.045-0.008,0.089-0.002,0.134-0.014c0.657-0.183,1.099-0.763,1.099-1.444V11h19  V58z M29.64,9.483l-0.003,0.007L29.5,9.764v0.042l-0.1,0.23l0.1,0.152v0.112V34.39l-5-8.333l-5,8.333V10.236L21.118,7h9.764  L29.64,9.483z M32.118,9l2-4H19.882l-2,4h-4.67c-1.894,0-3.516-1.379-3.693-3.14c-0.101-0.998,0.214-1.957,0.887-2.701  C11.071,2.422,12.017,2,13,2h37.5v1h-5c-0.553,0-1,0.447-1,1s0.447,1,1,1h5v1h-4c-0.553,0-1,0.447-1,1s0.447,1,1,1h4v1H32.118z"
-     id="path3"
-     style="stroke:none;stroke-opacity:1;fill:#96928b;fill-opacity:1;" /><g
-     id="g5" /><g
-     id="g7" /><g
-     id="g9" /><g
-     id="g11" /><g
-     id="g13" /><g
-     id="g15" /><g
-     id="g17" /><g
-     id="g19" /><g
-     id="g21" /><g
-     id="g23" /><g
-     id="g25" /><g
-     id="g27" /><g
-     id="g29" /><g
-     id="g31" /><g
-     id="g33" /></svg>
\ No newline at end of file
diff --git a/edumed/static/img/menu/olimpiada/svg/literatura_active.svg b/edumed/static/img/menu/olimpiada/svg/literatura_active.svg
deleted file mode 100644 (file)
index 20395e7..0000000
+++ /dev/null
@@ -1,63 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
-
-<svg
-   xmlns:dc="http://purl.org/dc/elements/1.1/"
-   xmlns:cc="http://creativecommons.org/ns#"
-   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
-   xmlns:svg="http://www.w3.org/2000/svg"
-   xmlns="http://www.w3.org/2000/svg"
-   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
-   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
-   version="1.1"
-   id="Capa_1"
-   x="0px"
-   y="0px"
-   viewBox="0 0 60 60"
-   style="enable-background:new 0 0 60 60;"
-   xml:space="preserve"
-   inkscape:version="0.48.4 r9939"
-   width="100%"
-   height="100%"
-   sodipodi:docname="literatura.svg"><metadata
-     id="metadata39"><rdf:RDF><cc:Work
-         rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
-           rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
-     id="defs37" /><sodipodi:namedview
-     pagecolor="#ffffff"
-     bordercolor="#666666"
-     borderopacity="1"
-     objecttolerance="10"
-     gridtolerance="10"
-     guidetolerance="10"
-     inkscape:pageopacity="0"
-     inkscape:pageshadow="2"
-     inkscape:window-width="769"
-     inkscape:window-height="480"
-     id="namedview35"
-     showgrid="false"
-     inkscape:zoom="3.9333333"
-     inkscape:cx="30"
-     inkscape:cy="30"
-     inkscape:window-x="0"
-     inkscape:window-y="24"
-     inkscape:window-maximized="0"
-     inkscape:current-layer="Capa_1" /><path
-     d="M13,0c-1.547,0-3.033,0.662-4.078,1.817C7.895,2.954,7.389,4.476,7.525,6H7.5v48.958C7.5,57.738,9.762,60,12.542,60H52.5V11  V9V0H13z M9.5,54.958V9.998c0.836,0.629,1.875,1.002,3,1.002v46.996C10.842,57.973,9.5,56.621,9.5,54.958z M50.5,58h-36V11h3v25.201  c0,0.682,0.441,1.262,1.099,1.444c0.137,0.037,0.273,0.056,0.408,0.056c0.015,0,0.029-0.005,0.044-0.006  c0.045-0.001,0.088-0.012,0.133-0.017c0.103-0.012,0.202-0.033,0.299-0.066c0.048-0.016,0.093-0.035,0.138-0.056  c0.094-0.043,0.18-0.097,0.263-0.159c0.036-0.027,0.073-0.05,0.106-0.08c0.111-0.099,0.212-0.211,0.292-0.346l4.217-7.028  l4.217,7.029c0.327,0.545,0.939,0.801,1.55,0.687c0.045-0.008,0.089-0.002,0.134-0.014c0.657-0.183,1.099-0.763,1.099-1.444V11h19  V58z M29.64,9.483l-0.003,0.007L29.5,9.764v0.042l-0.1,0.23l0.1,0.152v0.112V34.39l-5-8.333l-5,8.333V10.236L21.118,7h9.764  L29.64,9.483z M32.118,9l2-4H19.882l-2,4h-4.67c-1.894,0-3.516-1.379-3.693-3.14c-0.101-0.998,0.214-1.957,0.887-2.701  C11.071,2.422,12.017,2,13,2h37.5v1h-5c-0.553,0-1,0.447-1,1s0.447,1,1,1h5v1h-4c-0.553,0-1,0.447-1,1s0.447,1,1,1h4v1H32.118z"
-     id="path3"
-     style="stroke:none;stroke-opacity:1;fill:#ed7831;fill-opacity:1" /><g
-     id="g5" /><g
-     id="g7" /><g
-     id="g9" /><g
-     id="g11" /><g
-     id="g13" /><g
-     id="g15" /><g
-     id="g17" /><g
-     id="g19" /><g
-     id="g21" /><g
-     id="g23" /><g
-     id="g25" /><g
-     id="g27" /><g
-     id="g29" /><g
-     id="g31" /><g
-     id="g33" /></svg>
\ No newline at end of file
diff --git a/edumed/static/img/menu/olimpiada/svg/program.svg b/edumed/static/img/menu/olimpiada/svg/program.svg
deleted file mode 100644 (file)
index 2418f09..0000000
+++ /dev/null
@@ -1,104 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
-
-<svg
-   xmlns:dc="http://purl.org/dc/elements/1.1/"
-   xmlns:cc="http://creativecommons.org/ns#"
-   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
-   xmlns:svg="http://www.w3.org/2000/svg"
-   xmlns="http://www.w3.org/2000/svg"
-   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
-   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
-   version="1.1"
-   id="Capa_1"
-   x="0px"
-   y="0px"
-   viewBox="0 0 54 54"
-   style="enable-background:new 0 0 54 54;"
-   xml:space="preserve"
-   inkscape:version="0.48.4 r9939"
-   width="100%"
-   height="100%"
-   sodipodi:docname="program.svg"><metadata
-     id="metadata57"><rdf:RDF><cc:Work
-         rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
-           rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs
-     id="defs55" /><sodipodi:namedview
-     pagecolor="#ffffff"
-     bordercolor="#666666"
-     borderopacity="1"
-     objecttolerance="10"
-     gridtolerance="10"
-     guidetolerance="10"
-     inkscape:pageopacity="0"
-     inkscape:pageshadow="2"
-     inkscape:window-width="769"
-     inkscape:window-height="480"
-     id="namedview53"
-     showgrid="false"
-     inkscape:zoom="4.3703704"
-     inkscape:cx="27"
-     inkscape:cy="27"
-     inkscape:window-x="0"
-     inkscape:window-y="24"
-     inkscape:window-maximized="0"
-     inkscape:current-layer="Capa_1" /><g
-     id="g3"
-     style="fill:#96928b;fill-opacity:1;"><path
-       d="M53.516,1.143c-0.3-0.182-0.674-0.19-0.983-0.027L36,9.869L19.468,1.116c-0.013-0.007-0.028-0.009-0.041-0.015   c-0.048-0.023-0.097-0.04-0.147-0.055c-0.028-0.008-0.055-0.017-0.083-0.023c-0.055-0.011-0.111-0.015-0.168-0.017   c-0.025-0.001-0.05-0.004-0.076-0.003c-0.054,0.003-0.107,0.013-0.16,0.025c-0.03,0.006-0.06,0.01-0.089,0.019   c-0.007,0.002-0.014,0.002-0.02,0.004l-18,6C0.275,7.187,0,7.569,0,8v43c0,0.321,0.154,0.623,0.416,0.812   C0.588,51.935,0.793,52,1,52c0.106,0,0.213-0.017,0.316-0.052l17.646-5.882l16.657,6.859c0.014,0.006,0.03,0.004,0.044,0.009   C35.773,52.973,35.885,53,36,53c0.09,0,0.179-0.015,0.266-0.039c0.028-0.008,0.054-0.021,0.082-0.031   c0.04-0.015,0.082-0.026,0.12-0.046l17-9C53.795,43.711,54,43.37,54,43V2C54,1.649,53.816,1.324,53.516,1.143z M2,8.721l16-5.333   v26.992c-0.43,0.078-0.854,0.166-1.264,0.274c-0.534,0.142-0.852,0.689-0.71,1.223c0.119,0.448,0.523,0.744,0.966,0.744   c0.084,0,0.171-0.011,0.257-0.033c0.24-0.064,0.502-0.096,0.751-0.148v11.84L2,49.612V8.721z M20,32.16   c0.321-0.025,0.632-0.066,0.961-0.073c0.552-0.012,0.99-0.469,0.979-1.021c-0.012-0.545-0.457-0.979-1-0.979   c-0.007,0-0.015,0-0.022,0c-0.31,0.007-0.615,0.024-0.918,0.045V3.661l15,7.941v21.194c-0.714-0.031-1.44-0.115-2.201-0.262   c-0.544-0.107-1.067,0.249-1.172,0.791s0.25,1.067,0.792,1.172c0.886,0.172,1.746,0.256,2.582,0.289v15.721L20,44.33V32.16z    M52,42.397l-15,7.941v-15.66c0.372-0.169,0.62-0.549,0.587-0.98c-0.029-0.374-0.269-0.674-0.587-0.821V11.602l15-7.941V42.397z"
-       id="path5"
-       style="fill:#96928b;fill-opacity:1" /><path
-       d="M11,9c-2.757,0-5,2.243-5,5c0,2.415,1.721,4.434,4,4.899V21c0,0.553,0.448,1,1,1s1-0.447,1-1v-2.101   c2.279-0.465,4-2.484,4-4.899C16,11.243,13.757,9,11,9z M11,17c-1.654,0-3-1.346-3-3s1.346-3,3-3s3,1.346,3,3S12.654,17,11,17z"
-       id="path7"
-       style="fill:#96928b;fill-opacity:1" /><path
-       d="M45.07,27.673c0.12,0.047,0.243,0.068,0.364,0.068c0.4,0,0.777-0.241,0.932-0.636c0.47-1.199,0.847-2.553,1.123-4.024   c0.102-0.542-0.256-1.064-0.799-1.167c-0.546-0.09-1.065,0.257-1.167,0.8c-0.252,1.348-0.595,2.58-1.019,3.663   C44.303,26.89,44.556,27.471,45.07,27.673z"
-       id="path9"
-       style="fill:#96928b;fill-opacity:1" /><path
-       d="M12.805,32.342c-1.207,0.757-2.295,1.705-3.235,2.82c-0.356,0.422-0.302,1.053,0.12,1.409   c0.188,0.158,0.417,0.235,0.644,0.235c0.285,0,0.567-0.121,0.765-0.355c0.806-0.956,1.737-1.769,2.768-2.414   c0.468-0.294,0.609-0.911,0.316-1.379C13.89,32.19,13.272,32.048,12.805,32.342z"
-       id="path11"
-       style="fill:#96928b;fill-opacity:1" /><path
-       d="M8.627,38.276c-0.502-0.23-1.096-0.013-1.327,0.489c-1.026,2.226-1.28,4.023-1.291,4.099   c-0.075,0.547,0.307,1.05,0.854,1.125c0.046,0.007,0.093,0.01,0.138,0.01c0.491,0,0.919-0.362,0.99-0.861   c0.002-0.016,0.231-1.597,1.125-3.534C9.347,39.101,9.128,38.508,8.627,38.276z"
-       id="path13"
-       style="fill:#96928b;fill-opacity:1" /><path
-       d="M40.423,33.729c0.153,0,0.309-0.035,0.454-0.109c1.292-0.661,2.431-1.599,3.384-2.786c0.346-0.431,0.277-1.061-0.154-1.406   c-0.43-0.343-1.06-0.276-1.406,0.154c-0.776,0.967-1.696,1.726-2.735,2.257c-0.492,0.252-0.687,0.854-0.435,1.346   C39.709,33.53,40.06,33.729,40.423,33.729z"
-       id="path15"
-       style="fill:#96928b;fill-opacity:1" /><path
-       d="M29.17,31.432c-0.441-0.185-0.699-0.313-0.716-0.322c-0.065-0.033-0.134-0.06-0.205-0.078   c-1.083-0.278-2.15-0.498-3.173-0.654c-0.545-0.086-1.056,0.291-1.14,0.837c-0.083,0.546,0.292,1.057,0.838,1.14   c0.926,0.142,1.893,0.34,2.877,0.59c0.134,0.064,0.39,0.185,0.748,0.334c0.126,0.053,0.257,0.077,0.385,0.077   c0.391,0,0.763-0.23,0.923-0.614C29.92,32.23,29.68,31.644,29.17,31.432z"
-       id="path17"
-       style="fill:#96928b;fill-opacity:1" /><path
-       d="M46.923,19.931c0.022,0.001,0.043,0.002,0.065,0.002c0.523,0,0.963-0.406,0.997-0.937c0.062-0.961,0.093-1.978,0.093-3.02   c0-0.347-0.003-0.699-0.01-1.058c-0.01-0.553-0.49-0.973-1.018-0.982c-0.552,0.01-0.992,0.466-0.982,1.018   c0.006,0.347,0.01,0.688,0.01,1.022c0,1-0.03,1.973-0.089,2.893C45.954,19.42,46.372,19.895,46.923,19.931z"
-       id="path19"
-       style="fill:#96928b;fill-opacity:1" /><path
-       d="M8.293,28.707C8.488,28.902,8.744,29,9,29s0.512-0.098,0.707-0.293L11,27.414l1.293,1.293C12.488,28.902,12.744,29,13,29   s0.512-0.098,0.707-0.293c0.391-0.391,0.391-1.023,0-1.414L12.414,26l1.293-1.293c0.391-0.391,0.391-1.023,0-1.414   s-1.023-0.391-1.414,0L11,24.586l-1.293-1.293c-0.391-0.391-1.023-0.391-1.414,0s-0.391,1.023,0,1.414L9.586,26l-1.293,1.293   C7.902,27.683,7.902,28.316,8.293,28.707z"
-       id="path21"
-       style="fill:#96928b;fill-opacity:1" /></g><g
-     id="g23"
-     style="fill:#96928b;fill-opacity:1;" /><g
-     id="g25"
-     style="fill:#96928b;fill-opacity:1;" /><g
-     id="g27"
-     style="fill:#96928b;fill-opacity:1;" /><g
-     id="g29"
-     style="fill:#96928b;fill-opacity:1;" /><g
-     id="g31"
-     style="fill:#96928b;fill-opacity:1;" /><g
-     id="g33"
-     style="fill:#96928b;fill-opacity:1;" /><g
-     id="g35"
-     style="fill:#96928b;fill-opacity:1;" /><g
-     id="g37"
-     style="fill:#96928b;fill-opacity:1;" /><g
-     id="g39"
-     style="fill:#96928b;fill-opacity:1;" /><g
-     id="g41"
-     style="fill:#96928b;fill-opacity:1;" /><g
-     id="g43"
-     style="fill:#96928b;fill-opacity:1;" /><g
-     id="g45"
-     style="fill:#96928b;fill-opacity:1;" /><g
-     id="g47"
-     style="fill:#96928b;fill-opacity:1;" /><g
-     id="g49"
-     style="fill:#96928b;fill-opacity:1;" /><g
-     id="g51"
-     style="fill:#96928b;fill-opacity:1;" /></svg>
\ No newline at end of file
diff --git a/edumed/static/img/menu/olimpiada/svg/program_active.svg b/edumed/static/img/menu/olimpiada/svg/program_active.svg
deleted file mode 100644 (file)
index cf39f15..0000000
+++ /dev/null
@@ -1,104 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
-
-<svg
-   xmlns:dc="http://purl.org/dc/elements/1.1/"
-   xmlns:cc="http://creativecommons.org/ns#"
-   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
-   xmlns:svg="http://www.w3.org/2000/svg"
-   xmlns="http://www.w3.org/2000/svg"
-   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
-   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
-   version="1.1"
-   id="Capa_1"
-   x="0px"
-   y="0px"
-   viewBox="0 0 54 54"
-   style="enable-background:new 0 0 54 54;"
-   xml:space="preserve"
-   inkscape:version="0.48.4 r9939"
-   width="100%"
-   height="100%"
-   sodipodi:docname="program.svg"><metadata
-     id="metadata57"><rdf:RDF><cc:Work
-         rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
-           rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
-     id="defs55" /><sodipodi:namedview
-     pagecolor="#ffffff"
-     bordercolor="#666666"
-     borderopacity="1"
-     objecttolerance="10"
-     gridtolerance="10"
-     guidetolerance="10"
-     inkscape:pageopacity="0"
-     inkscape:pageshadow="2"
-     inkscape:window-width="769"
-     inkscape:window-height="480"
-     id="namedview53"
-     showgrid="false"
-     inkscape:zoom="4.3703704"
-     inkscape:cx="27"
-     inkscape:cy="27"
-     inkscape:window-x="0"
-     inkscape:window-y="24"
-     inkscape:window-maximized="0"
-     inkscape:current-layer="Capa_1" /><g
-     id="g3"
-     style="fill:#ed7831;fill-opacity:1"><path
-       d="M53.516,1.143c-0.3-0.182-0.674-0.19-0.983-0.027L36,9.869L19.468,1.116c-0.013-0.007-0.028-0.009-0.041-0.015   c-0.048-0.023-0.097-0.04-0.147-0.055c-0.028-0.008-0.055-0.017-0.083-0.023c-0.055-0.011-0.111-0.015-0.168-0.017   c-0.025-0.001-0.05-0.004-0.076-0.003c-0.054,0.003-0.107,0.013-0.16,0.025c-0.03,0.006-0.06,0.01-0.089,0.019   c-0.007,0.002-0.014,0.002-0.02,0.004l-18,6C0.275,7.187,0,7.569,0,8v43c0,0.321,0.154,0.623,0.416,0.812   C0.588,51.935,0.793,52,1,52c0.106,0,0.213-0.017,0.316-0.052l17.646-5.882l16.657,6.859c0.014,0.006,0.03,0.004,0.044,0.009   C35.773,52.973,35.885,53,36,53c0.09,0,0.179-0.015,0.266-0.039c0.028-0.008,0.054-0.021,0.082-0.031   c0.04-0.015,0.082-0.026,0.12-0.046l17-9C53.795,43.711,54,43.37,54,43V2C54,1.649,53.816,1.324,53.516,1.143z M2,8.721l16-5.333   v26.992c-0.43,0.078-0.854,0.166-1.264,0.274c-0.534,0.142-0.852,0.689-0.71,1.223c0.119,0.448,0.523,0.744,0.966,0.744   c0.084,0,0.171-0.011,0.257-0.033c0.24-0.064,0.502-0.096,0.751-0.148v11.84L2,49.612V8.721z M20,32.16   c0.321-0.025,0.632-0.066,0.961-0.073c0.552-0.012,0.99-0.469,0.979-1.021c-0.012-0.545-0.457-0.979-1-0.979   c-0.007,0-0.015,0-0.022,0c-0.31,0.007-0.615,0.024-0.918,0.045V3.661l15,7.941v21.194c-0.714-0.031-1.44-0.115-2.201-0.262   c-0.544-0.107-1.067,0.249-1.172,0.791s0.25,1.067,0.792,1.172c0.886,0.172,1.746,0.256,2.582,0.289v15.721L20,44.33V32.16z    M52,42.397l-15,7.941v-15.66c0.372-0.169,0.62-0.549,0.587-0.98c-0.029-0.374-0.269-0.674-0.587-0.821V11.602l15-7.941V42.397z"
-       id="path5"
-       style="fill:#ed7831;fill-opacity:1" /><path
-       d="M11,9c-2.757,0-5,2.243-5,5c0,2.415,1.721,4.434,4,4.899V21c0,0.553,0.448,1,1,1s1-0.447,1-1v-2.101   c2.279-0.465,4-2.484,4-4.899C16,11.243,13.757,9,11,9z M11,17c-1.654,0-3-1.346-3-3s1.346-3,3-3s3,1.346,3,3S12.654,17,11,17z"
-       id="path7"
-       style="fill:#ed7831;fill-opacity:1" /><path
-       d="M45.07,27.673c0.12,0.047,0.243,0.068,0.364,0.068c0.4,0,0.777-0.241,0.932-0.636c0.47-1.199,0.847-2.553,1.123-4.024   c0.102-0.542-0.256-1.064-0.799-1.167c-0.546-0.09-1.065,0.257-1.167,0.8c-0.252,1.348-0.595,2.58-1.019,3.663   C44.303,26.89,44.556,27.471,45.07,27.673z"
-       id="path9"
-       style="fill:#ed7831;fill-opacity:1" /><path
-       d="M12.805,32.342c-1.207,0.757-2.295,1.705-3.235,2.82c-0.356,0.422-0.302,1.053,0.12,1.409   c0.188,0.158,0.417,0.235,0.644,0.235c0.285,0,0.567-0.121,0.765-0.355c0.806-0.956,1.737-1.769,2.768-2.414   c0.468-0.294,0.609-0.911,0.316-1.379C13.89,32.19,13.272,32.048,12.805,32.342z"
-       id="path11"
-       style="fill:#ed7831;fill-opacity:1" /><path
-       d="M8.627,38.276c-0.502-0.23-1.096-0.013-1.327,0.489c-1.026,2.226-1.28,4.023-1.291,4.099   c-0.075,0.547,0.307,1.05,0.854,1.125c0.046,0.007,0.093,0.01,0.138,0.01c0.491,0,0.919-0.362,0.99-0.861   c0.002-0.016,0.231-1.597,1.125-3.534C9.347,39.101,9.128,38.508,8.627,38.276z"
-       id="path13"
-       style="fill:#ed7831;fill-opacity:1" /><path
-       d="M40.423,33.729c0.153,0,0.309-0.035,0.454-0.109c1.292-0.661,2.431-1.599,3.384-2.786c0.346-0.431,0.277-1.061-0.154-1.406   c-0.43-0.343-1.06-0.276-1.406,0.154c-0.776,0.967-1.696,1.726-2.735,2.257c-0.492,0.252-0.687,0.854-0.435,1.346   C39.709,33.53,40.06,33.729,40.423,33.729z"
-       id="path15"
-       style="fill:#ed7831;fill-opacity:1" /><path
-       d="M29.17,31.432c-0.441-0.185-0.699-0.313-0.716-0.322c-0.065-0.033-0.134-0.06-0.205-0.078   c-1.083-0.278-2.15-0.498-3.173-0.654c-0.545-0.086-1.056,0.291-1.14,0.837c-0.083,0.546,0.292,1.057,0.838,1.14   c0.926,0.142,1.893,0.34,2.877,0.59c0.134,0.064,0.39,0.185,0.748,0.334c0.126,0.053,0.257,0.077,0.385,0.077   c0.391,0,0.763-0.23,0.923-0.614C29.92,32.23,29.68,31.644,29.17,31.432z"
-       id="path17"
-       style="fill:#ed7831;fill-opacity:1" /><path
-       d="M46.923,19.931c0.022,0.001,0.043,0.002,0.065,0.002c0.523,0,0.963-0.406,0.997-0.937c0.062-0.961,0.093-1.978,0.093-3.02   c0-0.347-0.003-0.699-0.01-1.058c-0.01-0.553-0.49-0.973-1.018-0.982c-0.552,0.01-0.992,0.466-0.982,1.018   c0.006,0.347,0.01,0.688,0.01,1.022c0,1-0.03,1.973-0.089,2.893C45.954,19.42,46.372,19.895,46.923,19.931z"
-       id="path19"
-       style="fill:#ed7831;fill-opacity:1" /><path
-       d="M8.293,28.707C8.488,28.902,8.744,29,9,29s0.512-0.098,0.707-0.293L11,27.414l1.293,1.293C12.488,28.902,12.744,29,13,29   s0.512-0.098,0.707-0.293c0.391-0.391,0.391-1.023,0-1.414L12.414,26l1.293-1.293c0.391-0.391,0.391-1.023,0-1.414   s-1.023-0.391-1.414,0L11,24.586l-1.293-1.293c-0.391-0.391-1.023-0.391-1.414,0s-0.391,1.023,0,1.414L9.586,26l-1.293,1.293   C7.902,27.683,7.902,28.316,8.293,28.707z"
-       id="path21"
-       style="fill:#ed7831;fill-opacity:1" /></g><g
-     id="g23"
-     style="fill:#ed7831;fill-opacity:1" /><g
-     id="g25"
-     style="fill:#ed7831;fill-opacity:1" /><g
-     id="g27"
-     style="fill:#ed7831;fill-opacity:1" /><g
-     id="g29"
-     style="fill:#ed7831;fill-opacity:1" /><g
-     id="g31"
-     style="fill:#ed7831;fill-opacity:1" /><g
-     id="g33"
-     style="fill:#ed7831;fill-opacity:1" /><g
-     id="g35"
-     style="fill:#ed7831;fill-opacity:1" /><g
-     id="g37"
-     style="fill:#ed7831;fill-opacity:1" /><g
-     id="g39"
-     style="fill:#ed7831;fill-opacity:1" /><g
-     id="g41"
-     style="fill:#ed7831;fill-opacity:1" /><g
-     id="g43"
-     style="fill:#ed7831;fill-opacity:1" /><g
-     id="g45"
-     style="fill:#ed7831;fill-opacity:1" /><g
-     id="g47"
-     style="fill:#ed7831;fill-opacity:1" /><g
-     id="g49"
-     style="fill:#ed7831;fill-opacity:1" /><g
-     id="g51"
-     style="fill:#ed7831;fill-opacity:1" /></svg>
\ No newline at end of file
diff --git a/edumed/static/img/menu/olimpiada/svg/regulamin.svg b/edumed/static/img/menu/olimpiada/svg/regulamin.svg
deleted file mode 100644 (file)
index 61c274e..0000000
+++ /dev/null
@@ -1,98 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
-
-<svg
-   xmlns:dc="http://purl.org/dc/elements/1.1/"
-   xmlns:cc="http://creativecommons.org/ns#"
-   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
-   xmlns:svg="http://www.w3.org/2000/svg"
-   xmlns="http://www.w3.org/2000/svg"
-   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
-   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
-   version="1.1"
-   id="Capa_1"
-   x="0px"
-   y="0px"
-   viewBox="0 0 60 60"
-   style="enable-background:new 0 0 60 60;"
-   xml:space="preserve"
-   inkscape:version="0.48.4 r9939"
-   width="100%"
-   height="100%"
-   sodipodi:docname="regulamin.svg"><metadata
-     id="metadata53"><rdf:RDF><cc:Work
-         rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
-           rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs
-     id="defs51" /><sodipodi:namedview
-     pagecolor="#ffffff"
-     bordercolor="#666666"
-     borderopacity="1"
-     objecttolerance="10"
-     gridtolerance="10"
-     guidetolerance="10"
-     inkscape:pageopacity="0"
-     inkscape:pageshadow="2"
-     inkscape:window-width="769"
-     inkscape:window-height="480"
-     id="namedview49"
-     showgrid="false"
-     inkscape:zoom="3.9333333"
-     inkscape:cx="30"
-     inkscape:cy="30"
-     inkscape:window-x="0"
-     inkscape:window-y="24"
-     inkscape:window-maximized="0"
-     inkscape:current-layer="Capa_1" /><g
-     id="g3"
-     style="fill:#96928b;fill-opacity:1"><path
-       d="M38.914,0H6.5v60h47V14.586L38.914,0z M39.5,3.414L50.086,14H39.5V3.414z M8.5,58V2h29v14h14v42H8.5z"
-       id="path5"
-       style="fill:#96928b;fill-opacity:1" /><path
-       d="M42.5,21h-16c-0.552,0-1,0.447-1,1s0.448,1,1,1h16c0.552,0,1-0.447,1-1S43.052,21,42.5,21z"
-       id="path7"
-       style="fill:#96928b;fill-opacity:1" /><path
-       d="M22.875,18.219l-4.301,3.441l-1.367-1.367c-0.391-0.391-1.023-0.391-1.414,0s-0.391,1.023,0,1.414l2,2   C17.987,23.901,18.243,24,18.5,24c0.22,0,0.441-0.072,0.624-0.219l5-4c0.432-0.346,0.501-0.975,0.156-1.406   C23.936,17.943,23.306,17.874,22.875,18.219z"
-       id="path9"
-       style="fill:#96928b;fill-opacity:1" /><path
-       d="M42.5,32h-16c-0.552,0-1,0.447-1,1s0.448,1,1,1h16c0.552,0,1-0.447,1-1S43.052,32,42.5,32z"
-       id="path11"
-       style="fill:#96928b;fill-opacity:1" /><path
-       d="M22.875,29.219l-4.301,3.441l-1.367-1.367c-0.391-0.391-1.023-0.391-1.414,0s-0.391,1.023,0,1.414l2,2   C17.987,34.901,18.243,35,18.5,35c0.22,0,0.441-0.072,0.624-0.219l5-4c0.432-0.346,0.501-0.975,0.156-1.406   C23.936,28.943,23.306,28.874,22.875,29.219z"
-       id="path13"
-       style="fill:#96928b;fill-opacity:1" /><path
-       d="M42.5,43h-16c-0.552,0-1,0.447-1,1s0.448,1,1,1h16c0.552,0,1-0.447,1-1S43.052,43,42.5,43z"
-       id="path15"
-       style="fill:#96928b;fill-opacity:1" /><path
-       d="M22.875,40.219l-4.301,3.441l-1.367-1.367c-0.391-0.391-1.023-0.391-1.414,0s-0.391,1.023,0,1.414l2,2   C17.987,45.901,18.243,46,18.5,46c0.22,0,0.441-0.072,0.624-0.219l5-4c0.432-0.346,0.501-0.975,0.156-1.406   C23.936,39.943,23.306,39.874,22.875,40.219z"
-       id="path17"
-       style="fill:#96928b;fill-opacity:1" /></g><g
-     id="g19"
-     style="fill:#96928b;fill-opacity:1" /><g
-     id="g21"
-     style="fill:#96928b;fill-opacity:1" /><g
-     id="g23"
-     style="fill:#96928b;fill-opacity:1" /><g
-     id="g25"
-     style="fill:#96928b;fill-opacity:1" /><g
-     id="g27"
-     style="fill:#96928b;fill-opacity:1" /><g
-     id="g29"
-     style="fill:#96928b;fill-opacity:1" /><g
-     id="g31"
-     style="fill:#96928b;fill-opacity:1" /><g
-     id="g33"
-     style="fill:#96928b;fill-opacity:1" /><g
-     id="g35"
-     style="fill:#96928b;fill-opacity:1" /><g
-     id="g37"
-     style="fill:#96928b;fill-opacity:1" /><g
-     id="g39"
-     style="fill:#96928b;fill-opacity:1" /><g
-     id="g41"
-     style="fill:#96928b;fill-opacity:1" /><g
-     id="g43"
-     style="fill:#96928b;fill-opacity:1" /><g
-     id="g45"
-     style="fill:#96928b;fill-opacity:1" /><g
-     id="g47"
-     style="fill:#96928b;fill-opacity:1" /></svg>
\ No newline at end of file
diff --git a/edumed/static/img/menu/olimpiada/svg/regulamin_active.svg b/edumed/static/img/menu/olimpiada/svg/regulamin_active.svg
deleted file mode 100644 (file)
index 50f8f6d..0000000
+++ /dev/null
@@ -1,98 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
-
-<svg
-   xmlns:dc="http://purl.org/dc/elements/1.1/"
-   xmlns:cc="http://creativecommons.org/ns#"
-   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
-   xmlns:svg="http://www.w3.org/2000/svg"
-   xmlns="http://www.w3.org/2000/svg"
-   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
-   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
-   version="1.1"
-   id="Capa_1"
-   x="0px"
-   y="0px"
-   viewBox="0 0 60 60"
-   style="enable-background:new 0 0 60 60;"
-   xml:space="preserve"
-   inkscape:version="0.48.4 r9939"
-   width="100%"
-   height="100%"
-   sodipodi:docname="regulamin.svg"><metadata
-     id="metadata53"><rdf:RDF><cc:Work
-         rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
-           rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
-     id="defs51" /><sodipodi:namedview
-     pagecolor="#ffffff"
-     bordercolor="#666666"
-     borderopacity="1"
-     objecttolerance="10"
-     gridtolerance="10"
-     guidetolerance="10"
-     inkscape:pageopacity="0"
-     inkscape:pageshadow="2"
-     inkscape:window-width="769"
-     inkscape:window-height="480"
-     id="namedview49"
-     showgrid="false"
-     inkscape:zoom="3.9333333"
-     inkscape:cx="30"
-     inkscape:cy="30"
-     inkscape:window-x="0"
-     inkscape:window-y="24"
-     inkscape:window-maximized="0"
-     inkscape:current-layer="Capa_1" /><g
-     id="g3"
-     style="fill:#ed7831;fill-opacity:1"><path
-       d="M38.914,0H6.5v60h47V14.586L38.914,0z M39.5,3.414L50.086,14H39.5V3.414z M8.5,58V2h29v14h14v42H8.5z"
-       id="path5"
-       style="fill:#ed7831;fill-opacity:1" /><path
-       d="M42.5,21h-16c-0.552,0-1,0.447-1,1s0.448,1,1,1h16c0.552,0,1-0.447,1-1S43.052,21,42.5,21z"
-       id="path7"
-       style="fill:#ed7831;fill-opacity:1" /><path
-       d="M22.875,18.219l-4.301,3.441l-1.367-1.367c-0.391-0.391-1.023-0.391-1.414,0s-0.391,1.023,0,1.414l2,2   C17.987,23.901,18.243,24,18.5,24c0.22,0,0.441-0.072,0.624-0.219l5-4c0.432-0.346,0.501-0.975,0.156-1.406   C23.936,17.943,23.306,17.874,22.875,18.219z"
-       id="path9"
-       style="fill:#ed7831;fill-opacity:1" /><path
-       d="M42.5,32h-16c-0.552,0-1,0.447-1,1s0.448,1,1,1h16c0.552,0,1-0.447,1-1S43.052,32,42.5,32z"
-       id="path11"
-       style="fill:#ed7831;fill-opacity:1" /><path
-       d="M22.875,29.219l-4.301,3.441l-1.367-1.367c-0.391-0.391-1.023-0.391-1.414,0s-0.391,1.023,0,1.414l2,2   C17.987,34.901,18.243,35,18.5,35c0.22,0,0.441-0.072,0.624-0.219l5-4c0.432-0.346,0.501-0.975,0.156-1.406   C23.936,28.943,23.306,28.874,22.875,29.219z"
-       id="path13"
-       style="fill:#ed7831;fill-opacity:1" /><path
-       d="M42.5,43h-16c-0.552,0-1,0.447-1,1s0.448,1,1,1h16c0.552,0,1-0.447,1-1S43.052,43,42.5,43z"
-       id="path15"
-       style="fill:#ed7831;fill-opacity:1" /><path
-       d="M22.875,40.219l-4.301,3.441l-1.367-1.367c-0.391-0.391-1.023-0.391-1.414,0s-0.391,1.023,0,1.414l2,2   C17.987,45.901,18.243,46,18.5,46c0.22,0,0.441-0.072,0.624-0.219l5-4c0.432-0.346,0.501-0.975,0.156-1.406   C23.936,39.943,23.306,39.874,22.875,40.219z"
-       id="path17"
-       style="fill:#ed7831;fill-opacity:1" /></g><g
-     id="g19"
-     style="fill:#ed7831;fill-opacity:1" /><g
-     id="g21"
-     style="fill:#ed7831;fill-opacity:1" /><g
-     id="g23"
-     style="fill:#ed7831;fill-opacity:1" /><g
-     id="g25"
-     style="fill:#ed7831;fill-opacity:1" /><g
-     id="g27"
-     style="fill:#ed7831;fill-opacity:1" /><g
-     id="g29"
-     style="fill:#ed7831;fill-opacity:1" /><g
-     id="g31"
-     style="fill:#ed7831;fill-opacity:1" /><g
-     id="g33"
-     style="fill:#ed7831;fill-opacity:1" /><g
-     id="g35"
-     style="fill:#ed7831;fill-opacity:1" /><g
-     id="g37"
-     style="fill:#ed7831;fill-opacity:1" /><g
-     id="g39"
-     style="fill:#ed7831;fill-opacity:1" /><g
-     id="g41"
-     style="fill:#ed7831;fill-opacity:1" /><g
-     id="g43"
-     style="fill:#ed7831;fill-opacity:1" /><g
-     id="g45"
-     style="fill:#ed7831;fill-opacity:1" /><g
-     id="g47"
-     style="fill:#ed7831;fill-opacity:1" /></svg>
\ No newline at end of file
diff --git a/edumed/static/img/menu/olimpiada_active.png b/edumed/static/img/menu/olimpiada_active.png
deleted file mode 100644 (file)
index 8dce21b..0000000
Binary files a/edumed/static/img/menu/olimpiada_active.png and /dev/null differ
diff --git a/edumed/static/img/menu/svg/convert.txt b/edumed/static/img/menu/svg/convert.txt
deleted file mode 100644 (file)
index ecf1788..0000000
+++ /dev/null
@@ -1 +0,0 @@
-for f in *.svg; do convert -background none "$f" -resize 44x34 -gravity center -extent 44x34 png/"`basename \"$f\" .svg`.png"; done
diff --git a/edumed/static/img/menu/svg/dla-trenera.svg b/edumed/static/img/menu/svg/dla-trenera.svg
deleted file mode 100644 (file)
index 0f8622b..0000000
+++ /dev/null
@@ -1,69 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
-
-<svg
-   xmlns:dc="http://purl.org/dc/elements/1.1/"
-   xmlns:cc="http://creativecommons.org/ns#"
-   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
-   xmlns:svg="http://www.w3.org/2000/svg"
-   xmlns="http://www.w3.org/2000/svg"
-   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
-   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
-   version="1.1"
-   id="Capa_1"
-   x="0px"
-   y="0px"
-   width="757.671px"
-   height="757.671px"
-   viewBox="0 0 757.671 757.671"
-   style="enable-background:new 0 0 757.671 757.671;"
-   xml:space="preserve"
-   inkscape:version="0.91 r13725"
-   sodipodi:docname="dla trenera.svg"><metadata
-     id="metadata44"><rdf:RDF><cc:Work
-         rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
-           rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
-     id="defs42" /><sodipodi:namedview
-     pagecolor="#ffffff"
-     bordercolor="#666666"
-     borderopacity="1"
-     objecttolerance="10"
-     gridtolerance="10"
-     guidetolerance="10"
-     inkscape:pageopacity="0"
-     inkscape:pageshadow="2"
-     inkscape:window-width="711"
-     inkscape:window-height="480"
-     id="namedview40"
-     showgrid="false"
-     inkscape:zoom="0.31148083"
-     inkscape:cx="-117.18217"
-     inkscape:cy="378.83551"
-     inkscape:window-x="0"
-     inkscape:window-y="24"
-     inkscape:window-maximized="0"
-     inkscape:current-layer="Capa_1" /><g
-     id="g3"
-     style="fill:#96928b;fill-opacity:1"><g
-       id="Shape_13"
-       style="fill:#96928b;fill-opacity:1"><g
-         id="g6"
-         style="fill:#96928b;fill-opacity:1"><path
-           d="M583.68,495.079H451.693v-50.213c91.013-32.567,153.67-119.792,153.67-215.774C605.363,102.772,503.086,0,377.378,0     c-102.933,0-189.837,70.104-217.1,165.604c-0.044,0.087-0.131,0.146-0.161,0.233c-0.51,1.151-0.597,2.346-0.787,3.526     c-5.1,19.074-8.058,39.037-8.058,59.729c0,95.822,63.094,183.061,154.719,215.789v50.198h-133.27     c-53.215,0-99.887,45.623-99.887,97.629v150.377c0,8.058,6.528,14.586,14.571,14.586h582.857c8.043,0,14.571-6.528,14.571-14.586     V592.708C684.835,540.702,637.566,495.079,583.68,495.079z M377.378,29.172c78.481,0,146.282,46.06,178.602,112.608     c-0.524,0.117-1.049,0.015-1.559,0.189c-0.933,0.32-95.298,31.693-178.763,50.33c-64.202,14.338-152.257-16.349-184.139-28.851     C218.375,85.418,291.436,29.172,377.378,29.172z M655.693,728.499H101.979V592.708c0-36.473,33.062-68.457,70.744-68.457H320.55     c8.043,0,14.571-6.528,14.571-14.586v-75.319c0-6.412-4.196-12.08-10.316-13.945c-85.024-25.966-144.403-104.637-144.403-191.293     c0-12.736,1.297-25.15,3.555-37.215c29.522,11.467,93.752,33.325,154.545,33.325c14.892,0,29.594-1.326,43.51-4.43     c84.937-18.958,180.671-50.811,181.633-51.131c1.137-0.379,2.011-1.107,2.987-1.705c6.178,19.293,9.603,39.824,9.603,61.171     c0,86.846-58.941,165.503-143.354,191.294c-6.134,1.851-10.331,7.519-10.331,13.931v75.319c0,8.059,6.528,14.586,14.572,14.586     H583.68c37.682,0,72.013,32.626,72.013,68.457V728.499z"
-           id="path8"
-           style="fill:#96928b;fill-opacity:1" /></g></g></g><g
-     id="g10" /><g
-     id="g12" /><g
-     id="g14" /><g
-     id="g16" /><g
-     id="g18" /><g
-     id="g20" /><g
-     id="g22" /><g
-     id="g24" /><g
-     id="g26" /><g
-     id="g28" /><g
-     id="g30" /><g
-     id="g32" /><g
-     id="g34" /><g
-     id="g36" /><g
-     id="g38" /></svg>
\ No newline at end of file
diff --git a/edumed/static/img/menu/svg/dla-trenera_active.svg b/edumed/static/img/menu/svg/dla-trenera_active.svg
deleted file mode 100644 (file)
index 1dd32dc..0000000
+++ /dev/null
@@ -1,69 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
-
-<svg
-   xmlns:dc="http://purl.org/dc/elements/1.1/"
-   xmlns:cc="http://creativecommons.org/ns#"
-   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
-   xmlns:svg="http://www.w3.org/2000/svg"
-   xmlns="http://www.w3.org/2000/svg"
-   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
-   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
-   version="1.1"
-   id="Capa_1"
-   x="0px"
-   y="0px"
-   width="757.671px"
-   height="757.671px"
-   viewBox="0 0 757.671 757.671"
-   style="enable-background:new 0 0 757.671 757.671;"
-   xml:space="preserve"
-   inkscape:version="0.91 r13725"
-   sodipodi:docname="dla trenera.svg"><metadata
-     id="metadata44"><rdf:RDF><cc:Work
-         rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
-           rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
-     id="defs42" /><sodipodi:namedview
-     pagecolor="#ffffff"
-     bordercolor="#666666"
-     borderopacity="1"
-     objecttolerance="10"
-     gridtolerance="10"
-     guidetolerance="10"
-     inkscape:pageopacity="0"
-     inkscape:pageshadow="2"
-     inkscape:window-width="711"
-     inkscape:window-height="480"
-     id="namedview40"
-     showgrid="false"
-     inkscape:zoom="0.31148083"
-     inkscape:cx="-117.18217"
-     inkscape:cy="378.83551"
-     inkscape:window-x="0"
-     inkscape:window-y="24"
-     inkscape:window-maximized="0"
-     inkscape:current-layer="Capa_1" /><g
-     id="g3"
-     style="fill:#ed7831;fill-opacity:1"><g
-       id="Shape_13"
-       style="fill:#ed7831;fill-opacity:1"><g
-         id="g6"
-         style="fill:#ed7831;fill-opacity:1"><path
-           d="M583.68,495.079H451.693v-50.213c91.013-32.567,153.67-119.792,153.67-215.774C605.363,102.772,503.086,0,377.378,0     c-102.933,0-189.837,70.104-217.1,165.604c-0.044,0.087-0.131,0.146-0.161,0.233c-0.51,1.151-0.597,2.346-0.787,3.526     c-5.1,19.074-8.058,39.037-8.058,59.729c0,95.822,63.094,183.061,154.719,215.789v50.198h-133.27     c-53.215,0-99.887,45.623-99.887,97.629v150.377c0,8.058,6.528,14.586,14.571,14.586h582.857c8.043,0,14.571-6.528,14.571-14.586     V592.708C684.835,540.702,637.566,495.079,583.68,495.079z M377.378,29.172c78.481,0,146.282,46.06,178.602,112.608     c-0.524,0.117-1.049,0.015-1.559,0.189c-0.933,0.32-95.298,31.693-178.763,50.33c-64.202,14.338-152.257-16.349-184.139-28.851     C218.375,85.418,291.436,29.172,377.378,29.172z M655.693,728.499H101.979V592.708c0-36.473,33.062-68.457,70.744-68.457H320.55     c8.043,0,14.571-6.528,14.571-14.586v-75.319c0-6.412-4.196-12.08-10.316-13.945c-85.024-25.966-144.403-104.637-144.403-191.293     c0-12.736,1.297-25.15,3.555-37.215c29.522,11.467,93.752,33.325,154.545,33.325c14.892,0,29.594-1.326,43.51-4.43     c84.937-18.958,180.671-50.811,181.633-51.131c1.137-0.379,2.011-1.107,2.987-1.705c6.178,19.293,9.603,39.824,9.603,61.171     c0,86.846-58.941,165.503-143.354,191.294c-6.134,1.851-10.331,7.519-10.331,13.931v75.319c0,8.059,6.528,14.586,14.572,14.586     H583.68c37.682,0,72.013,32.626,72.013,68.457V728.499z"
-           id="path8"
-           style="fill:#ed7831;fill-opacity:1" /></g></g></g><g
-     id="g10" /><g
-     id="g12" /><g
-     id="g14" /><g
-     id="g16" /><g
-     id="g18" /><g
-     id="g20" /><g
-     id="g22" /><g
-     id="g24" /><g
-     id="g26" /><g
-     id="g28" /><g
-     id="g30" /><g
-     id="g32" /><g
-     id="g34" /><g
-     id="g36" /><g
-     id="g38" /></svg>
\ No newline at end of file
diff --git a/edumed/static/img/menu/svg/dla-ucznia.svg b/edumed/static/img/menu/svg/dla-ucznia.svg
deleted file mode 100644 (file)
index 22162b8..0000000
+++ /dev/null
@@ -1,72 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
-
-<svg
-   xmlns:dc="http://purl.org/dc/elements/1.1/"
-   xmlns:cc="http://creativecommons.org/ns#"
-   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
-   xmlns:svg="http://www.w3.org/2000/svg"
-   xmlns="http://www.w3.org/2000/svg"
-   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
-   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
-   version="1.1"
-   id="Capa_1"
-   x="0px"
-   y="0px"
-   viewBox="0 0 470 470"
-   style="enable-background:new 0 0 470 470;"
-   xml:space="preserve"
-   inkscape:version="0.91 r13725"
-   sodipodi:docname="dla ucznia.svg"><metadata
-     id="metadata47"><rdf:RDF><cc:Work
-         rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
-           rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs
-     id="defs45" /><sodipodi:namedview
-     pagecolor="#ffffff"
-     bordercolor="#666666"
-     borderopacity="1"
-     objecttolerance="10"
-     gridtolerance="10"
-     guidetolerance="10"
-     inkscape:pageopacity="0"
-     inkscape:pageshadow="2"
-     inkscape:window-width="711"
-     inkscape:window-height="480"
-     id="namedview43"
-     showgrid="false"
-     inkscape:zoom="0.50212766"
-     inkscape:cx="235"
-     inkscape:cy="235"
-     inkscape:window-x="102"
-     inkscape:window-y="144"
-     inkscape:window-maximized="0"
-     inkscape:current-layer="Capa_1" /><g
-     id="g3"
-     style="fill-opacity:1;fill:#96928b"><path
-       d="M107.5,15h60.021v69.559c-2.525,7.419-3.771,14.829-3.771,22.606c0,39.287,31.962,71.25,71.25,71.25   c39.287,0,71.25-31.963,71.25-71.25c0-7.778-1.246-15.188-3.771-22.608V15H340v90.674l-7.675,18.53   c-1.586,3.827,0.231,8.214,4.059,9.799c3.827,1.589,8.214-0.231,9.799-4.059l1.317-3.18l1.317,3.18   c1.196,2.889,3.988,4.632,6.932,4.632c0.956,0,1.929-0.185,2.867-0.573c3.827-1.585,5.645-5.972,4.059-9.799L355,105.674V15h7.5   c4.143,0,7.5-3.357,7.5-7.5S366.643,0,362.5,0h-255c-4.142,0-7.5,3.357-7.5,7.5S103.358,15,107.5,15z M235,163.415   c-31.016,0-56.25-25.233-56.25-56.25c0-5.524,0.8-10.822,2.424-16.11c6.048-2.862,12.801-4.365,19.7-4.365   c10.687,0,21.103,3.77,29.329,10.614c1.39,1.157,3.094,1.735,4.797,1.735c1.704,0,3.407-0.578,4.798-1.735   c8.225-6.845,18.641-10.614,29.328-10.614c6.9,0,13.652,1.503,19.7,4.365c1.624,5.288,2.424,10.585,2.424,16.11   C291.25,138.182,266.017,163.415,235,163.415z M287.479,74.469c-5.879-1.832-12.077-2.779-18.353-2.779   c-12.18,0-24.093,3.688-34.126,10.479c-10.034-6.792-21.947-10.479-34.126-10.479c-6.275,0-12.473,0.947-18.353,2.779V15h104.958   V74.469z"
-       id="path5"
-       style="fill-opacity:1;fill:#96928b" /><path
-       d="M462.5,320.915h-92.712c-2.487-45.183-27.294-84.51-63.555-107.126c-0.456-0.363-0.945-0.661-1.455-0.903   c-20.375-12.353-44.261-19.471-69.778-19.471s-49.403,7.118-69.779,19.471c-0.509,0.242-0.998,0.539-1.453,0.902   c-36.262,22.616-61.07,61.943-63.557,107.127H7.5c-4.142,0-7.5,3.357-7.5,7.5s3.358,7.5,7.5,7.5h23.039l9.482,127.143   c0.293,3.941,3.582,6.942,7.471,6.942c0.187,0,0.376-0.007,0.565-0.021c4.131-0.309,7.229-3.906,6.921-8.037L45.58,335.915h378.84   l-9.399,126.027c-0.308,4.131,2.791,7.729,6.922,8.037c0.189,0.014,0.378,0.021,0.565,0.021c3.889,0,7.178-3.001,7.472-6.942   l9.482-127.143H462.5c4.143,0,7.5-3.357,7.5-7.5S466.643,320.915,462.5,320.915z M235,239.172c-4.142,0-7.5,3.357-7.5,7.5v21.437   l-46.724-46.725c14.19-7.218,29.999-11.691,46.724-12.728v8.016c0,4.143,3.358,7.5,7.5,7.5c4.143,0,7.5-3.357,7.5-7.5v-8.016   c16.725,1.037,32.533,5.509,46.724,12.728L242.5,268.108v-21.437C242.5,242.529,239.143,239.172,235,239.172z M167.459,229.28   l62.238,62.238c0.2,0.194,0.371,0.35,0.55,0.497c0.087,0.071,0.178,0.133,0.267,0.199c0.107,0.08,0.212,0.163,0.323,0.237   c0.105,0.071,0.215,0.131,0.323,0.196c0.102,0.061,0.202,0.125,0.307,0.182c0.11,0.059,0.223,0.108,0.336,0.162   c0.109,0.052,0.217,0.106,0.329,0.152c0.11,0.045,0.222,0.082,0.333,0.122c0.12,0.043,0.238,0.089,0.36,0.126   c0.111,0.033,0.223,0.058,0.335,0.086c0.125,0.032,0.249,0.067,0.377,0.092c0.129,0.025,0.26,0.041,0.39,0.06   c0.112,0.016,0.221,0.037,0.334,0.048c0.246,0.024,0.493,0.037,0.74,0.037c0.247,0,0.494-0.013,0.74-0.037   c0.115-0.011,0.226-0.033,0.339-0.049c0.129-0.019,0.257-0.033,0.385-0.059c0.13-0.026,0.257-0.062,0.385-0.094   c0.109-0.027,0.219-0.051,0.326-0.084c0.125-0.038,0.247-0.084,0.369-0.129c0.108-0.039,0.217-0.074,0.324-0.118   c0.115-0.048,0.226-0.104,0.338-0.157c0.109-0.052,0.22-0.1,0.328-0.157c0.107-0.058,0.208-0.123,0.312-0.185   c0.107-0.064,0.215-0.124,0.319-0.193c0.111-0.074,0.214-0.156,0.321-0.236c0.09-0.067,0.182-0.13,0.27-0.202   c0.162-0.133,0.316-0.275,0.466-0.421c0.027-0.026,0.056-0.048,0.083-0.075l62.238-62.238   c29.708,20.304,49.859,53.598,52.217,91.634H115.241C117.599,282.878,137.751,249.585,167.459,229.28z"
-       id="path7"
-       style="fill-opacity:1;fill:#96928b" /><path
-       d="M159.737,360.916h-30c-4.142,0-7.5,3.357-7.5,7.5c0,22.175-16.638,40.368-38.701,42.32   c-4.086,0.361-7.124,3.938-6.818,8.028l3.303,44.293c0.293,3.941,3.582,6.943,7.471,6.942c0.187,0,0.376-0.007,0.565-0.021   c4.131-0.309,7.229-3.906,6.921-8.037l-2.789-37.394c11.417-2.521,21.831-8.484,29.866-17.214   c8.082-8.778,13.166-19.729,14.694-31.419h22.987c4.142,0,7.5-3.357,7.5-7.5S163.879,360.916,159.737,360.916z"
-       id="path9"
-       style="fill-opacity:1;fill:#96928b" /><path
-       d="M386.465,410.736c-22.064-1.952-38.702-20.146-38.702-42.32c0-4.143-3.357-7.5-7.5-7.5H189.737c-4.142,0-7.5,3.357-7.5,7.5   s3.358,7.5,7.5,7.5H333.25c1.528,11.69,6.612,22.641,14.693,31.42c8.035,8.729,18.449,14.691,29.866,17.213l-2.789,37.394   c-0.308,4.131,2.791,7.729,6.922,8.037c0.189,0.014,0.378,0.021,0.565,0.021c3.889,0,7.178-3.001,7.472-6.942l3.304-44.293   C393.588,414.675,390.551,411.098,386.465,410.736z"
-       id="path11"
-       style="fill-opacity:1;fill:#96928b" /></g><g
-     id="g13" /><g
-     id="g15" /><g
-     id="g17" /><g
-     id="g19" /><g
-     id="g21" /><g
-     id="g23" /><g
-     id="g25" /><g
-     id="g27" /><g
-     id="g29" /><g
-     id="g31" /><g
-     id="g33" /><g
-     id="g35" /><g
-     id="g37" /><g
-     id="g39" /><g
-     id="g41" /></svg>
\ No newline at end of file
diff --git a/edumed/static/img/menu/svg/dla-ucznia_active.svg b/edumed/static/img/menu/svg/dla-ucznia_active.svg
deleted file mode 100644 (file)
index 5a46fe0..0000000
+++ /dev/null
@@ -1,72 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
-
-<svg
-   xmlns:dc="http://purl.org/dc/elements/1.1/"
-   xmlns:cc="http://creativecommons.org/ns#"
-   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
-   xmlns:svg="http://www.w3.org/2000/svg"
-   xmlns="http://www.w3.org/2000/svg"
-   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
-   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
-   version="1.1"
-   id="Capa_1"
-   x="0px"
-   y="0px"
-   viewBox="0 0 470 470"
-   style="enable-background:new 0 0 470 470;"
-   xml:space="preserve"
-   inkscape:version="0.91 r13725"
-   sodipodi:docname="dla ucznia.svg"><metadata
-     id="metadata47"><rdf:RDF><cc:Work
-         rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
-           rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs
-     id="defs45" /><sodipodi:namedview
-     pagecolor="#ffffff"
-     bordercolor="#666666"
-     borderopacity="1"
-     objecttolerance="10"
-     gridtolerance="10"
-     guidetolerance="10"
-     inkscape:pageopacity="0"
-     inkscape:pageshadow="2"
-     inkscape:window-width="711"
-     inkscape:window-height="480"
-     id="namedview43"
-     showgrid="false"
-     inkscape:zoom="0.50212766"
-     inkscape:cx="235"
-     inkscape:cy="235"
-     inkscape:window-x="102"
-     inkscape:window-y="144"
-     inkscape:window-maximized="0"
-     inkscape:current-layer="Capa_1" /><g
-     id="g3"
-     style="fill-opacity:1;fill:#ed7831"><path
-       d="M107.5,15h60.021v69.559c-2.525,7.419-3.771,14.829-3.771,22.606c0,39.287,31.962,71.25,71.25,71.25   c39.287,0,71.25-31.963,71.25-71.25c0-7.778-1.246-15.188-3.771-22.608V15H340v90.674l-7.675,18.53   c-1.586,3.827,0.231,8.214,4.059,9.799c3.827,1.589,8.214-0.231,9.799-4.059l1.317-3.18l1.317,3.18   c1.196,2.889,3.988,4.632,6.932,4.632c0.956,0,1.929-0.185,2.867-0.573c3.827-1.585,5.645-5.972,4.059-9.799L355,105.674V15h7.5   c4.143,0,7.5-3.357,7.5-7.5S366.643,0,362.5,0h-255c-4.142,0-7.5,3.357-7.5,7.5S103.358,15,107.5,15z M235,163.415   c-31.016,0-56.25-25.233-56.25-56.25c0-5.524,0.8-10.822,2.424-16.11c6.048-2.862,12.801-4.365,19.7-4.365   c10.687,0,21.103,3.77,29.329,10.614c1.39,1.157,3.094,1.735,4.797,1.735c1.704,0,3.407-0.578,4.798-1.735   c8.225-6.845,18.641-10.614,29.328-10.614c6.9,0,13.652,1.503,19.7,4.365c1.624,5.288,2.424,10.585,2.424,16.11   C291.25,138.182,266.017,163.415,235,163.415z M287.479,74.469c-5.879-1.832-12.077-2.779-18.353-2.779   c-12.18,0-24.093,3.688-34.126,10.479c-10.034-6.792-21.947-10.479-34.126-10.479c-6.275,0-12.473,0.947-18.353,2.779V15h104.958   V74.469z"
-       id="path5"
-       style="fill-opacity:1;fill:#ed7831" /><path
-       d="M462.5,320.915h-92.712c-2.487-45.183-27.294-84.51-63.555-107.126c-0.456-0.363-0.945-0.661-1.455-0.903   c-20.375-12.353-44.261-19.471-69.778-19.471s-49.403,7.118-69.779,19.471c-0.509,0.242-0.998,0.539-1.453,0.902   c-36.262,22.616-61.07,61.943-63.557,107.127H7.5c-4.142,0-7.5,3.357-7.5,7.5s3.358,7.5,7.5,7.5h23.039l9.482,127.143   c0.293,3.941,3.582,6.942,7.471,6.942c0.187,0,0.376-0.007,0.565-0.021c4.131-0.309,7.229-3.906,6.921-8.037L45.58,335.915h378.84   l-9.399,126.027c-0.308,4.131,2.791,7.729,6.922,8.037c0.189,0.014,0.378,0.021,0.565,0.021c3.889,0,7.178-3.001,7.472-6.942   l9.482-127.143H462.5c4.143,0,7.5-3.357,7.5-7.5S466.643,320.915,462.5,320.915z M235,239.172c-4.142,0-7.5,3.357-7.5,7.5v21.437   l-46.724-46.725c14.19-7.218,29.999-11.691,46.724-12.728v8.016c0,4.143,3.358,7.5,7.5,7.5c4.143,0,7.5-3.357,7.5-7.5v-8.016   c16.725,1.037,32.533,5.509,46.724,12.728L242.5,268.108v-21.437C242.5,242.529,239.143,239.172,235,239.172z M167.459,229.28   l62.238,62.238c0.2,0.194,0.371,0.35,0.55,0.497c0.087,0.071,0.178,0.133,0.267,0.199c0.107,0.08,0.212,0.163,0.323,0.237   c0.105,0.071,0.215,0.131,0.323,0.196c0.102,0.061,0.202,0.125,0.307,0.182c0.11,0.059,0.223,0.108,0.336,0.162   c0.109,0.052,0.217,0.106,0.329,0.152c0.11,0.045,0.222,0.082,0.333,0.122c0.12,0.043,0.238,0.089,0.36,0.126   c0.111,0.033,0.223,0.058,0.335,0.086c0.125,0.032,0.249,0.067,0.377,0.092c0.129,0.025,0.26,0.041,0.39,0.06   c0.112,0.016,0.221,0.037,0.334,0.048c0.246,0.024,0.493,0.037,0.74,0.037c0.247,0,0.494-0.013,0.74-0.037   c0.115-0.011,0.226-0.033,0.339-0.049c0.129-0.019,0.257-0.033,0.385-0.059c0.13-0.026,0.257-0.062,0.385-0.094   c0.109-0.027,0.219-0.051,0.326-0.084c0.125-0.038,0.247-0.084,0.369-0.129c0.108-0.039,0.217-0.074,0.324-0.118   c0.115-0.048,0.226-0.104,0.338-0.157c0.109-0.052,0.22-0.1,0.328-0.157c0.107-0.058,0.208-0.123,0.312-0.185   c0.107-0.064,0.215-0.124,0.319-0.193c0.111-0.074,0.214-0.156,0.321-0.236c0.09-0.067,0.182-0.13,0.27-0.202   c0.162-0.133,0.316-0.275,0.466-0.421c0.027-0.026,0.056-0.048,0.083-0.075l62.238-62.238   c29.708,20.304,49.859,53.598,52.217,91.634H115.241C117.599,282.878,137.751,249.585,167.459,229.28z"
-       id="path7"
-       style="fill-opacity:1;fill:#ed7831" /><path
-       d="M159.737,360.916h-30c-4.142,0-7.5,3.357-7.5,7.5c0,22.175-16.638,40.368-38.701,42.32   c-4.086,0.361-7.124,3.938-6.818,8.028l3.303,44.293c0.293,3.941,3.582,6.943,7.471,6.942c0.187,0,0.376-0.007,0.565-0.021   c4.131-0.309,7.229-3.906,6.921-8.037l-2.789-37.394c11.417-2.521,21.831-8.484,29.866-17.214   c8.082-8.778,13.166-19.729,14.694-31.419h22.987c4.142,0,7.5-3.357,7.5-7.5S163.879,360.916,159.737,360.916z"
-       id="path9"
-       style="fill-opacity:1;fill:#ed7831" /><path
-       d="M386.465,410.736c-22.064-1.952-38.702-20.146-38.702-42.32c0-4.143-3.357-7.5-7.5-7.5H189.737c-4.142,0-7.5,3.357-7.5,7.5   s3.358,7.5,7.5,7.5H333.25c1.528,11.69,6.612,22.641,14.693,31.42c8.035,8.729,18.449,14.691,29.866,17.213l-2.789,37.394   c-0.308,4.131,2.791,7.729,6.922,8.037c0.189,0.014,0.378,0.021,0.565,0.021c3.889,0,7.178-3.001,7.472-6.942l3.304-44.293   C393.588,414.675,390.551,411.098,386.465,410.736z"
-       id="path11"
-       style="fill-opacity:1;fill:#ed7831" /></g><g
-     id="g13" /><g
-     id="g15" /><g
-     id="g17" /><g
-     id="g19" /><g
-     id="g21" /><g
-     id="g23" /><g
-     id="g25" /><g
-     id="g27" /><g
-     id="g29" /><g
-     id="g31" /><g
-     id="g33" /><g
-     id="g35" /><g
-     id="g37" /><g
-     id="g39" /><g
-     id="g41" /></svg>
\ No newline at end of file
diff --git a/edumed/static/img/menu/svg/kompetencje.svg b/edumed/static/img/menu/svg/kompetencje.svg
deleted file mode 100644 (file)
index 754b6f4..0000000
+++ /dev/null
@@ -1,76 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!-- Generator: Adobe Illustrator 17.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
-
-<svg
-   xmlns:dc="http://purl.org/dc/elements/1.1/"
-   xmlns:cc="http://creativecommons.org/ns#"
-   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
-   xmlns:svg="http://www.w3.org/2000/svg"
-   xmlns="http://www.w3.org/2000/svg"
-   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
-   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
-   version="1.1"
-   id="Capa_1"
-   x="0px"
-   y="0px"
-   viewBox="0 0 455 455"
-   style="enable-background:new 0 0 455 455;"
-   xml:space="preserve"
-   inkscape:version="0.91 r13725"
-   sodipodi:docname="kompetencje.svg"><metadata
-     id="metadata43"><rdf:RDF><cc:Work
-         rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
-           rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs
-     id="defs41"><filter
-       inkscape:collect="always"
-       style="color-interpolation-filters:sRGB"
-       id="filter4183"
-       x="-2.8610229e-09"
-       width="1"
-       y="-2.8610229e-09"
-       height="1"><feGaussianBlur
-         inkscape:collect="always"
-         stdDeviation="5.4240227e-07"
-         id="feGaussianBlur4185" /></filter></defs><sodipodi:namedview
-     pagecolor="#ffffff"
-     bordercolor="#666666"
-     borderopacity="1"
-     objecttolerance="10"
-     gridtolerance="10"
-     guidetolerance="10"
-     inkscape:pageopacity="0"
-     inkscape:pageshadow="2"
-     inkscape:window-width="711"
-     inkscape:window-height="480"
-     id="namedview39"
-     showgrid="false"
-     inkscape:zoom="0.51868132"
-     inkscape:cx="227.5"
-     inkscape:cy="227.5"
-     inkscape:window-x="0"
-     inkscape:window-y="24"
-     inkscape:window-maximized="0"
-     inkscape:current-layer="Capa_1" /><g
-     id="g3"
-     style="fill:#96928b;fill-opacity:1;filter:url(#filter4183)"><path
-       d="M388.367,66.633C345.397,23.664,288.268,0,227.5,0S109.603,23.664,66.633,66.633C23.664,109.602,0,166.732,0,227.5   s23.664,117.897,66.633,160.867C109.603,431.336,166.732,455,227.5,455s117.897-23.664,160.867-66.633   C431.336,345.397,455,288.268,455,227.5S431.336,109.602,388.367,66.633z M227.5,440C110.327,440,15,344.673,15,227.5   S110.327,15,227.5,15S440,110.327,440,227.5S344.673,440,227.5,440z"
-       id="path5"
-       style="fill:#96928b;fill-opacity:1" /><path
-       d="M408.47,287.517c-18.08-8.265-40.271-15.036-65.283-20.114C344.382,254.329,345,240.979,345,227.5   s-0.618-26.829-1.813-39.904c25.012-5.077,47.203-11.849,65.283-20.114c3.767-1.722,5.425-6.172,3.703-9.939   c-1.723-3.767-6.17-5.425-9.939-3.703c-16.541,7.561-37.264,13.873-60.703,18.693c-3.177-24.893-8.47-48.544-15.617-69.895   c9.22-4.434,18.175-9.499,26.797-15.195c3.456-2.283,4.407-6.936,2.124-10.392s-6.937-4.407-10.392-2.124   c-7.634,5.043-15.545,9.563-23.684,13.548c-6.54-16.612-14.271-31.532-23.066-44.147c-2.368-3.397-7.043-4.233-10.441-1.864   c-3.397,2.369-4.232,7.043-1.863,10.441c8.268,11.861,15.541,25.944,21.696,41.67c-22.829,9.232-47.17,14.423-72.084,15.291V37.5   c0-4.142-3.357-7.5-7.5-7.5s-7.5,3.358-7.5,7.5v72.367c-24.914-0.868-49.255-6.059-72.084-15.291   c6.155-15.726,13.428-29.808,21.696-41.67c2.369-3.398,1.534-8.073-1.863-10.441c-3.399-2.369-8.073-1.534-10.441,1.864   c-8.794,12.615-16.526,27.534-23.066,44.147c-8.139-3.984-16.05-8.504-23.684-13.548c-3.455-2.283-8.108-1.332-10.392,2.124   c-2.283,3.456-1.332,8.109,2.124,10.392c8.622,5.696,17.577,10.762,26.797,15.195c-7.147,21.352-12.44,45.002-15.617,69.895   c-23.439-4.82-44.162-11.132-60.703-18.693c-3.767-1.722-8.218-0.064-9.939,3.703s-0.063,8.217,3.703,9.939   c18.08,8.265,40.271,15.036,65.283,20.114C110.618,200.671,110,214.021,110,227.5s0.618,26.829,1.813,39.904   c-25.012,5.077-47.203,11.849-65.283,20.114c-3.767,1.722-5.425,6.172-3.703,9.939c1.723,3.767,6.172,5.426,9.939,3.703   c16.541-7.561,37.264-13.873,60.703-18.693c3.177,24.893,8.47,48.544,15.617,69.895c-9.22,4.434-18.174,9.499-26.797,15.195   c-3.456,2.283-4.407,6.936-2.124,10.392c2.282,3.456,6.936,4.407,10.392,2.124c7.634-5.043,15.545-9.563,23.684-13.548   c6.54,16.613,14.271,31.532,23.066,44.147c1.458,2.091,3.789,3.211,6.159,3.211c1.479,0,2.976-0.437,4.282-1.348   c3.397-2.369,4.232-7.043,1.863-10.442c-8.268-11.862-15.541-25.944-21.696-41.67c22.829-9.232,47.17-14.423,72.084-15.291V417.5   c0,4.142,3.357,7.5,7.5,7.5s7.5-3.358,7.5-7.5v-72.367c24.914,0.868,49.255,6.059,72.084,15.291   c-6.155,15.726-13.428,29.808-21.696,41.67c-2.369,3.398-1.534,8.073,1.863,10.442c1.307,0.911,2.802,1.348,4.282,1.348   c2.37,0,4.701-1.12,6.159-3.211c8.794-12.615,16.526-27.535,23.066-44.147c8.139,3.984,16.05,8.504,23.684,13.548   c1.272,0.841,2.708,1.243,4.127,1.243c2.435,0,4.822-1.184,6.265-3.367c2.283-3.456,1.332-8.109-2.124-10.392   c-8.623-5.696-17.577-10.761-26.797-15.195c7.147-21.352,12.44-45.002,15.617-69.895c23.439,4.82,44.162,11.132,60.703,18.693   c1.011,0.462,2.07,0.681,3.113,0.681c2.845,0,5.566-1.627,6.826-4.384C413.895,293.689,412.236,289.239,408.47,287.517z M330,227.5   c0,12.557-0.556,24.979-1.62,37.147c-28.573-4.837-60.255-7.576-93.38-7.936V198.29c33.125-0.36,64.807-3.1,93.38-7.936   C329.444,202.521,330,214.943,330,227.5z M312.169,108.701c6.696,20.307,11.653,42.838,14.616,66.603   c-28.137,4.822-59.465,7.607-91.785,7.981v-58.414C261.662,124.004,287.719,118.516,312.169,108.701z M142.831,108.701   c24.45,9.815,50.507,15.302,77.169,16.171v58.414c-32.32-0.374-63.648-3.159-91.785-7.981   C131.179,151.539,136.136,129.008,142.831,108.701z M125,227.5c0-12.557,0.556-24.979,1.62-37.147   c28.573,4.837,60.255,7.576,93.38,7.936v58.421c-33.125,0.36-64.807,3.1-93.38,7.936C125.556,252.479,125,240.057,125,227.5z    M142.832,346.299c-6.696-20.307-11.653-42.838-14.617-66.603c28.137-4.822,59.465-7.607,91.785-7.981v58.414   C193.338,330.996,167.281,336.484,142.832,346.299z M312.168,346.299c-24.449-9.815-50.507-15.302-77.168-16.171v-58.414   c32.32,0.374,63.648,3.159,91.785,7.981C323.821,303.461,318.864,325.992,312.168,346.299z"
-       id="path7"
-       style="fill:#96928b;fill-opacity:1" /></g><g
-     id="g9" /><g
-     id="g11" /><g
-     id="g13" /><g
-     id="g15" /><g
-     id="g17" /><g
-     id="g19" /><g
-     id="g21" /><g
-     id="g23" /><g
-     id="g25" /><g
-     id="g27" /><g
-     id="g29" /><g
-     id="g31" /><g
-     id="g33" /><g
-     id="g35" /><g
-     id="g37" /></svg>
\ No newline at end of file
diff --git a/edumed/static/img/menu/svg/kompetencje_active.svg b/edumed/static/img/menu/svg/kompetencje_active.svg
deleted file mode 100644 (file)
index fa61ac2..0000000
+++ /dev/null
@@ -1,76 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!-- Generator: Adobe Illustrator 17.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
-
-<svg
-   xmlns:dc="http://purl.org/dc/elements/1.1/"
-   xmlns:cc="http://creativecommons.org/ns#"
-   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
-   xmlns:svg="http://www.w3.org/2000/svg"
-   xmlns="http://www.w3.org/2000/svg"
-   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
-   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
-   version="1.1"
-   id="Capa_1"
-   x="0px"
-   y="0px"
-   viewBox="0 0 455 455"
-   style="enable-background:new 0 0 455 455;"
-   xml:space="preserve"
-   inkscape:version="0.91 r13725"
-   sodipodi:docname="kompetencje.svg"><metadata
-     id="metadata43"><rdf:RDF><cc:Work
-         rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
-           rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs
-     id="defs41"><filter
-       inkscape:collect="always"
-       style="color-interpolation-filters:sRGB"
-       id="filter4183"
-       x="-2.8610229e-09"
-       width="1"
-       y="-2.8610229e-09"
-       height="1"><feGaussianBlur
-         inkscape:collect="always"
-         stdDeviation="5.4240227e-07"
-         id="feGaussianBlur4185" /></filter></defs><sodipodi:namedview
-     pagecolor="#ffffff"
-     bordercolor="#666666"
-     borderopacity="1"
-     objecttolerance="10"
-     gridtolerance="10"
-     guidetolerance="10"
-     inkscape:pageopacity="0"
-     inkscape:pageshadow="2"
-     inkscape:window-width="711"
-     inkscape:window-height="480"
-     id="namedview39"
-     showgrid="false"
-     inkscape:zoom="0.51868132"
-     inkscape:cx="227.5"
-     inkscape:cy="227.5"
-     inkscape:window-x="0"
-     inkscape:window-y="24"
-     inkscape:window-maximized="0"
-     inkscape:current-layer="Capa_1" /><g
-     id="g3"
-     style="fill:#ed7831;fill-opacity:1;filter:url(#filter4183)"><path
-       d="M388.367,66.633C345.397,23.664,288.268,0,227.5,0S109.603,23.664,66.633,66.633C23.664,109.602,0,166.732,0,227.5   s23.664,117.897,66.633,160.867C109.603,431.336,166.732,455,227.5,455s117.897-23.664,160.867-66.633   C431.336,345.397,455,288.268,455,227.5S431.336,109.602,388.367,66.633z M227.5,440C110.327,440,15,344.673,15,227.5   S110.327,15,227.5,15S440,110.327,440,227.5S344.673,440,227.5,440z"
-       id="path5"
-       style="fill:#ed7831;fill-opacity:1" /><path
-       d="M408.47,287.517c-18.08-8.265-40.271-15.036-65.283-20.114C344.382,254.329,345,240.979,345,227.5   s-0.618-26.829-1.813-39.904c25.012-5.077,47.203-11.849,65.283-20.114c3.767-1.722,5.425-6.172,3.703-9.939   c-1.723-3.767-6.17-5.425-9.939-3.703c-16.541,7.561-37.264,13.873-60.703,18.693c-3.177-24.893-8.47-48.544-15.617-69.895   c9.22-4.434,18.175-9.499,26.797-15.195c3.456-2.283,4.407-6.936,2.124-10.392s-6.937-4.407-10.392-2.124   c-7.634,5.043-15.545,9.563-23.684,13.548c-6.54-16.612-14.271-31.532-23.066-44.147c-2.368-3.397-7.043-4.233-10.441-1.864   c-3.397,2.369-4.232,7.043-1.863,10.441c8.268,11.861,15.541,25.944,21.696,41.67c-22.829,9.232-47.17,14.423-72.084,15.291V37.5   c0-4.142-3.357-7.5-7.5-7.5s-7.5,3.358-7.5,7.5v72.367c-24.914-0.868-49.255-6.059-72.084-15.291   c6.155-15.726,13.428-29.808,21.696-41.67c2.369-3.398,1.534-8.073-1.863-10.441c-3.399-2.369-8.073-1.534-10.441,1.864   c-8.794,12.615-16.526,27.534-23.066,44.147c-8.139-3.984-16.05-8.504-23.684-13.548c-3.455-2.283-8.108-1.332-10.392,2.124   c-2.283,3.456-1.332,8.109,2.124,10.392c8.622,5.696,17.577,10.762,26.797,15.195c-7.147,21.352-12.44,45.002-15.617,69.895   c-23.439-4.82-44.162-11.132-60.703-18.693c-3.767-1.722-8.218-0.064-9.939,3.703s-0.063,8.217,3.703,9.939   c18.08,8.265,40.271,15.036,65.283,20.114C110.618,200.671,110,214.021,110,227.5s0.618,26.829,1.813,39.904   c-25.012,5.077-47.203,11.849-65.283,20.114c-3.767,1.722-5.425,6.172-3.703,9.939c1.723,3.767,6.172,5.426,9.939,3.703   c16.541-7.561,37.264-13.873,60.703-18.693c3.177,24.893,8.47,48.544,15.617,69.895c-9.22,4.434-18.174,9.499-26.797,15.195   c-3.456,2.283-4.407,6.936-2.124,10.392c2.282,3.456,6.936,4.407,10.392,2.124c7.634-5.043,15.545-9.563,23.684-13.548   c6.54,16.613,14.271,31.532,23.066,44.147c1.458,2.091,3.789,3.211,6.159,3.211c1.479,0,2.976-0.437,4.282-1.348   c3.397-2.369,4.232-7.043,1.863-10.442c-8.268-11.862-15.541-25.944-21.696-41.67c22.829-9.232,47.17-14.423,72.084-15.291V417.5   c0,4.142,3.357,7.5,7.5,7.5s7.5-3.358,7.5-7.5v-72.367c24.914,0.868,49.255,6.059,72.084,15.291   c-6.155,15.726-13.428,29.808-21.696,41.67c-2.369,3.398-1.534,8.073,1.863,10.442c1.307,0.911,2.802,1.348,4.282,1.348   c2.37,0,4.701-1.12,6.159-3.211c8.794-12.615,16.526-27.535,23.066-44.147c8.139,3.984,16.05,8.504,23.684,13.548   c1.272,0.841,2.708,1.243,4.127,1.243c2.435,0,4.822-1.184,6.265-3.367c2.283-3.456,1.332-8.109-2.124-10.392   c-8.623-5.696-17.577-10.761-26.797-15.195c7.147-21.352,12.44-45.002,15.617-69.895c23.439,4.82,44.162,11.132,60.703,18.693   c1.011,0.462,2.07,0.681,3.113,0.681c2.845,0,5.566-1.627,6.826-4.384C413.895,293.689,412.236,289.239,408.47,287.517z M330,227.5   c0,12.557-0.556,24.979-1.62,37.147c-28.573-4.837-60.255-7.576-93.38-7.936V198.29c33.125-0.36,64.807-3.1,93.38-7.936   C329.444,202.521,330,214.943,330,227.5z M312.169,108.701c6.696,20.307,11.653,42.838,14.616,66.603   c-28.137,4.822-59.465,7.607-91.785,7.981v-58.414C261.662,124.004,287.719,118.516,312.169,108.701z M142.831,108.701   c24.45,9.815,50.507,15.302,77.169,16.171v58.414c-32.32-0.374-63.648-3.159-91.785-7.981   C131.179,151.539,136.136,129.008,142.831,108.701z M125,227.5c0-12.557,0.556-24.979,1.62-37.147   c28.573,4.837,60.255,7.576,93.38,7.936v58.421c-33.125,0.36-64.807,3.1-93.38,7.936C125.556,252.479,125,240.057,125,227.5z    M142.832,346.299c-6.696-20.307-11.653-42.838-14.617-66.603c28.137-4.822,59.465-7.607,91.785-7.981v58.414   C193.338,330.996,167.281,336.484,142.832,346.299z M312.168,346.299c-24.449-9.815-50.507-15.302-77.168-16.171v-58.414   c32.32,0.374,63.648,3.159,91.785,7.981C323.821,303.461,318.864,325.992,312.168,346.299z"
-       id="path7"
-       style="fill:#ed7831;fill-opacity:1" /></g><g
-     id="g9" /><g
-     id="g11" /><g
-     id="g13" /><g
-     id="g15" /><g
-     id="g17" /><g
-     id="g19" /><g
-     id="g21" /><g
-     id="g23" /><g
-     id="g25" /><g
-     id="g27" /><g
-     id="g29" /><g
-     id="g31" /><g
-     id="g33" /><g
-     id="g35" /><g
-     id="g37" /></svg>
\ No newline at end of file
diff --git a/edumed/static/img/menu/svg/lekcje.svg b/edumed/static/img/menu/svg/lekcje.svg
deleted file mode 100644 (file)
index 2bd7384..0000000
+++ /dev/null
@@ -1,102 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
-
-<svg
-   xmlns:dc="http://purl.org/dc/elements/1.1/"
-   xmlns:cc="http://creativecommons.org/ns#"
-   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
-   xmlns:svg="http://www.w3.org/2000/svg"
-   xmlns="http://www.w3.org/2000/svg"
-   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
-   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
-   version="1.1"
-   id="Capa_1"
-   x="0px"
-   y="0px"
-   viewBox="0 0 468.74 468.74"
-   style="enable-background:new 0 0 468.74 468.74;"
-   xml:space="preserve"
-   inkscape:version="0.91 r13725"
-   sodipodi:docname="lekcje.svg"><metadata
-     id="metadata67"><rdf:RDF><cc:Work
-         rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
-           rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs
-     id="defs65" /><sodipodi:namedview
-     pagecolor="#ffffff"
-     bordercolor="#666666"
-     borderopacity="1"
-     objecttolerance="10"
-     gridtolerance="10"
-     guidetolerance="10"
-     inkscape:pageopacity="0"
-     inkscape:pageshadow="2"
-     inkscape:window-width="711"
-     inkscape:window-height="480"
-     id="namedview63"
-     showgrid="false"
-     inkscape:zoom="0.50347742"
-     inkscape:cx="234.37"
-     inkscape:cy="234.37"
-     inkscape:window-x="0"
-     inkscape:window-y="24"
-     inkscape:window-maximized="0"
-     inkscape:current-layer="Capa_1" /><g
-     id="g3"
-     style="fill:#96928b;fill-opacity:1"><path
-       d="M461.24,59.245h-21.87v-22.5c0-4.142-3.357-7.5-7.5-7.5H263.104c-10.817,0-21.035,4.134-28.733,11.373   c-7.698-7.238-17.917-11.373-28.732-11.373H36.87c-4.143,0-7.5,3.358-7.5,7.5v22.5H7.5c-4.143,0-7.5,3.358-7.5,7.5v263.346   c0,20.678,16.822,37.5,37.5,37.5h144.37v56.904h-32.5c-4.143,0-7.5,3.358-7.5,7.5s3.357,7.5,7.5,7.5h170c4.143,0,7.5-3.358,7.5-7.5   s-3.357-7.5-7.5-7.5h-32.5v-34.404c0-4.142-3.357-7.5-7.5-7.5s-7.5,3.358-7.5,7.5v34.404h-75v-56.904h234.37   c20.678,0,37.5-16.822,37.5-37.5V66.745C468.74,62.603,465.383,59.245,461.24,59.245z M453.74,74.245v213.14h-14.37V74.245H453.74z    M44.37,44.245h161.268c9.056,0,17.461,4.514,22.486,12.075c1.39,2.092,3.734,3.349,6.246,3.349s4.856-1.257,6.247-3.349   c5.023-7.561,13.43-12.074,22.486-12.074H424.37v243.14h-380V44.245z M29.37,74.245v213.14H15V74.245H29.37z M431.24,352.591H37.5   c-12.406,0-22.5-10.093-22.5-22.5v-27.707h438.74v27.707C453.74,342.498,443.646,352.591,431.24,352.591z"
-       id="path5"
-       style="fill:#96928b;fill-opacity:1" /><path
-       d="M234.37,272.385c4.143,0,7.5-3.358,7.5-7.5V82.168c0-4.142-3.357-7.5-7.5-7.5s-7.5,3.358-7.5,7.5v182.716   C226.87,269.027,230.228,272.385,234.37,272.385z"
-       id="path7"
-       style="fill:#96928b;fill-opacity:1" /><path
-       d="M77.5,84.245h114.965c4.143,0,7.5-3.358,7.5-7.5s-3.357-7.5-7.5-7.5H77.5c-4.143,0-7.5,3.358-7.5,7.5   S73.357,84.245,77.5,84.245z"
-       id="path9"
-       style="fill:#96928b;fill-opacity:1" /><path
-       d="M77.5,119.873h114.965c4.143,0,7.5-3.358,7.5-7.5s-3.357-7.5-7.5-7.5H77.5c-4.143,0-7.5,3.358-7.5,7.5   S73.357,119.873,77.5,119.873z"
-       id="path11"
-       style="fill:#96928b;fill-opacity:1" /><path
-       d="M77.5,155.501h57.482c4.143,0,7.5-3.358,7.5-7.5s-3.357-7.5-7.5-7.5H77.5c-4.143,0-7.5,3.358-7.5,7.5   S73.357,155.501,77.5,155.501z"
-       id="path13"
-       style="fill:#96928b;fill-opacity:1" /><path
-       d="M77.5,191.129h114.965c4.143,0,7.5-3.358,7.5-7.5s-3.357-7.5-7.5-7.5H77.5c-4.143,0-7.5,3.358-7.5,7.5   S73.357,191.129,77.5,191.129z"
-       id="path15"
-       style="fill:#96928b;fill-opacity:1" /><path
-       d="M77.5,226.757h114.965c4.143,0,7.5-3.358,7.5-7.5s-3.357-7.5-7.5-7.5H77.5c-4.143,0-7.5,3.358-7.5,7.5   S73.357,226.757,77.5,226.757z"
-       id="path17"
-       style="fill:#96928b;fill-opacity:1" /><path
-       d="M77.5,262.385h57.482c4.143,0,7.5-3.358,7.5-7.5s-3.357-7.5-7.5-7.5H77.5c-4.143,0-7.5,3.358-7.5,7.5   S73.357,262.385,77.5,262.385z"
-       id="path19"
-       style="fill:#96928b;fill-opacity:1" /><path
-       d="M276.275,84.245h114.964c4.143,0,7.5-3.358,7.5-7.5s-3.357-7.5-7.5-7.5H276.275c-4.143,0-7.5,3.358-7.5,7.5   S272.133,84.245,276.275,84.245z"
-       id="path21"
-       style="fill:#96928b;fill-opacity:1" /><path
-       d="M276.275,119.873h114.964c4.143,0,7.5-3.358,7.5-7.5s-3.357-7.5-7.5-7.5H276.275c-4.143,0-7.5,3.358-7.5,7.5   S272.133,119.873,276.275,119.873z"
-       id="path23"
-       style="fill:#96928b;fill-opacity:1" /><path
-       d="M276.275,155.501h57.481c4.143,0,7.5-3.358,7.5-7.5s-3.357-7.5-7.5-7.5h-57.481c-4.143,0-7.5,3.358-7.5,7.5   S272.133,155.501,276.275,155.501z"
-       id="path25"
-       style="fill:#96928b;fill-opacity:1" /><path
-       d="M276.275,191.129h114.964c4.143,0,7.5-3.358,7.5-7.5s-3.357-7.5-7.5-7.5H276.275c-4.143,0-7.5,3.358-7.5,7.5   S272.133,191.129,276.275,191.129z"
-       id="path27"
-       style="fill:#96928b;fill-opacity:1" /><path
-       d="M276.275,226.757h114.964c4.143,0,7.5-3.358,7.5-7.5s-3.357-7.5-7.5-7.5H276.275c-4.143,0-7.5,3.358-7.5,7.5   S272.133,226.757,276.275,226.757z"
-       id="path29"
-       style="fill:#96928b;fill-opacity:1" /><path
-       d="M276.275,262.385h57.481c4.143,0,7.5-3.358,7.5-7.5s-3.357-7.5-7.5-7.5h-57.481c-4.143,0-7.5,3.358-7.5,7.5   S272.133,262.385,276.275,262.385z"
-       id="path31"
-       style="fill:#96928b;fill-opacity:1" /></g><g
-     id="g33" /><g
-     id="g35" /><g
-     id="g37" /><g
-     id="g39" /><g
-     id="g41" /><g
-     id="g43" /><g
-     id="g45" /><g
-     id="g47" /><g
-     id="g49" /><g
-     id="g51" /><g
-     id="g53" /><g
-     id="g55" /><g
-     id="g57" /><g
-     id="g59" /><g
-     id="g61" /></svg>
\ No newline at end of file
diff --git a/edumed/static/img/menu/svg/lekcje_active.svg b/edumed/static/img/menu/svg/lekcje_active.svg
deleted file mode 100644 (file)
index bc8b24a..0000000
+++ /dev/null
@@ -1,102 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
-
-<svg
-   xmlns:dc="http://purl.org/dc/elements/1.1/"
-   xmlns:cc="http://creativecommons.org/ns#"
-   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
-   xmlns:svg="http://www.w3.org/2000/svg"
-   xmlns="http://www.w3.org/2000/svg"
-   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
-   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
-   version="1.1"
-   id="Capa_1"
-   x="0px"
-   y="0px"
-   viewBox="0 0 468.74 468.74"
-   style="enable-background:new 0 0 468.74 468.74;"
-   xml:space="preserve"
-   inkscape:version="0.91 r13725"
-   sodipodi:docname="lekcje.svg"><metadata
-     id="metadata67"><rdf:RDF><cc:Work
-         rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
-           rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs
-     id="defs65" /><sodipodi:namedview
-     pagecolor="#ffffff"
-     bordercolor="#666666"
-     borderopacity="1"
-     objecttolerance="10"
-     gridtolerance="10"
-     guidetolerance="10"
-     inkscape:pageopacity="0"
-     inkscape:pageshadow="2"
-     inkscape:window-width="711"
-     inkscape:window-height="480"
-     id="namedview63"
-     showgrid="false"
-     inkscape:zoom="0.50347742"
-     inkscape:cx="234.37"
-     inkscape:cy="234.37"
-     inkscape:window-x="0"
-     inkscape:window-y="24"
-     inkscape:window-maximized="0"
-     inkscape:current-layer="Capa_1" /><g
-     id="g3"
-     style="fill:#ed7831;fill-opacity:1"><path
-       d="M461.24,59.245h-21.87v-22.5c0-4.142-3.357-7.5-7.5-7.5H263.104c-10.817,0-21.035,4.134-28.733,11.373   c-7.698-7.238-17.917-11.373-28.732-11.373H36.87c-4.143,0-7.5,3.358-7.5,7.5v22.5H7.5c-4.143,0-7.5,3.358-7.5,7.5v263.346   c0,20.678,16.822,37.5,37.5,37.5h144.37v56.904h-32.5c-4.143,0-7.5,3.358-7.5,7.5s3.357,7.5,7.5,7.5h170c4.143,0,7.5-3.358,7.5-7.5   s-3.357-7.5-7.5-7.5h-32.5v-34.404c0-4.142-3.357-7.5-7.5-7.5s-7.5,3.358-7.5,7.5v34.404h-75v-56.904h234.37   c20.678,0,37.5-16.822,37.5-37.5V66.745C468.74,62.603,465.383,59.245,461.24,59.245z M453.74,74.245v213.14h-14.37V74.245H453.74z    M44.37,44.245h161.268c9.056,0,17.461,4.514,22.486,12.075c1.39,2.092,3.734,3.349,6.246,3.349s4.856-1.257,6.247-3.349   c5.023-7.561,13.43-12.074,22.486-12.074H424.37v243.14h-380V44.245z M29.37,74.245v213.14H15V74.245H29.37z M431.24,352.591H37.5   c-12.406,0-22.5-10.093-22.5-22.5v-27.707h438.74v27.707C453.74,342.498,443.646,352.591,431.24,352.591z"
-       id="path5"
-       style="fill:#ed7831;fill-opacity:1" /><path
-       d="M234.37,272.385c4.143,0,7.5-3.358,7.5-7.5V82.168c0-4.142-3.357-7.5-7.5-7.5s-7.5,3.358-7.5,7.5v182.716   C226.87,269.027,230.228,272.385,234.37,272.385z"
-       id="path7"
-       style="fill:#ed7831;fill-opacity:1" /><path
-       d="M77.5,84.245h114.965c4.143,0,7.5-3.358,7.5-7.5s-3.357-7.5-7.5-7.5H77.5c-4.143,0-7.5,3.358-7.5,7.5   S73.357,84.245,77.5,84.245z"
-       id="path9"
-       style="fill:#ed7831;fill-opacity:1" /><path
-       d="M77.5,119.873h114.965c4.143,0,7.5-3.358,7.5-7.5s-3.357-7.5-7.5-7.5H77.5c-4.143,0-7.5,3.358-7.5,7.5   S73.357,119.873,77.5,119.873z"
-       id="path11"
-       style="fill:#ed7831;fill-opacity:1" /><path
-       d="M77.5,155.501h57.482c4.143,0,7.5-3.358,7.5-7.5s-3.357-7.5-7.5-7.5H77.5c-4.143,0-7.5,3.358-7.5,7.5   S73.357,155.501,77.5,155.501z"
-       id="path13"
-       style="fill:#ed7831;fill-opacity:1" /><path
-       d="M77.5,191.129h114.965c4.143,0,7.5-3.358,7.5-7.5s-3.357-7.5-7.5-7.5H77.5c-4.143,0-7.5,3.358-7.5,7.5   S73.357,191.129,77.5,191.129z"
-       id="path15"
-       style="fill:#ed7831;fill-opacity:1" /><path
-       d="M77.5,226.757h114.965c4.143,0,7.5-3.358,7.5-7.5s-3.357-7.5-7.5-7.5H77.5c-4.143,0-7.5,3.358-7.5,7.5   S73.357,226.757,77.5,226.757z"
-       id="path17"
-       style="fill:#ed7831;fill-opacity:1" /><path
-       d="M77.5,262.385h57.482c4.143,0,7.5-3.358,7.5-7.5s-3.357-7.5-7.5-7.5H77.5c-4.143,0-7.5,3.358-7.5,7.5   S73.357,262.385,77.5,262.385z"
-       id="path19"
-       style="fill:#ed7831;fill-opacity:1" /><path
-       d="M276.275,84.245h114.964c4.143,0,7.5-3.358,7.5-7.5s-3.357-7.5-7.5-7.5H276.275c-4.143,0-7.5,3.358-7.5,7.5   S272.133,84.245,276.275,84.245z"
-       id="path21"
-       style="fill:#ed7831;fill-opacity:1" /><path
-       d="M276.275,119.873h114.964c4.143,0,7.5-3.358,7.5-7.5s-3.357-7.5-7.5-7.5H276.275c-4.143,0-7.5,3.358-7.5,7.5   S272.133,119.873,276.275,119.873z"
-       id="path23"
-       style="fill:#ed7831;fill-opacity:1" /><path
-       d="M276.275,155.501h57.481c4.143,0,7.5-3.358,7.5-7.5s-3.357-7.5-7.5-7.5h-57.481c-4.143,0-7.5,3.358-7.5,7.5   S272.133,155.501,276.275,155.501z"
-       id="path25"
-       style="fill:#ed7831;fill-opacity:1" /><path
-       d="M276.275,191.129h114.964c4.143,0,7.5-3.358,7.5-7.5s-3.357-7.5-7.5-7.5H276.275c-4.143,0-7.5,3.358-7.5,7.5   S272.133,191.129,276.275,191.129z"
-       id="path27"
-       style="fill:#ed7831;fill-opacity:1" /><path
-       d="M276.275,226.757h114.964c4.143,0,7.5-3.358,7.5-7.5s-3.357-7.5-7.5-7.5H276.275c-4.143,0-7.5,3.358-7.5,7.5   S272.133,226.757,276.275,226.757z"
-       id="path29"
-       style="fill:#ed7831;fill-opacity:1" /><path
-       d="M276.275,262.385h57.481c4.143,0,7.5-3.358,7.5-7.5s-3.357-7.5-7.5-7.5h-57.481c-4.143,0-7.5,3.358-7.5,7.5   S272.133,262.385,276.275,262.385z"
-       id="path31"
-       style="fill:#ed7831;fill-opacity:1" /></g><g
-     id="g33" /><g
-     id="g35" /><g
-     id="g37" /><g
-     id="g39" /><g
-     id="g41" /><g
-     id="g43" /><g
-     id="g45" /><g
-     id="g47" /><g
-     id="g49" /><g
-     id="g51" /><g
-     id="g53" /><g
-     id="g55" /><g
-     id="g57" /><g
-     id="g59" /><g
-     id="g61" /></svg>
\ No newline at end of file
diff --git a/edumed/static/img/menu/svg/o-nas.svg b/edumed/static/img/menu/svg/o-nas.svg
deleted file mode 100644 (file)
index 540d2c5..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<svg
-   xmlns:dc="http://purl.org/dc/elements/1.1/"
-   xmlns:cc="http://creativecommons.org/ns#"
-   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
-   xmlns:svg="http://www.w3.org/2000/svg"
-   xmlns="http://www.w3.org/2000/svg"
-   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
-   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
-   version="1.1"
-   viewBox="0 0 470 470"
-   enable-background="new 0 0 470 470"
-   id="svg2"
-   inkscape:version="0.91 r13725"
-   sodipodi:docname="o nas.svg">
-  <metadata
-     id="metadata10">
-    <rdf:RDF>
-      <cc:Work
-         rdf:about="">
-        <dc:format>image/svg+xml</dc:format>
-        <dc:type
-           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
-      </cc:Work>
-    </rdf:RDF>
-  </metadata>
-  <defs
-     id="defs8" />
-  <sodipodi:namedview
-     pagecolor="#ffffff"
-     bordercolor="#666666"
-     borderopacity="1"
-     objecttolerance="10"
-     gridtolerance="10"
-     guidetolerance="10"
-     inkscape:pageopacity="0"
-     inkscape:pageshadow="2"
-     inkscape:window-width="711"
-     inkscape:window-height="480"
-     id="namedview6"
-     showgrid="false"
-     inkscape:zoom="0.50212766"
-     inkscape:cx="235"
-     inkscape:cy="235"
-     inkscape:window-x="0"
-     inkscape:window-y="24"
-     inkscape:window-maximized="0"
-     inkscape:current-layer="svg2" />
-  <path
-     d="m469.19,46.536c-1.467-2.894-4.636-4.521-7.832-4.021l-40.045,6.173 6.173-40.045c0.494-3.205-1.128-6.365-4.021-7.832-2.894-1.467-6.402-0.908-8.695,1.386l-46.484,46.484c-1.127,1.128-1.866,2.585-2.108,4.161l-7.358,47.733-26.609,26.609c-36.654-34.03-84.102-52.694-134.454-52.694-52.864,0-102.536,20.559-139.866,57.889-37.332,37.331-57.891,87.003-57.891,139.867s20.559,102.535 57.889,139.866c37.331,37.33 87.003,57.888 139.866,57.888s102.536-20.559 139.866-57.889c37.33-37.331 57.889-87.003 57.889-139.866 0-42.051-12.996-82.189-37.583-116.076-2.433-3.354-7.125-4.1-10.475-1.666-3.353,2.433-4.099,7.122-1.666,10.475 22.717,31.31 34.724,68.402 34.724,107.268 0,100.771-81.984,182.754-182.755,182.754-100.771,0-182.755-81.983-182.755-182.754s81.984-182.755 182.755-182.755c46.345,1.42109e-14 90.026,17.105 123.84,48.308l-34.284,34.284c-24.653-22.076-56.23-34.173-89.557-34.173-74.074,0-134.337,60.264-134.337,134.337s60.263,134.337 134.337,134.337 134.336-60.264 134.336-134.337c0-24.723-6.76-48.882-19.548-69.866-2.156-3.537-6.771-4.658-10.308-2.501-3.537,2.155-4.656,6.771-2.501,10.308 11.354,18.632 17.356,40.092 17.356,62.06 0,65.803-53.534,119.337-119.336,119.337-65.803,0-119.337-53.534-119.337-119.337s53.534-119.337 119.337-119.337c29.327,0 57.131,10.538 78.937,29.793l-34.365,34.365c-12.575-10.193-28.141-15.74-44.572-15.74-39.104,0-70.918,31.814-70.918,70.919s31.814,70.918 70.918,70.918c39.105,0 70.918-31.813 70.918-70.918 0-6.967-1.008-13.853-2.995-20.468-1.192-3.967-5.374-6.219-9.341-5.024-3.967,1.191-6.217,5.373-5.024,9.341 1.566,5.214 2.36,10.647 2.36,16.151 0,30.833-25.085,55.918-55.918,55.918s-55.918-25.085-55.918-55.918c0-30.834 25.085-55.919 55.918-55.919 12.416,0 24.2,4.021 33.886,11.426l-39.19,39.19c-2.929,2.93-2.929,7.678 0,10.607 1.464,1.464 3.384,2.196 5.303,2.196 1.919,0 3.839-0.732 5.303-2.196l134.539-134.539c0.046-0.046 31.828-31.828 31.828-31.828l47.733-7.359c1.576-0.242 3.033-0.981 4.161-2.108l46.484-46.484c2.297-2.297 2.856-5.805 1.39-8.698zm-88.563,11.017l28.542-28.541-3.866,25.079-28.542,28.542 3.866-25.08zm31.82,31.821l-25.078,3.866 28.542-28.542 25.077-3.866-28.541,28.542z"
-     id="path4"
-     style="fill-opacity:1;fill:#96928b" />
-</svg>
diff --git a/edumed/static/img/menu/svg/o-nas_active.svg b/edumed/static/img/menu/svg/o-nas_active.svg
deleted file mode 100644 (file)
index 9878327..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<svg
-   xmlns:dc="http://purl.org/dc/elements/1.1/"
-   xmlns:cc="http://creativecommons.org/ns#"
-   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
-   xmlns:svg="http://www.w3.org/2000/svg"
-   xmlns="http://www.w3.org/2000/svg"
-   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
-   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
-   version="1.1"
-   viewBox="0 0 470 470"
-   enable-background="new 0 0 470 470"
-   id="svg2"
-   inkscape:version="0.91 r13725"
-   sodipodi:docname="o nas.svg">
-  <metadata
-     id="metadata10">
-    <rdf:RDF>
-      <cc:Work
-         rdf:about="">
-        <dc:format>image/svg+xml</dc:format>
-        <dc:type
-           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
-      </cc:Work>
-    </rdf:RDF>
-  </metadata>
-  <defs
-     id="defs8" />
-  <sodipodi:namedview
-     pagecolor="#ffffff"
-     bordercolor="#666666"
-     borderopacity="1"
-     objecttolerance="10"
-     gridtolerance="10"
-     guidetolerance="10"
-     inkscape:pageopacity="0"
-     inkscape:pageshadow="2"
-     inkscape:window-width="711"
-     inkscape:window-height="480"
-     id="namedview6"
-     showgrid="false"
-     inkscape:zoom="0.50212766"
-     inkscape:cx="235"
-     inkscape:cy="235"
-     inkscape:window-x="0"
-     inkscape:window-y="24"
-     inkscape:window-maximized="0"
-     inkscape:current-layer="svg2" />
-  <path
-     d="m469.19,46.536c-1.467-2.894-4.636-4.521-7.832-4.021l-40.045,6.173 6.173-40.045c0.494-3.205-1.128-6.365-4.021-7.832-2.894-1.467-6.402-0.908-8.695,1.386l-46.484,46.484c-1.127,1.128-1.866,2.585-2.108,4.161l-7.358,47.733-26.609,26.609c-36.654-34.03-84.102-52.694-134.454-52.694-52.864,0-102.536,20.559-139.866,57.889-37.332,37.331-57.891,87.003-57.891,139.867s20.559,102.535 57.889,139.866c37.331,37.33 87.003,57.888 139.866,57.888s102.536-20.559 139.866-57.889c37.33-37.331 57.889-87.003 57.889-139.866 0-42.051-12.996-82.189-37.583-116.076-2.433-3.354-7.125-4.1-10.475-1.666-3.353,2.433-4.099,7.122-1.666,10.475 22.717,31.31 34.724,68.402 34.724,107.268 0,100.771-81.984,182.754-182.755,182.754-100.771,0-182.755-81.983-182.755-182.754s81.984-182.755 182.755-182.755c46.345,1.42109e-14 90.026,17.105 123.84,48.308l-34.284,34.284c-24.653-22.076-56.23-34.173-89.557-34.173-74.074,0-134.337,60.264-134.337,134.337s60.263,134.337 134.337,134.337 134.336-60.264 134.336-134.337c0-24.723-6.76-48.882-19.548-69.866-2.156-3.537-6.771-4.658-10.308-2.501-3.537,2.155-4.656,6.771-2.501,10.308 11.354,18.632 17.356,40.092 17.356,62.06 0,65.803-53.534,119.337-119.336,119.337-65.803,0-119.337-53.534-119.337-119.337s53.534-119.337 119.337-119.337c29.327,0 57.131,10.538 78.937,29.793l-34.365,34.365c-12.575-10.193-28.141-15.74-44.572-15.74-39.104,0-70.918,31.814-70.918,70.919s31.814,70.918 70.918,70.918c39.105,0 70.918-31.813 70.918-70.918 0-6.967-1.008-13.853-2.995-20.468-1.192-3.967-5.374-6.219-9.341-5.024-3.967,1.191-6.217,5.373-5.024,9.341 1.566,5.214 2.36,10.647 2.36,16.151 0,30.833-25.085,55.918-55.918,55.918s-55.918-25.085-55.918-55.918c0-30.834 25.085-55.919 55.918-55.919 12.416,0 24.2,4.021 33.886,11.426l-39.19,39.19c-2.929,2.93-2.929,7.678 0,10.607 1.464,1.464 3.384,2.196 5.303,2.196 1.919,0 3.839-0.732 5.303-2.196l134.539-134.539c0.046-0.046 31.828-31.828 31.828-31.828l47.733-7.359c1.576-0.242 3.033-0.981 4.161-2.108l46.484-46.484c2.297-2.297 2.856-5.805 1.39-8.698zm-88.563,11.017l28.542-28.541-3.866,25.079-28.542,28.542 3.866-25.08zm31.82,31.821l-25.078,3.866 28.542-28.542 25.077-3.866-28.541,28.542z"
-     id="path4"
-     style="fill-opacity:1;fill:#ed7831" />
-</svg>
diff --git a/edumed/static/img/menu/svg/olimpiada.svg b/edumed/static/img/menu/svg/olimpiada.svg
deleted file mode 100644 (file)
index 5d0b8eb..0000000
+++ /dev/null
@@ -1,109 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<svg
-   xmlns:dc="http://purl.org/dc/elements/1.1/"
-   xmlns:cc="http://creativecommons.org/ns#"
-   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
-   xmlns:svg="http://www.w3.org/2000/svg"
-   xmlns="http://www.w3.org/2000/svg"
-   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
-   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
-   version="1.1"
-   viewBox="0 0 455.881 455.881"
-   enable-background="new 0 0 455.881 455.881"
-   id="svg2"
-   inkscape:version="0.91 r13725"
-   sodipodi:docname="olimpiada.svg">
-  <metadata
-     id="metadata38">
-    <rdf:RDF>
-      <cc:Work
-         rdf:about="">
-        <dc:format>image/svg+xml</dc:format>
-        <dc:type
-           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
-      </cc:Work>
-    </rdf:RDF>
-  </metadata>
-  <defs
-     id="defs36" />
-  <sodipodi:namedview
-     pagecolor="#ffffff"
-     bordercolor="#666666"
-     borderopacity="1"
-     objecttolerance="10"
-     gridtolerance="10"
-     guidetolerance="10"
-     inkscape:pageopacity="0"
-     inkscape:pageshadow="2"
-     inkscape:window-width="711"
-     inkscape:window-height="480"
-     id="namedview34"
-     showgrid="false"
-     inkscape:zoom="0.51767894"
-     inkscape:cx="227.94051"
-     inkscape:cy="227.94051"
-     inkscape:window-x="0"
-     inkscape:window-y="24"
-     inkscape:window-maximized="0"
-     inkscape:current-layer="svg2" />
-  <g
-     id="g4"
-     style="fill:#96928b;fill-opacity:1">
-    <path
-       d="m321.218,257.555c15.516-20.46 23.717-44.881 23.717-70.624 0-31.563-12.379-61.151-34.857-83.314-22.474-22.158-52.261-34.124-83.828-33.668-30.591,0.433-59.412,12.708-81.154,34.564-21.741,21.855-33.867,50.741-34.145,81.335-0.238,26.228 8.011,51.088 23.855,71.894 25.721,33.776 39.887,75.149 39.887,116.498v45.244c0,20.069 16.327,36.396 36.396,36.396h33.854c20.069,0 36.396-16.328 36.396-36.396v-45.241c0.001-41.806 13.691-82.157 39.879-116.688zm-174.478-8.9c-13.808-18.132-20.997-39.803-20.79-62.67 0.499-54.935 45.588-100.26 100.512-101.037 27.553-0.37 53.493,10.035 73.084,29.352 19.597,19.321 30.389,45.116 30.389,72.632 0,22.442-7.147,43.729-20.669,61.56-27.593,36.385-42.45,78.833-43.058,122.93h-76.536c-0.627-43.669-15.817-87.161-42.932-122.767zm42.953,165.746v-6.072l76.647,8.781v2.374c0,1.25-0.13,2.468-0.336,3.659l-76.311-8.742zm0-21.17v-6.809h76.647v15.59l-76.647-8.781zm21.396,47.65c-8.057,0-15.082-4.48-18.731-11.077l64.567,7.397c-3.421,2.321-7.545,3.679-11.981,3.679h-33.855z"
-       id="path6"
-       style="fill:#96928b;fill-opacity:1" />
-    <path
-       d="m153.776,198.213c-0.585-3.925-0.864-7.957-0.827-11.983 0.038-4.142-3.289-7.53-7.431-7.568-4.114-0.036-7.53,3.289-7.568,7.431-0.044,4.81 0.289,9.632 0.99,14.333 0.555,3.722 3.755,6.395 7.409,6.395 0.368,0 0.741-0.027 1.116-0.083 4.096-0.612 6.922-4.428 6.311-8.525z"
-       id="path8"
-       style="fill:#96928b;fill-opacity:1" />
-    <path
-       d="m197.913,312.135c0.776,0 1.566-0.122 2.344-0.377 3.935-1.294 6.076-5.533 4.782-9.467-8.312-25.277-20.7-48.827-36.82-69.994-2.664-3.499-5.025-7.226-7.016-11.079-1.902-3.68-6.427-5.12-10.107-3.218-3.679,1.902-5.12,6.427-3.218,10.107 2.39,4.622 5.218,9.089 8.408,13.278 15.106,19.836 26.715,41.904 34.504,65.591 1.038,3.157 3.971,5.159 7.123,5.159z"
-       id="path10"
-       style="fill:#96928b;fill-opacity:1" />
-    <path
-       d="m306.746,212.613c-3.804-1.639-8.217,0.117-9.855,3.921-2.376,5.518-5.451,10.781-9.139,15.643-2.503,3.3-1.856,8.005 1.444,10.508 1.355,1.028 2.947,1.524 4.526,1.524 2.267,0 4.507-1.023 5.982-2.969 4.419-5.827 8.107-12.143 10.963-18.772 1.639-3.804-0.116-8.217-3.921-9.855z"
-       id="path12"
-       style="fill:#96928b;fill-opacity:1" />
-    <path
-       d="m227.941,111.938c41.352,0 74.994,33.643 74.994,74.995 0,2.351-0.108,4.72-0.321,7.041-0.378,4.125 2.658,7.775 6.783,8.154 0.233,0.021 0.464,0.032 0.694,0.032 3.833,0 7.103-2.923 7.46-6.815 0.254-2.775 0.384-5.605 0.384-8.412 0-49.623-40.371-89.995-89.994-89.995-4.142,0-7.5,3.358-7.5,7.5s3.358,7.5 7.5,7.5z"
-       id="path14"
-       style="fill:#96928b;fill-opacity:1" />
-    <path
-       d="m227.941,57c4.142,0 7.5-3.358 7.5-7.5v-42c0-4.142-3.358-7.5-7.5-7.5s-7.5,3.358-7.5,7.5v42c0,4.142 3.358,7.5 7.5,7.5z"
-       id="path16"
-       style="fill:#96928b;fill-opacity:1" />
-    <path
-       d="m152.065,71.82c1.39,2.407 3.91,3.752 6.502,3.752 1.272,0 2.562-0.324 3.743-1.006 3.587-2.071 4.817-6.658 2.746-10.245l-20.99-36.36c-2.072-3.588-6.658-4.817-10.245-2.746-3.587,2.071-4.817,6.658-2.746,10.245l20.99,36.36z"
-       id="path18"
-       style="fill:#96928b;fill-opacity:1" />
-    <path
-       d="m388.22,272.115l-36.36-20.99c-3.588-2.072-8.175-0.842-10.245,2.746-2.071,3.587-0.842,8.174 2.746,10.245l36.36,20.99c1.181,0.682 2.47,1.006 3.743,1.006 2.592,0 5.113-1.346 6.502-3.752 2.071-3.587 0.841-8.174-2.746-10.245z"
-       id="path20"
-       style="fill:#96928b;fill-opacity:1" />
-    <path
-       d="m67.661,104.366l36.36,20.99c1.181,0.682 2.47,1.006 3.743,1.006 2.592,0 5.113-1.346 6.502-3.752 2.071-3.587 0.842-8.174-2.746-10.245l-36.36-20.99c-3.587-2.072-8.174-0.842-10.245,2.746-2.071,3.587-0.842,8.173 2.746,10.245z"
-       id="path22"
-       style="fill:#96928b;fill-opacity:1" />
-    <path
-       d="m408.68,180.74h-42c-4.142,0-7.5,3.358-7.5,7.5s3.358,7.5 7.5,7.5h42c4.142,0 7.5-3.358 7.5-7.5s-3.357-7.5-7.5-7.5z"
-       id="path24"
-       style="fill:#96928b;fill-opacity:1" />
-    <path
-       d="m96.7,188.24c0-4.142-3.358-7.5-7.5-7.5h-42c-4.142,0-7.5,3.358-7.5,7.5s3.358,7.5 7.5,7.5h42c4.143,0 7.5-3.358 7.5-7.5z"
-       id="path26"
-       style="fill:#96928b;fill-opacity:1" />
-    <path
-       d="m348.117,126.362c1.272,0 2.562-0.324 3.743-1.006l36.36-20.99c3.587-2.071 4.817-6.658 2.746-10.245-2.071-3.587-6.659-4.817-10.245-2.746l-36.36,20.99c-3.587,2.071-4.817,6.658-2.746,10.245 1.389,2.406 3.911,3.752 6.502,3.752z"
-       id="path28"
-       style="fill:#96928b;fill-opacity:1" />
-    <path
-       d="m104.021,251.125l-36.36,20.99c-3.587,2.071-4.817,6.658-2.746,10.245 1.389,2.406 3.91,3.752 6.502,3.752 1.272,0 2.562-0.324 3.743-1.006l36.36-20.99c3.587-2.071 4.817-6.658 2.746-10.245-2.07-3.588-6.66-4.817-10.245-2.746z"
-       id="path30"
-       style="fill:#96928b;fill-opacity:1" />
-    <path
-       d="m293.571,74.566c1.181,0.682 2.47,1.006 3.743,1.006 2.592,0 5.113-1.346 6.502-3.752l20.99-36.36c2.071-3.587 0.841-8.174-2.746-10.245-3.586-2.071-8.174-0.842-10.245,2.746l-20.99,36.36c-2.071,3.587-0.841,8.174 2.746,10.245z"
-       id="path32"
-       style="fill:#96928b;fill-opacity:1" />
-  </g>
-</svg>
diff --git a/edumed/static/img/menu/svg/olimpiada_active.svg b/edumed/static/img/menu/svg/olimpiada_active.svg
deleted file mode 100644 (file)
index c5b390f..0000000
+++ /dev/null
@@ -1,109 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<svg
-   xmlns:dc="http://purl.org/dc/elements/1.1/"
-   xmlns:cc="http://creativecommons.org/ns#"
-   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
-   xmlns:svg="http://www.w3.org/2000/svg"
-   xmlns="http://www.w3.org/2000/svg"
-   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
-   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
-   version="1.1"
-   viewBox="0 0 455.881 455.881"
-   enable-background="new 0 0 455.881 455.881"
-   id="svg2"
-   inkscape:version="0.91 r13725"
-   sodipodi:docname="olimpiada.svg">
-  <metadata
-     id="metadata38">
-    <rdf:RDF>
-      <cc:Work
-         rdf:about="">
-        <dc:format>image/svg+xml</dc:format>
-        <dc:type
-           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
-      </cc:Work>
-    </rdf:RDF>
-  </metadata>
-  <defs
-     id="defs36" />
-  <sodipodi:namedview
-     pagecolor="#ffffff"
-     bordercolor="#666666"
-     borderopacity="1"
-     objecttolerance="10"
-     gridtolerance="10"
-     guidetolerance="10"
-     inkscape:pageopacity="0"
-     inkscape:pageshadow="2"
-     inkscape:window-width="711"
-     inkscape:window-height="480"
-     id="namedview34"
-     showgrid="false"
-     inkscape:zoom="0.51767894"
-     inkscape:cx="227.94051"
-     inkscape:cy="227.94051"
-     inkscape:window-x="0"
-     inkscape:window-y="24"
-     inkscape:window-maximized="0"
-     inkscape:current-layer="svg2" />
-  <g
-     id="g4"
-     style="fill:#ed7831;fill-opacity:1">
-    <path
-       d="m321.218,257.555c15.516-20.46 23.717-44.881 23.717-70.624 0-31.563-12.379-61.151-34.857-83.314-22.474-22.158-52.261-34.124-83.828-33.668-30.591,0.433-59.412,12.708-81.154,34.564-21.741,21.855-33.867,50.741-34.145,81.335-0.238,26.228 8.011,51.088 23.855,71.894 25.721,33.776 39.887,75.149 39.887,116.498v45.244c0,20.069 16.327,36.396 36.396,36.396h33.854c20.069,0 36.396-16.328 36.396-36.396v-45.241c0.001-41.806 13.691-82.157 39.879-116.688zm-174.478-8.9c-13.808-18.132-20.997-39.803-20.79-62.67 0.499-54.935 45.588-100.26 100.512-101.037 27.553-0.37 53.493,10.035 73.084,29.352 19.597,19.321 30.389,45.116 30.389,72.632 0,22.442-7.147,43.729-20.669,61.56-27.593,36.385-42.45,78.833-43.058,122.93h-76.536c-0.627-43.669-15.817-87.161-42.932-122.767zm42.953,165.746v-6.072l76.647,8.781v2.374c0,1.25-0.13,2.468-0.336,3.659l-76.311-8.742zm0-21.17v-6.809h76.647v15.59l-76.647-8.781zm21.396,47.65c-8.057,0-15.082-4.48-18.731-11.077l64.567,7.397c-3.421,2.321-7.545,3.679-11.981,3.679h-33.855z"
-       id="path6"
-       style="fill:#ed7831;fill-opacity:1" />
-    <path
-       d="m153.776,198.213c-0.585-3.925-0.864-7.957-0.827-11.983 0.038-4.142-3.289-7.53-7.431-7.568-4.114-0.036-7.53,3.289-7.568,7.431-0.044,4.81 0.289,9.632 0.99,14.333 0.555,3.722 3.755,6.395 7.409,6.395 0.368,0 0.741-0.027 1.116-0.083 4.096-0.612 6.922-4.428 6.311-8.525z"
-       id="path8"
-       style="fill:#ed7831;fill-opacity:1" />
-    <path
-       d="m197.913,312.135c0.776,0 1.566-0.122 2.344-0.377 3.935-1.294 6.076-5.533 4.782-9.467-8.312-25.277-20.7-48.827-36.82-69.994-2.664-3.499-5.025-7.226-7.016-11.079-1.902-3.68-6.427-5.12-10.107-3.218-3.679,1.902-5.12,6.427-3.218,10.107 2.39,4.622 5.218,9.089 8.408,13.278 15.106,19.836 26.715,41.904 34.504,65.591 1.038,3.157 3.971,5.159 7.123,5.159z"
-       id="path10"
-       style="fill:#ed7831;fill-opacity:1" />
-    <path
-       d="m306.746,212.613c-3.804-1.639-8.217,0.117-9.855,3.921-2.376,5.518-5.451,10.781-9.139,15.643-2.503,3.3-1.856,8.005 1.444,10.508 1.355,1.028 2.947,1.524 4.526,1.524 2.267,0 4.507-1.023 5.982-2.969 4.419-5.827 8.107-12.143 10.963-18.772 1.639-3.804-0.116-8.217-3.921-9.855z"
-       id="path12"
-       style="fill:#ed7831;fill-opacity:1" />
-    <path
-       d="m227.941,111.938c41.352,0 74.994,33.643 74.994,74.995 0,2.351-0.108,4.72-0.321,7.041-0.378,4.125 2.658,7.775 6.783,8.154 0.233,0.021 0.464,0.032 0.694,0.032 3.833,0 7.103-2.923 7.46-6.815 0.254-2.775 0.384-5.605 0.384-8.412 0-49.623-40.371-89.995-89.994-89.995-4.142,0-7.5,3.358-7.5,7.5s3.358,7.5 7.5,7.5z"
-       id="path14"
-       style="fill:#ed7831;fill-opacity:1" />
-    <path
-       d="m227.941,57c4.142,0 7.5-3.358 7.5-7.5v-42c0-4.142-3.358-7.5-7.5-7.5s-7.5,3.358-7.5,7.5v42c0,4.142 3.358,7.5 7.5,7.5z"
-       id="path16"
-       style="fill:#ed7831;fill-opacity:1" />
-    <path
-       d="m152.065,71.82c1.39,2.407 3.91,3.752 6.502,3.752 1.272,0 2.562-0.324 3.743-1.006 3.587-2.071 4.817-6.658 2.746-10.245l-20.99-36.36c-2.072-3.588-6.658-4.817-10.245-2.746-3.587,2.071-4.817,6.658-2.746,10.245l20.99,36.36z"
-       id="path18"
-       style="fill:#ed7831;fill-opacity:1" />
-    <path
-       d="m388.22,272.115l-36.36-20.99c-3.588-2.072-8.175-0.842-10.245,2.746-2.071,3.587-0.842,8.174 2.746,10.245l36.36,20.99c1.181,0.682 2.47,1.006 3.743,1.006 2.592,0 5.113-1.346 6.502-3.752 2.071-3.587 0.841-8.174-2.746-10.245z"
-       id="path20"
-       style="fill:#ed7831;fill-opacity:1" />
-    <path
-       d="m67.661,104.366l36.36,20.99c1.181,0.682 2.47,1.006 3.743,1.006 2.592,0 5.113-1.346 6.502-3.752 2.071-3.587 0.842-8.174-2.746-10.245l-36.36-20.99c-3.587-2.072-8.174-0.842-10.245,2.746-2.071,3.587-0.842,8.173 2.746,10.245z"
-       id="path22"
-       style="fill:#ed7831;fill-opacity:1" />
-    <path
-       d="m408.68,180.74h-42c-4.142,0-7.5,3.358-7.5,7.5s3.358,7.5 7.5,7.5h42c4.142,0 7.5-3.358 7.5-7.5s-3.357-7.5-7.5-7.5z"
-       id="path24"
-       style="fill:#ed7831;fill-opacity:1" />
-    <path
-       d="m96.7,188.24c0-4.142-3.358-7.5-7.5-7.5h-42c-4.142,0-7.5,3.358-7.5,7.5s3.358,7.5 7.5,7.5h42c4.143,0 7.5-3.358 7.5-7.5z"
-       id="path26"
-       style="fill:#ed7831;fill-opacity:1" />
-    <path
-       d="m348.117,126.362c1.272,0 2.562-0.324 3.743-1.006l36.36-20.99c3.587-2.071 4.817-6.658 2.746-10.245-2.071-3.587-6.659-4.817-10.245-2.746l-36.36,20.99c-3.587,2.071-4.817,6.658-2.746,10.245 1.389,2.406 3.911,3.752 6.502,3.752z"
-       id="path28"
-       style="fill:#ed7831;fill-opacity:1" />
-    <path
-       d="m104.021,251.125l-36.36,20.99c-3.587,2.071-4.817,6.658-2.746,10.245 1.389,2.406 3.91,3.752 6.502,3.752 1.272,0 2.562-0.324 3.743-1.006l36.36-20.99c3.587-2.071 4.817-6.658 2.746-10.245-2.07-3.588-6.66-4.817-10.245-2.746z"
-       id="path30"
-       style="fill:#ed7831;fill-opacity:1" />
-    <path
-       d="m293.571,74.566c1.181,0.682 2.47,1.006 3.743,1.006 2.592,0 5.113-1.346 6.502-3.752l20.99-36.36c2.071-3.587 0.841-8.174-2.746-10.245-3.586-2.071-8.174-0.842-10.245,2.746l-20.99,36.36c-2.071,3.587-0.841,8.174 2.746,10.245z"
-       id="path32"
-       style="fill:#ed7831;fill-opacity:1" />
-  </g>
-</svg>
diff --git a/edumed/static/img/nina-white.png b/edumed/static/img/nina-white.png
deleted file mode 100644 (file)
index 3d2afe7..0000000
Binary files a/edumed/static/img/nina-white.png and /dev/null differ
diff --git a/edumed/static/img/nina.jpg b/edumed/static/img/nina.jpg
deleted file mode 100644 (file)
index a056df0..0000000
Binary files a/edumed/static/img/nina.jpg and /dev/null differ
diff --git a/edumed/static/img/ornaments/draggable.png b/edumed/static/img/ornaments/draggable.png
deleted file mode 100644 (file)
index 75af63e..0000000
Binary files a/edumed/static/img/ornaments/draggable.png and /dev/null differ
diff --git a/edumed/static/img/sciezki-kopernika/cc.jpg b/edumed/static/img/sciezki-kopernika/cc.jpg
deleted file mode 100644 (file)
index 0ff7abc..0000000
Binary files a/edumed/static/img/sciezki-kopernika/cc.jpg and /dev/null differ
diff --git a/edumed/static/img/sciezki-kopernika/fe.jpg b/edumed/static/img/sciezki-kopernika/fe.jpg
deleted file mode 100644 (file)
index f353aa7..0000000
Binary files a/edumed/static/img/sciezki-kopernika/fe.jpg and /dev/null differ
diff --git a/edumed/static/img/sciezki-kopernika/fnp.png b/edumed/static/img/sciezki-kopernika/fnp.png
deleted file mode 100644 (file)
index d6bb0c7..0000000
Binary files a/edumed/static/img/sciezki-kopernika/fnp.png and /dev/null differ
diff --git a/edumed/static/img/sciezki-kopernika/ue.jpg b/edumed/static/img/sciezki-kopernika/ue.jpg
deleted file mode 100644 (file)
index 30ae44f..0000000
Binary files a/edumed/static/img/sciezki-kopernika/ue.jpg and /dev/null differ
diff --git a/edumed/static/jquery/colorbox/colorbox.css b/edumed/static/jquery/colorbox/colorbox.css
deleted file mode 100644 (file)
index b75b0ce..0000000
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
-    ColorBox Core Style:
-    The following CSS is consistent between example themes and should not be altered.
-*/
-#colorbox, #cboxOverlay, #cboxWrapper{position:absolute; top:0; left:0; z-index:9999; overflow:hidden;}
-#cboxOverlay{position:fixed; width:100%; height:100%;}
-#cboxMiddleLeft, #cboxBottomLeft{clear:left;}
-#cboxContent{position:relative;}
-#cboxLoadedContent{overflow:auto; -webkit-overflow-scrolling: touch;}
-#cboxTitle{margin:0;}
-#cboxLoadingOverlay, #cboxLoadingGraphic{position:absolute; top:0; left:0; width:100%; height:100%;}
-#cboxPrevious, #cboxNext, #cboxClose, #cboxSlideshow{cursor:pointer;}
-.cboxPhoto{float:left; margin:auto; border:0; display:block; max-width:none;}
-.cboxIframe{width:100%; height:100%; display:block; border:0;}
-#colorbox, #cboxContent, #cboxLoadedContent{box-sizing:content-box; -moz-box-sizing:content-box; -webkit-box-sizing:content-box;}
-
-/* 
-    User Style:
-    Change the following styles to modify the appearance of ColorBox.  They are
-    ordered & tabbed in a way that represents the nesting of the generated HTML.
-*/
-#cboxOverlay{background:url(images/overlay.png) repeat 0 0;}
-#colorbox{outline:0;}
-    #cboxTopLeft{width:21px; height:21px; background:url(images/controls.png) no-repeat -101px 0;}
-    #cboxTopRight{width:21px; height:21px; background:url(images/controls.png) no-repeat -130px 0;}
-    #cboxBottomLeft{width:21px; height:21px; background:url(images/controls.png) no-repeat -101px -29px;}
-    #cboxBottomRight{width:21px; height:21px; background:url(images/controls.png) no-repeat -130px -29px;}
-    #cboxMiddleLeft{width:21px; background:url(images/controls.png) left top repeat-y;}
-    #cboxMiddleRight{width:21px; background:url(images/controls.png) right top repeat-y;}
-    #cboxTopCenter{height:21px; background:url(images/border.png) 0 0 repeat-x;}
-    #cboxBottomCenter{height:21px; background:url(images/border.png) 0 -29px repeat-x;}
-    #cboxContent{background:#fff; overflow:hidden;}
-        .cboxIframe{background:#fff;}
-        #cboxError{padding:50px; border:1px solid #ccc;}
-        #cboxLoadedContent{margin-bottom:28px;}
-        #cboxTitle{position:absolute; bottom:4px; left:0; text-align:center; width:100%; color:#949494;}
-        #cboxCurrent{position:absolute; bottom:4px; left:58px; color:#949494;}
-        #cboxLoadingOverlay{background:url(images/loading_background.png) no-repeat center center;}
-        #cboxLoadingGraphic{background:url(images/loading.gif) no-repeat center center;}
-
-        /* these elements are buttons, and may need to have additional styles reset to avoid unwanted base styles */
-        #cboxPrevious, #cboxNext, #cboxSlideshow, #cboxClose {border:0; padding:0; margin:0; overflow:visible; width:auto; background:none; }
-        
-        /* avoid outlines on :active (mouseclick), but preserve outlines on :focus (tabbed navigating) */
-        #cboxPrevious:active, #cboxNext:active, #cboxSlideshow:active, #cboxClose:active {outline:0;}
-
-        #cboxSlideshow{position:absolute; bottom:4px; right:30px; color:#0092ef;}
-        #cboxPrevious{position:absolute; bottom:0; left:0; background:url(images/controls.png) no-repeat -75px 0; width:25px; height:25px; text-indent:-9999px;}
-        #cboxPrevious:hover{background-position:-75px -25px;}
-        #cboxNext{position:absolute; bottom:0; left:27px; background:url(images/controls.png) no-repeat -50px 0; width:25px; height:25px; text-indent:-9999px;}
-        #cboxNext:hover{background-position:-50px -25px;}
-        #cboxClose{position:absolute; bottom:0; right:0; background:url(images/controls.png) no-repeat -25px 0; width:25px; height:25px; text-indent:-9999px;}
-        #cboxClose:hover{background-position:-25px -25px;}
-
-/*
-  The following fixes a problem where IE7 and IE8 replace a PNG's alpha transparency with a black fill
-  when an alpha filter (opacity change) is set on the element or ancestor element.  This style is not applied to or needed in IE9.
-  See: http://jacklmoore.com/notes/ie-transparency-problems/
-*/
-.cboxIE #cboxTopLeft,
-.cboxIE #cboxTopCenter,
-.cboxIE #cboxTopRight,
-.cboxIE #cboxBottomLeft,
-.cboxIE #cboxBottomCenter,
-.cboxIE #cboxBottomRight,
-.cboxIE #cboxMiddleLeft,
-.cboxIE #cboxMiddleRight {
-    filter: progid:DXImageTransform.Microsoft.gradient(startColorstr=#00FFFFFF,endColorstr=#00FFFFFF);
-}
-
-/*
-  The following provides PNG transparency support for IE6
-  Feel free to remove this and the /ie6/ directory if you have dropped IE6 support.
-*/
-.cboxIE6 #cboxTopLeft{background:url(images/ie6/borderTopLeft.png);}
-.cboxIE6 #cboxTopCenter{background:url(images/ie6/borderTopCenter.png);}
-.cboxIE6 #cboxTopRight{background:url(images/ie6/borderTopRight.png);}
-.cboxIE6 #cboxBottomLeft{background:url(images/ie6/borderBottomLeft.png);}
-.cboxIE6 #cboxBottomCenter{background:url(images/ie6/borderBottomCenter.png);}
-.cboxIE6 #cboxBottomRight{background:url(images/ie6/borderBottomRight.png);}
-.cboxIE6 #cboxMiddleLeft{background:url(images/ie6/borderMiddleLeft.png);}
-.cboxIE6 #cboxMiddleRight{background:url(images/ie6/borderMiddleRight.png);}
-
-.cboxIE6 #cboxTopLeft,
-.cboxIE6 #cboxTopCenter,
-.cboxIE6 #cboxTopRight,
-.cboxIE6 #cboxBottomLeft,
-.cboxIE6 #cboxBottomCenter,
-.cboxIE6 #cboxBottomRight,
-.cboxIE6 #cboxMiddleLeft,
-.cboxIE6 #cboxMiddleRight {
-    _behavior: expression(this.src = this.src ? this.src : this.currentStyle.backgroundImage.split('"')[1], this.style.background = "none", this.style.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src=" + this.src + ", sizingMethod='scale')");
-}
diff --git a/edumed/static/jquery/colorbox/images/border.png b/edumed/static/jquery/colorbox/images/border.png
deleted file mode 100644 (file)
index f463a10..0000000
Binary files a/edumed/static/jquery/colorbox/images/border.png and /dev/null differ
diff --git a/edumed/static/jquery/colorbox/images/controls.png b/edumed/static/jquery/colorbox/images/controls.png
deleted file mode 100644 (file)
index dcfd6fb..0000000
Binary files a/edumed/static/jquery/colorbox/images/controls.png and /dev/null differ
diff --git a/edumed/static/jquery/colorbox/images/ie6/borderBottomCenter.png b/edumed/static/jquery/colorbox/images/ie6/borderBottomCenter.png
deleted file mode 100644 (file)
index 0d4475e..0000000
Binary files a/edumed/static/jquery/colorbox/images/ie6/borderBottomCenter.png and /dev/null differ
diff --git a/edumed/static/jquery/colorbox/images/ie6/borderBottomLeft.png b/edumed/static/jquery/colorbox/images/ie6/borderBottomLeft.png
deleted file mode 100644 (file)
index 2775eba..0000000
Binary files a/edumed/static/jquery/colorbox/images/ie6/borderBottomLeft.png and /dev/null differ
diff --git a/edumed/static/jquery/colorbox/images/ie6/borderBottomRight.png b/edumed/static/jquery/colorbox/images/ie6/borderBottomRight.png
deleted file mode 100644 (file)
index f7f5137..0000000
Binary files a/edumed/static/jquery/colorbox/images/ie6/borderBottomRight.png and /dev/null differ
diff --git a/edumed/static/jquery/colorbox/images/ie6/borderMiddleLeft.png b/edumed/static/jquery/colorbox/images/ie6/borderMiddleLeft.png
deleted file mode 100644 (file)
index a2d63d1..0000000
Binary files a/edumed/static/jquery/colorbox/images/ie6/borderMiddleLeft.png and /dev/null differ
diff --git a/edumed/static/jquery/colorbox/images/ie6/borderMiddleRight.png b/edumed/static/jquery/colorbox/images/ie6/borderMiddleRight.png
deleted file mode 100644 (file)
index fd7c3e8..0000000
Binary files a/edumed/static/jquery/colorbox/images/ie6/borderMiddleRight.png and /dev/null differ
diff --git a/edumed/static/jquery/colorbox/images/ie6/borderTopCenter.png b/edumed/static/jquery/colorbox/images/ie6/borderTopCenter.png
deleted file mode 100644 (file)
index 2937a9c..0000000
Binary files a/edumed/static/jquery/colorbox/images/ie6/borderTopCenter.png and /dev/null differ
diff --git a/edumed/static/jquery/colorbox/images/ie6/borderTopLeft.png b/edumed/static/jquery/colorbox/images/ie6/borderTopLeft.png
deleted file mode 100644 (file)
index f9d458b..0000000
Binary files a/edumed/static/jquery/colorbox/images/ie6/borderTopLeft.png and /dev/null differ
diff --git a/edumed/static/jquery/colorbox/images/ie6/borderTopRight.png b/edumed/static/jquery/colorbox/images/ie6/borderTopRight.png
deleted file mode 100644 (file)
index 74b8583..0000000
Binary files a/edumed/static/jquery/colorbox/images/ie6/borderTopRight.png and /dev/null differ
diff --git a/edumed/static/jquery/colorbox/images/loading.gif b/edumed/static/jquery/colorbox/images/loading.gif
deleted file mode 100644 (file)
index b4695d8..0000000
Binary files a/edumed/static/jquery/colorbox/images/loading.gif and /dev/null differ
diff --git a/edumed/static/jquery/colorbox/images/loading_background.png b/edumed/static/jquery/colorbox/images/loading_background.png
deleted file mode 100644 (file)
index 6ae83e6..0000000
Binary files a/edumed/static/jquery/colorbox/images/loading_background.png and /dev/null differ
diff --git a/edumed/static/jquery/colorbox/images/overlay.png b/edumed/static/jquery/colorbox/images/overlay.png
deleted file mode 100644 (file)
index 53ea98f..0000000
Binary files a/edumed/static/jquery/colorbox/images/overlay.png and /dev/null differ
diff --git a/edumed/static/jquery/colorbox/jquery.colorbox-min.js b/edumed/static/jquery/colorbox/jquery.colorbox-min.js
deleted file mode 100644 (file)
index 45295d2..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-/*!
-       jQuery ColorBox v1.4.1 - 2013-02-14
-       (c) 2013 Jack Moore - jacklmoore.com/colorbox
-       license: http://www.opensource.org/licenses/mit-license.php
-*/
-(function(e,t,i){function o(i,o,n){var r=t.createElement(i);return o&&(r.id=Y+o),n&&(r.style.cssText=n),e(r)}function n(e){var t=T.length,i=(A+e)%t;return 0>i?t+i:i}function r(e,t){return Math.round((/%/.test(e)?("x"===t?k.width():k.height())/100:1)*parseInt(e,10))}function h(e){return K.photo||K.photoRegex.test(e)}function l(e){return K.retinaUrl&&i.devicePixelRatio>1?e.replace(K.photoRegex,K.retinaSuffix):e}function s(t){e.contains(w[0],t.target)||w[0]===t.target||(t.stopPropagation(),w.focus())}function a(){var t,i=e.data(N,V);null==i?(K=e.extend({},J),console&&console.log&&console.log("Error: cboxElement missing settings object")):K=e.extend({},i);for(t in K)e.isFunction(K[t])&&"on"!==t.slice(0,2)&&(K[t]=K[t].call(N));K.rel=K.rel||N.rel||e(N).data("rel")||"nofollow",K.href=K.href||e(N).attr("href"),K.title=K.title||N.title,"string"==typeof K.href&&(K.href=e.trim(K.href))}function d(i,o){e(t).trigger(i),at.trigger(i),e.isFunction(o)&&o.call(N)}function c(){var e,t,i,o,n,r=Y+"Slideshow_",h="click."+Y;K.slideshow&&T[1]?(t=function(){clearTimeout(e)},i=function(){(K.loop||T[A+1])&&(e=setTimeout(G.next,K.slideshowSpeed))},o=function(){M.html(K.slideshowStop).unbind(h).one(h,n),at.bind(it,i).bind(tt,t).bind(ot,n),w.removeClass(r+"off").addClass(r+"on")},n=function(){t(),at.unbind(it,i).unbind(tt,t).unbind(ot,n),M.html(K.slideshowStart).unbind(h).one(h,function(){G.next(),o()}),w.removeClass(r+"on").addClass(r+"off")},K.slideshowAuto?o():n()):w.removeClass(r+"off "+r+"on")}function u(i){U||(N=i,a(),T=e(N),A=0,"nofollow"!==K.rel&&(T=e("."+Z).filter(function(){var t,i=e.data(this,V);return i&&(t=e(this).data("rel")||i.rel||this.rel),t===K.rel}),A=T.index(N),-1===A&&(T=T.add(N),A=T.length-1)),m.css({opacity:parseFloat(K.opacity),cursor:K.overlayClose?"pointer":"auto",visibility:"visible"}).show(),j||(j=q=!0,w.css({visibility:"hidden",display:"block"}),E=o(dt,"LoadedContent","width:0; height:0; overflow:hidden").appendTo(v),_=x.height()+C.height()+v.outerHeight(!0)-v.height(),z=y.width()+b.width()+v.outerWidth(!0)-v.width(),D=E.outerHeight(!0),B=E.outerWidth(!0),K.w=r(K.initialWidth,"x"),K.h=r(K.initialHeight,"y"),G.position(),lt&&k.bind("resize."+st+" scroll."+st,function(){m.css({width:k.width(),height:k.height(),top:k.scrollTop(),left:k.scrollLeft()})}).trigger("resize."+st),c(),d(et,K.onOpen),P.add(W).hide(),R.html(K.close).show(),w.focus(),t.addEventListener&&(t.addEventListener("focus",s,!0),at.one(nt,function(){t.removeEventListener("focus",s,!0)})),K.returnFocus&&at.one(nt,function(){e(N).focus()})),G.load(!0))}function f(){!w&&t.body&&(X=!1,k=e(i),w=o(dt).attr({id:V,"class":ht?Y+(lt?"IE6":"IE"):"",role:"dialog",tabindex:"-1"}).hide(),m=o(dt,"Overlay",lt?"position:absolute":"").hide(),L=o(dt,"LoadingOverlay").add(o(dt,"LoadingGraphic")),g=o(dt,"Wrapper"),v=o(dt,"Content").append(W=o(dt,"Title"),H=o(dt,"Current"),F=o("button","Previous"),S=o("button","Next"),M=o("button","Slideshow"),L,R=o("button","Close")),g.append(o(dt).append(o(dt,"TopLeft"),x=o(dt,"TopCenter"),o(dt,"TopRight")),o(dt,!1,"clear:left").append(y=o(dt,"MiddleLeft"),v,b=o(dt,"MiddleRight")),o(dt,!1,"clear:left").append(o(dt,"BottomLeft"),C=o(dt,"BottomCenter"),o(dt,"BottomRight"))).find("div div").css({"float":"left"}),I=o(dt,!1,"position:absolute; width:9999px; visibility:hidden; display:none"),P=S.add(F).add(H).add(M),e(t.body).append(m,w.append(g,I)))}function p(){function i(e){e.which>1||e.shiftKey||e.altKey||e.metaKey||(e.preventDefault(),u(this))}return w?(X||(X=!0,S.click(function(){G.next()}),F.click(function(){G.prev()}),R.click(function(){G.close()}),m.click(function(){K.overlayClose&&G.close()}),e(t).bind("keydown."+Y,function(e){var t=e.keyCode;j&&K.escKey&&27===t&&(e.preventDefault(),G.close()),j&&K.arrowKey&&T[1]&&!e.altKey&&(37===t?(e.preventDefault(),F.click()):39===t&&(e.preventDefault(),S.click()))}),e.isFunction(e.fn.on)?e(t).on("click."+Y,"."+Z,i):e("."+Z).live("click."+Y,i)),!0):!1}var m,w,g,v,x,y,b,C,T,k,E,I,L,W,H,M,S,F,R,P,K,_,z,D,B,N,A,O,j,q,U,$,G,Q,X,J={transition:"elastic",speed:300,width:!1,initialWidth:"600",innerWidth:!1,maxWidth:!1,height:!1,initialHeight:"450",innerHeight:!1,maxHeight:!1,scalePhotos:!0,scrolling:!0,inline:!1,html:!1,iframe:!1,fastIframe:!0,photo:!1,href:!1,title:!1,rel:!1,opacity:.9,preloading:!0,className:!1,retinaImage:!1,retinaUrl:!1,retinaSuffix:"@2x.$1",current:"image {current} of {total}",previous:"previous",next:"next",close:"close",xhrError:"This content failed to load.",imgError:"This image failed to load.",open:!1,returnFocus:!0,reposition:!0,loop:!0,slideshow:!1,slideshowAuto:!0,slideshowSpeed:2500,slideshowStart:"start slideshow",slideshowStop:"stop slideshow",photoRegex:/\.(gif|png|jp(e|g|eg)|bmp|ico)((#|\?).*)?$/i,onOpen:!1,onLoad:!1,onComplete:!1,onCleanup:!1,onClosed:!1,overlayClose:!0,escKey:!0,arrowKey:!0,top:!1,bottom:!1,left:!1,right:!1,fixed:!1,data:void 0},V="colorbox",Y="cbox",Z=Y+"Element",et=Y+"_open",tt=Y+"_load",it=Y+"_complete",ot=Y+"_cleanup",nt=Y+"_closed",rt=Y+"_purge",ht=!e.support.leadingWhitespace,lt=ht&&!i.XMLHttpRequest,st=Y+"_IE6",at=e({}),dt="div";e.colorbox||(e(f),G=e.fn[V]=e[V]=function(t,i){var o=this;if(t=t||{},f(),p()){if(e.isFunction(o))o=e("<a/>"),t.open=!0;else if(!o[0])return o;i&&(t.onComplete=i),o.each(function(){e.data(this,V,e.extend({},e.data(this,V)||J,t))}).addClass(Z),(e.isFunction(t.open)&&t.open.call(o)||t.open)&&u(o[0])}return o},G.position=function(e,t){function i(e){x[0].style.width=C[0].style.width=v[0].style.width=parseInt(e.style.width,10)-z+"px",v[0].style.height=y[0].style.height=b[0].style.height=parseInt(e.style.height,10)-_+"px"}var o,n,h,l=0,s=0,a=w.offset();k.unbind("resize."+Y),w.css({top:-9e4,left:-9e4}),n=k.scrollTop(),h=k.scrollLeft(),K.fixed&&!lt?(a.top-=n,a.left-=h,w.css({position:"fixed"})):(l=n,s=h,w.css({position:"absolute"})),s+=K.right!==!1?Math.max(k.width()-K.w-B-z-r(K.right,"x"),0):K.left!==!1?r(K.left,"x"):Math.round(Math.max(k.width()-K.w-B-z,0)/2),l+=K.bottom!==!1?Math.max(k.height()-K.h-D-_-r(K.bottom,"y"),0):K.top!==!1?r(K.top,"y"):Math.round(Math.max(k.height()-K.h-D-_,0)/2),w.css({top:a.top,left:a.left,visibility:"visible"}),e=w.width()===K.w+B&&w.height()===K.h+D?0:e||0,g[0].style.width=g[0].style.height="9999px",o={width:K.w+B+z,height:K.h+D+_,top:l,left:s},0===e&&w.css(o),w.dequeue().animate(o,{duration:e,complete:function(){i(this),q=!1,g[0].style.width=K.w+B+z+"px",g[0].style.height=K.h+D+_+"px",K.reposition&&setTimeout(function(){k.bind("resize."+Y,G.position)},1),t&&t()},step:function(){i(this)}})},G.resize=function(e){j&&(e=e||{},e.width&&(K.w=r(e.width,"x")-B-z),e.innerWidth&&(K.w=r(e.innerWidth,"x")),E.css({width:K.w}),e.height&&(K.h=r(e.height,"y")-D-_),e.innerHeight&&(K.h=r(e.innerHeight,"y")),e.innerHeight||e.height||(E.css({height:"auto"}),K.h=E.height()),E.css({height:K.h}),G.position("none"===K.transition?0:K.speed))},G.prep=function(t){function i(){return K.w=K.w||E.width(),K.w=K.mw&&K.mw<K.w?K.mw:K.w,K.w}function r(){return K.h=K.h||E.height(),K.h=K.mh&&K.mh<K.h?K.mh:K.h,K.h}if(j){var l,s="none"===K.transition?0:K.speed;E.empty().remove(),E=o(dt,"LoadedContent").append(t),E.hide().appendTo(I.show()).css({width:i(),overflow:K.scrolling?"auto":"hidden"}).css({height:r()}).prependTo(v),I.hide(),e(O).css({"float":"none"}),l=function(){function t(){ht&&w[0].style.removeAttribute("filter")}var i,r,l=T.length,a="frameBorder",c="allowTransparency";j&&(r=function(){clearTimeout($),L.hide(),d(it,K.onComplete)},ht&&O&&E.fadeIn(100),W.html(K.title).add(E).show(),l>1?("string"==typeof K.current&&H.html(K.current.replace("{current}",A+1).replace("{total}",l)).show(),S[K.loop||l-1>A?"show":"hide"]().html(K.next),F[K.loop||A?"show":"hide"]().html(K.previous),K.slideshow&&M.show(),K.preloading&&e.each([n(-1),n(1)],function(){var t,i,o=T[this],n=e.data(o,V);n&&n.href?(t=n.href,e.isFunction(t)&&(t=t.call(o))):t=e(o).attr("href"),t&&(h(t)||n.photo)&&(i=new Image,i.src=t)})):P.hide(),K.iframe?(i=o("iframe")[0],a in i&&(i[a]=0),c in i&&(i[c]="true"),K.scrolling||(i.scrolling="no"),e(i).attr({src:K.href,name:(new Date).getTime(),"class":Y+"Iframe",allowFullScreen:!0,webkitAllowFullScreen:!0,mozallowfullscreen:!0}).one("load",r).appendTo(E),at.one(rt,function(){i.src="//about:blank"}),K.fastIframe&&e(i).trigger("load")):r(),"fade"===K.transition?w.fadeTo(s,1,t):t())},"fade"===K.transition?w.fadeTo(s,0,function(){G.position(0,l)}):G.position(s,l)}},G.load=function(t){var n,s,c,u=G.prep;q=!0,O=!1,N=T[A],t||a(),Q&&w.add(m).removeClass(Q),K.className&&w.add(m).addClass(K.className),Q=K.className,d(rt),d(tt,K.onLoad),K.h=K.height?r(K.height,"y")-D-_:K.innerHeight&&r(K.innerHeight,"y"),K.w=K.width?r(K.width,"x")-B-z:K.innerWidth&&r(K.innerWidth,"x"),K.mw=K.w,K.mh=K.h,K.maxWidth&&(K.mw=r(K.maxWidth,"x")-B-z,K.mw=K.w&&K.w<K.mw?K.w:K.mw),K.maxHeight&&(K.mh=r(K.maxHeight,"y")-D-_,K.mh=K.h&&K.h<K.mh?K.h:K.mh),n=K.href,$=setTimeout(function(){L.show()},100),K.inline?(c=o(dt).hide().insertBefore(e(n)[0]),at.one(rt,function(){c.replaceWith(E.children())}),u(e(n))):K.iframe?u(" "):K.html?u(K.html):h(n)?(n=l(n),e(O=new Image).addClass(Y+"Photo").bind("error",function(){K.title=!1,u(o(dt,"Error").html(K.imgError))}).one("load",function(){var e;K.retinaImage&&i.devicePixelRatio>1&&(O.height=O.height/i.devicePixelRatio,O.width=O.width/i.devicePixelRatio),K.scalePhotos&&(s=function(){O.height-=O.height*e,O.width-=O.width*e},K.mw&&O.width>K.mw&&(e=(O.width-K.mw)/O.width,s()),K.mh&&O.height>K.mh&&(e=(O.height-K.mh)/O.height,s())),K.h&&(O.style.marginTop=Math.max(K.mh-O.height,0)/2+"px"),T[1]&&(K.loop||T[A+1])&&(O.style.cursor="pointer",O.onclick=function(){G.next()}),ht&&(O.style.msInterpolationMode="bicubic"),setTimeout(function(){u(O)},1)}),setTimeout(function(){O.src=n},1)):n&&I.load(n,K.data,function(t,i){u("error"===i?o(dt,"Error").html(K.xhrError):e(this).contents())})},G.next=function(){!q&&T[1]&&(K.loop||T[A+1])&&(A=n(1),G.load())},G.prev=function(){!q&&T[1]&&(K.loop||A)&&(A=n(-1),G.load())},G.close=function(){j&&!U&&(U=!0,j=!1,d(ot,K.onCleanup),k.unbind("."+Y+" ."+st),m.fadeTo(200,0),w.stop().fadeTo(300,0,function(){w.add(m).css({opacity:1,cursor:"auto"}).hide(),d(rt),E.empty().remove(),setTimeout(function(){U=!1,d(nt,K.onClosed)},1)}))},G.remove=function(){e([]).add(w).add(m).remove(),w=null,e("."+Z).removeData(V).removeClass(Z),e(t).unbind("click."+Y)},G.element=function(){return e(N)},G.settings=J)})(jQuery,document,window);
\ No newline at end of file
diff --git a/edumed/static/jquery/colorbox/jquery.colorbox-pl.js b/edumed/static/jquery/colorbox/jquery.colorbox-pl.js
deleted file mode 100644 (file)
index 370cdca..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-/*\r
-       jQuery ColorBox language configuration\r
-       language: Polski (pl)\r
-       translated by: Tomasz Wasiński\r
-       site: 2bevisible.pl\r
-*/\r
-jQuery.extend(jQuery.colorbox.settings, {\r
-       current: "{current}. obrazek z {total}",\r
-       previous: "Poprzedni",\r
-       next: "Następny",\r
-       close: "Zamknij",\r
-       xhrError: "Nie udało się załadować treści.",\r
-       imgError: "Nie udało się załadować obrazka.",\r
-       slideshowStart: "rozpocznij pokaz slajdów",\r
-       slideshowStop: "zatrzymaj pokaz slajdów"\r
-});
\ No newline at end of file
diff --git a/edumed/static/js/formset.js b/edumed/static/js/formset.js
deleted file mode 100755 (executable)
index 7a4657f..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-(function($) {
-    $(function() {
-
-
-function cloneMore(selector, type) {
-    var newElement = $(selector).clone(true);
-    var total = $('#id_' + type + '-TOTAL_FORMS').val();
-    newElement.find(':input').each(function() {
-        var name = $(this).attr('name').replace('__prefix__', total);
-        var id = 'id_' + name;
-        $(this).attr({'name': name, 'id': id});
-    });
-    newElement.find('label').each(function() {
-        var newFor = $(this).attr('for').replace('__prefix__', total);
-        $(this).attr('for', newFor);
-    });
-    newElement.attr({'style': '', 'id': ''});
-    total++;
-    $('#id_' + type + '-TOTAL_FORMS').val(total);
-    $(selector).before(newElement);
-}
-
-
-
-            $('.add_more').click(function() {
-                cloneMore($(this).data('selector'), $(this).data('prefix'));
-            });
-
-    });
-})(jQuery);
diff --git a/edumed/templates/404.html b/edumed/templates/404.html
deleted file mode 100644 (file)
index 74ee437..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-{% extends "base.html" %}
-{% load i18n %}
-
-{% block title %}{% trans "Page not found" %}{% endblock %}
-
-{% block body %}
-
-<h1>{% trans "Page not found" %}</h1>
-
-<p class="notice">
-    {% trans "The page you were looking for doesn't exist." %}
-</p>
-
-{% endblock %}
diff --git a/edumed/templates/404_mil.html b/edumed/templates/404_mil.html
deleted file mode 100644 (file)
index bdc4f15..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-{% extends "base_mil.html" %}
-{% load i18n %}
-
-{% block title %}{% trans "Page not found" %}{% endblock %}
-
-{% block body %}
-
-<h1>{% trans "Page not found" %}</h1>
-
-<p class="notice">
-    {% trans "The page you were looking for doesn't exist." %}
-</p>
-
-{% endblock %}
diff --git a/edumed/templates/500.html b/edumed/templates/500.html
deleted file mode 100644 (file)
index be751c1..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-<h1>Wystąpił błąd serwera.</h1>
-
-<p>Coś poszło nie tak. Administratorzy zostali już powiadomieni.</p>
-
-<p>Przepraszamy!</p>
diff --git a/edumed/templates/annoy.html b/edumed/templates/annoy.html
deleted file mode 100755 (executable)
index d48e669..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-{% load static %}
-<a id='annoy-on' href="http://nowoczesnapolska.org.pl/pomoz-nam/wesprzyj-nas/">1%</a>
-<div id='annoy'>
-    <a href="http://nowoczesnapolska.org.pl/pomoz-nam/wesprzyj-nas/">
-        <img src='http://static.wolnelektury.pl/img/procent.png' alt="Logo akcji 1%" style="float:left;margin: 0 2em" /></a>
-    <p>Droga użytkowniczko, drogi użytkowniku!</p>
-    <p>Czy wiesz, że Edukacja Medialna to jeden z&nbsp;projektów
-    <strong>fundacji Nowoczesna Polska</strong> –
-    organizacji pożytku publicznego działającej na rzecz wolności korzystania
-    z&nbsp;dóbr kultury? Wesprzyj nasze działania, przeznaczając na nie 1% swojego podatku.
-    Możesz to zrobić, wpisując w&nbsp;zeznaniu podatkowym numer
-    <strong>KRS 0000070056</strong>.</p>
-
-    <p><a href="http://nowoczesnapolska.org.pl/pomoz-nam/wesprzyj-nas/">Dowiedz się więcej</a></p>
-    
-    <a id='annoy-off'>x</a>
-    <div style="clear:both;"></div>
-</div>
diff --git a/edumed/templates/base.html b/edumed/templates/base.html
deleted file mode 100644 (file)
index 6f1341d..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-{% extends "base_super.html" %}
-{% load sponsor_tags %}
-{% load compressed %}
-
-
-{% block tagline %}Scenariusze zajęć, ćwiczenia, materiały{% endblock %}
-
-{% block top_navigation %}
-    <li><a class="menu-lekcje" href="{% url "catalogue_lessons" %}">Lekcje</a></li>
-    <li><a class="menu-kompetencje" href="{% url "curriculum" %}">Kompetencje</a></li>
-    <li><a class="menu-olimpiada" href="https://olimpiadacyfrowa.pl">Olimpiada</a></li>
-    <li><a class="menu-trener" href="{% url "info" "dlatrenera/" %}">Dla trenera</a></li>
-    <li><a class="menu-kurs" href="http://kurs.edukacjamedialna.edu.pl">Dla ucznia</a></li>
-    <li><a class="menu-o-nas" href="{% url "info" "o-nas/" %}">O projekcie</a></li>
-{% endblock %}
-
-{% block sponsors %}
-    {% sponsor_page "footer" %}
-{% endblock %}
-
-{% block extra_script %}
-    {% compressed_js 'base' %}
-{% endblock %}
-
-{% block copyrights %}
-    <p>Ikonki w menu: <a href="http://www.flaticon.com/authors/freepik">Designed by Freepik and distributed by Flaticon</a></p>
-{% endblock %}
\ No newline at end of file
diff --git a/edumed/templates/base_forum.html b/edumed/templates/base_forum.html
deleted file mode 100755 (executable)
index 587a1e8..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-{% extends "base.html" %}
-{% load i18n %}
-
-{% block body %}
-<div class="forum-body">
-    {% block breadcrumb %}{% endblock %}
-    <a href="{% url 'forum_search' %}" style="position: absolute; top: 0; right: 5px;">{% trans 'Forum search' %}</a>
-    {% block content %}{% endblock %}
-</div>
-{% endblock %}
diff --git a/edumed/templates/base_mil.html b/edumed/templates/base_mil.html
deleted file mode 100644 (file)
index 7a88f45..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-{% extends "base_super.html" %}
-{% load subdomainurls %}
-{% load fnp_lang %}
-{% load sponsor_tags %}
-{% load static %}
-
-{% load i18n %}
-
-{% block header_class %}header-mil{% endblock %}
-
-{% block logo %}
-<img src="{% static "img/logo-mil.png" %}" alt="Edukacja medialna"/>
-{% endblock %}
-
-{% block top_navigation %}
-    <li><a class="menu-consultations" href="{% url "mil_home" "katalog" %}">{% trans 'About Catalogue' %}</a></li>
-    <li><a class="menu-kompetencje" href="{% url "curriculum" %}">{% trans 'Competencies' %}</a></li>
-    {% comment %}<li><a class="menu-takepart" href="{% url "comment_document_index" %}">{% trans 'Take Part' %}</a></li>{% endcomment %}
-        {% if request.LANGUAGE_CODE == 'pl' %}
-            <li><a class="menu-knowledgebase" href="{% url 'knowledge_base' 'katalog' url='' %}">Baza wiedzy</a></li>
-        {% endif %}
-        <li><a class="menu-kontakt" href="{% url 'mil_contact' 'katalog' %}">{% trans 'Contact' %}</a></li>
-        <li>{% lang_switcher %}</li>
-{% endblock %}
-
-{% block sponsors %}
-    {% sponsor_page "footer_mil" %}
-{% endblock %}
-
-{% block organizer %}
-    Projekt prowadzi:<br/>
-    <a href="http://nowoczesnapolska.org.pl">
-        <img src="{% static "img/logo_fnp_white.png" %}" alt="Fundacja Nowoczesna Polska" />
-    </a><br/>
-    <a href="http://http://www.nina.gov.pl/">
-        <img src="{% static "img/nina-white.png" %}" alt="Narodowy Instytut Audiowizualny" />
-    </a>
-{% endblock %}
\ No newline at end of file
diff --git a/edumed/templates/base_super.html b/edumed/templates/base_super.html
deleted file mode 100644 (file)
index fc82730..0000000
+++ /dev/null
@@ -1,114 +0,0 @@
-<!DOCTYPE html>
-{% load i18n static %}
-{% load fnp_common fnp_share fnp_lang macros %}
-{% load compressed static %}
-{% load subdomainurls %}
-{% load piwik_tags %}
-
-{% macro title %}{% block title %}{% endblock %}{% endmacro %}
-{% macro site_name %}Edukacja medialna{% endmacro %}
-
-<html prefix="og: http://ogp.me/ns#">
-    <head>
-       <title>{% block full_title %}{% usemacro title %} :: {% usemacro site_name %}{% endblock %}</title>
-       <link rel="shortcut icon" type="image/png" href="{% static "img/favicon.png" %}" />
-        {% compressed_css 'base' %}
-
-        <meta charset="UTF-8" />
-        <meta property='og:url' content='{% block ogurl %}{{ "/"|build_absolute_uri:request }}{% endblock %}' />
-        <meta property='og:title' content='{% block og_title %}{% usemacro title %}{% endblock %}' />
-        <meta property='og:site_name' content='{% block og_site_name %}{% usemacro site_name %}{% endblock %}' />
-        <meta property='og:description' content='{% block og_description %}{% endblock %}' />
-        <meta property='og:type' content='{% block og_type %}website{% endblock %}' />
-        <meta property='og:image' content='{% block og_image %}http://edukacjamedialna.edu.pl/static/img/logo.png{% endblock %}' />
-        <meta property='og:locale' content='pl_PL' />
-        <!--[if lt IE 9]><script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script></script><![endif]-->
-    </head>
-    <body id="{% block body-id %}body{% endblock %}">
-        {% load fnp_annoy %}{% annoy %}
-        {% comment %}
-        <div id="banners">
-            <a href="https://nowoczesnapolska.org.pl/pomoz-nam/wesprzyj-nas/">
-                <img src="{% static 'img/banners/960x150_edukacjaMedialna.jpg' %}"
-                     alt="Wesprzyj działalność Nowoczesnej Polski"/>
-            </a>
-        </div>
-        {% endcomment %}
-        <div id="header-wrapper">
-        <header class="main {% block header_class %}{% endblock %}" style="position:relative;">
-            <!--img
-                src="{% static "tlo.png" %}"
-                style="position:absolute; opacity: 0.5; top:0; left: -83px; z-index:1000"
-                -->
-            {% if request.user.is_authenticated %}
-                <a href="{% url 'logout' subdomain=None %}" style="position: absolute; top:5px; right: 10px; font-size: 12px;">Wyloguj</a>
-            {% endif %}
-            <div id="header-top">
-            <a id="logo" href="/">{% block logo %}<img src="{% static "img/logo.png" %}" alt="Edukacja medialna"/>{% endblock %}</a>
-            <div id="organizer">
-                {% block organizer %}
-                Projekt prowadzi:<br/>
-                <a href="http://nowoczesnapolska.org.pl">
-                    <img src="{% static "img/logo_fnp.png" %}" alt="Fundacja Nowoczesna Polska" />
-                </a>
-                {% endblock %}
-            </div>
-            <nav><ul>
-                {% block top_navigation %}
-                {% endblock %}
-            </ul></nav>
-            </div>
-
-            <div id="tagline">{% block tagline %}{% endblock %}</div>
-            {% block searchbox %}
-              <div id="search">
-                  <form action="{% url 'haystack_search' None %}">
-                      <input name="q" placeholder="szukaj" /><button><span>&rarr;</span></button>
-                  </form>
-              </div>
-            {% endblock %}
-            <div class="clr"></div>
-        </header>
-        </div>
-
-        <div id="content">{% block body %}{% endblock %}</div>
-
-        <footer class="main">
-            {# chunks? #}
-            {% block footer_contact %}
-                <div class="footer-item">
-                    <p>
-                    fundacja Nowoczesna Polska<br/>
-                    <br/>
-                    ul. Marszałkowska 84/92 lok. 125<br/>
-                    00-514 Warszawa<br/>
-                    tel: +48 22 621 30 17<br/>
-                    e-mail: fundacja@nowoczesnapolska.org.pl
-                    <br/><br/>
-                    KRS: 0000070056<br/>
-                    REGON: 017423865<br/>
-                    Nr konta: 59 1030 0019 0109 8530 0040 5685
-                    </p>
-                </div>
-            {% endblock %}
-            <div class="footer-item" style="margin-right:0;">
-                <p>
-                Webdesign Ortografika<br/>
-                <br/>
-                Jeśli nie oznaczono inaczej, wszystkie materiały na stronie są objęte wolną licencją
-                <a href="http://creativecommons.org/licenses/by-sa/3.0/deed.pl">Creative Commons Uznanie autorstwa
-                – Na tych samych warunkach 3.0</a>.
-                {% block copyrights %}{% endblock %}
-                </p>
-            </div>
-            {% block sponsors %}
-            {% endblock %}
-            <div class="clr"></div>
-            <div class="footer-extra">{% block footer_extra %}{% endblock %}</div>
-        </footer>
-
-    <script src="//ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
-    {% block extra_script %}{% endblock %}
-    {% tracking_code %}
-    </body>
-</html>
diff --git a/edumed/templates/contact/collegium-mlodych-test/form.html b/edumed/templates/contact/collegium-mlodych-test/form.html
deleted file mode 100644 (file)
index 5235b54..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-{% extends "contact/form.html" %}
-
-{% block body %}
-    {% include 'sciezki_logos.html' %}
-    {{ block.super }}
-{% endblock %}
-
-{% block form %}
-    {{ form.as_p }}
-    <p>
-      Test powstał w ramach projektu „Collegium Młodych – media i technologie” realizowanego w ramach
-      III Osi priorytetowej: Szkolnictwo wyższe dla gospodarki i rozwoju, Działanie 3.1 Kompetencje
-      w szkolnictwie wyższym Programu Operacyjnego Wiedza Edukacja Rozwój, współfinansowanego przez
-      Unię Europejską w ramach Europejskiego Funduszu Społecznego. Nr umowy POWR.03.01.00-00-C078/16-00.
-    </p>
-    <p>
-      Użytkowników, którzy wypełnili test kompetencji, zachęcamy do wypełnienia
-      <a href="/media/chunks/attachment/ZAKRES_DANYCH_OSOBOWYCH_DO_PRZETWARZANIA.pdf">FORMULARZU DANYCH OSOBOWYCH</a>
-      i przesłania go na adres fundacji. Pozwoli nam to na zaraportowanie naszych działań do
-      Narodowego Centrum Badań i Rozwoju.
-    </p>
-    <p>
-      Administratorem danych osobowych jest Fundacja Nowoczesna Polska (ul. Marszałkowska 84/92 lok. 125,
-      00-514 Warszawa). Podanie danych osobowych jest dobrowolne. Dane są przetwarzane w zakresie niezbędnym
-      do udziału w projekcie „Collegium Młodych - media i technologie”. Osobom, których dane są zbierane,
-      przysługuje prawo dostępu do treści swoich danych oraz ich poprawiania. Więcej informacji w
-      <a href="https://nowoczesnapolska.org.pl/prywatnosc/">polityce prywatności</a>.
-    </p>
-    <p>
-      Projekt „Collegium Młodych – media i technologie” jest finansowany ze środków
-      Narodowego Centrum Badań i Rozwoju. Dane zawarte w formularzu mogą być przekazane NCBiR
-      w ramach sprawozdawczości i kontroli realizacji projektu.
-    </p>
-    <p><button>{{ form.submit_label }}</button></p>
-{% endblock %}
diff --git a/edumed/templates/contact/collegium-mlodych-test/mail_subject.txt b/edumed/templates/contact/collegium-mlodych-test/mail_subject.txt
deleted file mode 100644 (file)
index f315550..0000000
+++ /dev/null
@@ -1 +0,0 @@
-Wyniki testu
\ No newline at end of file
diff --git a/edumed/templates/contact/collegium-mlodych-test/results.html b/edumed/templates/contact/collegium-mlodych-test/results.html
deleted file mode 100644 (file)
index 49d2682..0000000
+++ /dev/null
@@ -1,61 +0,0 @@
-{% extends base_template|default:"base.html" %}
-{% load i18n %}
-{% load contact_tags %}
-
-{% block title %}Wyniki{% endblock %}
-
-{% block body %}
-    {% include 'sciezki_logos.html' %}
-    <h1>Wyniki</h1>
-
-    <p>Suma uzyskanych punktów: {{ results.points|floatformat }} na {{ results.total }} możliwych.</p>
-
-    {% if 'collegium-mlodych'|is_enabled %}
-        <p class="box-button" style="max-width: 20em;"><a href="{% url 'contact_form' 'collegium-mlodych' %}" class="nice-button">Zgłoś się na warsztaty</a></p>
-    {% endif %}
-
-    {% for question in results.questions %}
-        <strong>{{ question.label }}</strong>
-        <ol class="alpha">
-            {% for answer, chosen, correct in question.answers %}
-                <li style="{% if chosen %}font-weight: bold;{% endif %}{% if correct %}color: #00cc44;{% endif %}">{{ answer }}</li>
-            {% endfor %}
-        </ol>
-        <p><strong>Komentarze do odpowiedzi:</strong></p>
-        {% for answer in question.answer_data %}
-            <p><strong>{{ answer.letter }}</strong>:</p>
-            {{ answer.comment }}
-        {% endfor %}
-    {% endfor %}
-    {% if 'collegium-mlodych'|is_enabled %}
-        <p class="box-button" style="max-width: 20em;"><a href="{% url 'contact_form' 'collegium-mlodych' %}" class="nice-button">Zgłoś się na warsztaty</a></p>
-    {% endif %}
-    {% comment %}
-    <p>Pytania stworzyli: Grzegorz Stunża, Marcin Wilkowski.</p>
-    <p>Komentarzami opatrzyła: Justyna Bakalarska.</p>
-    {% endcomment %}
-    <p>
-      Test powstał w ramach projektu „Collegium Młodych – media i technologie” realizowanego w ramach
-      III Osi priorytetowej: Szkolnictwo wyższe dla gospodarki i rozwoju, Działanie 3.1 Kompetencje
-      w szkolnictwie wyższym Programu Operacyjnego Wiedza Edukacja Rozwój, współfinansowanego przez
-      Unię Europejską w ramach Europejskiego Funduszu Społecznego. Nr umowy POWR.03.01.00-00-C078/16-00.
-    </p>
-    <p>
-      Użytkowników, którzy wypełnili test kompetencji, zachęcamy do wypełnienia
-      <a href="/media/chunks/attachment/ZAKRES_DANYCH_OSOBOWYCH_DO_PRZETWARZANIA.pdf">FORMULARZU DANYCH OSOBOWYCH</a>
-      i przesłania go na adres fundacji. Pozwoli nam to na zaraportowanie naszych działań do
-      Narodowego Centrum Badań i Rozwoju.
-    </p>
-    <p>
-      Administratorem danych osobowych jest Fundacja Nowoczesna Polska (ul. Marszałkowska 84/92 lok. 125,
-      00-514 Warszawa). Podanie danych osobowych jest dobrowolne. Dane są przetwarzane w zakresie niezbędnym
-      do udziału w projekcie „Collegium Młodych - media i technologie”. Osobom, których dane są zbierane,
-      przysługuje prawo dostępu do treści swoich danych oraz ich poprawiania. Więcej informacji w
-      <a href="https://nowoczesnapolska.org.pl/prywatnosc/">polityce prywatności</a>.
-    </p>
-    <p>
-      Projekt „Collegium Młodych – media i technologie” jest finansowany ze środków
-      Narodowego Centrum Badań i Rozwoju. Dane zawarte w formularzu mogą być przekazane NCBiR
-      w ramach sprawozdawczości i kontroli realizacji projektu.
-    </p>
-{% endblock %}
\ No newline at end of file
diff --git a/edumed/templates/contact/collegium-mlodych-test/results_email.txt b/edumed/templates/contact/collegium-mlodych-test/results_email.txt
deleted file mode 100644 (file)
index 3b015ac..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-{% load contact_tags %}Witaj,
-
-Oto wyniki testu:
-
-Suma uzyskanych punktów: {{ results.points|floatformat }} na {{ results.total }} możliwych.
-
-Pod poniższym adresem możesz obejrzeć swoje odpowiedzi z komentarzami:
-https://edukacjamedialna.edu.pl{% url 'contact_results' contact.id contact.digest %}
-{% if 'collegium-mlodych'|is_enabled %}
-Zgłoś się na warsztaty:
-https://edukacjamedialna.edu.pl{% url 'contact_form' 'collegium-mlodych' %}
-{% endif %}
-Z pozdrowieniami,
-fundacja Nowoczesna Polska
-
---
-Wiadomość wysłana automatycznie. Prosimy na nią nie odpowiadać.
\ No newline at end of file
diff --git a/edumed/templates/contact/collegium-mlodych/form.html b/edumed/templates/contact/collegium-mlodych/form.html
deleted file mode 100644 (file)
index d1ddbf8..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-{% extends "contact/form.html" %}
-
-{% block body %}
-    {% include 'sciezki_logos.html' %}
-    {{ block.super }}
-{% endblock %}
-
-{% block form_extra %}
-    <tr>
-      <td colspan="2">
-        <p>
-          Warsztaty realizowane są w ramach projektu „Collegium Młodych – media i technologie” realizowanego w ramach
-          III Osi priorytetowej: Szkolnictwo wyższe dla gospodarki i rozwoju, Działanie 3.1 Kompetencje
-          w szkolnictwie wyższym Programu Operacyjnego Wiedza Edukacja Rozwój, współfinansowanego przez
-          Unię Europejską w ramach Europejskiego Funduszu Społecznego. Nr umowy POWR.03.01.00-00-C078/16-00.
-        </p>
-        <p>
-          Administratorem danych osobowych jest Fundacja Nowoczesna Polska (ul. Marszałkowska 84/92 lok. 125,
-          00-514 Warszawa). Podanie danych osobowych jest dobrowolne. Dane są przetwarzane w zakresie niezbędnym
-          do udziału w projekcie „Collegium Młodych - media i technologie”. Osobom, których dane są zbierane,
-          przysługuje prawo dostępu do treści swoich danych oraz ich poprawiania. Więcej informacji w
-          <a href="https://nowoczesnapolska.org.pl/prywatnosc/">polityce prywatności</a>.
-        </p>
-        <p>
-          Projekt „Collegium Młodych – media i technologie” jest finansowany ze środków
-          Narodowego Centrum Badań i Rozwoju. Dane zawarte w formularzu mogą być przekazane NCBiR
-          w ramach sprawozdawczości i kontroli realizacji projektu.
-        </p>
-      </td>
-    </tr>
-{% endblock %}
\ No newline at end of file
diff --git a/edumed/templates/contact/collegium-mlodych/mail_body.txt b/edumed/templates/contact/collegium-mlodych/mail_body.txt
deleted file mode 100644 (file)
index 71ca78f..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-Witaj,
-
-Dziękujemy za przesłanie zgłoszenia do udziału w warsztatach z zakresu edukacji medialnej i cyfrowej prowadzonych przez Collegium Civitas i Fundację Nowoczesna Polska w ramach projektu „Collegium Młodych – media i technologie”.
-
-Pamiętaj, że aby zaakceptować Twoje zgłoszenie, musimy otrzymać komplet dokumentów rekrutacyjnych w formie papierowej, opatrzonych wymaganymi podpisami, oraz potwierdzić dane w nich zawarte. O ostatecznej decyzji powiadomimy Ciebie i Twojego rodzica / opiekuna prawnego w późniejszym terminie.
-
-Wzory dokumentów rekrutacyjnych znajdziesz pod adresem
-http://edukacjamedialna.edu.pl/media/chunks/attachment/dokumenty_rekrutacyjne_v2.zip.
-
-Po wypełnieniu i podpisaniu odeślij je na adres:
-
-Fundacja Nowoczesna Polska
-ul. Marszałkowska 84/92 lok. 125
-00-514 Warszawa
-z dopiskiem: Warsztaty – Ścieżki Kopernika
-
-Jeśli masz jakieś pytania, napisz do nas: warsztaty@nowoczesnapolska.org.pl lub zadzwoń: (22) 465-15-35.
-
-Pozdrawiamy,
-fundacja Nowoczesna Polska
\ No newline at end of file
diff --git a/edumed/templates/contact/collegium-mlodych/mail_subject.txt b/edumed/templates/contact/collegium-mlodych/mail_subject.txt
deleted file mode 100644 (file)
index 28ae8f2..0000000
+++ /dev/null
@@ -1 +0,0 @@
-Potwierdzenie otrzymania zgłoszenia
\ No newline at end of file
diff --git a/edumed/templates/contact/collegium-mlodych/on_hold.html b/edumed/templates/contact/collegium-mlodych/on_hold.html
deleted file mode 100644 (file)
index f8e645d..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-{% extends "base.html" %}
-
-{% block title %}{{ title }}{% endblock %}
-
-{% block body %}
-
-    <h1>{{ title }}</h1>
-
-    {% block contact_form_description %}
-        <p class="notice">W związku z dużym zainteresowaniem warsztatami rekrutacja została wstrzymana na czas weryfikacji zgłoszeń uczestników.</p>
-    {% endblock %}
-
-{% endblock %}
diff --git a/edumed/templates/contact/collegium-mlodych/thanks.html b/edumed/templates/contact/collegium-mlodych/thanks.html
deleted file mode 100644 (file)
index 4d470bc..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-{% extends "contact/thanks.html" %}
-
-{% block body %}
-    {% include "sciezki_logos.html" %}
-    {{ block.super }}
-{% endblock %}
-
-{% block contact_form_description %}
-    <p>Dziękujemy za przesłanie zgłoszenia do udziału w warsztatach z zakresu edukacji medialnej i cyfrowej prowadzonych przez Collegium Civitas i Fundację Nowoczesna Polska w ramach projektu „Collegium Młodych – media i technologie”.</p>
-
-    <p>Pamiętaj, że aby zaakceptować Twoje zgłoszenie, musimy otrzymać komplet dokumentów rekrutacyjnych w formie papierowej, opatrzonych wymaganymi podpisami, oraz potwierdzić dane w nich zawarte. O ostatecznej decyzji powiadomimy Ciebie i Twojego rodzica / opiekuna prawnego w późniejszym terminie.</p>
-
-    <p class="box-button"><a href="/media/chunks/attachment/dokumenty_rekrutacyjne_v2.zip" class="dl-button">Pobierz wzory dokumentów rekrutacyjnych</a></p>
-
-    <p>Po wypełnieniu i podpisaniu dokumentów, odeślij je na adres:</p>
-
-    <p>Fundacja Nowoczesna Polska<br>
-    ul. Marszałkowska 84/92 lok. 125<br>
-    00-514 Warszawa<br>
-    z dopiskiem: Warsztaty – Ścieżki Kopernika</p>
-
-    <p>Jeśli masz jakieś pytania, napisz do nas:
-    <a href="mailto:warsztaty@nowoczesnapolska.org.pl">warsztaty@nowoczesnapolska.org.pl</a> lub zadzwoń: (22) 465-15-35.</p>
-
-    <p>Pozdrawiamy,<br>
-    fundacja Nowoczesna Polska</p>
-{% endblock %}
diff --git a/edumed/templates/contact/konkurs/mail_body.txt b/edumed/templates/contact/konkurs/mail_body.txt
deleted file mode 100644 (file)
index 6e4ba7c..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-Dziękujemy za rejestrację udziału w konkursie MediaLog.
-
-Przypominamy, że prace można nadsyłać do 6 maja 2013 na adres 
-edukacjamedialna@nowoczesnapolska.org.pl. W mailu należy podać dane 
-kontaktowe Autora/ów pracy, Opiekuna (osoby, która zarejestrowała udział 
-danej instytucji w konkursie i prowadziła zajęcia z edukacji medialnej) 
-oraz nazwę instytucji (szkoły, biblioteki, domu kultury itp.). 
-W przypadku prac opublikowanych już wcześniej wystarczy w mailu podać
-link do odpowiedniej strony.
-
-W razie jakichkolwiek wątpliwości prosimy o kontakt:
-http://edukacjamedialna.edu.pl/info/kontakt/
-
--- 
-Wiadomość wysłana automatycznie. Prosimy na nią nie odpowiadać.
diff --git a/edumed/templates/contact/konkurs/mail_subject.txt b/edumed/templates/contact/konkurs/mail_subject.txt
deleted file mode 100644 (file)
index 386c1e6..0000000
+++ /dev/null
@@ -1 +0,0 @@
-Zgłoszenie na konkurs MediaLog zostało zarejestrowane.
diff --git a/edumed/templates/contact/konkurs/thanks.html b/edumed/templates/contact/konkurs/thanks.html
deleted file mode 100644 (file)
index 6c4a518..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-{% extends "contact/thanks.html" %}
-
-{% block contact_form_description %}
-<p>Dziękujemy za rejestrację udziału w konkursie MediaLog.</p>
-
-<p>Przypominamy, że prace można nadsyłać do 6 maja 2013 na adres 
-edukacjamedialna@nowoczesnapolska.org.pl. W mailu należy podać dane 
-kontaktowe Autora/ów pracy, Opiekuna (osoby, która zarejestrowała udział 
-danej instytucji w konkursie i prowadziła zajęcia z edukacji medialnej) 
-oraz nazwę instytucji (szkoły, biblioteki, domu kultury itp.). 
-W przypadku prac opublikowanych już wcześniej wystarczy w mailu podać
-link do odpowiedniej strony.</p>
-{% endblock %}
diff --git a/edumed/templates/contact/misja-cybernautow/mail_body.txt b/edumed/templates/contact/misja-cybernautow/mail_body.txt
deleted file mode 100644 (file)
index ddbcc44..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-Treść maila potwierdzającego rejestrację zespołu.
-
-Link do formularza edycji: https://{{ site_domain }}{{ contact.update_url }}
-
-W razie jakichkolwiek wątpliwości prosimy o kontakt:
-http://edukacjamedialna.edu.pl/info/kontakt/
-
---
-Wiadomość wysłana automatycznie. Prosimy na nią nie odpowiadać.
diff --git a/edumed/templates/contact/olimpiada/form.html b/edumed/templates/contact/olimpiada/form.html
deleted file mode 100755 (executable)
index c28925a..0000000
+++ /dev/null
@@ -1,93 +0,0 @@
-{% extends "base.html" %}
-{% load chunks %}
-{% load honeypot %}
-
-{% block title %}{{ form.form_title }}{% endblock %}
-
-{% block body %}
-
-
-
-
-
-
-    <h1>{% block contact_form_title %}{{ form.form_title }}{% endblock %}</h1>
-
-    <div class="form-info">
-    {% block contact_form_description %}
-        {% chunk "contact_form__"|add:form.form_tag %}
-    {% endblock %}
-    </div>
-
-    <form method="POST" action="." enctype="multipart/form-data" class="submit-form">
-    {% csrf_token %}
-    {% render_honeypot_field %}
-    <h3>Dane Przewodniczącego i szkoły zgłaszającej Uczestników:</h3>
-    <table>
-        {{ form.as_table }}
-    </table>
-
-    {% with formsets.commission as formset %}
-
-        <h3>Dane członków Komisji Szkolnej:</h3>
-
-        {{ formset.management_form }}
-
-        <ul class="errorlist">
-        {% for err in formset.non_form_errors %}
-            <li>{{ err }}</li>
-        {% endfor %}
-        </ul>
-
-        {% for form in formset.forms %}
-            <table>
-                {{ form.as_table }}
-            </table>
-        {% endfor %}
-
-        <div id="formstub-{{ formset.prefix }}" style="display:none">
-            <table>
-                {{ formset.empty_form.as_table }}
-            </table>
-        </div>
-
-        <input type="button" value="+ Dodaj kolejną osobę" class="add_more" data-selector="#formstub-{{formset.prefix}}" data-prefix="{{formset.prefix}}">
-    {% endwith %}
-
-
-    {% with formsets.student as formset %}
-        <h3>Dane Uczestników:</h3>
-
-        {{ formset.management_form }}
-
-        <ul class="errorlist">
-        {% for err in formset.non_form_errors %}
-            <li>{{ err }}</li>
-        {% endfor %}
-        </ul>
-
-        {% for form in formset.forms %}
-            <h4>Uczestnik/Uczestniczka:</h4>
-
-            <table>
-                {{ form.as_table }}
-            </table>
-        {% endfor %}
-
-        <div id="formstub-{{ formset.prefix }}" style="display:none">
-            <h4>Uczestnik/Uczestniczka:</h4>
-            <table>
-                {{ formset.empty_form.as_table }}
-            </table>
-        </div>
-
-        <input type="button" value="+ Dodaj kolejną osobę" class="add_more" data-selector="#formstub-{{formset.prefix}}" data-prefix="{{formset.prefix}}">
-    {% endwith %}
-
-    <p>
-    <button style="font-size:1.5em;">{% block contact_form_submit %}{{ form.submit_label }}{% endblock %}</button>
-    </p>
-    </form>
-
-
-{% endblock %}
diff --git a/edumed/templates/contact/olimpiada/mail_body.txt b/edumed/templates/contact/olimpiada/mail_body.txt
deleted file mode 100755 (executable)
index 0a63f92..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-Dziękujemy za rejestrację w Olimpiadzie Cyfrowej.
-Do udziału zostały zgłoszone następujące osoby:
-{% for student in contact.body.student %}* {{ student.first_name }} {{ student.last_name }}{% endfor %}
-
-Każdy zgłoszony uczeń powinien otrzymać wiadomość z potwierdzeniem
-rejestracji. Prosimy upewnić się, czy potwierdzenie dotarło do każdego
-ze zgłoszonych uczniów. W ten sposób zweryfikujemy, czy podane adresy
-są prawidłowe.
-
-Pierwszy etap Olimpiady (test on-line) odbędzie się
-15 listopada 2016 r. o godz. 10:00 i potrwa 90 minut.
-
-Wszystkie ogłoszenia związane z Turniejem będą publikowane na stronie https://olimpiadacyfrowa.pl.
-W razie pytań lub wątpliwości można kontaktować się z nami, pisząc na adres: olimpiada@nowoczesnapolska.org.pl.
-
-Z pozdrowieniami,
-
-Zespół Olimpiady Cyfrowej
-Fundacja Nowoczesna Polska
\ No newline at end of file
diff --git a/edumed/templates/contact/olimpiada/mail_subject.txt b/edumed/templates/contact/olimpiada/mail_subject.txt
deleted file mode 100755 (executable)
index b40c079..0000000
+++ /dev/null
@@ -1 +0,0 @@
-Potwierdzenie zgłoszenia uczniów do Olimpiady Cyfrowej
\ No newline at end of file
diff --git a/edumed/templates/contact/olimpiada/student_mail_body.html b/edumed/templates/contact/olimpiada/student_mail_body.html
deleted file mode 100644 (file)
index eb3df3e..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-Witaj,
-
-Przewodniczący Komisji Szkolnej właśnie zgłosił Cię do Olimpiady Cyfrowej.
-Cieszymy się, że chcesz wziąć w niej udział.
-
-Pierwszy etap Olimpiady (test on-line) odbędzie się 15 listopada 2016 r.
-o godz. 10:00 i potrwa 90 minut.
-
-Szczegółowe informacje na temat pierwszego etapu Olimpiady oraz wszystkie
-ogłoszenia z nią związane będą publikowane na stronie https://olimpiadacyfrowa.pl.
-W razie pytań lub wątpliwości możesz kontaktować się z nami, pisząc na adres
-olimpiada@nowoczesnapolska.org.pl.
-
-Z pozdrowieniami,
-
-Zespół Olimpiady Cyfrowej
-Fundacja Nowoczesna Polska
diff --git a/edumed/templates/contact/olimpiada/student_mail_subject.html b/edumed/templates/contact/olimpiada/student_mail_subject.html
deleted file mode 100644 (file)
index 4910d3f..0000000
+++ /dev/null
@@ -1 +0,0 @@
-Potwierdzenie zgłoszenia do Olimpiady Cyfrowej
\ No newline at end of file
diff --git a/edumed/templates/contact/olimpiada/thanks.html b/edumed/templates/contact/olimpiada/thanks.html
deleted file mode 100755 (executable)
index f05dd36..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-{% extends "contact/thanks.html" %}
-
-{% block contact_form_description %}
-<p>Dziękujemy za rejestrację w Olimpiadzie Cyfrowej.</p>
-
-<p>Na adres e-mail Przewodniczącego/Przewodniczącej została wysłana wiadomość potwierdzająca
-rejestrację.</p>
-
-<p>Każdy zgłoszony uczeń powinien otrzymać wiadomość z potwierdzeniem
-rejestracji.
-Prosimy upewnić się, że potwierdzenie dotarło do każdego ze
-zgłoszonych uczniów.
-W ten sposób zweryfikujemy, czy podane adresy są prawidłowe. </p>
-
-<p>Zespół Olimpiady Cyfrowej<br>
-fundacja Nowoczesna Polska</p>
-{% endblock %}
diff --git a/edumed/templates/contact/sciezki-kopernika-test/form.html b/edumed/templates/contact/sciezki-kopernika-test/form.html
deleted file mode 100644 (file)
index 59433a2..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-{% extends "contact/form.html" %}
-
-{% block body %}
-    {% include 'sciezki_logos.html' %}
-    {{ block.super }}
-{% endblock %}
-
-{% block form %}
-    {{ form.as_p }}
-    <p><button>{{ form.submit_label }}</button></p>
-{% endblock %}
diff --git a/edumed/templates/contact/sciezki-kopernika-test/mail_subject.txt b/edumed/templates/contact/sciezki-kopernika-test/mail_subject.txt
deleted file mode 100644 (file)
index f315550..0000000
+++ /dev/null
@@ -1 +0,0 @@
-Wyniki testu
\ No newline at end of file
diff --git a/edumed/templates/contact/sciezki-kopernika-test/results.html b/edumed/templates/contact/sciezki-kopernika-test/results.html
deleted file mode 100644 (file)
index 46f51ad..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-{% extends base_template|default:"base.html" %}
-{% load i18n %}
-
-{% block title %}Wyniki{% endblock %}
-
-{% block body %}
-    {% include 'sciezki_logos.html' %}
-    <h1>Wyniki</h1>
-
-    <p>Suma uzyskanych punktów: {{ results.points|floatformat }} na {{ results.total }} możliwych.</p>
-
-    {#<p class="box-button" style="max-width: 20em;"><a href="{% url 'contact_form' 'sciezki-kopernika' %}" class="nice-button">Zgłoś się na warsztaty</a></p>#}
-
-    {% for question in results.questions %}
-        <strong>{{ question.label }}</strong>
-        <ol class="alpha">
-            {% for answer, chosen, correct in question.answers %}
-                <li style="{% if chosen %}font-weight: bold;{% endif %}{% if correct %}color: #00cc44;{% endif %}">{{ answer }}</li>
-            {% endfor %}
-        </ol>
-        {% if question.chosen == question.correct %}
-            <p>Wybrana poprawna odpowiedź {{ question.chosen }}.</p>
-        {% else %}
-            <p>Wybrana odpowiedź {{ question.chosen }}, poprawna odpowiedź {{ question.correct }}.</p>
-        {% endif %}
-        <p><strong>Komentarz do odpowiedzi:</strong></p>
-        {{ question.comment }}
-    {% endfor %}
-    {#<p class="box-button" style="max-width: 20em;"><a href="{% url 'contact_form' 'sciezki-kopernika' %}" class="nice-button">Zgłoś się na warsztaty</a></p>#}
-    <p>Pytania stworzyli: Grzegorz Stunża, Marcin Wilkowski.</p>
-    <p>Komentarzami opatrzyli: Paulina Piasecka, Paweł Maranowski.</p>
-
-{% endblock %}
\ No newline at end of file
diff --git a/edumed/templates/contact/sciezki-kopernika-test/results_email.txt b/edumed/templates/contact/sciezki-kopernika-test/results_email.txt
deleted file mode 100644 (file)
index 7b68c48..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-Witaj,
-
-Oto wyniki testu:
-
-Suma uzyskanych punktów: {{ results.points|floatformat }} na {{ results.total }} możliwych.
-
-Pod poniższym adresem możesz obejrzeć swoje odpowiedzi z komentarzami:
-https://edukacjamedialna.edu.pl{% url 'contact_results' contact.id contact.digest %}
-
-{% comment %}
-Zgłoś się na warsztaty:
-https://edukacjamedialna.edu.pl{% url 'contact_form' 'sciezki-kopernika' %}
-{% endcomment %}
-
-Z pozdrowieniami,
-fundacja Nowoczesna Polska
-
---
-Wiadomość wysłana automatycznie. Prosimy na nią nie odpowiadać.
\ No newline at end of file
diff --git a/edumed/templates/contact/sciezki-kopernika/form.html b/edumed/templates/contact/sciezki-kopernika/form.html
deleted file mode 100644 (file)
index 31f6534..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-{% extends "contact/form.html" %}
-
-{% block body %}
-    {% include 'sciezki_logos.html' %}
-    {{ block.super }}
-{% endblock %}
\ No newline at end of file
diff --git a/edumed/templates/contact/sciezki-kopernika/mail_body.txt b/edumed/templates/contact/sciezki-kopernika/mail_body.txt
deleted file mode 100644 (file)
index 0760553..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-Witaj,
-
-Dziękujemy za przesłanie zgłoszenia do udziału w warsztatach z zakresu edukacji medialnej i cyfrowej prowadzonych przez Collegium Civitas i Fundację Nowoczesna Polska w ramach projektu „Collegium Młodych – media i technologie”.
-
-Pamiętaj, że aby zaakceptować Twoje zgłoszenie, musimy otrzymać komplet dokumentów rekrutacyjnych w formie papierowej, opatrzonych wymaganymi podpisami, oraz potwierdzić dane w nich zawarte. O ostatecznej decyzji powiadomimy Ciebie i Twojego rodzica / opiekuna prawnego w późniejszym terminie.
-
-Wzory dokumentów rekrutacyjnych znajdziesz pod adresem
-http://edukacjamedialna.edu.pl/media/chunks/attachment/dokumenty_rekrutacyjne.zip.
-
-Po wypełnieniu i podpisaniu odeślij je na adres:
-
-Fundacja Nowoczesna Polska
-ul. Marszałkowska 84/92 lok. 125
-00-514 Warszawa
-z dopiskiem: Warsztaty – Ścieżki Kopernika
-
-Jeśli masz jakieś pytania, napisz do nas: warsztaty@nowoczesnapolska.org.pl lub zadzwoń: (22) 465-15-35.
-
-Pozdrawiamy,
-fundacja Nowoczesna Polska
\ No newline at end of file
diff --git a/edumed/templates/contact/sciezki-kopernika/mail_subject.txt b/edumed/templates/contact/sciezki-kopernika/mail_subject.txt
deleted file mode 100644 (file)
index 28ae8f2..0000000
+++ /dev/null
@@ -1 +0,0 @@
-Potwierdzenie otrzymania zgłoszenia
\ No newline at end of file
diff --git a/edumed/templates/contact/sciezki-kopernika/thanks.html b/edumed/templates/contact/sciezki-kopernika/thanks.html
deleted file mode 100644 (file)
index b55caa3..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-{% extends "contact/thanks.html" %}
-
-{% block body %}
-    {% include "sciezki_logos.html" %}
-    {{ block.super }}
-{% endblock %}
-
-{% block contact_form_description %}
-    <p>Dziękujemy za przesłanie zgłoszenia do udziału w warsztatach z zakresu edukacji medialnej i cyfrowej prowadzonych przez Collegium Civitas i Fundację Nowoczesna Polska w ramach projektu „Collegium Młodych – media i technologie”.</p>
-
-    <p>Pamiętaj, że aby zaakceptować Twoje zgłoszenie, musimy otrzymać komplet dokumentów rekrutacyjnych w formie papierowej, opatrzonych wymaganymi podpisami, oraz potwierdzić dane w nich zawarte. O ostatecznej decyzji powiadomimy Ciebie i Twojego rodzica / opiekuna prawnego w późniejszym terminie.</p>
-
-    <p class="box-button"><a href="/media/chunks/attachment/dokumenty_rekrutacyjne.zip" class="dl-button">Pobierz wzory dokumentów rekrutacyjnych</a></p>
-
-    <p>Po wypełnieniu i podpisaniu dokumentów, odeślij je na adres:</p>
-
-    <p>Fundacja Nowoczesna Polska<br>
-    ul. Marszałkowska 84/92 lok. 125<br>
-    00-514 Warszawa<br>
-    z dopiskiem: Warsztaty – Ścieżki Kopernika</p>
-
-    <p>Jeśli masz jakieś pytania, napisz do nas:
-    <a href="mailto:warsztaty@nowoczesnapolska.org.pl">warsztaty@nowoczesnapolska.org.pl</a> lub zadzwoń: (22) 465-15-35.</p>
-
-    <p>Pozdrawiamy,<br>
-    fundacja Nowoczesna Polska</p>
-{% endblock %}
diff --git a/edumed/templates/contact/sugestie/mail_body.txt b/edumed/templates/contact/sugestie/mail_body.txt
deleted file mode 100644 (file)
index ad38005..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-Dziękujemy,
-
-Zgłoszenie na stronie {{ site_name }}
-zostało przekazane koordynatorce projektu.
-
-W razie jakichkolwiek dodatkowych wątpliwości prosimy o kontakt:
-http://edukacjamedialna.edu.pl/info/kontakt/
-
--- 
-Wiadomość wysłana automatycznie. Prosimy na nią nie odpowiadać.
diff --git a/edumed/templates/contact/sugestie/mail_subject.txt b/edumed/templates/contact/sugestie/mail_subject.txt
deleted file mode 100644 (file)
index 19fcbfa..0000000
+++ /dev/null
@@ -1 +0,0 @@
-Zgłoszenie na stronie {{ site_name }} zostało zarejestrowane.
diff --git a/edumed/templates/contact/sugestie/thanks.html b/edumed/templates/contact/sugestie/thanks.html
deleted file mode 100644 (file)
index 5c89bba..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-{% extends "contact/thanks.html" %}
-
-{% block contact_form_description %}
-<p>Dziękujemy, zgłoszenie zostało zarejestrowane.</p>
-{% endblock %}
diff --git a/edumed/templates/contact/tem/mail_body.txt b/edumed/templates/contact/tem/mail_body.txt
deleted file mode 100755 (executable)
index bb22ccb..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-Dziękujemy za przesłanie zgłoszenia.
-
-O wynikach rekrutacji poinformujemy uczestników do 30 kwietnia. 
-
-Z pozdrowieniami
-
-Zespół Edukacji Medialnej
-fundacja Nowoczesna Polska
diff --git a/edumed/templates/contact/tem/mail_subject.txt b/edumed/templates/contact/tem/mail_subject.txt
deleted file mode 100755 (executable)
index edd517f..0000000
+++ /dev/null
@@ -1 +0,0 @@
-TEM - szkolenie dla trenerów edukacji medialnej
diff --git a/edumed/templates/contact/tem/thanks.html b/edumed/templates/contact/tem/thanks.html
deleted file mode 100755 (executable)
index 0f0c893..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-{% extends "contact/thanks.html" %}
-
-{% block contact_form_description %}
-<p>Dziękujemy za przesłanie zgłoszenia.</p>
-
-<p>O wynikach rekrutacji poinformujemy uczestników do 30 kwietnia.</p>
-{% endblock %}
diff --git a/edumed/templates/contact/trenerzy-cybernauci/mail_body.txt b/edumed/templates/contact/trenerzy-cybernauci/mail_body.txt
deleted file mode 100644 (file)
index 948a6d8..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-Dziękujemy za przesłanie zgłoszenia do udziału w Szkoleniu Trenerskim i wdrażaniu Programu Szkoleniowego w ramach projektu „Cybernauci”.
-
-Zakończenie naboru dokumentów nastąpi 7 maja. Następnie dokumenty zostaną poddane weryfikacji formalnej i merytorycznej, w wyniku której zostaną wyłonione osoby do drugiego etapu rekrutacji – rozmów telefonicznych.
-
-O stanie rekrutacji będziemy informować mailowo.
-
-Z pozdrowieniami,
-zespół projektu „Cybernauci”
-
----
-
-„Cybernauci - kompleksowy projekt kształtowania bezpiecznych zachowań w sieci” jest finansowany ze środków Ministra Edukacji Narodowej.
-
-Parter projektu: Collegium Civitas
-Patronat honorowy: Ministerstwo Cyfryzacji, Rzecznik Praw Dziecka Marek Michalak, Ośrodek Rozwoju Edukacji
diff --git a/edumed/templates/contact/trenerzy-cybernauci/mail_subject.txt b/edumed/templates/contact/trenerzy-cybernauci/mail_subject.txt
deleted file mode 100644 (file)
index 15eaebc..0000000
+++ /dev/null
@@ -1 +0,0 @@
-Dziękujemy za przesłanie formularza zgłoszeniowego
\ No newline at end of file
diff --git a/edumed/templates/contact/trenerzy-cybernauci2017 b/edumed/templates/contact/trenerzy-cybernauci2017
deleted file mode 120000 (symlink)
index 66a5718..0000000
+++ /dev/null
@@ -1 +0,0 @@
-trenerzy-cybernauci
\ No newline at end of file
diff --git a/edumed/templates/contact/wspolpraca/mail_body.txt b/edumed/templates/contact/wspolpraca/mail_body.txt
deleted file mode 100644 (file)
index 1e68866..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-Dziękujemy,
-
-Zgłoszenie na stronie {{ site_name }} zostało zarejestrowane.
-
-W razie jakichkolwiek dodatkowych wątpliwości prosimy o kontakt:
-http://edukacjamedialna.edu.pl/info/kontakt/
-
--- 
-Wiadomość wysłana automatycznie. Prosimy na nią nie odpowiadać.
diff --git a/edumed/templates/contact/wspolpraca/mail_subject.txt b/edumed/templates/contact/wspolpraca/mail_subject.txt
deleted file mode 100644 (file)
index 19fcbfa..0000000
+++ /dev/null
@@ -1 +0,0 @@
-Zgłoszenie na stronie {{ site_name }} zostało zarejestrowane.
diff --git a/edumed/templates/contact/wspolpraca/thanks.html b/edumed/templates/contact/wspolpraca/thanks.html
deleted file mode 100644 (file)
index 5c89bba..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-{% extends "contact/thanks.html" %}
-
-{% block contact_form_description %}
-<p>Dziękujemy, zgłoszenie zostało zarejestrowane.</p>
-{% endblock %}
diff --git a/edumed/templates/contact/wtem/form.html b/edumed/templates/contact/wtem/form.html
deleted file mode 100755 (executable)
index e340633..0000000
+++ /dev/null
@@ -1,71 +0,0 @@
-{% extends "base.html" %}
-{% load chunks %}
-
-{% block title %}{{ form.form_title }}{% endblock %}
-
-{% block body %}
-
-
-
-
-
-
-    <h1>{% block contact_form_title %}{{ form.form_title }}{% endblock %}</h1>
-
-    <div class="form-info">
-    {% block contact_form_description %}
-        {% chunk "contact_form__"|add:form.form_tag %}
-    {% endblock %}
-    </div>
-
-    <form method="POST" action="." enctype="multipart/form-data" class="submit-form">
-    {% csrf_token %}
-    <h3>Dane Opiekuna/Opiekunki i instytucji zgłaszającej Uczestnika:</h3>
-    <table>
-        {{ form.as_table }}
-    </table>
-
-    {% for formset in formsets %}
-
-        <h3>Dane Uczestników i Uczestniczek:</h3>
-       <p>Można zgłosić 3 do 5 osób.</p>
-
-        {{ formset.management_form }}
-
-        <ul class="errorlist">
-        {% for err in formset.non_form_errors %}
-            <li>{{ err }}</li>
-        {% endfor %}
-        </ul>
-
-        {% for form in formset.forms %}
-            <h4>Uczestnik lub Uczestniczka nr {{ forloop.counter }}:</h4>
-
-            <table>
-                {{ form.as_table }}
-            </table>
-        {% endfor %}
-
-{% comment %}
-        <div id="formstub-{{ formset.prefix }}" style="display:none">
-            <h3>Dane Uczestnika/Uczestniczki:</h3>
-            <table>
-                {{ formset.empty_form.as_table }}
-            </table>
-        </div>
-
-        <input type="button" value="+ Dodaj kolejną osobę" class="add_more" data-selector="#formstub-{{formset.prefix}}" data-prefix="{{formset.prefix}}">
-{% endcomment %}
-        <script>
-
-        </script>
-
-    {% endfor %}
-
-    <p>
-    <button style="font-size:1.5em;">{% block contact_form_submit %}{{ form.submit_label }}{% endblock %}</button>
-    </p>
-    </form>
-
-
-{% endblock %}
diff --git a/edumed/templates/contact/wtem/mail_body.txt b/edumed/templates/contact/wtem/mail_body.txt
deleted file mode 100755 (executable)
index 0a63f92..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-Dziękujemy za rejestrację w Olimpiadzie Cyfrowej.
-Do udziału zostały zgłoszone następujące osoby:
-{% for student in contact.body.student %}* {{ student.first_name }} {{ student.last_name }}{% endfor %}
-
-Każdy zgłoszony uczeń powinien otrzymać wiadomość z potwierdzeniem
-rejestracji. Prosimy upewnić się, czy potwierdzenie dotarło do każdego
-ze zgłoszonych uczniów. W ten sposób zweryfikujemy, czy podane adresy
-są prawidłowe.
-
-Pierwszy etap Olimpiady (test on-line) odbędzie się
-15 listopada 2016 r. o godz. 10:00 i potrwa 90 minut.
-
-Wszystkie ogłoszenia związane z Turniejem będą publikowane na stronie https://olimpiadacyfrowa.pl.
-W razie pytań lub wątpliwości można kontaktować się z nami, pisząc na adres: olimpiada@nowoczesnapolska.org.pl.
-
-Z pozdrowieniami,
-
-Zespół Olimpiady Cyfrowej
-Fundacja Nowoczesna Polska
\ No newline at end of file
diff --git a/edumed/templates/contact/wtem/mail_subject.txt b/edumed/templates/contact/wtem/mail_subject.txt
deleted file mode 100755 (executable)
index b40c079..0000000
+++ /dev/null
@@ -1 +0,0 @@
-Potwierdzenie zgłoszenia uczniów do Olimpiady Cyfrowej
\ No newline at end of file
diff --git a/edumed/templates/contact/wtem/student_mail_body.html b/edumed/templates/contact/wtem/student_mail_body.html
deleted file mode 100644 (file)
index eb3df3e..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-Witaj,
-
-Przewodniczący Komisji Szkolnej właśnie zgłosił Cię do Olimpiady Cyfrowej.
-Cieszymy się, że chcesz wziąć w niej udział.
-
-Pierwszy etap Olimpiady (test on-line) odbędzie się 15 listopada 2016 r.
-o godz. 10:00 i potrwa 90 minut.
-
-Szczegółowe informacje na temat pierwszego etapu Olimpiady oraz wszystkie
-ogłoszenia z nią związane będą publikowane na stronie https://olimpiadacyfrowa.pl.
-W razie pytań lub wątpliwości możesz kontaktować się z nami, pisząc na adres
-olimpiada@nowoczesnapolska.org.pl.
-
-Z pozdrowieniami,
-
-Zespół Olimpiady Cyfrowej
-Fundacja Nowoczesna Polska
diff --git a/edumed/templates/contact/wtem/student_mail_subject.html b/edumed/templates/contact/wtem/student_mail_subject.html
deleted file mode 100644 (file)
index 4910d3f..0000000
+++ /dev/null
@@ -1 +0,0 @@
-Potwierdzenie zgłoszenia do Olimpiady Cyfrowej
\ No newline at end of file
diff --git a/edumed/templates/contact/wtem/thanks.html b/edumed/templates/contact/wtem/thanks.html
deleted file mode 100755 (executable)
index 0185bcc..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-{% extends "contact/thanks.html" %}
-
-{% block contact_form_description %}
-<p>Dziękujemy za rejestrację w Wielkim Turnieju Edukacji Medialnej.</p>
-
-<p>Na adres adres e-mail Opiekuna została wysłana wiadomość potwierdzająca
-rejestrację.</p>
-
-<p>Każdy zgłoszony uczeń powinien otrzymać wiadomość z potwierdzeniem rejestracji.
-Prosimy upewnić się, czy potwierdzenie dotarło do każdego ze zgłoszonych uczniów.
-W ten sposób zweryfikujemy, czy podane adresy są prawidłowe. </p>
-
-<p>Zespół Edukacji Medialnej<br>
-fundacja Nowoczesna Polska</p>
-{% endblock %}
diff --git a/edumed/templates/flatpages/default.html b/edumed/templates/flatpages/default.html
deleted file mode 100755 (executable)
index 1ab012c..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-{% extends "base.html" %}
-{% load textile_pl from fnp_markup %}
-
-{% block title %}{{ flatpage.title }}{% endblock %}
-
-{% block body %}
-<div id="main-bar" class="flatpage">
-{{ flatpage.content|textile_pl }}
-</div>
-{% endblock %}
diff --git a/edumed/templates/flatpages/mil.html b/edumed/templates/flatpages/mil.html
deleted file mode 100644 (file)
index 5ac86a6..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-{% extends "base_mil.html" %}
-{% load textile_pl from fnp_markup %}
-
-{% block title %}{{ flatpage.title }}{% endblock %}
-
-{% block body %}
-<div id="main-bar" class="flatpage">
-{{ flatpage.content|textile_pl }}
-</div>
-{% endblock %}
diff --git a/edumed/templates/flatpages/sciezki.html b/edumed/templates/flatpages/sciezki.html
deleted file mode 100644 (file)
index 9b0c392..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-{% extends "base.html" %}
-{% load textile_pl from fnp_markup %}
-
-{% block title %}{{ flatpage.title }}{% endblock %}
-
-{% block body %}
-    {% include "sciezki_logos.html" %}
-    <div id="main-bar" class="flatpage">
-        {{ flatpage.content|textile_pl }}
-    </div>
-{% endblock %}
diff --git a/edumed/templates/home.html b/edumed/templates/home.html
deleted file mode 100755 (executable)
index 2ea96c6..0000000
+++ /dev/null
@@ -1,68 +0,0 @@
-{% extends "base.html" %}
-{% load catalogue_tags %}
-{% load course_boxes_toc from curriculum_tags %}
-{% load chunk from chunks %}
-{% load static %}
-
-{% block full_title %}Edukacja medialna{% endblock %}
-
-{% block body %}
-
-{% catalogue_carousel %}
-
-<section id="main-promobox">
-  {% chunk "promobox" %}
-</section>
-
-<section id="main-sections">
-  <h1>Lekcje:</h1>
-  {% catalogue_levels_main %}
-</section>
-
-<section id="main-howto">
-  <h1>Nasze lekcje to:</h1>
-  <ul class="link-list">
-    <li><a class="knowledge" href="/info/jak-korzystac/#wiedza-w-pigulce">wiedza w pigułce</a></li>
-    <li><a class="activity" href="/info/jak-korzystac/#zadania">zadania</a></li>
-    <li><a class="lesson-plan" href="/info/jak-korzystac/#scenariusze">scenariusze</a></li>
-    <li><a class="reference" href="/info/jak-korzystac/#slowniczek">słowniczek</a></li>
-  </ul>
-  <p>Zobacz, <a href="{% url 'info' 'dobre-praktyki' %}">jak przeprowadzili je inni.</a></p>
-
-  <iframe width="220" height="124" src="//www.youtube.com/embed/XJ2q_ZCPIA8?controls=2&amp;rel=0&amp;showinfo=0&amp;theme=light" frameborder="0" allowfullscreen></iframe>
-</section>
-
-<section id="main-chosen">
-<h1>Według podstawy programowej:</h1>
-{% course_boxes_toc %}
-</section>
-
-
-<section id="main-tools">
-
-<section class="main-tools-box">
-<h1>Aktualności na stronie Fundacji</h1>
-{% latest_blog_posts "http://nowoczesnapolska.org.pl/feed" 5 %}
-</section>
-
-<section class="main-tools-box">
-<h1>Narzędzia</h1>
-<ul class="link-list">
-    <li><a href="{% url 'contact_form' 'sugestie' %}">Zgłoś błąd lub sugestię</a></li>
-    <li><a href="{% url 'info' 'jak-korzystac/' %}">Jak korzystać?</a></li>
-    <li><a href="{% url 'catalogue_lesson' 'slowniczek' %}">Słowniczek</a></li>
-    <li><a href="{% url 'catalogue_lesson' 'metody' %}">Metody edukacyjne</a></li>
-    {% if request.user.is_authenticated %}<li><a href="{% url 'pybb:index' %}">Forum</a></li>{% endif %}
-    <li><a href="{% url 'info' 'infografiki' %}">Infografiki</a></li>
-    <li><a href="{% url 'info' 'aplikacje-mobilne' %}">Aplikacje mobilne</a></li>
-    <li><a href="/media/chunks/attachment/poradnik-bezpieczenstwa-mobilnego.pdf">Poradnik bezpieczeństwa mobilnego (PDF)</a></li>
-    <li><a href="http://nowoczesnapolska.org.pl/prywatnosc/">Polityka prywatności i ciasteczka</a></li>
-</ul>
-</section>
-
-<div style="clear:both"></div>
-</section>
-
-
-{% endblock %}
-
diff --git a/edumed/templates/home_mil.html b/edumed/templates/home_mil.html
deleted file mode 100644 (file)
index 5811963..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-{% extends "base_mil.html" %}
-
-{% block body %}
-mil
-{% endblock %}
diff --git a/edumed/templates/olimpiada_teaser.html b/edumed/templates/olimpiada_teaser.html
deleted file mode 100644 (file)
index f5266d8..0000000
+++ /dev/null
@@ -1,45 +0,0 @@
-{% extends "base_super.html" %}
-{% load textile_pl from fnp_markup %}
-{% load sponsor_tags %}
-{% load compressed %}
-{% load static %}
-
-{% block full_title %}Olimpiada cyfrowa{% endblock %}
-
-{% block og_site_name %}Olimpiada cyfrowa{% endblock %}
-
-{% block ogurl %}https://olimpiadacyfrowa.pl{% endblock %}
-
-{% block og_image %}http://olimpiadacyfrowa.pl/media/chunks/attachment/olimpiada_cyfrowa_logo.png{% endblock %}
-
-{% block logo %}<img src="{% static "img/logo-oc.png" %}" height="73" alt="Olimpiada cyfrowa"/>{% endblock %}
-
-{% block searchbox %}{% endblock %}
-
-{% block top_navigation %}
-  <li><a class="menu-oc-regulamin" href="/regulamin/">Regulamin</a></li>
-  <li><a class="menu-oc-program" href="/program/">Program</a></li>
-  <li><a class="menu-oc-literatura" href="/literatura/">Literatura</a></li>
-  <li><a class="menu-oc-harmonogram" href="/harmonogram/">Harmonogram</a></li>
-  <li><a class="menu-oc-komitet" href="/sklad/">Rada i komitet</a></li>
-  <li><a class="menu-oc-kontakt" href="/kontakt/">Kontakt</a></li>
-{% endblock %}
-
-{% block body %}
-  <div id="main-bar" class="flatpage">
-    {{ flatpage.content|textile_pl }}
-  </div>
-{% endblock %}
-
-{% block copyrights %}
-  <br/>Ikonki w menu:
-  <a href="http://www.flaticon.com/authors/freepik">Designed by Freepik and distributed by Flaticon</a>
-{% endblock %}
-
-{% block sponsors %}
-    {% sponsor_page "footer_olimpiada" %}
-{% endblock %}
-
-{% block extra_script %}
-    {% compressed_js 'base' %}
-{% endblock %}
\ No newline at end of file
diff --git a/edumed/templates/pybb/_need_to_login_message.html b/edumed/templates/pybb/_need_to_login_message.html
deleted file mode 100755 (executable)
index bcc8550..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-{% load i18n %}
-<a href="{% url 'login' %}">{% trans "Login" %} / {% trans "register" %}</a> {% trans "to create to post a reply" %}.
diff --git a/edumed/templates/pybb/avatar.html b/edumed/templates/pybb/avatar.html
deleted file mode 100755 (executable)
index 0358753..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-{% load pybb_tags %}
-{% load libravatar_tags %}
-<div class="avatar">
-    {% pybb_get_profile user=user as user_profile %}
-    <a href="{{ user_profile.get_absolute_url }}">
-        <img src="{% libravatar user.email PYBB_AVATAR_WIDTH %}" alt="{{ user }} libravatar" width="{{ PYBB_AVATAR_WIDTH }}" height="{{ PYBB_AVATAR_HEIGHT }}" />
-    </a>
-</div>
diff --git a/edumed/templates/pybb/breadcrumb.html b/edumed/templates/pybb/breadcrumb.html
deleted file mode 100755 (executable)
index a537281..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-{% load i18n pybb_tags %}
-<ul class='breadcrumb'>
-    {% include "pybb/breadcrumb_top_extra_crumb.html" %}
-    <li><a href="{% url 'pybb:index' %}">Forum</a> <span class="divider">/</span></li>
-    {% if object %}
-        {% if object.get_parents %}
-            {% for obj in object.get_parents %}
-                <li>{% pybb_link obj %} <span class="divider">/</span></li>
-            {% endfor %}
-        {% endif %}
-        {% if extra_crumb %}
-            <li>{% pybb_link object %} <span class="divider">/</span></li>
-        {% else %}
-            <li>{{ object }}</li>
-        {% endif %}
-    {% endif %}
-    {% if extra_crumb %}
-        <li>{% trans extra_crumb %}</li>
-    {% endif %}
-</ul>
diff --git a/edumed/templates/pybb/breadcrumb_top_extra_crumb.html b/edumed/templates/pybb/breadcrumb_top_extra_crumb.html
deleted file mode 100755 (executable)
index dd09f97..0000000
+++ /dev/null
@@ -1 +0,0 @@
-<li><a href="{% url 'home' %}">Strona główna</a> <span class="divider">/</span></li>
diff --git a/edumed/templates/sciezki_logos.html b/edumed/templates/sciezki_logos.html
deleted file mode 100644 (file)
index 84cc45d..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-{% load static %}
-<img src="{% static 'img/sciezki-kopernika/fe.jpg' %}" height="60" style="margin-right: 20px;">
-<img src="{% static 'img/sciezki-kopernika/cc.jpg' %}" height="60" style="margin-right: 20px;">
-<img src="{% static 'img/sciezki-kopernika/fnp.png' %}" height="60" style="margin-right: 20px;">
-<img src="{% static 'img/sciezki-kopernika/ue.jpg' %}" height="60">
\ No newline at end of file
diff --git a/edumed/templates/search/search.html b/edumed/templates/search/search.html
deleted file mode 100755 (executable)
index 4216ab9..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-{% extends "base.html" %}
-
-{% block body %}
-    <h1>Wyszukiwanie</h1>
-
-    {% if query %}
-        {% for result in page.object_list %}
-            <p>
-                <a href="{{ result.object.get_absolute_url }}">{{ result.object.title }}</a>
-            </p>
-        {% empty %}
-            <p>Brak wyników.</p>
-        {% endfor %}
-
-        {% if page.has_previous or page.has_next %}
-            <div>
-                {% if page.has_previous %}<a href="?q={{ query }}&amp;page={{ page.previous_page_number }}">{% endif %}&laquo; Poprzednie{% if page.has_previous %}</a>{% endif %}
-                |
-                {% if page.has_next %}<a href="?q={{ query }}&amp;page={{ page.next_page_number }}">{% endif %}Następne &raquo;{% if page.has_next %}</a>{% endif %}
-            </div>
-        {% endif %}
-    {% else %}
-        <p>Brak wyników.</p>
-    {% endif %}
-{% endblock %}
diff --git a/edumed/templatetags/__init__.py b/edumed/templatetags/__init__.py
deleted file mode 100644 (file)
index d384124..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-# -*- coding: utf-8 -*-
-# This file is part of Wolnelektury, licensed under GNU Affero GPLv3 or later.
-# Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
-#
diff --git a/edumed/templatetags/inline_stylesheet.py b/edumed/templatetags/inline_stylesheet.py
deleted file mode 100644 (file)
index 76f0faf..0000000
+++ /dev/null
@@ -1,39 +0,0 @@
-# -*- coding: utf-8 -*-
-# https://github.com/jazzband/django-pipeline/issues/295#issuecomment-152095865
-# adjusted for older pipeline
-from __future__ import unicode_literals
-import codecs
-
-from django.contrib.staticfiles.storage import staticfiles_storage
-from django.utils.safestring import mark_safe
-from django import template
-from pipeline.templatetags import compressed
-
-register = template.Library()
-
-
-class StylesheetNode(compressed.CompressedCSSNode):
-    def render_css(self, package, path):
-        return self.render_individual_css(package, [path])
-
-    def render_individual_css(self, package, paths, **kwargs):
-        html = []
-        for path in paths:
-            with codecs.open(staticfiles_storage.path(path), 'r', 'utf-8') as f:
-                html.append(f.read())
-        html = '<style type="text/css">' + '\n'.join(html) + '</style>'
-        return mark_safe(html)
-
-
-@register.tag
-def inline_stylesheet(parser, token):
-    """ Template tag that mimics pipeline's stylesheet tag, but embeds
-    the resulting CSS directly in the page.
-    """
-    try:
-        tag_name, name = token.split_contents()
-    except ValueError:
-        raise template.TemplateSyntaxError(
-            '%r requires exactly one argument: the name of a group in the PIPELINE_CSS setting'
-            % token.split_contents()[0])
-    return StylesheetNode(name)
diff --git a/edumed/urls.py b/edumed/urls.py
deleted file mode 100644 (file)
index 262c433..0000000
+++ /dev/null
@@ -1,74 +0,0 @@
-# -*- coding: utf-8 -*-
-from django.conf.urls import patterns, include, url
-from django.conf import settings
-from django.contrib.flatpages.views import flatpage
-from django.shortcuts import redirect
-
-from .views import HomeView, AvatarlessProfileEditView, flatpage_with_template
-
-urlpatterns = patterns(
-    '',
-    url(r'^$', HomeView.as_view(), name="home"),
-    url(r'^lekcje/', include('catalogue.urls')),
-    url(r'^info/turniej/(?P<url>.*)$', lambda request, url: redirect('olimpiada', url)),
-    url(r'^info/(?P<url>.*)$', flatpage, name="info"),
-    url(r'^olimpiada/$', lambda request: flatpage(request, 'turniej/'), name='olimpiada'),
-    url(r'^olimpiada/(?P<url>.*)$', lambda request, url: flatpage(request, 'turniej/' + url), name='olimpiada'),
-    url(r'^olimpiada-teaser/(?P<url>.*)$',
-        lambda request, url: flatpage_with_template(request, 'turniej/' + url, 'olimpiada_teaser.html'),
-        name='olimpiada_teaser'),
-    url(r'^szukaj/', include('haystack.urls')),
-    url(r'^zglos/', include('contact.urls')),
-    url(r'^forum/profile/edit/$', AvatarlessProfileEditView.as_view(), name='edit_profile'),
-    url(r'^forum/', include('forum.urls')),
-    url(r'^forum/', include('pybb.urls', namespace='pybb')),
-    url(r'^kompetencje/', include('curriculum.urls')),
-    url(r'^wlem/', include('wtem.urls')),
-    url(r'^api/', include('api.urls')),
-)
-
-
-# Admin stuff, if necessary.
-if 'django.contrib.admin' in settings.INSTALLED_APPS:
-    from django.contrib import admin
-    admin.autodiscover()
-
-    if 'django_cas' in settings.INSTALLED_APPS:
-        urlpatterns += patterns(
-            '',
-            (r'^admin/logout/$', 'django_cas.views.logout'),
-        )
-    urlpatterns += patterns(
-        '',
-        url(r'^admin/doc/', include('django.contrib.admindocs.urls')),
-        url(r'^admin/', include(admin.site.urls)),
-    )
-
-# Auth stuff, if necessary
-if 'django_cas' in settings.INSTALLED_APPS:
-    urlpatterns += patterns(
-        '',
-        url(r'^accounts/login/$', 'django_cas.views.login', name='login'),
-        url(r'^accounts/logout/$', 'django_cas.views.logout', name='logout'),
-    )
-
-
-if settings.DEBUG:
-    from fnpdjango.utils.urls import i18n_patterns
-    from .views import mil_home_view, mil_contact_view, mil_knowledge_base_view
-    urlpatterns += i18n_patterns(
-        '',
-        url(r'^katalog/$', mil_home_view, name="mil_home"),
-        url(r'^wez-udzial/', include('comment.urls')),
-        url(r'^kontakt/$', mil_contact_view, name='mil_contact'),
-        url(r'^bazawiedzy/(?P<url>.*)$', mil_knowledge_base_view, name="knowledge_base"),
-    )
-
-
-if settings.DEBUG:
-    urlpatterns += patterns(
-        '',
-        url(r'^media/(?P<path>.*)$', 'django.views.static.serve', {
-            'document_root': settings.MEDIA_ROOT,
-        }),
-    )
diff --git a/edumed/utils.py b/edumed/utils.py
deleted file mode 100644 (file)
index 2dce875..0000000
+++ /dev/null
@@ -1,44 +0,0 @@
-# -*- coding: utf-8 -*-
-import codecs
-import csv
-import cStringIO
-
-from settings.apps import INSTALLED_APPS
-
-
-# source: https://docs.python.org/2/library/csv.html#examples
-class UnicodeCSVWriter(object):
-    """
-    A CSV writer which will write rows to CSV file "f",
-    which is encoded in the given encoding.
-    """
-
-    def __init__(self, f, dialect=csv.excel, encoding="utf-8", **kwds):
-        # Redirect output to a queue
-        self.queue = cStringIO.StringIO()
-        self.writer = csv.writer(self.queue, dialect=dialect, **kwds)
-        self.stream = f
-        self.encoder = codecs.getincrementalencoder(encoding)()
-
-    def writerow(self, row):
-        self.writer.writerow([s.encode("utf-8") for s in row])
-        # Fetch UTF-8 output from the queue ...
-        data = self.queue.getvalue()
-        data = data.decode("utf-8")
-        # ... and reencode it into the target encoding
-        data = self.encoder.encode(data)
-        # write to the target stream
-        self.stream.write(data)
-        # empty queue
-        self.queue.truncate(0)
-
-    def writerows(self, rows):
-        for row in rows:
-            self.writerow(row)
-
-
-def process_app_deps(list_with_deps):
-    return tuple(
-        (x[0] if type(x) == tuple else x)
-        for x in list_with_deps
-        if type(x) != tuple or x[1] in INSTALLED_APPS)
\ No newline at end of file
diff --git a/edumed/views.py b/edumed/views.py
deleted file mode 100644 (file)
index af9bad5..0000000
+++ /dev/null
@@ -1,64 +0,0 @@
-# -*- coding: utf-8 -*-
-from django.contrib.flatpages.views import flatpage
-from django.views.defaults import page_not_found
-from django.views.generic import TemplateView
-from pybb.views import ProfileEditView
-
-from .forms import AvatarlessEditProfileForm
-
-
-class HomeView(TemplateView):
-    template_name = "home.html"
-
-
-def mil_home_view(request):
-    return flatpage(request, url='/' if request.LANGUAGE_CODE == 'pl' else '/en/')
-
-
-def mil_404_view(request):
-    return page_not_found(request, '404_mil.html')
-
-
-def mil_contact_view(request):
-    return flatpage(request, url='/kontakt_mil/' if request.LANGUAGE_CODE == 'pl' else '/contact_mil/')
-
-
-def mil_knowledge_base_view(request, url):
-    return flatpage(request, url='bazawiedzy/' + url)
-
-
-class AvatarlessProfileEditView(ProfileEditView):
-    form_class = AvatarlessEditProfileForm
-
-
-def flatpage_with_template(request, url, template_name):
-    """
-    Public interface to the flat page view.
-
-    Models: `flatpages.flatpages`
-    Templates: Uses the template defined by the ``template_name`` field,
-        or :template:`flatpages/default.html` if template_name is not defined.
-    Context:
-        flatpage
-            `flatpages.flatpages` object
-    """
-    from django.conf import settings
-    from django.contrib.flatpages.models import FlatPage
-    from django.contrib.flatpages.views import render_flatpage
-    from django.contrib.sites.models import get_current_site
-    from django.http.response import Http404, HttpResponsePermanentRedirect
-    from django.shortcuts import get_object_or_404
-    if not url.startswith('/'):
-        url = '/' + url
-    site_id = get_current_site(request).id
-    try:
-        f = get_object_or_404(FlatPage, url__exact=url, sites__id__exact=site_id)
-    except Http404:
-        if not url.endswith('/') and settings.APPEND_SLASH:
-            url += '/'
-            get_object_or_404(FlatPage, url__exact=url, sites__id__exact=site_id)
-            return HttpResponsePermanentRedirect('%s/' % request.path)
-        else:
-            raise
-    f.template_name = template_name
-    return render_flatpage(request, f)
diff --git a/edumed/wsgi.py b/edumed/wsgi.py
deleted file mode 100644 (file)
index 840d8e5..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-"""
-WSGI config for edumed project.
-
-This module contains the WSGI application used by Django's development server
-and any production WSGI deployments. It should expose a module-level variable
-named ``application``. Django's ``runserver`` and ``runfcgi`` commands discover
-this application via the ``WSGI_APPLICATION`` setting.
-
-Usually you will have the standard Django WSGI application here, but it also
-might make sense to replace the whole Django WSGI application with a custom one
-that later delegates to the Django one. For example, you could introduce WSGI
-middleware here, or combine a Django application with an application of another
-framework.
-
-"""
-import os
-import sys
-
-ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
-
-# Add apps and lib directories to PYTHONPATH
-sys.path = [
-    os.path.join(ROOT, 'lib/librarian'),
-] + sys.path
-
-os.environ.setdefault("DJANGO_SETTINGS_MODULE", "edumed.settings")
-
-# This application object is used by any WSGI server configured to use this
-# file. This includes Django's development server, if the WSGI_APPLICATION
-# setting points here.
-from django.core.wsgi import get_wsgi_application
-application = get_wsgi_application()
-
-# Apply WSGI middleware here.
-# from helloworld.wsgi import HelloWorldApplication
-# application = HelloWorldApplication(application)
diff --git a/fabfile.py b/fabfile.py
deleted file mode 100644 (file)
index 5e108a7..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-# -*- coding: utf-8 -*-
-from fnpdjango.deploy import *
-
-env.project_name = 'edumed'
-env.hosts = ['giewont.icm.edu.pl']
-env.user = 'edumed'
-env.app_path = '/srv/edukacjamedialna.edu.pl'
-env.services = [
-    Supervisord('edumed'),
-]
diff --git a/forum/__init__.py b/forum/__init__.py
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/forum/forms.py b/forum/forms.py
deleted file mode 100644 (file)
index 37c9b35..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-# -*- coding: utf-8 -*-
-from django import forms
-from django.forms.models import ModelChoiceIterator
-from django.utils.translation import ugettext as _
-import pybb.forms
-
-from catalogue.models import Lesson
-
-
-class GroupedModelChoiceIterator(ModelChoiceIterator):
-    def __init__(self, field):
-        super(GroupedModelChoiceIterator, self).__init__(field)
-        self.queryset = self.field.grouping_model.objects
-        self.items_queryset = self.field.queryset
-    
-    def choice(self, obj):
-        items_query = self.items_queryset.filter(**{self.field.grouping_fk_field: obj})
-        items = [super(GroupedModelChoiceIterator, self).choice(item) for item in items_query.all()]
-        return unicode(obj), items
-
-
-class GroupedModelChoiceField(forms.ModelChoiceField):
-    
-    def __init__(self, queryset, grouping_fk_field, **kwargs):
-        self.grouping_fk_field = grouping_fk_field
-        self.grouping_model = queryset.model._meta.get_field(grouping_fk_field).rel.to
-        super(GroupedModelChoiceField, self).__init__(queryset, **kwargs)
-
-    def _get_choices(self):
-        toret = super(GroupedModelChoiceField, self)._get_choices()
-        if isinstance(toret, ModelChoiceIterator):
-            toret = GroupedModelChoiceIterator(self)
-        return toret
-
-    choices = property(_get_choices, forms.ModelChoiceField.choices.fset)
-
-
-class PostForm(pybb.forms.PostForm):
-    lesson = GroupedModelChoiceField(
-        label=_('Related lesson'), queryset=Lesson.objects.all(),
-        grouping_fk_field='section', required=False)
diff --git a/forum/locale/pl/LC_MESSAGES/django.mo b/forum/locale/pl/LC_MESSAGES/django.mo
deleted file mode 100644 (file)
index 219ea2a..0000000
Binary files a/forum/locale/pl/LC_MESSAGES/django.mo and /dev/null differ
diff --git a/forum/locale/pl/LC_MESSAGES/django.po b/forum/locale/pl/LC_MESSAGES/django.po
deleted file mode 100644 (file)
index bc13e50..0000000
+++ /dev/null
@@ -1,60 +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.
-#
-#, fuzzy
-msgid ""
-msgstr ""
-"Project-Id-Version: PACKAGE VERSION\n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2013-08-29 10:00+0200\n"
-"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
-"Last-Translator: FULL NAME <EMAIL@ADDRESS>\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:9 templates/forum/related_lesson_info.html:2
-msgid "Related lesson"
-msgstr "Powiązana lekcja"
-
-#: templates/pybb/topic.html:27 templates/pybb/topic.html.py:47
-msgid "Posts"
-msgstr ""
-
-#: templates/pybb/topic.html:55
-msgid "Unstick topic"
-msgstr ""
-
-#: templates/pybb/topic.html:57
-msgid "Stick topic"
-msgstr ""
-
-#: templates/pybb/topic.html:61
-msgid "Open topic"
-msgstr ""
-
-#: templates/pybb/topic.html:63
-msgid "Close topic"
-msgstr ""
-
-#: templates/pybb/topic.html:66
-msgid "Admin"
-msgstr ""
-
-#: templates/pybb/topic.html:75
-msgid "Unsubscribe"
-msgstr ""
-
-#: templates/pybb/topic.html:77
-msgid "Subscribe"
-msgstr ""
-
-#: templates/pybb/topic.html:96
-msgid "Subscribers"
-msgstr ""
diff --git a/forum/middleware.py b/forum/middleware.py
deleted file mode 100644 (file)
index 1b6e26b..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-# -*- coding: utf-8 -*-
-from urllib import urlencode
-
-from django.contrib.auth import REDIRECT_FIELD_NAME
-from django.http import HttpResponseRedirect
-from django.core.urlresolvers import reverse
-from django_cas.views import login as cas_login
-
-
-class ForumMiddleware(object):
-    @staticmethod
-    def process_request(request):
-        if request.path.startswith(reverse('pybb:index')) \
-                and (not hasattr(request, 'user') or not request.user.is_authenticated()):
-            params = urlencode({REDIRECT_FIELD_NAME: request.get_full_path()})
-            return HttpResponseRedirect(reverse(cas_login) + '?' + params)
diff --git a/forum/migrations/0001_initial.py b/forum/migrations/0001_initial.py
deleted file mode 100644 (file)
index 3a80106..0000000
+++ /dev/null
@@ -1,164 +0,0 @@
-# -*- coding: utf-8 -*-
-import datetime
-from south.db import db
-from south.v2 import SchemaMigration
-from django.db import models
-
-
-class Migration(SchemaMigration):
-
-    def forwards(self, orm):
-        # Adding model 'Topic'
-        db.create_table(u'forum_topic', (
-            ('pybb_topic', self.gf('django.db.models.fields.related.OneToOneField')(to=orm['pybb.Topic'], unique=True, primary_key=True)),
-            ('lesson', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['catalogue.Lesson'], null=True, blank=True)),
-        ))
-        db.send_create_signal(u'forum', ['Topic'])
-
-
-    def backwards(self, orm):
-        # Deleting model 'Topic'
-        db.delete_table(u'forum_topic')
-
-
-    models = {
-        u'auth.group': {
-            'Meta': {'object_name': 'Group'},
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
-            'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
-        },
-        u'auth.permission': {
-            'Meta': {'ordering': "(u'content_type__app_label', u'content_type__model', u'codename')", 'unique_together': "((u'content_type', u'codename'),)", 'object_name': 'Permission'},
-            'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['contenttypes.ContentType']"}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
-        },
-        u'auth.user': {
-            'Meta': {'object_name': 'User'},
-            'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
-            'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
-            'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
-            'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
-            'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
-            'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
-            'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
-            'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
-            'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
-        },
-        u'catalogue.lesson': {
-            'Meta': {'ordering': "['section', 'level', 'order']", 'object_name': 'Lesson'},
-            'curriculum_courses': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['curriculum.CurriculumCourse']", 'symmetrical': 'False', 'blank': 'True'}),
-            'dc': ('jsonfield.fields.JSONField', [], {'default': "'{}'"}),
-            'html_file': ('django.db.models.fields.files.FileField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'level': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['curriculum.Level']"}),
-            'order': ('django.db.models.fields.IntegerField', [], {'db_index': 'True'}),
-            'package': ('django.db.models.fields.files.FileField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
-            'pdf': ('django.db.models.fields.files.FileField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
-            'section': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['catalogue.Section']", 'null': 'True', 'blank': 'True'}),
-            'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '255'}),
-            'student_package': ('django.db.models.fields.files.FileField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
-            'student_pdf': ('django.db.models.fields.files.FileField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
-            'title': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
-            'type': ('django.db.models.fields.CharField', [], {'max_length': '15', 'db_index': 'True'}),
-            'xml_file': ('django.db.models.fields.files.FileField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'})
-        },
-        u'catalogue.section': {
-            'Meta': {'ordering': "['order']", 'object_name': 'Section'},
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'image': ('django.db.models.fields.files.ImageField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
-            'order': ('django.db.models.fields.IntegerField', [], {}),
-            'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '255'}),
-            'title': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'}),
-            'xml_file': ('django.db.models.fields.files.FileField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'})
-        },
-        u'contenttypes.contenttype': {
-            'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
-            'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
-        },
-        u'curriculum.curriculumcourse': {
-            'Meta': {'ordering': "['slug']", 'object_name': 'CurriculumCourse'},
-            'accusative': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'slug': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}),
-            'title': ('django.db.models.fields.CharField', [], {'max_length': '255'})
-        },
-        u'curriculum.level': {
-            'Meta': {'ordering': "['order']", 'object_name': 'Level'},
-            'group': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
-            'order': ('django.db.models.fields.IntegerField', [], {}),
-            'slug': ('django.db.models.fields.CharField', [], {'max_length': '255'})
-        },
-        u'forum.topic': {
-            'Meta': {'object_name': 'Topic'},
-            'lesson': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['catalogue.Lesson']", 'null': 'True', 'blank': 'True'}),
-            'pybb_topic': ('django.db.models.fields.related.OneToOneField', [], {'to': u"orm['pybb.Topic']", 'unique': 'True', 'primary_key': 'True'})
-        },
-        u'pybb.category': {
-            'Meta': {'ordering': "['position']", 'object_name': 'Category'},
-            'hidden': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '80'}),
-            'position': ('django.db.models.fields.IntegerField', [], {'default': '0', 'blank': 'True'})
-        },
-        u'pybb.forum': {
-            'Meta': {'ordering': "['position']", 'object_name': 'Forum'},
-            'category': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'forums'", 'to': u"orm['pybb.Category']"}),
-            'description': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
-            'headline': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
-            'hidden': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'moderators': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'to': u"orm['auth.User']", 'null': 'True', 'blank': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '80'}),
-            'position': ('django.db.models.fields.IntegerField', [], {'default': '0', 'blank': 'True'}),
-            'post_count': ('django.db.models.fields.IntegerField', [], {'default': '0', 'blank': 'True'}),
-            'readed_by': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'readed_forums'", 'symmetrical': 'False', 'through': u"orm['pybb.ForumReadTracker']", 'to': u"orm['auth.User']"}),
-            'topic_count': ('django.db.models.fields.IntegerField', [], {'default': '0', 'blank': 'True'}),
-            'updated': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'})
-        },
-        u'pybb.forumreadtracker': {
-            'Meta': {'unique_together': "(('user', 'forum'),)", 'object_name': 'ForumReadTracker'},
-            'forum': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['pybb.Forum']", 'null': 'True', 'blank': 'True'}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'time_stamp': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}),
-            'user': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['auth.User']"})
-        },
-        u'pybb.topic': {
-            'Meta': {'ordering': "['-created']", 'object_name': 'Topic'},
-            'closed': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'created': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}),
-            'forum': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'topics'", 'to': u"orm['pybb.Forum']"}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
-            'on_moderation': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'poll_question': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
-            'poll_type': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
-            'post_count': ('django.db.models.fields.IntegerField', [], {'default': '0', 'blank': 'True'}),
-            'readed_by': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'readed_topics'", 'symmetrical': 'False', 'through': u"orm['pybb.TopicReadTracker']", 'to': u"orm['auth.User']"}),
-            'sticky': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'subscribers': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'subscriptions'", 'blank': 'True', 'to': u"orm['auth.User']"}),
-            'updated': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}),
-            'user': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['auth.User']"}),
-            'views': ('django.db.models.fields.IntegerField', [], {'default': '0', 'blank': 'True'})
-        },
-        u'pybb.topicreadtracker': {
-            'Meta': {'unique_together': "(('user', 'topic'),)", 'object_name': 'TopicReadTracker'},
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'time_stamp': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}),
-            'topic': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['pybb.Topic']", 'null': 'True', 'blank': 'True'}),
-            'user': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['auth.User']"})
-        }
-    }
-
-    complete_apps = ['forum']
\ No newline at end of file
diff --git a/forum/migrations/__init__.py b/forum/migrations/__init__.py
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/forum/models.py b/forum/models.py
deleted file mode 100644 (file)
index 5ec506b..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-# -*- coding: utf-8 -*-
-from django.db import models
-
-import pybb.models
-
-from catalogue.models import Lesson
-
-
-class Topic(models.Model):
-    pybb_topic = models.OneToOneField(pybb.models.Topic, primary_key=True, related_name='edumed_topic')
-    lesson = models.ForeignKey(Lesson, null=True, blank=True, related_name='forum_topics')
diff --git a/forum/search_indexes.py b/forum/search_indexes.py
deleted file mode 100644 (file)
index 0a3f413..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-# -*- coding: utf-8 -*-
-from haystack import indexes
-from pybb.models import Post
-
-
-class PostIndex(indexes.SearchIndex, indexes.Indexable):
-    text = indexes.CharField(document=True, use_template=True)
-
-    def get_model(self):
-        return Post
diff --git a/forum/templates/forum/related_lesson_info.html b/forum/templates/forum/related_lesson_info.html
deleted file mode 100644 (file)
index 1f807f6..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-{% load i18n %}
-{% if lesson %}
-<h5 style="margin-top: -20px;">{% trans 'Related lesson' %}: <a href="{{lesson.get_absolute_url}}">{{lesson.title}}</a></h5>
-{% endif %}
\ No newline at end of file
diff --git a/forum/templates/forum/search_results.html b/forum/templates/forum/search_results.html
deleted file mode 100644 (file)
index b656a40..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-{% extends 'pybb/base.html' %}
-{% load i18n %}
-
-
-{% block content %}
-    
-        <h1>{% trans 'Search' %}</h1>
-        <form method="get">
-            {{form.q}}
-            <tr>
-                <td>&nbsp;</td>
-                <td>
-                    <input type="submit" value="{% trans 'Search' %}">
-                </td>
-            </tr>
-        </form>
-
-    {% if query %}
-        <hr/>
-        {% for result in page.object_list %}
-            <p class="search-result">
-                <strong>Temat:</strong> <a href="{{ result.object.get_absolute_url }}">{{ result.object.topic.name }}</a><br/>
-                {% autoescape off %}
-                {% for snippet in result.highlighted.text %}
-                    {{snippet}}{% if not forloop.last %} <strong>...</strong> {% endif %}
-                {% endfor %}
-                {% endautoescape %}
-            </p>
-        {% empty %}
-            <p>Brak wyników.</p>
-        {% endfor %}
-
-        {% if page.has_previous or page.has_next %}
-            <div>
-                {% if page.has_previous %}<a href="?q={{ query }}&amp;page={{ page.previous_page_number }}">{% endif %}&laquo; Poprzednie{% if page.has_previous %}</a>{% endif %}
-                |
-                {% if page.has_next %}<a href="?q={{ query }}&amp;page={{ page.next_page_number }}">{% endif %}Następne &raquo;{% if page.has_next %}</a>{% endif %}
-            </div>
-        {% endif %}
-    {% endif %}
-{% endblock %}
\ No newline at end of file
diff --git a/forum/templates/pybb/category.html b/forum/templates/pybb/category.html
deleted file mode 100644 (file)
index 53c3c50..0000000
+++ /dev/null
@@ -1,47 +0,0 @@
-{% load url from future %}
-{% load i18n pybb_tags %}
-
-{% if category.forums_accessed|pybb_forum_unread:user|length > 0 %}
-<div class='category'>
-    <table class="table category-table">
-        <thead>
-            <tr class="forum-row head-row">
-                <th class="forum-name">
-                    {% trans "Forum" %}
-                </th>
-                <th class="forum-topic-count">
-                    {% trans "Topics" %}
-                </th>
-                <th class="forum-post-count">
-                    {% trans "Posts" %}
-                </th>
-                <th class="forum-last-post">
-                    {% trans "Last posts" %}
-                </th>
-            </tr>
-        </thead>
-        <tbody>
-        {% for forum in category.forums_accessed|pybb_forum_unread:user %}
-            <tr class="forum-row">
-                <td class="forum-name {% if forum.unread %} forum-unread{% endif %}">
-                    <div class="state-indicator"></div>
-                    <a href="{{ forum.get_absolute_url }}">{{ forum.name }}</a> {% if forum.hidden %}[{% trans "Hidden" %}]{% endif %}
-                    <div class="forum-description">
-                        {{ forum.description|safe }}
-                    </div>
-                </td>
-                <td class="forum-topic-count">
-                    {{ forum.topic_count }}
-                </td>
-                <td class="forum-post-count">
-                    {{ forum.post_count }}
-                </td>
-                <td class="forum-last-post">
-                    {% include "pybb/forum_last_update_info.html" %}
-                </td>
-            </tr>
-        {% endfor %}
-        </tbody>
-    </table>
-</div>
-{% endif %}
\ No newline at end of file
diff --git a/forum/templates/pybb/forum_last_update_info.html b/forum/templates/pybb/forum_last_update_info.html
deleted file mode 100644 (file)
index c3256a9..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-{% load humanize %}
-{% if forum.updated %}
-    {{ forum.last_post.user }}
-    {{ forum.updated|naturaltime }}
-{% endif %}
\ No newline at end of file
diff --git a/forum/templates/pybb/post_form.html b/forum/templates/pybb/post_form.html
deleted file mode 100644 (file)
index 5db31a4..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-{% load url from future %}
-{% load i18n pybb_tags %}
-<form class="post-form" action="
-    {% if forum %}
-        {% url 'pybb:add_topic' forum.pk %}
-    {% else %}
-        {% if topic %}
-            {% url 'pybb:add_post' topic.pk %}
-        {% else %}
-            {% url 'pybb:edit_post' pk=object.pk %}
-        {% endif %}
-    {% endif %}" method="post" enctype="multipart/form-data">
-  {% csrf_token %}
-  <fieldset>
-    {% include "pybb/form_errors.html" %}
-    {% if form.name %} {% include "pybb/form_field.html" with field=form.name %} {% endif %}
-
-    {% if lesson_editable %}
-        {% include "pybb/form_field.html" with field=form.lesson %}
-    {% endif %}
-
-    {% if form.login %} {% include "pybb/form_field.html" with field=form.login %}  {% endif %}
-    {% if form.body %} {% include "pybb/form_field.html" with field=form.body %}  {% endif %}
-    <div id='emoticons'>
-      {% for smile, url in form.available_smiles.items %}
-        <a href='#' title='{{ smile|safe }}'><img src='{{ STATIC_URL }}{{ form.smiles_prefix }}{{ url }}'></a>
-      {% endfor %}
-    </div>
-
-    {% if form.poll_type and request.user.is_superuser %}
-      {% include "pybb/poll_edit_form.html" %}
-    {% endif %}
-    {% include "pybb/attachments_formset.html" %}
-    <p class="submit">{% include "pybb/_button_submit.html" %}</p>
-  </fieldset>
-</form>
diff --git a/forum/templates/pybb/topic.html b/forum/templates/pybb/topic.html
deleted file mode 100644 (file)
index f11f2cb..0000000
+++ /dev/null
@@ -1,102 +0,0 @@
-{% extends 'pybb/base.html' %}
-
-{% load url from future %}
-
-{% load pybb_tags i18n %}
-
-{% block title %}{{ topic }}{% endblock %}
-
-{% block extra_script %}
-    {{ block.super }}
-    {% include "pybb/_markitup.html" %}
-    <script type="text/javascript" src="{{ STATIC_URL }}pybb/js/jquery.formset.min.js"></script>
-{% endblock %}
-
-{% block breadcrumb %}
-    {% with object=topic %}
-        {% include "pybb/breadcrumb.html" %}
-    {% endwith %}
-{% endblock %}
-
-{% block content %}
-    <div class="topic">
-        <h1>{{ topic.name }}</h1>
-        
-        {% include 'forum/related_lesson_info.html' with lesson=topic.edumed_topic.lesson %}
-        
-        {% with _('Posts') as label %}
-            {% include "pybb/pagination.html" %}
-        {% endwith %}
-
-        {% if topic.poll_type %}
-            {% include 'pybb/poll.html' %}
-        {% endif %}
-
-        <div class="posts">
-            {% if first_post %}{% ifnotequal first_post post_list.0 %}
-                {% with first_post as post %}
-                    <li class="first_post">{% include "pybb/post_template.html" %}</li>
-                {% endwith %}
-            {% endifnotequal %}{% endif %}
-            {% for post in post_list %}
-                {% cycle 'odd' 'even' as rowcolors silent %}
-                {% include "pybb/post_template.html" %}
-            {% endfor %}
-        </div>
-        <div>&nbsp;</div>
-        {% with _('Posts') as label %}
-            {% include "pybb/pagination.html" %}
-        {% endwith %}
-
-        {% if user.is_authenticated %}
-            <div class="controls">
-                {% if user.is_moderator %}
-                    {% if topic.sticky %}
-                        <a href="{% url 'pybb:unstick_topic' topic.id %}">{% trans "Unstick topic" %}</a> /
-                    {% else %}
-                        <a href="{% url 'pybb:stick_topic' topic.id %}">{% trans "Stick topic" %}</a> /
-                    {% endif %}
-
-                    {% if topic.closed %}
-                        <a href="{% url 'pybb:open_topic' topic.id %}">{% trans "Open topic" %}</a> /
-                    {% else %}
-                        <a href="{% url 'pybb:close_topic' topic.id %}">{% trans "Close topic" %}</a> /
-                    {% endif %}
-                    {% if perms.pybb.change_topic and user.is_staff %}
-                        <a href="{% url 'admin:pybb_topic_change' topic.id %}">{% trans 'Admin' %}</a> /
-                    {% endif %}
-                    {% comment %}
-            <a href="{% url 'pybb:merge_topics' %}?topic={{ topic.id }}">{% trans 'Merge topics' %}</a> /
-            {% endcomment %}
-                {% endif %}
-
-                {% if user.is_subscribed %}
-                    <a href="{% url 'pybb:delete_subscription' topic.id %}?from_topic">{% trans "Unsubscribe" %}</a>
-                {% else %}
-                    <a href="{% url 'pybb:add_subscription' topic.id %}">{% trans "Subscribe" %}</a>
-                {% endif %}
-            </div>
-        {% endif %}
-
-        {% if user.is_authenticated or PYBB_ENABLE_ANONYMOUS_POST %}
-            {% pybb_get_profile user=user as user_profile %}
-
-            {% if not user_profile.is_banned %}
-                {% if not topic.closed %}
-                    {% include "pybb/post_form.html" %}
-                {% endif %}
-            {% endif %}
-        {% else %}
-            {% include 'pybb/_need_to_login_message.html' %}
-        {% endif %}
-
-        {% if user.is_staff %}
-            <div class="subscriber-list">
-                {% trans "Subscribers" %}:
-                {% for subscriber in topic.subscribers.all %}
-                    <a href="{% url 'pybb:user' subscriber.username %}">{{ subscriber.username }}</a>,
-                {% endfor %}
-            </div>
-        {% endif %}
-    </div>
-{% endblock %}
diff --git a/forum/templates/pybb/topic_last_message_info.html b/forum/templates/pybb/topic_last_message_info.html
deleted file mode 100644 (file)
index ff49ffa..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-{% load humanize %}
-{% if topic.updated %}
-    {{ topic.last_post.user }}
-    {{ topic.updated|naturaltime }}
-    
-{% endif %}
\ No newline at end of file
diff --git a/forum/templates/search/indexes/pybb/post_text.txt b/forum/templates/search/indexes/pybb/post_text.txt
deleted file mode 100644 (file)
index c51be26..0000000
+++ /dev/null
@@ -1 +0,0 @@
-{{object.body_text}}
\ No newline at end of file
diff --git a/forum/urls.py b/forum/urls.py
deleted file mode 100644 (file)
index c669808..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-# -*- coding: utf-8 -*-
-from django.conf.urls import patterns, url
-from haystack.query import SearchQuerySet
-from haystack.views import SearchView, search_view_factory
-from haystack.forms import SearchForm
-from pybb.models import Post
-
-from .views import AddPostView, EditPostView
-
-
-urlpatterns = patterns(
-    '',
-    url(r'^forum/(?P<forum_id>\d+)/topic/add/$', AddPostView.as_view()),
-    url(r'^post/(?P<pk>\d+)/edit/$', EditPostView.as_view()),
-)
-
-PostsSearchQuerySet = SearchQuerySet().models(Post).highlight()
-
-urlpatterns += patterns(
-    'haystack.views',
-    url(r'^szukaj/$', search_view_factory(
-        view_class=SearchView,
-        template='forum/search_results.html',
-        searchqueryset=PostsSearchQuerySet,
-        form_class=SearchForm
-    ), name='forum_search'))
diff --git a/forum/views.py b/forum/views.py
deleted file mode 100644 (file)
index 6750d99..0000000
+++ /dev/null
@@ -1,58 +0,0 @@
-# -*- coding: utf-8 -*-
-from django.core.exceptions import ObjectDoesNotExist
-import pybb.views
-import pybb.forms
-
-from .forms import PostForm
-from .models import Topic
-
-
-class PostEditMixin(pybb.views.PostEditMixin):
-
-    def get_form_class(self):
-        toret = super(PostEditMixin, self).get_form_class()
-        if issubclass(toret, pybb.forms.PostForm):
-            toret = PostForm
-        return toret
-
-    def form_valid(self, form):
-        toret = super(PostEditMixin, self).form_valid(form)
-
-        pybb_post = self.object
-        pybb_topic = pybb_post.topic
-        topic, topic_created = Topic.objects.get_or_create(pybb_topic=pybb_topic)
-
-        if pybb_post == pybb_topic.head:
-            topic.lesson = form.cleaned_data['lesson']
-            topic.save()
-
-        return toret
-
-
-class AddPostView(PostEditMixin, pybb.views.AddPostView):
-    def get_context_data(self, **kwargs):
-        ctx = super(AddPostView, self).get_context_data(**kwargs)
-        ctx['lesson_editable'] = self._creates_new_topic()
-        return ctx
-
-    def _creates_new_topic(self):
-        return self.forum is not None
-
-
-class EditPostView(PostEditMixin, pybb.views.EditPostView):
-    def get_context_data(self, **kwargs):
-        ctx = super(EditPostView, self).get_context_data(**kwargs)
-        ctx['lesson_editable'] = self._edits_topics_head()
-        return ctx
-
-    def _edits_topics_head(self):
-        return self.object == self.object.topic.head
-
-    def get_form_kwargs(self):
-        kwargs = super(EditPostView, self).get_form_kwargs()
-        try:
-            lesson = self.object.topic.edumed_topic.lesson
-        except ObjectDoesNotExist:
-            lesson = None
-        kwargs['initial']['lesson'] = lesson
-        return kwargs
diff --git a/lib/librarian b/lib/librarian
deleted file mode 160000 (submodule)
index 978c34b..0000000
+++ /dev/null
@@ -1 +0,0 @@
-Subproject commit 978c34b8de4031e3759225138b2c30d2cc28035d
diff --git a/manage.py b/manage.py
deleted file mode 100755 (executable)
index 28228a0..0000000
--- a/manage.py
+++ /dev/null
@@ -1,15 +0,0 @@
-#!/usr/bin/env python
-import os
-import sys
-
-ROOT = os.path.dirname(os.path.abspath(__file__))
-sys.path = [
-    os.path.join(ROOT, 'lib/librarian'),
-] + sys.path
-
-if __name__ == "__main__":
-    os.environ.setdefault("DJANGO_SETTINGS_MODULE", "edumed.settings")
-
-    from django.core.management import execute_from_command_line
-
-    execute_from_command_line(sys.argv)
diff --git a/publishers/__init__.py b/publishers/__init__.py
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/publishers/admin.py b/publishers/admin.py
deleted file mode 100644 (file)
index 95bd7ab..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-# -*- coding: utf-8 -*-
-from django.contrib import admin
-from .models import Publisher
-
-admin.site.register(Publisher)
diff --git a/publishers/migrations/0001_initial.py b/publishers/migrations/0001_initial.py
deleted file mode 100644 (file)
index 1a77507..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-# -*- coding: utf-8 -*-
-import datetime
-from south.db import db
-from south.v2 import SchemaMigration
-from django.db import models
-
-
-class Migration(SchemaMigration):
-
-    def forwards(self, orm):
-        # Adding model 'Publisher'
-        db.create_table(u'publishers_publisher', (
-            (u'id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
-            ('name', self.gf('django.db.models.fields.CharField')(max_length=255)),
-            ('logo', self.gf('django.db.models.fields.files.ImageField')(max_length=100)),
-        ))
-        db.send_create_signal(u'publishers', ['Publisher'])
-
-
-    def backwards(self, orm):
-        # Deleting model 'Publisher'
-        db.delete_table(u'publishers_publisher')
-
-
-    models = {
-        u'publishers.publisher': {
-            'Meta': {'object_name': 'Publisher'},
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'logo': ('django.db.models.fields.files.ImageField', [], {'max_length': '100'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '255'})
-        }
-    }
-
-    complete_apps = ['publishers']
\ No newline at end of file
diff --git a/publishers/migrations/__init__.py b/publishers/migrations/__init__.py
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/publishers/models.py b/publishers/models.py
deleted file mode 100644 (file)
index 14ed63a..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-# -*- coding: utf-8 -*-
-from django.db import models
-
-
-class Publisher(models.Model):
-    name = models.CharField(max_length=255)
-    logo = models.ImageField(upload_to='publishers/logo')
-
-    def __unicode__(self):
-        return self.name
diff --git a/src/api/__init__.py b/src/api/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/src/api/admin.py b/src/api/admin.py
new file mode 100644 (file)
index 0000000..8c38f3f
--- /dev/null
@@ -0,0 +1,3 @@
+from django.contrib import admin
+
+# Register your models here.
diff --git a/src/api/handlers.py b/src/api/handlers.py
new file mode 100644 (file)
index 0000000..5746b0c
--- /dev/null
@@ -0,0 +1,62 @@
+# -*- coding: utf-8 -*-
+import json
+
+from django.contrib.sites.models import Site
+from django.core.urlresolvers import reverse
+from django.utils.functional import lazy
+from piston.handler import BaseHandler
+from piston.utils import rc
+
+from catalogue.forms import LessonImportForm
+from catalogue.models import Lesson
+
+API_BASE = EDUMED_BASE = MEDIA_BASE = lazy(
+    lambda: u'https://' + Site.objects.get_current().domain, unicode)()
+
+
+class LessonDetails(object):
+    """Custom fields used for representing Lessons."""
+
+    @classmethod
+    def href(cls, lesson):
+        """ Returns an URI for a Lesson in the API. """
+        return API_BASE + reverse("api_lesson", args=[lesson.slug])
+
+    @classmethod
+    def url(cls, lesson):
+        """ Returns Lesson's URL on the site. """
+        return EDUMED_BASE + lesson.get_absolute_url()
+
+
+class LessonDetailHandler(BaseHandler, LessonDetails):
+    """ Main handler for Lesson objects.
+
+    Responsible for single Lesson details.
+    """
+    allowed_methods = ['GET']
+    fields = ['title', 'url']
+
+    def read(self, request, lesson):
+        """ Returns details of a lesson, identified by a slug. """
+        try:
+            return Lesson.objects.get(slug=lesson)
+        except Lesson.DoesNotExist:
+            return rc.NOT_FOUND
+
+
+class LessonsHandler(LessonDetailHandler):
+    allowed_methods = ('GET', 'POST')
+    model = Lesson
+    fields = ['href', 'title', 'url']
+
+    def create(self, request, *args, **kwargs):
+        if not request.user.has_perm('catalogue.add_lesson'):
+            return rc.FORBIDDEN
+
+        data = json.loads(request.POST.get('data'))
+        form = LessonImportForm(data)
+        if form.is_valid():
+            form.save()
+            return rc.CREATED
+        else:
+            return rc.NOT_FOUND
diff --git a/src/api/helpers.py b/src/api/helpers.py
new file mode 100644 (file)
index 0000000..a40373a
--- /dev/null
@@ -0,0 +1,9 @@
+# -*- coding: utf-8 -*-
+from piston.resource import Resource
+
+
+class CsrfExemptResource(Resource):
+    """A Custom Resource that is csrf exempt"""
+    def __init__(self, handler, authentication=None):
+        super(CsrfExemptResource, self).__init__(handler, authentication)
+        self.csrf_exempt = getattr(self.handler, 'csrf_exempt', True)
\ No newline at end of file
diff --git a/src/api/models.py b/src/api/models.py
new file mode 100644 (file)
index 0000000..71a8362
--- /dev/null
@@ -0,0 +1,3 @@
+from django.db import models
+
+# Create your models here.
diff --git a/src/api/templates/oauth/challenge.html b/src/api/templates/oauth/challenge.html
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/src/api/templates/piston/authorize_token.html b/src/api/templates/piston/authorize_token.html
new file mode 100644 (file)
index 0000000..0151b58
--- /dev/null
@@ -0,0 +1,20 @@
+{% extends "base.html" %}
+{% load i18n %}
+
+{% block titleextra %}Zezwól na dostęp do Edukacji Medialnej{% endblock %}
+
+{% block body %}
+  <h1>Zezwól na dostęp do Edukacji Medialnej</h1>
+
+  <div class="normal-text">
+    <p>
+      Potwierdź dostęp do Edukacji Medialnej jako użytkownik <strong>{{ user }}</strong>.
+    </p>
+
+    <form action="{% url 'piston.authentication.oauth_user_auth' %}" method="POST">
+      {% csrf_token %}
+      {{ form.as_p }}
+      <button type="submit">Potwierdź</button>
+    </form>
+  </div>
+{% endblock %}
diff --git a/src/api/tests.py b/src/api/tests.py
new file mode 100644 (file)
index 0000000..7ce503c
--- /dev/null
@@ -0,0 +1,3 @@
+from django.test import TestCase
+
+# Create your tests here.
diff --git a/src/api/urls.py b/src/api/urls.py
new file mode 100644 (file)
index 0000000..a111872
--- /dev/null
@@ -0,0 +1,31 @@
+# -*- coding: utf-8 -*-
+from django.conf.urls import patterns, url
+from django.views.decorators.csrf import csrf_exempt
+from piston.authentication import OAuthAuthentication, oauth_access_token
+from piston.resource import Resource
+
+from api import handlers
+from api.helpers import CsrfExemptResource
+
+auth = OAuthAuthentication(realm="Edukacja Medialna")
+
+lesson_list_resource = CsrfExemptResource(handler=handlers.LessonsHandler, authentication=auth)
+lesson_resource = Resource(handler=handlers.LessonDetailHandler)
+
+urlpatterns = patterns(
+    'piston.authentication',
+    url(r'^oauth/request_token/$', 'oauth_request_token'),
+    url(r'^oauth/authorize/$', 'oauth_user_auth'),
+    url(r'^oauth/access_token/$', csrf_exempt(oauth_access_token)),
+)
+
+urlpatterns += patterns(
+    '',
+    # url(r'^$', TemplateView.as_view(template_name='api/main.html'), name='api'),
+
+    # objects details
+    url(r'^lessons/(?P<lesson>[a-z0-9-]+)/$', lesson_resource, name="api_lesson"),
+
+    # lessons
+    url(r'^lessons/$', lesson_list_resource, name='api_lesson_list'),
+)
diff --git a/src/api/views.py b/src/api/views.py
new file mode 100644 (file)
index 0000000..91ea44a
--- /dev/null
@@ -0,0 +1,3 @@
+from django.shortcuts import render
+
+# Create your views here.
diff --git a/src/catalogue/__init__.py b/src/catalogue/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/src/catalogue/admin.py b/src/catalogue/admin.py
new file mode 100755 (executable)
index 0000000..8256d66
--- /dev/null
@@ -0,0 +1,17 @@
+# -*- coding: utf-8 -*-
+from django.contrib import admin
+from .models import Attachment, Section, Lesson, LessonStub
+
+
+class AttachmentInline(admin.TabularInline):
+    model = Attachment
+
+
+class LessonAdmin(admin.ModelAdmin):
+    inlines = [AttachmentInline]
+    list_display = ['title', 'section', 'type']
+    list_filter = ['level', 'type']
+
+admin.site.register(Section)
+admin.site.register(Lesson, LessonAdmin)
+admin.site.register(LessonStub)
diff --git a/src/catalogue/forms.py b/src/catalogue/forms.py
new file mode 100644 (file)
index 0000000..7230b23
--- /dev/null
@@ -0,0 +1,35 @@
+# -*- coding: utf-8 -*-
+import json
+import os.path
+import shutil
+import urllib
+from tempfile import mkdtemp
+
+from django.forms import Form, CharField
+
+from librarian import IOFile
+from catalogue.models import Lesson
+
+
+class LessonImportForm(Form):
+    lesson_xml = CharField()
+    gallery_url = CharField(required=False)
+    attachments = CharField(required=False)
+
+    def save(self):
+        temp_dir = mkdtemp()
+        attachment_names = json.loads(self.cleaned_data['attachments'])
+        attachments = {}
+        remote_gallery_url = self.cleaned_data['gallery_url']
+        if remote_gallery_url and attachment_names:
+            for attachment_name in attachment_names:
+                attachment_url = ('%s%s' % (remote_gallery_url, attachment_name)).encode('utf-8')
+                temp_filename = os.path.join(temp_dir, attachment_name)
+                urllib.urlretrieve(attachment_url, temp_filename)
+                attachments[attachment_name] = IOFile.from_filename(temp_filename)
+
+        lesson = Lesson.publish(
+            IOFile.from_string(self.cleaned_data['lesson_xml'], attachments=attachments))
+        if os.path.isdir(temp_dir):
+            shutil.rmtree(temp_dir)
+        return lesson
diff --git a/src/catalogue/management/__init__.py b/src/catalogue/management/__init__.py
new file mode 100755 (executable)
index 0000000..e69de29
diff --git a/src/catalogue/management/commands/__init__.py b/src/catalogue/management/commands/__init__.py
new file mode 100755 (executable)
index 0000000..e69de29
diff --git a/src/catalogue/management/commands/extract_attachments.py b/src/catalogue/management/commands/extract_attachments.py
new file mode 100644 (file)
index 0000000..1735cbf
--- /dev/null
@@ -0,0 +1,41 @@
+# -*- coding: utf-8 -*-
+# This file is part of EduMed, licensed under GNU Affero GPLv3 or later.
+# Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
+#
+import errno
+from optparse import make_option
+import os
+import shutil
+
+from django.core.management.base import BaseCommand
+
+
+def makedir(directory):
+    try:
+        os.makedirs(directory)
+    except OSError as e:
+        if e.errno != errno.EEXIST:
+            raise
+
+
+class Command(BaseCommand):
+    help = 'Extracts attachments from given lessons.'
+
+    option_list = BaseCommand.option_list + (
+        make_option('--slugs', dest='slugs_path', metavar="PATH", default=None,
+                    help='PATH to file with lesson slugs.'),
+    )
+
+    def handle(self, **options):
+        from catalogue.models import Lesson
+
+        lessons = Lesson.objects.order_by('slug')
+        if options.get('slugs_path'):
+            slugs = [line.strip() for line in open(options.get('slugs_path')) if line.strip()]
+            lessons = lessons.filter(slug__in=slugs)
+
+        for lesson in lessons:
+            makedir('materialy/%s' % lesson.slug)
+            for attachment in lesson.attachment_set.all():
+                shutil.copy(attachment.file.path, 'materialy/%s/%s.%s' % (lesson.slug, attachment.slug, attachment.ext))
+
diff --git a/src/catalogue/management/commands/importlessons.py b/src/catalogue/management/commands/importlessons.py
new file mode 100755 (executable)
index 0000000..296590b
--- /dev/null
@@ -0,0 +1,148 @@
+# -*- coding: utf-8 -*-
+# This file is part of EduMed, licensed under GNU Affero GPLv3 or later.
+# Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
+#
+import os
+import sys
+from optparse import make_option
+
+from django.core.management.base import BaseCommand
+from django.db import transaction
+
+from catalogue.models import Lesson, Section
+from librarian import IOFile
+
+
+class Command(BaseCommand):
+    option_list = BaseCommand.option_list + (
+        make_option('-q', '--quiet', action='store_false', dest='verbose', default=True,
+                    help='Verbosity level; 0=minimal output, 1=normal output, 2=all output'),
+        make_option('-a', '--attachments', dest='attachments', metavar="PATH", default='materialy',
+                    help='Attachments dir path.'),
+        make_option('--ignore-incomplete', action='store_true', dest='ignore_incomplete', default=False,
+                    help='Attachments dir path.'),
+        make_option('--dont-repackage', action='store_false', dest='repackage', default=True,
+                    help='Don\'t refresh level packages.'),
+    )
+    help = 'Imports lessons from the specified directories.'
+    args = 'directory [directory ...]'
+
+    def __init__(self):
+        super(Command, self).__init__()
+        self.options = None
+        self.levels = None
+
+    @staticmethod
+    def all_attachments(path):
+        files = {}
+        if not os.path.isdir(path):
+            return files
+
+        def read_dir(path):
+            for name in os.listdir(path):
+                fullname = os.path.join(path, name)
+                if os.path.isdir(fullname):
+                    read_dir(fullname)
+                else:
+                    f = IOFile.from_filename(fullname)
+                    files[name.decode('utf-8')] = f
+                    files.setdefault(name.replace(" ", "").decode('utf-8'), f)
+
+        read_dir(path)
+        return files
+
+    @transaction.atomic
+    def handle(self, *directories, **options):
+
+        repackage = options.get('repackage')
+
+        self.levels = set()
+
+        curdir = os.path.abspath(os.curdir)
+        self.options = options
+
+        files_imported = 0
+        files_skipped = 0
+
+        for dir_name in directories:
+            abs_dir = os.path.join(curdir, dir_name)
+            if not os.path.isdir(abs_dir):
+                print self.style.ERROR("%s: Not a directory. Skipping." % abs_dir)
+            else:
+                files_imported_dir, files_skipped_dir = self.import_from_dir(abs_dir)
+                files_imported += files_imported_dir
+                files_skipped += files_skipped_dir
+
+        if self.levels and repackage:
+            print "Rebuilding level packages:"
+            for level in self.levels:
+                print level.name
+                level.build_packages()
+
+        # Print results
+        print
+        print "Results: %d files imported, %d skipped, %d total." % (
+            files_imported, files_skipped, files_imported + files_skipped)
+        print
+
+    def import_from_dir(self, abs_dir):
+        verbose = self.options.get('verbose')
+        files_imported = 0
+        files_skipped = 0
+        att_dir = os.path.join(abs_dir, self.options['attachments'])
+        attachments = self.all_attachments(att_dir)
+        # files queue
+        files = sorted(os.listdir(abs_dir))
+        postponed = {}
+        ignore_incomplete = set()
+        while files:
+            file_name = files.pop(0)
+            file_path = os.path.join(abs_dir, file_name)
+            file_base, ext = os.path.splitext(file_path)
+
+            if os.path.isdir(file_path):
+                dir_imported, dir_skipped = self.import_from_dir(file_path)
+                files_imported += dir_imported
+                files_skipped += files_skipped
+                continue
+
+            # Skip files that are not XML files
+            if not ext == '.xml':
+                continue
+
+            if verbose > 0:
+                print "Parsing '%s'" % file_path
+            else:
+                sys.stdout.write('.')
+                sys.stdout.flush()
+
+            try:
+                iofile = IOFile.from_filename(file_path)
+                iofile.attachments = attachments
+                lesson = Lesson.publish(iofile, file_name in ignore_incomplete)
+            except Section.IncompleteError:
+                if file_name not in postponed or postponed[file_name] < files_imported:
+                    # Push it back into the queue, maybe the missing lessons will show up.
+                    if verbose > 0:
+                        print self.style.NOTICE('Waiting for missing lessons.')
+                    files.append(file_name)
+                    postponed[file_name] = files_imported
+                elif self.options['ignore_incomplete'] and file_name not in ignore_incomplete:
+                    files.append(file_name)
+                    ignore_incomplete.add(file_name)
+                    postponed[file_name] = files_imported
+                else:
+                    # We're in a loop, nothing's being imported - some lesson is really missing.
+                    raise
+            except BaseException:
+                import traceback
+                traceback.print_exc()
+                files_skipped += 1
+            else:
+                files_imported += 1
+                if hasattr(lesson, 'level'):
+                    self.levels.add(lesson.level)
+            finally:
+                if verbose > 0:
+                    print
+        return files_imported, files_skipped
diff --git a/src/catalogue/management/commands/repackage.py b/src/catalogue/management/commands/repackage.py
new file mode 100755 (executable)
index 0000000..a2851f6
--- /dev/null
@@ -0,0 +1,15 @@
+# -*- coding: utf-8 -*-
+# This file is part of EduMed, licensed under GNU Affero GPLv3 or later.
+# Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
+#
+from django.core.management.base import BaseCommand
+
+
+class Command(BaseCommand):
+    help = 'Rebuilds downloadable packages.'
+
+    def handle(self, **options):
+        from curriculum.models import Level
+
+        for level in Level.objects.all():
+            level.build_packages()
diff --git a/src/catalogue/management/commands/republish.py b/src/catalogue/management/commands/republish.py
new file mode 100644 (file)
index 0000000..48f9345
--- /dev/null
@@ -0,0 +1,46 @@
+# -*- coding: utf-8 -*-
+# This file is part of EduMed, licensed under GNU Affero GPLv3 or later.
+# Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
+#
+from optparse import make_option
+
+import librarian
+from django.core.management.base import BaseCommand
+
+
+class Command(BaseCommand):
+    help = 'Republishes all lessons.'
+
+    option_list = BaseCommand.option_list + (
+        make_option('--exclude', dest='exclude', metavar="PATH", default=None,
+                    help='PATH to file with excluded lesson slugs.'),
+        make_option('--ignore-incomplete', action='store_true', dest='ignore_incomplete', default=False,
+                    help='Attachments dir path.'),
+        make_option('--dont-repackage', action='store_false', dest='repackage', default=True,
+                    help='Don\'t refresh level packages.'),
+    )
+
+    def handle(self, **options):
+        from catalogue.models import Lesson
+        from curriculum.models import Level
+
+        lessons = Lesson.objects.order_by('slug')
+
+        if options.get('exclude'):
+            slugs = [line.strip() for line in open(options['exclude'])]
+            lessons = lessons.exclude(slug__in=slugs)
+
+        for lesson in lessons:
+            print
+            print 'Republishing: %s' % lesson.slug
+            try:
+                lesson.republish(repackage_level=False)
+            except librarian.ParseError as e:
+                print '!!!!!! PARSE ERROR !!!!!!'
+                print e
+
+        if options.get('repackage'):
+            print 'Rebuilding levels...'
+            for level in Level.objects.all():
+                print level.name
+                level.build_packages()
diff --git a/src/catalogue/migrations/0001_initial.py b/src/catalogue/migrations/0001_initial.py
new file mode 100644 (file)
index 0000000..846c559
--- /dev/null
@@ -0,0 +1,74 @@
+# -*- coding: utf-8 -*-
+import datetime
+from south.db import db
+from south.v2 import SchemaMigration
+from django.db import models
+
+
+class Migration(SchemaMigration):
+
+    def forwards(self, orm):
+        # Adding model 'Section'
+        db.create_table('catalogue_section', (
+            ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
+            ('title', self.gf('django.db.models.fields.CharField')(max_length=255)),
+            ('order', self.gf('django.db.models.fields.IntegerField')()),
+        ))
+        db.send_create_signal('catalogue', ['Section'])
+
+        # Adding model 'Lesson'
+        db.create_table('catalogue_lesson', (
+            ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
+            ('section', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['catalogue.Section'])),
+            ('level', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['curriculum.Level'])),
+            ('title', self.gf('django.db.models.fields.CharField')(max_length=255)),
+            ('slug', self.gf('django.db.models.fields.SlugField')(unique=True, max_length=50)),
+            ('depth', self.gf('django.db.models.fields.IntegerField')()),
+            ('order', self.gf('django.db.models.fields.IntegerField')()),
+            ('xml_file', self.gf('django.db.models.fields.files.FileField')(max_length=100)),
+            ('package', self.gf('django.db.models.fields.files.FileField')(max_length=100)),
+            ('student_package', self.gf('django.db.models.fields.files.FileField')(max_length=100)),
+            ('html_file', self.gf('django.db.models.fields.files.FileField')(max_length=100)),
+        ))
+        db.send_create_signal('catalogue', ['Lesson'])
+
+
+    def backwards(self, orm):
+        # Deleting model 'Section'
+        db.delete_table('catalogue_section')
+
+        # Deleting model 'Lesson'
+        db.delete_table('catalogue_lesson')
+
+
+    models = {
+        'catalogue.lesson': {
+            'Meta': {'ordering': "['section', 'level', 'depth', 'order']", 'object_name': 'Lesson'},
+            'depth': ('django.db.models.fields.IntegerField', [], {}),
+            'html_file': ('django.db.models.fields.files.FileField', [], {'max_length': '100'}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'level': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['curriculum.Level']"}),
+            'order': ('django.db.models.fields.IntegerField', [], {}),
+            'package': ('django.db.models.fields.files.FileField', [], {'max_length': '100'}),
+            'section': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['catalogue.Section']"}),
+            'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '50'}),
+            'student_package': ('django.db.models.fields.files.FileField', [], {'max_length': '100'}),
+            'title': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+            'xml_file': ('django.db.models.fields.files.FileField', [], {'max_length': '100'})
+        },
+        'catalogue.section': {
+            'Meta': {'object_name': 'Section'},
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'order': ('django.db.models.fields.IntegerField', [], {}),
+            'title': ('django.db.models.fields.CharField', [], {'max_length': '255'})
+        },
+        'curriculum.level': {
+            'Meta': {'ordering': "['order']", 'object_name': 'Level'},
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+            'order': ('django.db.models.fields.IntegerField', [], {}),
+            'slug': ('django.db.models.fields.SlugField', [], {'max_length': '50'})
+        }
+    }
+
+    complete_apps = ['catalogue']
\ No newline at end of file
diff --git a/src/catalogue/migrations/0002_auto__add_field_section_slug.py b/src/catalogue/migrations/0002_auto__add_field_section_slug.py
new file mode 100644 (file)
index 0000000..4b7ef4c
--- /dev/null
@@ -0,0 +1,53 @@
+# -*- coding: utf-8 -*-
+import datetime
+from south.db import db
+from south.v2 import SchemaMigration
+from django.db import models
+
+
+class Migration(SchemaMigration):
+
+    def forwards(self, orm):
+        # Adding field 'Section.slug'
+        db.add_column('catalogue_section', 'slug',
+                      self.gf('django.db.models.fields.SlugField')(default='x', max_length=50),
+                      keep_default=False)
+
+
+    def backwards(self, orm):
+        # Deleting field 'Section.slug'
+        db.delete_column('catalogue_section', 'slug')
+
+
+    models = {
+        'catalogue.lesson': {
+            'Meta': {'ordering': "['section', 'level', 'depth', 'order']", 'object_name': 'Lesson'},
+            'depth': ('django.db.models.fields.IntegerField', [], {}),
+            'html_file': ('django.db.models.fields.files.FileField', [], {'max_length': '100'}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'level': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['curriculum.Level']"}),
+            'order': ('django.db.models.fields.IntegerField', [], {}),
+            'package': ('django.db.models.fields.files.FileField', [], {'max_length': '100'}),
+            'section': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['catalogue.Section']"}),
+            'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '50'}),
+            'student_package': ('django.db.models.fields.files.FileField', [], {'max_length': '100'}),
+            'title': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+            'xml_file': ('django.db.models.fields.files.FileField', [], {'max_length': '100'})
+        },
+        'catalogue.section': {
+            'Meta': {'object_name': 'Section'},
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'order': ('django.db.models.fields.IntegerField', [], {}),
+            'slug': ('django.db.models.fields.SlugField', [], {'max_length': '50'}),
+            'title': ('django.db.models.fields.CharField', [], {'max_length': '255'})
+        },
+        'curriculum.level': {
+            'Meta': {'ordering': "['order']", 'object_name': 'Level'},
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+            'order': ('django.db.models.fields.IntegerField', [], {}),
+            'slug': ('django.db.models.fields.SlugField', [], {'max_length': '50'})
+        }
+    }
+
+    complete_apps = ['catalogue']
\ No newline at end of file
diff --git a/src/catalogue/migrations/0003_auto__chg_field_lesson_xml_file__chg_field_lesson_student_package__chg.py b/src/catalogue/migrations/0003_auto__chg_field_lesson_xml_file__chg_field_lesson_student_package__chg.py
new file mode 100644 (file)
index 0000000..8be90a8
--- /dev/null
@@ -0,0 +1,81 @@
+# -*- coding: utf-8 -*-
+import datetime
+from south.db import db
+from south.v2 import SchemaMigration
+from django.db import models
+
+
+class Migration(SchemaMigration):
+
+    def forwards(self, orm):
+
+        # Changing field 'Lesson.xml_file'
+        db.alter_column('catalogue_lesson', 'xml_file', self.gf('django.db.models.fields.files.FileField')(max_length=100, null=True))
+
+        # Changing field 'Lesson.student_package'
+        db.alter_column('catalogue_lesson', 'student_package', self.gf('django.db.models.fields.files.FileField')(max_length=100, null=True))
+
+        # Changing field 'Lesson.package'
+        db.alter_column('catalogue_lesson', 'package', self.gf('django.db.models.fields.files.FileField')(max_length=100, null=True))
+
+        # Changing field 'Lesson.html_file'
+        db.alter_column('catalogue_lesson', 'html_file', self.gf('django.db.models.fields.files.FileField')(max_length=100, null=True))
+        # Adding unique constraint on 'Section', fields ['title']
+        db.create_unique('catalogue_section', ['title'])
+
+        # Adding unique constraint on 'Section', fields ['slug']
+        db.create_unique('catalogue_section', ['slug'])
+
+
+    def backwards(self, orm):
+        # Removing unique constraint on 'Section', fields ['slug']
+        db.delete_unique('catalogue_section', ['slug'])
+
+        # Removing unique constraint on 'Section', fields ['title']
+        db.delete_unique('catalogue_section', ['title'])
+
+
+        # User chose to not deal with backwards NULL issues for 'Lesson.xml_file'
+        raise RuntimeError("Cannot reverse this migration. 'Lesson.xml_file' and its values cannot be restored.")
+
+        # User chose to not deal with backwards NULL issues for 'Lesson.student_package'
+        raise RuntimeError("Cannot reverse this migration. 'Lesson.student_package' and its values cannot be restored.")
+
+        # User chose to not deal with backwards NULL issues for 'Lesson.package'
+        raise RuntimeError("Cannot reverse this migration. 'Lesson.package' and its values cannot be restored.")
+
+        # User chose to not deal with backwards NULL issues for 'Lesson.html_file'
+        raise RuntimeError("Cannot reverse this migration. 'Lesson.html_file' and its values cannot be restored.")
+
+    models = {
+        'catalogue.lesson': {
+            'Meta': {'ordering': "['section', 'level', 'depth', 'order']", 'object_name': 'Lesson'},
+            'depth': ('django.db.models.fields.IntegerField', [], {}),
+            'html_file': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'level': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['curriculum.Level']"}),
+            'order': ('django.db.models.fields.IntegerField', [], {}),
+            'package': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
+            'section': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['catalogue.Section']"}),
+            'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '50'}),
+            'student_package': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
+            'title': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+            'xml_file': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'})
+        },
+        'catalogue.section': {
+            'Meta': {'object_name': 'Section'},
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'order': ('django.db.models.fields.IntegerField', [], {}),
+            'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '50'}),
+            'title': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'})
+        },
+        'curriculum.level': {
+            'Meta': {'ordering': "['order']", 'object_name': 'Level'},
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+            'order': ('django.db.models.fields.IntegerField', [], {}),
+            'slug': ('django.db.models.fields.SlugField', [], {'max_length': '50'})
+        }
+    }
+
+    complete_apps = ['catalogue']
\ No newline at end of file
diff --git a/src/catalogue/migrations/0004_auto__add_part__add_attachment__add_field_lesson_pdf__add_field_lesson.py b/src/catalogue/migrations/0004_auto__add_part__add_attachment__add_field_lesson_pdf__add_field_lesson.py
new file mode 100644 (file)
index 0000000..59ae0d7
--- /dev/null
@@ -0,0 +1,99 @@
+# -*- coding: utf-8 -*-
+import datetime
+from south.db import db
+from south.v2 import SchemaMigration
+from django.db import models
+
+
+class Migration(SchemaMigration):
+
+    def forwards(self, orm):
+        # Adding model 'Part'
+        db.create_table('catalogue_part', (
+            ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
+            ('lesson', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['catalogue.Lesson'])),
+            ('pdf', self.gf('django.db.models.fields.files.FileField')(max_length=100, null=True, blank=True)),
+            ('student_pdf', self.gf('django.db.models.fields.files.FileField')(max_length=100, null=True, blank=True)),
+        ))
+        db.send_create_signal('catalogue', ['Part'])
+
+        # Adding model 'Attachment'
+        db.create_table('catalogue_attachment', (
+            ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
+            ('lesson', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['catalogue.Lesson'])),
+            ('file', self.gf('django.db.models.fields.files.FileField')(max_length=100)),
+        ))
+        db.send_create_signal('catalogue', ['Attachment'])
+
+        # Adding field 'Lesson.pdf'
+        db.add_column('catalogue_lesson', 'pdf',
+                      self.gf('django.db.models.fields.files.FileField')(max_length=100, null=True, blank=True),
+                      keep_default=False)
+
+        # Adding field 'Lesson.student_pdf'
+        db.add_column('catalogue_lesson', 'student_pdf',
+                      self.gf('django.db.models.fields.files.FileField')(max_length=100, null=True, blank=True),
+                      keep_default=False)
+
+
+    def backwards(self, orm):
+        # Deleting model 'Part'
+        db.delete_table('catalogue_part')
+
+        # Deleting model 'Attachment'
+        db.delete_table('catalogue_attachment')
+
+        # Deleting field 'Lesson.pdf'
+        db.delete_column('catalogue_lesson', 'pdf')
+
+        # Deleting field 'Lesson.student_pdf'
+        db.delete_column('catalogue_lesson', 'student_pdf')
+
+
+    models = {
+        'catalogue.attachment': {
+            'Meta': {'object_name': 'Attachment'},
+            'file': ('django.db.models.fields.files.FileField', [], {'max_length': '100'}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'lesson': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['catalogue.Lesson']"})
+        },
+        'catalogue.lesson': {
+            'Meta': {'ordering': "['section', 'level', 'depth', 'order']", 'object_name': 'Lesson'},
+            'depth': ('django.db.models.fields.IntegerField', [], {}),
+            'html_file': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'level': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['curriculum.Level']"}),
+            'order': ('django.db.models.fields.IntegerField', [], {}),
+            'package': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
+            'pdf': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
+            'section': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['catalogue.Section']"}),
+            'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '50'}),
+            'student_package': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
+            'student_pdf': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
+            'title': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+            'xml_file': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'})
+        },
+        'catalogue.part': {
+            'Meta': {'object_name': 'Part'},
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'lesson': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['catalogue.Lesson']"}),
+            'pdf': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
+            'student_pdf': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'})
+        },
+        'catalogue.section': {
+            'Meta': {'ordering': "['order']", 'object_name': 'Section'},
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'order': ('django.db.models.fields.IntegerField', [], {}),
+            'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '50'}),
+            'title': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'})
+        },
+        'curriculum.level': {
+            'Meta': {'ordering': "['order']", 'object_name': 'Level'},
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+            'order': ('django.db.models.fields.IntegerField', [], {}),
+            'slug': ('django.db.models.fields.SlugField', [], {'max_length': '50'})
+        }
+    }
+
+    complete_apps = ['catalogue']
\ No newline at end of file
diff --git a/src/catalogue/migrations/0005_auto__add_field_lesson_dc.py b/src/catalogue/migrations/0005_auto__add_field_lesson_dc.py
new file mode 100644 (file)
index 0000000..ce7705f
--- /dev/null
@@ -0,0 +1,69 @@
+# -*- coding: utf-8 -*-
+import datetime
+from south.db import db
+from south.v2 import SchemaMigration
+from django.db import models
+
+
+class Migration(SchemaMigration):
+
+    def forwards(self, orm):
+        # Adding field 'Lesson.dc'
+        db.add_column('catalogue_lesson', 'dc',
+                      self.gf('jsonfield.fields.JSONField')(default='{}'),
+                      keep_default=False)
+
+
+    def backwards(self, orm):
+        # Deleting field 'Lesson.dc'
+        db.delete_column('catalogue_lesson', 'dc')
+
+
+    models = {
+        'catalogue.attachment': {
+            'Meta': {'object_name': 'Attachment'},
+            'file': ('django.db.models.fields.files.FileField', [], {'max_length': '100'}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'lesson': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['catalogue.Lesson']"})
+        },
+        'catalogue.lesson': {
+            'Meta': {'ordering': "['section', 'level', 'depth', 'order']", 'object_name': 'Lesson'},
+            'dc': ('jsonfield.fields.JSONField', [], {'default': "'{}'"}),
+            'depth': ('django.db.models.fields.IntegerField', [], {}),
+            'html_file': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'level': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['curriculum.Level']"}),
+            'order': ('django.db.models.fields.IntegerField', [], {}),
+            'package': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
+            'pdf': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
+            'section': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['catalogue.Section']"}),
+            'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '50'}),
+            'student_package': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
+            'student_pdf': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
+            'title': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+            'xml_file': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'})
+        },
+        'catalogue.part': {
+            'Meta': {'object_name': 'Part'},
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'lesson': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['catalogue.Lesson']"}),
+            'pdf': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
+            'student_pdf': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'})
+        },
+        'catalogue.section': {
+            'Meta': {'ordering': "['order']", 'object_name': 'Section'},
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'order': ('django.db.models.fields.IntegerField', [], {}),
+            'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '50'}),
+            'title': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'})
+        },
+        'curriculum.level': {
+            'Meta': {'ordering': "['order']", 'object_name': 'Level'},
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+            'order': ('django.db.models.fields.IntegerField', [], {}),
+            'slug': ('django.db.models.fields.SlugField', [], {'max_length': '50'})
+        }
+    }
+
+    complete_apps = ['catalogue']
\ No newline at end of file
diff --git a/src/catalogue/migrations/0006_auto__add_field_attachment_slug__add_field_attachment_ext__add_unique_.py b/src/catalogue/migrations/0006_auto__add_field_attachment_slug__add_field_attachment_ext__add_unique_.py
new file mode 100644 (file)
index 0000000..043627d
--- /dev/null
@@ -0,0 +1,85 @@
+# -*- coding: utf-8 -*-
+import datetime
+from south.db import db
+from south.v2 import SchemaMigration
+from django.db import models
+
+
+class Migration(SchemaMigration):
+
+    def forwards(self, orm):
+        # Adding field 'Attachment.slug'
+        db.add_column('catalogue_attachment', 'slug',
+                      self.gf('django.db.models.fields.CharField')(default='', max_length=255),
+                      keep_default=False)
+
+        # Adding field 'Attachment.ext'
+        db.add_column('catalogue_attachment', 'ext',
+                      self.gf('django.db.models.fields.CharField')(default='', max_length=15),
+                      keep_default=False)
+
+        # Adding unique constraint on 'Attachment', fields ['ext', 'lesson', 'slug']
+        db.create_unique('catalogue_attachment', ['ext', 'lesson_id', 'slug'])
+
+
+    def backwards(self, orm):
+        # Removing unique constraint on 'Attachment', fields ['ext', 'lesson', 'slug']
+        db.delete_unique('catalogue_attachment', ['ext', 'lesson_id', 'slug'])
+
+        # Deleting field 'Attachment.slug'
+        db.delete_column('catalogue_attachment', 'slug')
+
+        # Deleting field 'Attachment.ext'
+        db.delete_column('catalogue_attachment', 'ext')
+
+
+    models = {
+        'catalogue.attachment': {
+            'Meta': {'unique_together': "(['lesson', 'slug', 'ext'],)", 'object_name': 'Attachment'},
+            'ext': ('django.db.models.fields.CharField', [], {'max_length': '15'}),
+            'file': ('django.db.models.fields.files.FileField', [], {'max_length': '100'}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'lesson': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['catalogue.Lesson']"}),
+            'slug': ('django.db.models.fields.CharField', [], {'max_length': '255'})
+        },
+        'catalogue.lesson': {
+            'Meta': {'ordering': "['section', 'level', 'depth', 'order']", 'object_name': 'Lesson'},
+            'dc': ('jsonfield.fields.JSONField', [], {'default': "'{}'"}),
+            'depth': ('django.db.models.fields.IntegerField', [], {}),
+            'html_file': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'level': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['curriculum.Level']"}),
+            'order': ('django.db.models.fields.IntegerField', [], {}),
+            'package': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
+            'pdf': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
+            'section': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['catalogue.Section']"}),
+            'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '50'}),
+            'student_package': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
+            'student_pdf': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
+            'title': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+            'xml_file': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'})
+        },
+        'catalogue.part': {
+            'Meta': {'object_name': 'Part'},
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'lesson': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['catalogue.Lesson']"}),
+            'pdf': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
+            'student_pdf': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'})
+        },
+        'catalogue.section': {
+            'Meta': {'ordering': "['order']", 'object_name': 'Section'},
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'order': ('django.db.models.fields.IntegerField', [], {}),
+            'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '50'}),
+            'title': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'})
+        },
+        'curriculum.level': {
+            'Meta': {'ordering': "['order']", 'object_name': 'Level'},
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+            'order': ('django.db.models.fields.IntegerField', [], {}),
+            'slug': ('django.db.models.fields.SlugField', [], {'max_length': '50'})
+        }
+    }
+
+    complete_apps = ['catalogue']
\ No newline at end of file
diff --git a/src/catalogue/migrations/0007_auto__add_field_lesson_type__chg_field_lesson_section.py b/src/catalogue/migrations/0007_auto__add_field_lesson_type__chg_field_lesson_section.py
new file mode 100644 (file)
index 0000000..25204db
--- /dev/null
@@ -0,0 +1,96 @@
+# -*- coding: utf-8 -*-
+import datetime
+from south.db import db
+from south.v2 import SchemaMigration
+from django.db import models
+
+
+class Migration(SchemaMigration):
+
+    def forwards(self, orm):
+        # Adding field 'Lesson.type'
+        db.add_column('catalogue_lesson', 'type',
+                      self.gf('django.db.models.fields.CharField')(default='course', max_length=15, db_index=True),
+                      keep_default=False)
+
+        # Changing field 'Lesson.section'
+        db.alter_column('catalogue_lesson', 'section_id', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['catalogue.Section'], null=True))
+        # Adding index on 'Lesson', fields ['order']
+        db.create_index('catalogue_lesson', ['order'])
+
+        if not db.dry_run:
+            orm.Lesson.objects.filter(depth=0).update(type='synthetic')
+
+
+    def backwards(self, orm):
+        # Removing index on 'Lesson', fields ['order']
+        db.delete_index('catalogue_lesson', ['order'])
+
+        # Deleting field 'Lesson.type'
+        db.delete_column('catalogue_lesson', 'type')
+
+        section = 0
+        if not db.dry_run:
+            orm.Lesson.objects.filter(type='synthetic').update(depth=0)
+            try:
+                section = orm.Section.objects.all()[0]
+            except orm.Section.DoesNotExist:
+                pass
+
+        # Changing field 'Lesson.section'
+        db.alter_column('catalogue_lesson', 'section_id',
+            self.gf('django.db.models.fields.related.ForeignKey')(default=section, to=orm['catalogue.Section']))
+
+
+    models = {
+        'catalogue.attachment': {
+            'Meta': {'ordering': "['slug', 'ext']", 'unique_together': "(['lesson', 'slug', 'ext'],)", 'object_name': 'Attachment'},
+            'ext': ('django.db.models.fields.CharField', [], {'max_length': '15'}),
+            'file': ('django.db.models.fields.files.FileField', [], {'max_length': '100'}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'lesson': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['catalogue.Lesson']"}),
+            'slug': ('django.db.models.fields.CharField', [], {'max_length': '255'})
+        },
+        'catalogue.lesson': {
+            'Meta': {'ordering': "['section', 'level', 'order']", 'object_name': 'Lesson'},
+            'dc': ('jsonfield.fields.JSONField', [], {'default': "'{}'"}),
+            'depth': ('django.db.models.fields.IntegerField', [], {}),
+            'html_file': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'level': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['curriculum.Level']"}),
+            'order': ('django.db.models.fields.IntegerField', [], {'db_index': 'True'}),
+            'package': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
+            'pdf': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
+            'section': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['catalogue.Section']", 'null': 'True', 'blank': 'True'}),
+            'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '50'}),
+            'student_package': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
+            'student_pdf': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
+            'title': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+            'type': ('django.db.models.fields.CharField', [], {'max_length': '15', 'db_index': 'True'}),
+            'xml_file': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'})
+        },
+        'catalogue.part': {
+            'Meta': {'object_name': 'Part'},
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'lesson': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['catalogue.Lesson']"}),
+            'pdf': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
+            'student_pdf': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'})
+        },
+        'catalogue.section': {
+            'Meta': {'ordering': "['order']", 'object_name': 'Section'},
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'order': ('django.db.models.fields.IntegerField', [], {}),
+            'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '50'}),
+            'title': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'})
+        },
+        'curriculum.level': {
+            'Meta': {'ordering': "['order']", 'object_name': 'Level'},
+            'group': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+            'order': ('django.db.models.fields.IntegerField', [], {}),
+            'slug': ('django.db.models.fields.CharField', [], {'max_length': '255'})
+        }
+    }
+
+    complete_apps = ['catalogue']
diff --git a/src/catalogue/migrations/0008_auto__del_field_lesson_depth.py b/src/catalogue/migrations/0008_auto__del_field_lesson_depth.py
new file mode 100644 (file)
index 0000000..4bd650f
--- /dev/null
@@ -0,0 +1,72 @@
+# -*- coding: utf-8 -*-
+import datetime
+from south.db import db
+from south.v2 import SchemaMigration
+from django.db import models
+
+
+class Migration(SchemaMigration):
+
+    def forwards(self, orm):
+        # Deleting field 'Lesson.depth'
+        db.delete_column('catalogue_lesson', 'depth')
+
+
+    def backwards(self, orm):
+        # Adding field 'Lesson.depth'
+        db.add_column('catalogue_lesson', 'depth',
+                      self.gf('django.db.models.fields.IntegerField')(default=1),
+                      keep_default=False)
+
+
+    models = {
+        'catalogue.attachment': {
+            'Meta': {'ordering': "['slug', 'ext']", 'unique_together': "(['lesson', 'slug', 'ext'],)", 'object_name': 'Attachment'},
+            'ext': ('django.db.models.fields.CharField', [], {'max_length': '15'}),
+            'file': ('django.db.models.fields.files.FileField', [], {'max_length': '100'}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'lesson': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['catalogue.Lesson']"}),
+            'slug': ('django.db.models.fields.CharField', [], {'max_length': '255'})
+        },
+        'catalogue.lesson': {
+            'Meta': {'ordering': "['section', 'level', 'order']", 'object_name': 'Lesson'},
+            'dc': ('jsonfield.fields.JSONField', [], {'default': "'{}'"}),
+            'html_file': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'level': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['curriculum.Level']"}),
+            'order': ('django.db.models.fields.IntegerField', [], {'db_index': 'True'}),
+            'package': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
+            'pdf': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
+            'section': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['catalogue.Section']", 'null': 'True', 'blank': 'True'}),
+            'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '50'}),
+            'student_package': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
+            'student_pdf': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
+            'title': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+            'type': ('django.db.models.fields.CharField', [], {'max_length': '15', 'db_index': 'True'}),
+            'xml_file': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'})
+        },
+        'catalogue.part': {
+            'Meta': {'object_name': 'Part'},
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'lesson': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['catalogue.Lesson']"}),
+            'pdf': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
+            'student_pdf': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'})
+        },
+        'catalogue.section': {
+            'Meta': {'ordering': "['order']", 'object_name': 'Section'},
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'order': ('django.db.models.fields.IntegerField', [], {}),
+            'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '50'}),
+            'title': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'})
+        },
+        'curriculum.level': {
+            'Meta': {'ordering': "['order']", 'object_name': 'Level'},
+            'group': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+            'order': ('django.db.models.fields.IntegerField', [], {}),
+            'slug': ('django.db.models.fields.CharField', [], {'max_length': '255'})
+        }
+    }
+
+    complete_apps = ['catalogue']
diff --git a/src/catalogue/migrations/0009_auto__add_field_section_xml_file.py b/src/catalogue/migrations/0009_auto__add_field_section_xml_file.py
new file mode 100644 (file)
index 0000000..6686e5c
--- /dev/null
@@ -0,0 +1,73 @@
+# -*- coding: utf-8 -*-
+import datetime
+from south.db import db
+from south.v2 import SchemaMigration
+from django.db import models
+
+
+class Migration(SchemaMigration):
+
+    def forwards(self, orm):
+        # Adding field 'Section.xml_file'
+        db.add_column('catalogue_section', 'xml_file',
+                      self.gf('django.db.models.fields.files.FileField')(max_length=100, null=True, blank=True),
+                      keep_default=False)
+
+
+    def backwards(self, orm):
+        # Deleting field 'Section.xml_file'
+        db.delete_column('catalogue_section', 'xml_file')
+
+
+    models = {
+        'catalogue.attachment': {
+            'Meta': {'ordering': "['slug', 'ext']", 'unique_together': "(['lesson', 'slug', 'ext'],)", 'object_name': 'Attachment'},
+            'ext': ('django.db.models.fields.CharField', [], {'max_length': '15'}),
+            'file': ('django.db.models.fields.files.FileField', [], {'max_length': '100'}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'lesson': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['catalogue.Lesson']"}),
+            'slug': ('django.db.models.fields.CharField', [], {'max_length': '255'})
+        },
+        'catalogue.lesson': {
+            'Meta': {'ordering': "['section', 'level', 'order']", 'object_name': 'Lesson'},
+            'dc': ('jsonfield.fields.JSONField', [], {'default': "'{}'"}),
+            'html_file': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'level': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['curriculum.Level']"}),
+            'order': ('django.db.models.fields.IntegerField', [], {'db_index': 'True'}),
+            'package': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
+            'pdf': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
+            'section': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['catalogue.Section']", 'null': 'True', 'blank': 'True'}),
+            'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '50'}),
+            'student_package': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
+            'student_pdf': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
+            'title': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+            'type': ('django.db.models.fields.CharField', [], {'max_length': '15', 'db_index': 'True'}),
+            'xml_file': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'})
+        },
+        'catalogue.part': {
+            'Meta': {'object_name': 'Part'},
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'lesson': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['catalogue.Lesson']"}),
+            'pdf': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
+            'student_pdf': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'})
+        },
+        'catalogue.section': {
+            'Meta': {'ordering': "['order']", 'object_name': 'Section'},
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'order': ('django.db.models.fields.IntegerField', [], {}),
+            'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '50'}),
+            'title': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'}),
+            'xml_file': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'})
+        },
+        'curriculum.level': {
+            'Meta': {'ordering': "['order']", 'object_name': 'Level'},
+            'group': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+            'order': ('django.db.models.fields.IntegerField', [], {}),
+            'slug': ('django.db.models.fields.CharField', [], {'max_length': '255'})
+        }
+    }
+
+    complete_apps = ['catalogue']
\ No newline at end of file
diff --git a/src/catalogue/migrations/0010_auto.py b/src/catalogue/migrations/0010_auto.py
new file mode 100644 (file)
index 0000000..73602ca
--- /dev/null
@@ -0,0 +1,83 @@
+# -*- coding: utf-8 -*-
+import datetime
+from south.db import db
+from south.v2 import SchemaMigration
+from django.db import models
+
+
+class Migration(SchemaMigration):
+
+    def forwards(self, orm):
+        # Adding M2M table for field curriculum_courses on 'Lesson'
+        db.create_table('catalogue_lesson_curriculum_courses', (
+            ('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)),
+            ('lesson', models.ForeignKey(orm['catalogue.lesson'], null=False)),
+            ('curriculumcourse', models.ForeignKey(orm['curriculum.curriculumcourse'], null=False))
+        ))
+        db.create_unique('catalogue_lesson_curriculum_courses', ['lesson_id', 'curriculumcourse_id'])
+
+
+    def backwards(self, orm):
+        # Removing M2M table for field curriculum_courses on 'Lesson'
+        db.delete_table('catalogue_lesson_curriculum_courses')
+
+
+    models = {
+        'catalogue.attachment': {
+            'Meta': {'ordering': "['slug', 'ext']", 'unique_together': "(['lesson', 'slug', 'ext'],)", 'object_name': 'Attachment'},
+            'ext': ('django.db.models.fields.CharField', [], {'max_length': '15'}),
+            'file': ('django.db.models.fields.files.FileField', [], {'max_length': '100'}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'lesson': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['catalogue.Lesson']"}),
+            'slug': ('django.db.models.fields.CharField', [], {'max_length': '255'})
+        },
+        'catalogue.lesson': {
+            'Meta': {'ordering': "['section', 'level', 'order']", 'object_name': 'Lesson'},
+            'curriculum_courses': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['curriculum.CurriculumCourse']", 'symmetrical': 'False'}),
+            'dc': ('jsonfield.fields.JSONField', [], {'default': "'{}'"}),
+            'html_file': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'level': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['curriculum.Level']"}),
+            'order': ('django.db.models.fields.IntegerField', [], {'db_index': 'True'}),
+            'package': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
+            'pdf': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
+            'section': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['catalogue.Section']", 'null': 'True', 'blank': 'True'}),
+            'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '50'}),
+            'student_package': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
+            'student_pdf': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
+            'title': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+            'type': ('django.db.models.fields.CharField', [], {'max_length': '15', 'db_index': 'True'}),
+            'xml_file': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'})
+        },
+        'catalogue.part': {
+            'Meta': {'object_name': 'Part'},
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'lesson': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['catalogue.Lesson']"}),
+            'pdf': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
+            'student_pdf': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'})
+        },
+        'catalogue.section': {
+            'Meta': {'ordering': "['order']", 'object_name': 'Section'},
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'order': ('django.db.models.fields.IntegerField', [], {}),
+            'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '50'}),
+            'title': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'}),
+            'xml_file': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'})
+        },
+        'curriculum.curriculumcourse': {
+            'Meta': {'object_name': 'CurriculumCourse'},
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'slug': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}),
+            'title': ('django.db.models.fields.CharField', [], {'max_length': '255'})
+        },
+        'curriculum.level': {
+            'Meta': {'ordering': "['order']", 'object_name': 'Level'},
+            'group': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+            'order': ('django.db.models.fields.IntegerField', [], {}),
+            'slug': ('django.db.models.fields.CharField', [], {'max_length': '255'})
+        }
+    }
+
+    complete_apps = ['catalogue']
\ No newline at end of file
diff --git a/src/catalogue/migrations/0011_auto__chg_field_lesson_xml_file__chg_field_lesson_student_pdf__chg_fie.py b/src/catalogue/migrations/0011_auto__chg_field_lesson_xml_file__chg_field_lesson_student_pdf__chg_fie.py
new file mode 100644 (file)
index 0000000..5963f2b
--- /dev/null
@@ -0,0 +1,127 @@
+# -*- coding: utf-8 -*-
+import datetime
+from south.db import db
+from south.v2 import SchemaMigration
+from django.db import models
+
+
+class Migration(SchemaMigration):
+
+    def forwards(self, orm):
+
+        # Changing field 'Lesson.xml_file'
+        db.alter_column('catalogue_lesson', 'xml_file', self.gf('django.db.models.fields.files.FileField')(max_length=255, null=True))
+
+        # Changing field 'Lesson.student_pdf'
+        db.alter_column('catalogue_lesson', 'student_pdf', self.gf('django.db.models.fields.files.FileField')(max_length=255, null=True))
+
+        # Changing field 'Lesson.student_package'
+        db.alter_column('catalogue_lesson', 'student_package', self.gf('django.db.models.fields.files.FileField')(max_length=255, null=True))
+
+        # Changing field 'Lesson.package'
+        db.alter_column('catalogue_lesson', 'package', self.gf('django.db.models.fields.files.FileField')(max_length=255, null=True))
+
+        # Changing field 'Lesson.html_file'
+        db.alter_column('catalogue_lesson', 'html_file', self.gf('django.db.models.fields.files.FileField')(max_length=255, null=True))
+
+        # Changing field 'Lesson.pdf'
+        db.alter_column('catalogue_lesson', 'pdf', self.gf('django.db.models.fields.files.FileField')(max_length=255, null=True))
+
+        # Changing field 'Lesson.slug'
+        db.alter_column('catalogue_lesson', 'slug', self.gf('django.db.models.fields.SlugField')(unique=True, max_length=255))
+
+        # Changing field 'Section.xml_file'
+        db.alter_column('catalogue_section', 'xml_file', self.gf('django.db.models.fields.files.FileField')(max_length=255, null=True))
+
+        # Changing field 'Section.slug'
+        db.alter_column('catalogue_section', 'slug', self.gf('django.db.models.fields.SlugField')(unique=True, max_length=255))
+
+    def backwards(self, orm):
+
+        # Changing field 'Lesson.xml_file'
+        db.alter_column('catalogue_lesson', 'xml_file', self.gf('django.db.models.fields.files.FileField')(max_length=100, null=True))
+
+        # Changing field 'Lesson.student_pdf'
+        db.alter_column('catalogue_lesson', 'student_pdf', self.gf('django.db.models.fields.files.FileField')(max_length=100, null=True))
+
+        # Changing field 'Lesson.student_package'
+        db.alter_column('catalogue_lesson', 'student_package', self.gf('django.db.models.fields.files.FileField')(max_length=100, null=True))
+
+        # Changing field 'Lesson.package'
+        db.alter_column('catalogue_lesson', 'package', self.gf('django.db.models.fields.files.FileField')(max_length=100, null=True))
+
+        # Changing field 'Lesson.html_file'
+        db.alter_column('catalogue_lesson', 'html_file', self.gf('django.db.models.fields.files.FileField')(max_length=100, null=True))
+
+        # Changing field 'Lesson.pdf'
+        db.alter_column('catalogue_lesson', 'pdf', self.gf('django.db.models.fields.files.FileField')(max_length=100, null=True))
+
+        # Changing field 'Lesson.slug'
+        db.alter_column('catalogue_lesson', 'slug', self.gf('django.db.models.fields.SlugField')(max_length=50, unique=True))
+
+        # Changing field 'Section.xml_file'
+        db.alter_column('catalogue_section', 'xml_file', self.gf('django.db.models.fields.files.FileField')(max_length=100, null=True))
+
+        # Changing field 'Section.slug'
+        db.alter_column('catalogue_section', 'slug', self.gf('django.db.models.fields.SlugField')(max_length=50, unique=True))
+
+    models = {
+        'catalogue.attachment': {
+            'Meta': {'ordering': "['slug', 'ext']", 'unique_together': "(['lesson', 'slug', 'ext'],)", 'object_name': 'Attachment'},
+            'ext': ('django.db.models.fields.CharField', [], {'max_length': '15'}),
+            'file': ('django.db.models.fields.files.FileField', [], {'max_length': '100'}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'lesson': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['catalogue.Lesson']"}),
+            'slug': ('django.db.models.fields.CharField', [], {'max_length': '255'})
+        },
+        'catalogue.lesson': {
+            'Meta': {'ordering': "['section', 'level', 'order']", 'object_name': 'Lesson'},
+            'curriculum_courses': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['curriculum.CurriculumCourse']", 'symmetrical': 'False'}),
+            'dc': ('jsonfield.fields.JSONField', [], {'default': "'{}'"}),
+            'html_file': ('django.db.models.fields.files.FileField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'level': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['curriculum.Level']"}),
+            'order': ('django.db.models.fields.IntegerField', [], {'db_index': 'True'}),
+            'package': ('django.db.models.fields.files.FileField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
+            'pdf': ('django.db.models.fields.files.FileField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
+            'section': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['catalogue.Section']", 'null': 'True', 'blank': 'True'}),
+            'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '255'}),
+            'student_package': ('django.db.models.fields.files.FileField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
+            'student_pdf': ('django.db.models.fields.files.FileField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
+            'title': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+            'type': ('django.db.models.fields.CharField', [], {'max_length': '15', 'db_index': 'True'}),
+            'xml_file': ('django.db.models.fields.files.FileField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'})
+        },
+        'catalogue.part': {
+            'Meta': {'object_name': 'Part'},
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'lesson': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['catalogue.Lesson']"}),
+            'pdf': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
+            'student_pdf': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'})
+        },
+        'catalogue.section': {
+            'Meta': {'ordering': "['order']", 'object_name': 'Section'},
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'order': ('django.db.models.fields.IntegerField', [], {}),
+            'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '255'}),
+            'title': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'}),
+            'xml_file': ('django.db.models.fields.files.FileField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'})
+        },
+        'curriculum.curriculumcourse': {
+            'Meta': {'ordering': "['slug']", 'object_name': 'CurriculumCourse'},
+            'accusative': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'slug': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}),
+            'title': ('django.db.models.fields.CharField', [], {'max_length': '255'})
+        },
+        'curriculum.level': {
+            'Meta': {'ordering': "['order']", 'object_name': 'Level'},
+            'group': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+            'order': ('django.db.models.fields.IntegerField', [], {}),
+            'slug': ('django.db.models.fields.CharField', [], {'max_length': '255'})
+        }
+    }
+
+    complete_apps = ['catalogue']
\ No newline at end of file
diff --git a/src/catalogue/migrations/0012_auto__add_lessonstub.py b/src/catalogue/migrations/0012_auto__add_lessonstub.py
new file mode 100644 (file)
index 0000000..d8e53bb
--- /dev/null
@@ -0,0 +1,96 @@
+# -*- coding: utf-8 -*-
+import datetime
+from south.db import db
+from south.v2 import SchemaMigration
+from django.db import models
+
+
+class Migration(SchemaMigration):
+
+    def forwards(self, orm):
+        # Adding model 'LessonStub'
+        db.create_table('catalogue_lessonstub', (
+            ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
+            ('section', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['catalogue.Section'], null=True, blank=True)),
+            ('level', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['curriculum.Level'])),
+            ('title', self.gf('django.db.models.fields.CharField')(max_length=255)),
+            ('type', self.gf('django.db.models.fields.CharField')(max_length=15, db_index=True)),
+            ('order', self.gf('django.db.models.fields.IntegerField')(db_index=True)),
+        ))
+        db.send_create_signal('catalogue', ['LessonStub'])
+
+
+    def backwards(self, orm):
+        # Deleting model 'LessonStub'
+        db.delete_table('catalogue_lessonstub')
+
+
+    models = {
+        'catalogue.attachment': {
+            'Meta': {'ordering': "['slug', 'ext']", 'unique_together': "(['lesson', 'slug', 'ext'],)", 'object_name': 'Attachment'},
+            'ext': ('django.db.models.fields.CharField', [], {'max_length': '15'}),
+            'file': ('django.db.models.fields.files.FileField', [], {'max_length': '100'}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'lesson': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['catalogue.Lesson']"}),
+            'slug': ('django.db.models.fields.CharField', [], {'max_length': '255'})
+        },
+        'catalogue.lesson': {
+            'Meta': {'ordering': "['section', 'level', 'order']", 'object_name': 'Lesson'},
+            'curriculum_courses': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['curriculum.CurriculumCourse']", 'symmetrical': 'False'}),
+            'dc': ('jsonfield.fields.JSONField', [], {'default': "'{}'"}),
+            'html_file': ('django.db.models.fields.files.FileField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'level': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['curriculum.Level']"}),
+            'order': ('django.db.models.fields.IntegerField', [], {'db_index': 'True'}),
+            'package': ('django.db.models.fields.files.FileField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
+            'pdf': ('django.db.models.fields.files.FileField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
+            'section': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['catalogue.Section']", 'null': 'True', 'blank': 'True'}),
+            'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '255'}),
+            'student_package': ('django.db.models.fields.files.FileField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
+            'student_pdf': ('django.db.models.fields.files.FileField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
+            'title': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+            'type': ('django.db.models.fields.CharField', [], {'max_length': '15', 'db_index': 'True'}),
+            'xml_file': ('django.db.models.fields.files.FileField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'})
+        },
+        'catalogue.lessonstub': {
+            'Meta': {'ordering': "['section', 'level', 'order']", 'object_name': 'LessonStub'},
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'level': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['curriculum.Level']"}),
+            'order': ('django.db.models.fields.IntegerField', [], {'db_index': 'True'}),
+            'section': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['catalogue.Section']", 'null': 'True', 'blank': 'True'}),
+            'title': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+            'type': ('django.db.models.fields.CharField', [], {'max_length': '15', 'db_index': 'True'})
+        },
+        'catalogue.part': {
+            'Meta': {'object_name': 'Part'},
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'lesson': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['catalogue.Lesson']"}),
+            'pdf': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
+            'student_pdf': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'})
+        },
+        'catalogue.section': {
+            'Meta': {'ordering': "['order']", 'object_name': 'Section'},
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'order': ('django.db.models.fields.IntegerField', [], {}),
+            'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '255'}),
+            'title': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'}),
+            'xml_file': ('django.db.models.fields.files.FileField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'})
+        },
+        'curriculum.curriculumcourse': {
+            'Meta': {'ordering': "['slug']", 'object_name': 'CurriculumCourse'},
+            'accusative': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'slug': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}),
+            'title': ('django.db.models.fields.CharField', [], {'max_length': '255'})
+        },
+        'curriculum.level': {
+            'Meta': {'ordering': "['order']", 'object_name': 'Level'},
+            'group': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+            'order': ('django.db.models.fields.IntegerField', [], {}),
+            'slug': ('django.db.models.fields.CharField', [], {'max_length': '255'})
+        }
+    }
+
+    complete_apps = ['catalogue']
\ No newline at end of file
diff --git a/src/catalogue/migrations/0013_auto__add_field_section_image.py b/src/catalogue/migrations/0013_auto__add_field_section_image.py
new file mode 100644 (file)
index 0000000..e097d57
--- /dev/null
@@ -0,0 +1,91 @@
+# -*- coding: utf-8 -*-
+import datetime
+from south.db import db
+from south.v2 import SchemaMigration
+from django.db import models
+
+
+class Migration(SchemaMigration):
+
+    def forwards(self, orm):
+        # Adding field 'Section.image'
+        db.add_column(u'catalogue_section', 'image',
+                      self.gf('django.db.models.fields.files.ImageField')(max_length=100, null=True, blank=True),
+                      keep_default=False)
+
+
+    def backwards(self, orm):
+        # Deleting field 'Section.image'
+        db.delete_column(u'catalogue_section', 'image')
+
+
+    models = {
+        u'catalogue.attachment': {
+            'Meta': {'ordering': "['slug', 'ext']", 'unique_together': "(['lesson', 'slug', 'ext'],)", 'object_name': 'Attachment'},
+            'ext': ('django.db.models.fields.CharField', [], {'max_length': '15'}),
+            'file': ('django.db.models.fields.files.FileField', [], {'max_length': '100'}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'lesson': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['catalogue.Lesson']"}),
+            'slug': ('django.db.models.fields.CharField', [], {'max_length': '255'})
+        },
+        u'catalogue.lesson': {
+            'Meta': {'ordering': "['section', 'level', 'order']", 'object_name': 'Lesson'},
+            'curriculum_courses': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['curriculum.CurriculumCourse']", 'symmetrical': 'False', 'blank': 'True'}),
+            'dc': ('jsonfield.fields.JSONField', [], {'default': "'{}'"}),
+            'html_file': ('django.db.models.fields.files.FileField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'level': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['curriculum.Level']"}),
+            'order': ('django.db.models.fields.IntegerField', [], {'db_index': 'True'}),
+            'package': ('django.db.models.fields.files.FileField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
+            'pdf': ('django.db.models.fields.files.FileField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
+            'section': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['catalogue.Section']", 'null': 'True', 'blank': 'True'}),
+            'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '255'}),
+            'student_package': ('django.db.models.fields.files.FileField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
+            'student_pdf': ('django.db.models.fields.files.FileField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
+            'title': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+            'type': ('django.db.models.fields.CharField', [], {'max_length': '15', 'db_index': 'True'}),
+            'xml_file': ('django.db.models.fields.files.FileField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'})
+        },
+        u'catalogue.lessonstub': {
+            'Meta': {'ordering': "['section', 'level', 'order']", 'object_name': 'LessonStub'},
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'level': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['curriculum.Level']"}),
+            'order': ('django.db.models.fields.IntegerField', [], {'db_index': 'True'}),
+            'section': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['catalogue.Section']", 'null': 'True', 'blank': 'True'}),
+            'title': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+            'type': ('django.db.models.fields.CharField', [], {'max_length': '15', 'db_index': 'True'})
+        },
+        u'catalogue.part': {
+            'Meta': {'object_name': 'Part'},
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'lesson': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['catalogue.Lesson']"}),
+            'pdf': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
+            'student_pdf': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'})
+        },
+        u'catalogue.section': {
+            'Meta': {'ordering': "['order']", 'object_name': 'Section'},
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'image': ('django.db.models.fields.files.ImageField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
+            'order': ('django.db.models.fields.IntegerField', [], {}),
+            'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '255'}),
+            'title': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'}),
+            'xml_file': ('django.db.models.fields.files.FileField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'})
+        },
+        u'curriculum.curriculumcourse': {
+            'Meta': {'ordering': "['slug']", 'object_name': 'CurriculumCourse'},
+            'accusative': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'slug': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}),
+            'title': ('django.db.models.fields.CharField', [], {'max_length': '255'})
+        },
+        u'curriculum.level': {
+            'Meta': {'ordering': "['order']", 'object_name': 'Level'},
+            'group': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+            'order': ('django.db.models.fields.IntegerField', [], {}),
+            'slug': ('django.db.models.fields.CharField', [], {'max_length': '255'})
+        }
+    }
+
+    complete_apps = ['catalogue']
\ No newline at end of file
diff --git a/src/catalogue/migrations/0014_auto__add_field_section_summary.py b/src/catalogue/migrations/0014_auto__add_field_section_summary.py
new file mode 100644 (file)
index 0000000..7805ec7
--- /dev/null
@@ -0,0 +1,94 @@
+# -*- coding: utf-8 -*-
+import datetime
+from south.db import db
+from south.v2 import SchemaMigration
+from django.db import models
+
+
+class Migration(SchemaMigration):
+
+    def forwards(self, orm):
+        # Adding field 'Section.summary'
+        db.add_column(u'catalogue_section', 'summary',
+                      self.gf('django.db.models.fields.TextField')(null=True, blank=True),
+                      keep_default=False)
+
+
+    def backwards(self, orm):
+        # Deleting field 'Section.summary'
+        db.delete_column(u'catalogue_section', 'summary')
+
+
+    models = {
+        u'catalogue.attachment': {
+            'Meta': {'ordering': "['slug', 'ext']", 'unique_together': "(['lesson', 'slug', 'ext'],)", 'object_name': 'Attachment'},
+            'ext': ('django.db.models.fields.CharField', [], {'max_length': '15'}),
+            'file': ('django.db.models.fields.files.FileField', [], {'max_length': '100'}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'lesson': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['catalogue.Lesson']"}),
+            'slug': ('django.db.models.fields.CharField', [], {'max_length': '255'})
+        },
+        u'catalogue.lesson': {
+            'Meta': {'ordering': "['section', 'level', 'order']", 'object_name': 'Lesson'},
+            'curriculum_courses': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['curriculum.CurriculumCourse']", 'symmetrical': 'False', 'blank': 'True'}),
+            'dc': ('jsonfield.fields.JSONField', [], {'default': "'{}'"}),
+            'html_file': ('django.db.models.fields.files.FileField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'level': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['curriculum.Level']"}),
+            'order': ('django.db.models.fields.IntegerField', [], {'db_index': 'True'}),
+            'package': ('django.db.models.fields.files.FileField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
+            'pdf': ('django.db.models.fields.files.FileField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
+            'section': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['catalogue.Section']", 'null': 'True', 'blank': 'True'}),
+            'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '255'}),
+            'student_package': ('django.db.models.fields.files.FileField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
+            'student_pdf': ('django.db.models.fields.files.FileField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
+            'title': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+            'type': ('django.db.models.fields.CharField', [], {'max_length': '15', 'db_index': 'True'}),
+            'xml_file': ('django.db.models.fields.files.FileField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'})
+        },
+        u'catalogue.lessonstub': {
+            'Meta': {'ordering': "['section', 'level', 'order']", 'object_name': 'LessonStub'},
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'level': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['curriculum.Level']"}),
+            'order': ('django.db.models.fields.IntegerField', [], {'db_index': 'True'}),
+            'section': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['catalogue.Section']", 'null': 'True', 'blank': 'True'}),
+            'title': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+            'type': ('django.db.models.fields.CharField', [], {'max_length': '15', 'db_index': 'True'})
+        },
+        u'catalogue.part': {
+            'Meta': {'object_name': 'Part'},
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'lesson': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['catalogue.Lesson']"}),
+            'pdf': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
+            'student_pdf': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'})
+        },
+        u'catalogue.section': {
+            'Meta': {'ordering': "['order']", 'object_name': 'Section'},
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'image': ('django.db.models.fields.files.ImageField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
+            'order': ('django.db.models.fields.IntegerField', [], {}),
+            'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '255'}),
+            'summary': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
+            'title': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'}),
+            'xml_file': ('django.db.models.fields.files.FileField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'})
+        },
+        u'curriculum.curriculumcourse': {
+            'Meta': {'ordering': "['slug']", 'object_name': 'CurriculumCourse'},
+            'accusative': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'slug': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}),
+            'title': ('django.db.models.fields.CharField', [], {'max_length': '255'})
+        },
+        u'curriculum.level': {
+            'Meta': {'ordering': "['order']", 'object_name': 'Level'},
+            'group_en': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
+            'group_pl': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'name_en': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
+            'name_pl': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
+            'order': ('django.db.models.fields.IntegerField', [], {}),
+            'slug': ('django.db.models.fields.CharField', [], {'max_length': '255'})
+        }
+    }
+
+    complete_apps = ['catalogue']
\ No newline at end of file
diff --git a/src/catalogue/migrations/0015_auto__add_field_lesson_description.py b/src/catalogue/migrations/0015_auto__add_field_lesson_description.py
new file mode 100644 (file)
index 0000000..6d7dd5d
--- /dev/null
@@ -0,0 +1,95 @@
+# -*- coding: utf-8 -*-
+import datetime
+from south.db import db
+from south.v2 import SchemaMigration
+from django.db import models
+
+
+class Migration(SchemaMigration):
+
+    def forwards(self, orm):
+        # Adding field 'Lesson.description'
+        db.add_column(u'catalogue_lesson', 'description',
+                      self.gf('django.db.models.fields.TextField')(null=True, blank=True),
+                      keep_default=False)
+
+
+    def backwards(self, orm):
+        # Deleting field 'Lesson.description'
+        db.delete_column(u'catalogue_lesson', 'description')
+
+
+    models = {
+        u'catalogue.attachment': {
+            'Meta': {'ordering': "['slug', 'ext']", 'unique_together': "(['lesson', 'slug', 'ext'],)", 'object_name': 'Attachment'},
+            'ext': ('django.db.models.fields.CharField', [], {'max_length': '15'}),
+            'file': ('django.db.models.fields.files.FileField', [], {'max_length': '100'}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'lesson': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['catalogue.Lesson']"}),
+            'slug': ('django.db.models.fields.CharField', [], {'max_length': '255'})
+        },
+        u'catalogue.lesson': {
+            'Meta': {'ordering': "['section', 'level', 'order']", 'object_name': 'Lesson'},
+            'curriculum_courses': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['curriculum.CurriculumCourse']", 'symmetrical': 'False', 'blank': 'True'}),
+            'dc': ('jsonfield.fields.JSONField', [], {'default': "'{}'"}),
+            'description': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
+            'html_file': ('django.db.models.fields.files.FileField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'level': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['curriculum.Level']"}),
+            'order': ('django.db.models.fields.IntegerField', [], {'db_index': 'True'}),
+            'package': ('django.db.models.fields.files.FileField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
+            'pdf': ('django.db.models.fields.files.FileField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
+            'section': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['catalogue.Section']", 'null': 'True', 'blank': 'True'}),
+            'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '255'}),
+            'student_package': ('django.db.models.fields.files.FileField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
+            'student_pdf': ('django.db.models.fields.files.FileField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
+            'title': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+            'type': ('django.db.models.fields.CharField', [], {'max_length': '15', 'db_index': 'True'}),
+            'xml_file': ('django.db.models.fields.files.FileField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'})
+        },
+        u'catalogue.lessonstub': {
+            'Meta': {'ordering': "['section', 'level', 'order']", 'object_name': 'LessonStub'},
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'level': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['curriculum.Level']"}),
+            'order': ('django.db.models.fields.IntegerField', [], {'db_index': 'True'}),
+            'section': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['catalogue.Section']", 'null': 'True', 'blank': 'True'}),
+            'title': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+            'type': ('django.db.models.fields.CharField', [], {'max_length': '15', 'db_index': 'True'})
+        },
+        u'catalogue.part': {
+            'Meta': {'object_name': 'Part'},
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'lesson': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['catalogue.Lesson']"}),
+            'pdf': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
+            'student_pdf': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'})
+        },
+        u'catalogue.section': {
+            'Meta': {'ordering': "['order']", 'object_name': 'Section'},
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'image': ('django.db.models.fields.files.ImageField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
+            'order': ('django.db.models.fields.IntegerField', [], {}),
+            'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '255'}),
+            'summary': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
+            'title': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'}),
+            'xml_file': ('django.db.models.fields.files.FileField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'})
+        },
+        u'curriculum.curriculumcourse': {
+            'Meta': {'ordering': "['slug']", 'object_name': 'CurriculumCourse'},
+            'accusative': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'slug': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}),
+            'title': ('django.db.models.fields.CharField', [], {'max_length': '255'})
+        },
+        u'curriculum.level': {
+            'Meta': {'ordering': "['order']", 'object_name': 'Level'},
+            'group_en': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
+            'group_pl': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'name_en': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
+            'name_pl': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
+            'order': ('django.db.models.fields.IntegerField', [], {}),
+            'slug': ('django.db.models.fields.CharField', [], {'max_length': '255'})
+        }
+    }
+
+    complete_apps = ['catalogue']
\ No newline at end of file
diff --git a/src/catalogue/migrations/0016_auto__add_field_section_pic__add_field_section_pic_attribution__add_fi.py b/src/catalogue/migrations/0016_auto__add_field_section_pic__add_field_section_pic_attribution__add_fi.py
new file mode 100644 (file)
index 0000000..6be3fcf
--- /dev/null
@@ -0,0 +1,114 @@
+# -*- coding: utf-8 -*-
+import datetime
+from south.db import db
+from south.v2 import SchemaMigration
+from django.db import models
+
+
+class Migration(SchemaMigration):
+
+    def forwards(self, orm):
+        # Adding field 'Section.pic'
+        db.add_column(u'catalogue_section', 'pic',
+                      self.gf('django.db.models.fields.files.ImageField')(max_length=100, null=True, blank=True),
+                      keep_default=False)
+
+        # Adding field 'Section.pic_attribution'
+        db.add_column(u'catalogue_section', 'pic_attribution',
+                      self.gf('django.db.models.fields.CharField')(max_length=255, null=True, blank=True),
+                      keep_default=False)
+
+        # Adding field 'Section.pic_src'
+        db.add_column(u'catalogue_section', 'pic_src',
+                      self.gf('django.db.models.fields.URLField')(max_length=200, null=True, blank=True),
+                      keep_default=False)
+
+
+    def backwards(self, orm):
+        # Deleting field 'Section.pic'
+        db.delete_column(u'catalogue_section', 'pic')
+
+        # Deleting field 'Section.pic_attribution'
+        db.delete_column(u'catalogue_section', 'pic_attribution')
+
+        # Deleting field 'Section.pic_src'
+        db.delete_column(u'catalogue_section', 'pic_src')
+
+
+    models = {
+        u'catalogue.attachment': {
+            'Meta': {'ordering': "['slug', 'ext']", 'unique_together': "(['lesson', 'slug', 'ext'],)", 'object_name': 'Attachment'},
+            'ext': ('django.db.models.fields.CharField', [], {'max_length': '15'}),
+            'file': ('django.db.models.fields.files.FileField', [], {'max_length': '100'}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'lesson': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['catalogue.Lesson']"}),
+            'slug': ('django.db.models.fields.CharField', [], {'max_length': '255'})
+        },
+        u'catalogue.lesson': {
+            'Meta': {'ordering': "['section', 'level', 'order']", 'object_name': 'Lesson'},
+            'curriculum_courses': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['curriculum.CurriculumCourse']", 'symmetrical': 'False', 'blank': 'True'}),
+            'dc': ('jsonfield.fields.JSONField', [], {'default': "'{}'"}),
+            'description': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
+            'html_file': ('django.db.models.fields.files.FileField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'level': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['curriculum.Level']"}),
+            'order': ('django.db.models.fields.IntegerField', [], {'db_index': 'True'}),
+            'package': ('django.db.models.fields.files.FileField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
+            'pdf': ('django.db.models.fields.files.FileField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
+            'section': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['catalogue.Section']", 'null': 'True', 'blank': 'True'}),
+            'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '255'}),
+            'student_package': ('django.db.models.fields.files.FileField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
+            'student_pdf': ('django.db.models.fields.files.FileField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
+            'title': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+            'type': ('django.db.models.fields.CharField', [], {'max_length': '15', 'db_index': 'True'}),
+            'xml_file': ('django.db.models.fields.files.FileField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'})
+        },
+        u'catalogue.lessonstub': {
+            'Meta': {'ordering': "['section', 'level', 'order']", 'object_name': 'LessonStub'},
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'level': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['curriculum.Level']"}),
+            'order': ('django.db.models.fields.IntegerField', [], {'db_index': 'True'}),
+            'section': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['catalogue.Section']", 'null': 'True', 'blank': 'True'}),
+            'title': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+            'type': ('django.db.models.fields.CharField', [], {'max_length': '15', 'db_index': 'True'})
+        },
+        u'catalogue.part': {
+            'Meta': {'object_name': 'Part'},
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'lesson': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['catalogue.Lesson']"}),
+            'pdf': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
+            'student_pdf': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'})
+        },
+        u'catalogue.section': {
+            'Meta': {'ordering': "['order']", 'object_name': 'Section'},
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'image': ('django.db.models.fields.files.ImageField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
+            'order': ('django.db.models.fields.IntegerField', [], {}),
+            'pic': ('django.db.models.fields.files.ImageField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
+            'pic_attribution': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
+            'pic_src': ('django.db.models.fields.URLField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}),
+            'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '255'}),
+            'summary': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
+            'title': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'}),
+            'xml_file': ('django.db.models.fields.files.FileField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'})
+        },
+        u'curriculum.curriculumcourse': {
+            'Meta': {'ordering': "['slug']", 'object_name': 'CurriculumCourse'},
+            'accusative': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'slug': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}),
+            'title': ('django.db.models.fields.CharField', [], {'max_length': '255'})
+        },
+        u'curriculum.level': {
+            'Meta': {'ordering': "['order']", 'object_name': 'Level'},
+            'group_en': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
+            'group_pl': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'name_en': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
+            'name_pl': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
+            'order': ('django.db.models.fields.IntegerField', [], {}),
+            'slug': ('django.db.models.fields.CharField', [], {'max_length': '255'})
+        }
+    }
+
+    complete_apps = ['catalogue']
\ No newline at end of file
diff --git a/src/catalogue/migrations/0017_auto__chg_field_attachment_file.py b/src/catalogue/migrations/0017_auto__chg_field_attachment_file.py
new file mode 100644 (file)
index 0000000..dbe1123
--- /dev/null
@@ -0,0 +1,99 @@
+# -*- coding: utf-8 -*-
+from south.utils import datetime_utils as datetime
+from south.db import db
+from south.v2 import SchemaMigration
+from django.db import models
+
+
+class Migration(SchemaMigration):
+
+    def forwards(self, orm):
+
+        # Changing field 'Attachment.file'
+        db.alter_column(u'catalogue_attachment', 'file', self.gf('django.db.models.fields.files.FileField')(max_length=255))
+
+    def backwards(self, orm):
+
+        # Changing field 'Attachment.file'
+        db.alter_column(u'catalogue_attachment', 'file', self.gf('django.db.models.fields.files.FileField')(max_length=100))
+
+    models = {
+        u'catalogue.attachment': {
+            'Meta': {'ordering': "['slug', 'ext']", 'unique_together': "(['lesson', 'slug', 'ext'],)", 'object_name': 'Attachment'},
+            'ext': ('django.db.models.fields.CharField', [], {'max_length': '15'}),
+            'file': ('django.db.models.fields.files.FileField', [], {'max_length': '255'}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'lesson': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['catalogue.Lesson']"}),
+            'slug': ('django.db.models.fields.CharField', [], {'max_length': '255'})
+        },
+        u'catalogue.lesson': {
+            'Meta': {'ordering': "['section', 'level', 'order']", 'object_name': 'Lesson'},
+            'curriculum_courses': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['curriculum.CurriculumCourse']", 'symmetrical': 'False', 'blank': 'True'}),
+            'dc': ('jsonfield.fields.JSONField', [], {'default': "'{}'"}),
+            'description': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
+            'html_file': ('django.db.models.fields.files.FileField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'level': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['curriculum.Level']"}),
+            'order': ('django.db.models.fields.IntegerField', [], {'db_index': 'True'}),
+            'package': ('django.db.models.fields.files.FileField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
+            'pdf': ('django.db.models.fields.files.FileField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
+            'section': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['catalogue.Section']", 'null': 'True', 'blank': 'True'}),
+            'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '255'}),
+            'student_package': ('django.db.models.fields.files.FileField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
+            'student_pdf': ('django.db.models.fields.files.FileField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
+            'title': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+            'type': ('django.db.models.fields.CharField', [], {'max_length': '15', 'db_index': 'True'}),
+            'xml_file': ('django.db.models.fields.files.FileField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'})
+        },
+        u'catalogue.lessonstub': {
+            'Meta': {'ordering': "['section', 'level', 'order']", 'object_name': 'LessonStub'},
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'level': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['curriculum.Level']"}),
+            'order': ('django.db.models.fields.IntegerField', [], {'db_index': 'True'}),
+            'section': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['catalogue.Section']", 'null': 'True', 'blank': 'True'}),
+            'title': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+            'type': ('django.db.models.fields.CharField', [], {'max_length': '15', 'db_index': 'True'})
+        },
+        u'catalogue.part': {
+            'Meta': {'object_name': 'Part'},
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'lesson': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['catalogue.Lesson']"}),
+            'pdf': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
+            'student_pdf': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'})
+        },
+        u'catalogue.section': {
+            'Meta': {'ordering': "['order']", 'object_name': 'Section'},
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'image': ('django.db.models.fields.files.ImageField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
+            'order': ('django.db.models.fields.IntegerField', [], {}),
+            'pic': ('django.db.models.fields.files.ImageField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
+            'pic_attribution': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
+            'pic_src': ('django.db.models.fields.URLField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}),
+            'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '255'}),
+            'summary': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
+            'title': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'}),
+            'xml_file': ('django.db.models.fields.files.FileField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'})
+        },
+        u'curriculum.curriculumcourse': {
+            'Meta': {'ordering': "['slug']", 'object_name': 'CurriculumCourse'},
+            'accusative': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'slug': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}),
+            'title': ('django.db.models.fields.CharField', [], {'max_length': '255'})
+        },
+        u'curriculum.level': {
+            'Meta': {'ordering': "['order']", 'object_name': 'Level'},
+            'group_en': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
+            'group_pl': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'meta_name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'}),
+            'name_en': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
+            'name_pl': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
+            'order': ('django.db.models.fields.IntegerField', [], {}),
+            'package': ('django.db.models.fields.files.FileField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
+            'slug': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'}),
+            'student_package': ('django.db.models.fields.files.FileField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'})
+        }
+    }
+
+    complete_apps = ['catalogue']
\ No newline at end of file
diff --git a/src/catalogue/migrations/0018_auto__add_field_lesson_weasy_pdf.py b/src/catalogue/migrations/0018_auto__add_field_lesson_weasy_pdf.py
new file mode 100644 (file)
index 0000000..440b908
--- /dev/null
@@ -0,0 +1,102 @@
+# -*- coding: utf-8 -*-
+from south.utils import datetime_utils as datetime
+from south.db import db
+from south.v2 import SchemaMigration
+from django.db import models
+
+
+class Migration(SchemaMigration):
+
+    def forwards(self, orm):
+        # Adding field 'Lesson.weasy_pdf'
+        db.add_column(u'catalogue_lesson', 'weasy_pdf',
+                      self.gf('django.db.models.fields.files.FileField')(max_length=255, null=True, blank=True),
+                      keep_default=False)
+
+
+    def backwards(self, orm):
+        # Deleting field 'Lesson.weasy_pdf'
+        db.delete_column(u'catalogue_lesson', 'weasy_pdf')
+
+
+    models = {
+        u'catalogue.attachment': {
+            'Meta': {'ordering': "['slug', 'ext']", 'unique_together': "(['lesson', 'slug', 'ext'],)", 'object_name': 'Attachment'},
+            'ext': ('django.db.models.fields.CharField', [], {'max_length': '15'}),
+            'file': ('django.db.models.fields.files.FileField', [], {'max_length': '255'}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'lesson': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['catalogue.Lesson']"}),
+            'slug': ('django.db.models.fields.CharField', [], {'max_length': '255'})
+        },
+        u'catalogue.lesson': {
+            'Meta': {'ordering': "['section', 'level', 'order']", 'object_name': 'Lesson'},
+            'curriculum_courses': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['curriculum.CurriculumCourse']", 'symmetrical': 'False', 'blank': 'True'}),
+            'dc': ('jsonfield.fields.JSONField', [], {'default': "'{}'"}),
+            'description': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
+            'html_file': ('django.db.models.fields.files.FileField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'level': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['curriculum.Level']"}),
+            'order': ('django.db.models.fields.IntegerField', [], {'db_index': 'True'}),
+            'package': ('django.db.models.fields.files.FileField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
+            'pdf': ('django.db.models.fields.files.FileField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
+            'section': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['catalogue.Section']", 'null': 'True', 'blank': 'True'}),
+            'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '255'}),
+            'student_package': ('django.db.models.fields.files.FileField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
+            'student_pdf': ('django.db.models.fields.files.FileField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
+            'title': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+            'type': ('django.db.models.fields.CharField', [], {'max_length': '15', 'db_index': 'True'}),
+            'weasy_pdf': ('django.db.models.fields.files.FileField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
+            'xml_file': ('django.db.models.fields.files.FileField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'})
+        },
+        u'catalogue.lessonstub': {
+            'Meta': {'ordering': "['section', 'level', 'order']", 'object_name': 'LessonStub'},
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'level': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['curriculum.Level']"}),
+            'order': ('django.db.models.fields.IntegerField', [], {'db_index': 'True'}),
+            'section': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['catalogue.Section']", 'null': 'True', 'blank': 'True'}),
+            'title': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+            'type': ('django.db.models.fields.CharField', [], {'max_length': '15', 'db_index': 'True'})
+        },
+        u'catalogue.part': {
+            'Meta': {'object_name': 'Part'},
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'lesson': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['catalogue.Lesson']"}),
+            'pdf': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
+            'student_pdf': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'})
+        },
+        u'catalogue.section': {
+            'Meta': {'ordering': "['order']", 'object_name': 'Section'},
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'image': ('django.db.models.fields.files.ImageField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
+            'order': ('django.db.models.fields.IntegerField', [], {}),
+            'pic': ('django.db.models.fields.files.ImageField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
+            'pic_attribution': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
+            'pic_src': ('django.db.models.fields.URLField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}),
+            'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '255'}),
+            'summary': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
+            'title': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'}),
+            'xml_file': ('django.db.models.fields.files.FileField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'})
+        },
+        u'curriculum.curriculumcourse': {
+            'Meta': {'ordering': "['slug']", 'object_name': 'CurriculumCourse'},
+            'accusative': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'slug': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}),
+            'title': ('django.db.models.fields.CharField', [], {'max_length': '255'})
+        },
+        u'curriculum.level': {
+            'Meta': {'ordering': "['order']", 'object_name': 'Level'},
+            'group_en': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
+            'group_pl': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'meta_name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'}),
+            'name_en': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
+            'name_pl': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
+            'order': ('django.db.models.fields.IntegerField', [], {}),
+            'package': ('django.db.models.fields.files.FileField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
+            'slug': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'}),
+            'student_package': ('django.db.models.fields.files.FileField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'})
+        }
+    }
+
+    complete_apps = ['catalogue']
\ No newline at end of file
diff --git a/src/catalogue/migrations/__init__.py b/src/catalogue/migrations/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/src/catalogue/models.py b/src/catalogue/models.py
new file mode 100644 (file)
index 0000000..c73c762
--- /dev/null
@@ -0,0 +1,350 @@
+# -*- coding: utf-8
+from django.conf import settings
+from django.core.files import File
+from django.core.urlresolvers import reverse
+from django.db import models
+from jsonfield import JSONField
+from fnpdjango.storage import BofhFileSystemStorage
+
+from curriculum.models import Level, Curriculum, CurriculumCourse
+import logging
+
+bofh_storage = BofhFileSystemStorage()
+
+
+class Section(models.Model):
+    title = models.CharField(max_length=255, unique=True)
+    slug = models.SlugField(max_length=255, unique=True)
+    order = models.IntegerField()
+    xml_file = models.FileField(
+        upload_to="catalogue/section/xml",
+        null=True, blank=True, max_length=255,
+        storage=bofh_storage)
+    image = models.ImageField(upload_to="catalogue/section/image", null=True, blank=True)
+
+    pic = models.ImageField(upload_to="catalogue/section/pic", null=True, blank=True)
+    pic_attribution = models.CharField(max_length=255, null=True, blank=True)
+    pic_src = models.URLField(null=True, blank=True)
+    
+    summary = models.TextField(blank=True, null=True)
+
+    class Meta:
+        ordering = ['order']
+
+    class IncompleteError(BaseException):
+        pass
+
+    def __unicode__(self):
+        return self.title
+
+    def get_absolute_url(self):
+        return "%s#gimnazjum_%s" % (reverse("catalogue_lessons"), self.slug)
+
+    @classmethod
+    def publish(cls, infile, ignore_incomplete=False):
+        from librarian.parser import WLDocument
+        from django.core.files.base import ContentFile
+        xml = infile.get_string()
+        wldoc = WLDocument.from_string(xml)
+
+        lessons = []
+        for part in wldoc.book_info.parts:
+            try:
+                lessons.append(Lesson.objects.get(slug=part.slug))
+            except Lesson.DoesNotExist, e:
+                if not ignore_incomplete:
+                    raise cls.IncompleteError(part.slug)
+
+        slug = wldoc.book_info.url.slug
+        try:
+            section = cls.objects.get(slug=slug)
+        except cls.DoesNotExist:
+            section = cls(slug=slug, order=0)
+
+        # Save XML file
+        section.xml_file.save('%s.xml' % slug, ContentFile(xml), save=False)
+        section.title = wldoc.book_info.title
+        section.save()
+
+        section.lesson_set.all().update(section=None)
+        for i, lesson in enumerate(lessons):
+            lesson.section = section
+            lesson.order = i
+            lesson.save()
+
+        return section
+
+    def syntetic_lesson(self, level):
+        try:
+            return self.lesson_set.filter(type='synthetic', level=level)[0]
+        except IndexError:
+            return None
+
+
+class Lesson(models.Model):
+    section = models.ForeignKey(Section, null=True, blank=True)
+    level = models.ForeignKey(Level)
+    title = models.CharField(max_length=255)
+    slug = models.SlugField(max_length=255, unique=True)
+    type = models.CharField(max_length=15, db_index=True)
+    order = models.IntegerField(db_index=True)
+    dc = JSONField(default='{}')
+    curriculum_courses = models.ManyToManyField(CurriculumCourse, blank=True)
+    description = models.TextField(null=True, blank=True)
+
+    xml_file = models.FileField(
+        upload_to="catalogue/lesson/xml",
+        null=True, blank=True, max_length=255, storage=bofh_storage)
+    html_file = models.FileField(
+        upload_to="catalogue/lesson/html",
+        null=True, blank=True, max_length=255, storage=bofh_storage)
+    package = models.FileField(
+        upload_to="catalogue/lesson/pack",
+        null=True, blank=True, max_length=255, storage=bofh_storage)
+    student_package = models.FileField(
+        upload_to="catalogue/lesson/student_pack",
+        null=True, blank=True, max_length=255, storage=bofh_storage)
+    pdf = models.FileField(
+        upload_to="catalogue/lesson/pdf",
+        null=True, blank=True, max_length=255, storage=bofh_storage)
+    student_pdf = models.FileField(
+        upload_to="catalogue/lesson/student_pdf",
+        null=True, blank=True, max_length=255, storage=bofh_storage)
+    weasy_pdf = models.FileField(
+        upload_to="catalogue/lesson/weasy",
+        null=True, blank=True, max_length=255, storage=bofh_storage)
+
+    class Meta:
+        ordering = ['section', 'level', 'order']
+
+    def __unicode__(self):
+        return self.title
+
+    @models.permalink
+    def get_absolute_url(self):
+        return 'catalogue_lesson', [self.slug]
+
+    @classmethod
+    def publish(cls, infile, ignore_incomplete=False, repackage_level=False):
+        from librarian.parser import WLDocument
+        from django.core.files.base import ContentFile
+        wldoc = WLDocument(infile)
+
+        # Check if not section metadata block.
+        if wldoc.book_info.parts:
+            return Section.publish(infile, ignore_incomplete=ignore_incomplete)
+
+        slug = wldoc.book_info.url.slug
+        try:
+            lesson = cls.objects.get(slug=slug)
+            lesson.attachment_set.all().delete()
+        except cls.DoesNotExist:
+            lesson = cls(slug=slug, order=0)
+
+        # Save XML file
+        lesson.xml_file.save('%s.xml' % slug, ContentFile(infile.get_string()), save=False)
+        lesson.title = wldoc.book_info.title
+
+        lesson.level = Level.objects.get(meta_name=wldoc.book_info.audience)
+        lesson.populate_dc()
+        lesson.populate_description(wldoc=wldoc)
+        lesson.build_html(infile=infile)
+        lesson.build_pdf()
+        lesson.build_package()
+        if lesson.type != 'project':
+            lesson.build_pdf(student=True)
+            lesson.build_package(student=True)
+        if repackage_level:
+            lesson.level.build_packages()
+        return lesson
+
+    def republish(self, repackage_level=True, attachments=None):
+        from librarian import IOFile
+        import os.path
+        from django.conf import settings
+        if attachments is None:
+            attachments = {}
+            for attachment in self.attachment_set.all():
+                full_name = os.path.join(settings.MEDIA_ROOT, attachment.file.name)
+                f = IOFile.from_filename(full_name)
+                attachments['%s.%s' % (attachment.slug, attachment.ext)] = f
+        infile = IOFile.from_filename(self.xml_file.path, attachments=attachments)
+        Lesson.publish(infile, repackage_level=repackage_level)
+
+    def populate_dc(self):
+        from librarian.parser import WLDocument
+        wldoc = WLDocument.from_file(self.xml_file.path)
+        self.dc = wldoc.book_info.to_dict()
+        self.type = self.dc["type"]
+        assert self.type in ('appendix', 'course', 'synthetic', 'project', 'added', 'added-var'), \
+            u"Unknown lesson type: %s" % self.type
+        self.save()
+
+        courses = set()
+        for identifier in wldoc.book_info.curriculum:
+            identifier = (identifier or "").replace(' ', '')
+            if not identifier:
+                continue
+            try:
+                curr = Curriculum.objects.get(identifier__iexact=identifier)
+            except Curriculum.DoesNotExist:
+                logging.warn('Unknown curriculum course %s in lesson %s' % (identifier, self.slug))
+                pass
+            else:
+                courses.add(curr.course)
+        self.curriculum_courses = courses
+
+    def populate_description(self, wldoc=None, infile=None):
+        if wldoc is None:
+            wldoc = self.wldocument(infile)
+        if self.type == 'project':
+            lookup = u'Zadanie'
+        else:
+            lookup = u'Pomysł na lekcję'
+        for header in wldoc.edoc.findall('.//naglowek_rozdzial'):
+            if (header.text or '').strip() == lookup:
+                from lxml import etree
+                self.description = etree.tostring(
+                    header.getnext(), method='text', encoding='unicode').strip()
+                self.save()
+                return
+
+    def wldocument(self, infile=None):
+        from librarian import IOFile
+        from librarian.parser import WLDocument
+        from .publish import OrmDocProvider
+
+        if infile is None:
+            infile = IOFile.from_filename(self.xml_file.path)
+            for att in self.attachment_set.all():
+                infile.attachments["%s.%s" % (att.slug, att.ext)] = \
+                    IOFile.from_filename(att.file.path)
+        return WLDocument(infile, provider=OrmDocProvider())
+
+    def build_html(self, infile=None):
+        from .publish import HtmlFormat
+        wldoc = self.wldocument(infile)
+        html = HtmlFormat(wldoc).build()
+        self.html_file.save("%s.html" % self.slug, File(open(html.get_filename())))
+
+    def build_pdf(self, student=False):
+        from .publish import PdfFormat
+        # PDF uses document with attachments already saved as media,
+        # otherwise sorl.thumbnail complains about SuspiciousOperations.
+        wldoc = self.wldocument()
+        if student:
+            pdf = PdfFormat(wldoc).build()
+            self.student_pdf.save("%s.pdf" % self.slug, File(open(pdf.get_filename())))
+        else:
+            pdf = PdfFormat(wldoc, teacher=True).build()
+            self.pdf.save("%s.pdf" % self.slug, File(open(pdf.get_filename())))
+
+    def build_pdf_from_html(self, **kwargs):
+        from .publish import PdfFromHtmlFormat
+        wldoc = self.wldocument()
+        pdf = PdfFromHtmlFormat(
+            wldoc, media_root=settings.MEDIA_ROOT,
+            html_to_pdf_command=settings.HTML_TO_PDF_COMMAND,
+            **kwargs).build()
+        self.weasy_pdf.save("%s.pdf" % self.slug, File(open(pdf.get_filename())))
+
+    def add_to_zip(self, zipf, student=False, prefix=''):
+        pdf = self.student_pdf if student else self.pdf
+        if pdf:
+            zipf.write(pdf.path, "%s%s%s.pdf" % (prefix, self.slug, "_student" if student else ""))
+            for attachment in self.attachment_set.all():
+                zipf.write(attachment.file.path, u"%smaterialy/%s.%s" % (prefix, attachment.slug, attachment.ext))
+            zipf.write(self.xml_file.path, "%spliki-zrodlowe/%s.xml" % (prefix, self.slug))
+
+    def build_package(self, student=False):
+        from StringIO import StringIO
+        import zipfile
+        from django.core.files.base import ContentFile
+        buff = StringIO()
+        zipf = zipfile.ZipFile(buff, 'w', zipfile.ZIP_STORED)
+        self.add_to_zip(zipf, student)
+        zipf.close()
+        fieldname = "student_package" if student else "package"
+        getattr(self, fieldname).save(
+            "%s%s.zip" % (self.slug, "_student" if student else ""),
+            ContentFile(buff.getvalue()))
+
+    def get_syntetic(self):
+        if self.section is None:
+            return None
+        return self.section.syntetic_lesson(self.level)
+
+    def get_other_level(self):
+        if self.section is None:
+            return None
+        other_levels = self.section.lesson_set.exclude(level=self.level)
+        if other_levels.exists():
+            return other_levels[0].level
+
+    def get_previous(self):
+        if self.section is None:
+            return None
+        try:
+            return self.section.lesson_set.filter(
+                type=self.type, level=self.level,
+                order__lt=self.order).order_by('-order')[0]
+        except IndexError:
+            return None
+
+    def get_next(self):
+        if self.section is None:
+            return None
+        try:
+            return self.section.lesson_set.filter(
+                type=self.type, level=self.level,
+                order__gt=self.order).order_by('order')[0]
+        except IndexError:
+            return None
+
+    def requires_internet(self):
+        return any(requirement in self.dc.get('requires', []) for requirement in ('internet', 'Internet'))
+
+
+def attachment_path(instance, filename):
+    return 'catalogue/attachment/%s/%s' % (instance.lesson.slug, filename)
+
+
+class Attachment(models.Model):
+    slug = models.CharField(max_length=255)
+    ext = models.CharField(max_length=15)
+    lesson = models.ForeignKey(Lesson)
+    file = models.FileField(upload_to=attachment_path, storage=bofh_storage, max_length=255)
+
+    class Meta:
+        ordering = ['slug', 'ext']
+        unique_together = ['lesson', 'slug', 'ext']
+
+    def __unicode__(self):
+        return "%s.%s" % (self.slug, self.ext)
+
+
+class Part(models.Model):
+    lesson = models.ForeignKey(Lesson)
+    pdf = models.FileField(upload_to="catalogue/part/pdf", null=True, blank=True)
+    student_pdf = models.FileField(upload_to="catalogue/part/student_pdf", null=True, blank=True)
+
+
+class LessonStub(models.Model):
+    section = models.ForeignKey(Section, null=True, blank=True)
+    level = models.ForeignKey(Level)
+    title = models.CharField(max_length=255)
+    type = models.CharField(max_length=15, db_index=True)
+    order = models.IntegerField(db_index=True)
+
+    class Meta:
+        ordering = ['section', 'level', 'order']
+
+    def __unicode__(self):
+        return self.title
+
+    @property
+    def slug(self):
+        return ''
+
+    def add_to_zip(self, *args, **kwargs):
+        pass
diff --git a/src/catalogue/publish.py b/src/catalogue/publish.py
new file mode 100755 (executable)
index 0000000..293b89e
--- /dev/null
@@ -0,0 +1,174 @@
+# -*- coding: utf-8
+from django.core.files import File
+from django.core.urlresolvers import reverse
+from librarian import DocProvider, IOFile
+from librarian.pyhtml import EduModuleFormat
+from librarian.pypdf import EduModulePDFFormat
+from librarian.pdf_from_html import EduModulePdfFromHtmlFormat
+from .models import Lesson, Attachment
+from fnpdjango.utils.text.slughifi import slughifi
+
+
+# TODO: Using sorl.thumbnail for now,
+# but this should be done in Librarian,
+# directly using convert or PIL as a fallback.
+def get_image(src_img_path, width=None, default_width=1600, formats=('PNG', 'JPEG', 'GIF')):
+    """ Returns an object with `url` and `storage` attributes,
+        or None if using the original image is OK.
+    """
+
+    from PIL import Image
+    from sorl.thumbnail import get_thumbnail
+
+    # Does it need converting?
+    # Yes, if width is given explicitly.
+    convert = width is not None
+    if not convert:
+        # Looks like it doesn't need converting.
+        # But let's try opening it and checking its type.
+        try:
+            simg = Image.open(src_img_path)
+        except IOError:
+            # It doesn't look like image,
+            # but maybe it's convertable to one.
+            convert = True
+        else:
+            if simg.format not in formats:
+                # It's an image, but it's in some weird format.
+                convert = True
+                width = simg.size[0]
+
+    if convert:
+        if width is None:
+            width = default_width
+        try:
+            return get_thumbnail(src_img_path, '%sx%s' % (width, 10*width))
+        except:
+            # hard to predict what solr raises on invalid image
+            return None
+    else:
+        return None
+
+
+class HtmlFormat(EduModuleFormat):
+    IMAGE_FORMATS = ('PNG', 'JPEG', 'GIF')
+    DEFAULT_IMAGE_WIDTH = 1600
+
+    def find_attachment(self, slug, fmt):
+        lesson_slug = self.wldoc.book_info.url.slug
+        try:
+            # If already saved, use it.
+            att = Attachment.objects.get(lesson__slug=lesson_slug,
+                                         slug=slug, ext=fmt)
+        except Attachment.DoesNotExist, e:
+            # If attached to source IOFile, save now.
+            att_name = "%s.%s" % (slug, fmt)
+            try:
+                att_file = self.wldoc.source.attachments[att_name]
+            except KeyError:
+                print u"ATTACHMENT MISSING:", att_name
+                raise self.MaterialNotFound()
+            else:
+                lesson = Lesson.objects.get(slug=lesson_slug)
+                att = lesson.attachment_set.create(slug=slug, ext=fmt)
+                att.file.save(att_name, File(att_file.get_file()))
+                return att
+        else:
+            return att
+
+    def url_for_material(self, slug, fmt):
+        return self.find_attachment(slug, fmt).file.url
+
+    def url_for_image(self, slug, fmt, width=None):
+        try:
+            src_img = self.find_attachment(slug, fmt).file
+        except self.MaterialNotFound:
+            return ''
+        img = get_image(src_img.path, width, self.DEFAULT_IMAGE_WIDTH, self.IMAGE_FORMATS)
+        return (img or src_img).url
+
+    def text_to_anchor(self, text):
+        return slughifi(text)
+
+    def get_forma_url(self, forma):
+        return '%s#%s' % (
+            reverse('catalogue_lesson', args=['metody']),
+            self.text_to_anchor(forma)
+        )
+
+    def get_help_url(self, naglowek):
+        return '%s%s#%s' % (
+            '//edukacjamedialna.edu.pl',
+            reverse('info', args=['jak-korzystac/']),
+            self.naglowek_to_anchor(naglowek)
+        )
+
+
+class PdfFormat(EduModulePDFFormat):
+    IMAGE_FORMATS = ('PNG', 'JPEG', 'GIF')
+    DEFAULT_IMAGE_WIDTH = 1600
+
+    def get_image(self, name):
+        src_img = super(PdfFormat, self).get_image(name)
+        img = get_image(
+            src_img.get_filename(),
+            default_width=self.DEFAULT_IMAGE_WIDTH,
+            formats=self.IMAGE_FORMATS)
+        if img:
+            return IOFile.from_filename(img.storage.path(img))
+        else:
+            return src_img
+
+
+class PdfFromHtmlFormat(EduModulePdfFromHtmlFormat):
+    IMAGE_FORMATS = ('PNG', 'JPEG', 'GIF')
+    DEFAULT_IMAGE_WIDTH = 1600
+
+    def find_attachment(self, slug, fmt):
+        lesson_slug = self.wldoc.book_info.url.slug
+        try:
+            # If already saved, use it.
+            att = Attachment.objects.get(lesson__slug=lesson_slug,
+                                         slug=slug, ext=fmt)
+        except Attachment.DoesNotExist, e:
+            # If attached to source IOFile, save now.
+            att_name = "%s.%s" % (slug, fmt)
+            try:
+                att_file = self.wldoc.source.attachments[att_name]
+            except KeyError:
+                print u"ATTACHMENT MISSING:", att_name
+                raise self.MaterialNotFound()
+            else:
+                lesson = Lesson.objects.get(slug=lesson_slug)
+                att = lesson.attachment_set.create(slug=slug, ext=fmt)
+                att.file.save(att_name, File(att_file.get_file()))
+                return att
+        else:
+            return att
+
+    def url_for_material(self, slug, fmt):
+        return self.find_attachment(slug, fmt).file.url
+
+    def image(self, slug, fmt, width=None):
+        try:
+            src_img = self.find_attachment(slug, fmt).file
+        except self.MaterialNotFound:
+            return None
+        img = get_image(src_img.path, width, self.DEFAULT_IMAGE_WIDTH, self.IMAGE_FORMATS)
+        return img or src_img
+
+    def url_for_image(self, slug, fmt, image=None, **kwargs):
+        img = image or self.image(slug, fmt, **kwargs)
+        if img:
+            return img.url
+        else:
+            return ''
+
+    def text_to_anchor(self, text):
+        return slughifi(text)
+
+
+class OrmDocProvider(DocProvider):
+    def by_slug(self, slug):
+        """Should return a file-like object with a WL document XML."""
+        return IOFile.from_filename(Lesson.objects.get(slug=slug).xml_file.path)
diff --git a/src/catalogue/search_indexes.py b/src/catalogue/search_indexes.py
new file mode 100755 (executable)
index 0000000..035ce98
--- /dev/null
@@ -0,0 +1,10 @@
+# -*- coding: utf-8 -*-
+from haystack import indexes
+from .models import Lesson
+
+
+class LessonIndex(indexes.SearchIndex, indexes.Indexable):
+    text = indexes.CharField(document=True, use_template=True)
+
+    def get_model(self):
+        return Lesson
diff --git a/src/catalogue/static/catalogue/css/carousel.css b/src/catalogue/static/catalogue/css/carousel.css
new file mode 100644 (file)
index 0000000..992e285
--- /dev/null
@@ -0,0 +1,110 @@
+#catalogue-carousel {
+  float: left;
+  position: relative;
+  width: 43.75em;
+  height: 14.6875em;
+  overflow: hidden;
+  border-radius: 0.9375em;
+}
+  #catalogue-carousel #catalogue-carousel-links {
+    width: 28.75em;
+    height: 14.6875em;
+    list-style: none;
+    margin: 0;
+    padding: 0; }
+    #catalogue-carousel #catalogue-carousel-links li {
+      display: block;
+      position: absolute;
+      top: 0;
+      left: 0;
+      height: 100%;
+      background-size: 100% 100%;
+      border-top-left-radius: 0.9375em 6.38%;
+      border-bottom-left-radius: 0.9375em 6.38%;
+      z-index: 100;
+      background-color: #888; }
+      #catalogue-carousel #catalogue-carousel-links li a.catalogue-carousel-link {
+        display: block;
+        overflow: hidden;
+        width: 28.75em;
+        height: 100%;
+        background: url(/static/catalogue/img/carousel-left.png) 100% 0 no-repeat;
+        background-size: 4.375em 100%; }
+        #catalogue-carousel #catalogue-carousel-links li a.catalogue-carousel-link .catalogue-carousel-note {
+          position: relative;
+          height: 100%;
+          color: white;
+          margin-top: 8.5em; }
+          #catalogue-carousel #catalogue-carousel-links li a.catalogue-carousel-link .catalogue-carousel-note div:before {
+            content: " ";
+            display: block;
+            position: absolute;
+            height: 100%;
+            width: 100%;
+            z-index: -1;
+            background-color: black;
+            opacity: 0.6; }
+          #catalogue-carousel #catalogue-carousel-links li a.catalogue-carousel-link .catalogue-carousel-note div p {
+            padding: .4em 3em 0 .5em; }
+            #catalogue-carousel #catalogue-carousel-links li a.catalogue-carousel-link .catalogue-carousel-note div p strong {
+              font-size: 1.2em;
+              display: block; }
+            #catalogue-carousel #catalogue-carousel-links li a.catalogue-carousel-link .catalogue-carousel-note div p .more {
+              position: absolute;
+              right: 4em;
+              top: 4.5em; }
+      #catalogue-carousel #catalogue-carousel-links li a.catalogue-carousel-link:active {
+        outline: none; }
+      #catalogue-carousel #catalogue-carousel-links li .attribution {
+        text-align: right;
+        font-size: .75em;
+        position: absolute;
+        right: 5em;
+        top: .1em;
+        color: white;
+        font-weight: bold;
+        text-shadow: 0 0 5px #000; }
+  #catalogue-carousel #catalogue-carousel-switcher {
+    margin: 0;
+    padding: 0.1875em 0 0 3.625em;
+    width: 11.375em;
+    height: 14.6875em;
+    position: absolute;
+    right: 0;
+    top: 0;
+    list-style: none;
+    border-radius: 0 0.9375em 0.9375em 0;
+    background-color: #ed7831;
+    background-image: url(/static/catalogue/img/carousel-right.png);
+    background-position: 0 0;
+    background-repeat: no-repeat;
+    background-size: auto 14.6875em;
+    /* right part of mask as background */ }
+    #catalogue-carousel #catalogue-carousel-switcher li {
+      margin-bottom: .4em;
+      font-size: .85em;
+      line-height: 1em; }
+      #catalogue-carousel #catalogue-carousel-switcher li a {
+        text-transform: uppercase;
+        color: #363a3e; }
+      #catalogue-carousel #catalogue-carousel-switcher li a:before {
+        vertical-align: top;
+        margin-right: 1.5em; }
+      #catalogue-carousel #catalogue-carousel-switcher li .knowledge:before {
+        content: url(/static/img/icons/knowledge_dark.png); }
+      #catalogue-carousel #catalogue-carousel-switcher li .activity:before {
+        content: url(/static/img/icons/activity_dark.png); }
+      #catalogue-carousel #catalogue-carousel-switcher li .lesson-plan:before {
+        content: url(/static/img/icons/lesson-plan_dark.png); }
+      #catalogue-carousel #catalogue-carousel-switcher li .reference:before {
+        content: url(/static/img/icons/reference_dark.png); }
+    #catalogue-carousel #catalogue-carousel-switcher li.activeSlide a {
+      color: white; }
+    #catalogue-carousel #catalogue-carousel-switcher li.activeSlide .knowledge:before {
+      content: url(/static/img/icons/knowledge_white.png); }
+    #catalogue-carousel #catalogue-carousel-switcher li.activeSlide .activity:before {
+      content: url(/static/img/icons/activity_white.png); }
+    #catalogue-carousel #catalogue-carousel-switcher li.activeSlide .lesson-plan:before {
+      content: url(/static/img/icons/lesson-plan_white.png); }
+    #catalogue-carousel #catalogue-carousel-switcher li.activeSlide .reference:before {
+      content: url(/static/img/icons/reference_white.png); }
diff --git a/src/catalogue/static/catalogue/css/carousel.scss b/src/catalogue/static/catalogue/css/carousel.scss
new file mode 100755 (executable)
index 0000000..299f95b
--- /dev/null
@@ -0,0 +1,140 @@
+$px: .0625em;
+
+$ciemny: #363a3e;
+
+
+#catalogue-carousel {
+    float: left;
+    position: relative;
+    width: 700*$px;
+    height: 235*$px;
+    overflow: hidden;
+    border-radius: 15*$px;
+
+    #catalogue-carousel-links {
+        width: 460*$px;
+        height: 235*$px;
+        list-style: none;
+        margin: 0;
+        padding: 0;
+
+        li {
+            display: block;
+            position: absolute;
+            top: 0;
+            left: 0;
+            height: 100%;
+            background-size: 100% 100%;
+            border-top-left-radius: 15*$px 6.38%;
+            border-bottom-left-radius: 15*$px 6.38%;
+            z-index: 100;
+            background-color: #888;
+
+            a.catalogue-carousel-link {
+                display: block;
+                overflow: hidden;
+                width: 460*$px;
+                height: 100%;
+                background: url(/static/catalogue/img/carousel-left.png) 100% 0 no-repeat;
+                background-size: 70*$px 100%;
+                
+                .catalogue-carousel-note {
+                    position: relative;
+                    height: 100%;
+                    color: white;
+                    margin-top: 8.5em;
+
+                    div {
+                        &:before {
+                            content: " ";
+                            display: block;
+                            position: absolute;
+                            height: 100%;
+                            width: 100%;
+                            z-index: -1;
+                            background-color: black;
+                            opacity: 0.6;
+                        }
+
+                        p {
+                            padding: .4em 3em 0 .5em;
+
+                            strong {
+                                font-size: 1.2em;
+                                display: block;
+                            }
+
+                            .more {
+                                position: absolute;
+                                right: 4em;
+                                top: 4.5em;
+                            }
+                        }
+                    }
+                }
+            }
+            a.catalogue-carousel-link:active {
+                outline: none;
+            }
+            .attribution {
+                text-align: right;
+                font-size: .75em;
+                position: absolute;
+                right: 5em;
+                top: .1em;
+                color: white;
+                font-weight: bold;
+                text-shadow: 0 0 5px #000;
+            }
+
+        }
+    }
+    #catalogue-carousel-switcher {
+        margin: 0;
+        padding: 3*$px 0 0 58*$px;
+        width: 240*$px - 58*$px;
+        height: 243*$px - 8*$px;
+        position: absolute;
+        right: 0;
+        top: 0;
+        list-style: none;
+        border-radius: 0 15*$px 15*$px 0;
+        background-color: #ed7831;
+        background-image: url(/static/catalogue/img/carousel-right.png);
+        background-position: 0 0;
+        background-repeat: no-repeat;
+        background-size: auto 235*$px;
+        
+        /* right part of mask as background */
+
+        li {
+            margin-bottom: .4em;
+            font-size: .85em;
+            line-height: 1em;
+
+            a {
+                text-transform: uppercase;
+                color: $ciemny;
+            }
+            a:before {
+                vertical-align: top;
+                margin-right: 1.5em;
+            }
+            .knowledge:before {content: url(/static/img/icons/knowledge_dark.png);}
+            .activity:before {content: url(/static/img/icons/activity_dark.png);}
+            .lesson-plan:before {content: url(/static/img/icons/lesson-plan_dark.png);}
+            .reference:before {content: url(/static/img/icons/reference_dark.png);}
+        }
+        li.activeSlide {
+            a {
+                color: white;
+            }
+            .knowledge:before {content: url(/static/img/icons/knowledge_white.png);}
+            .activity:before {content: url(/static/img/icons/activity_white.png);}
+            .lesson-plan:before {content: url(/static/img/icons/lesson-plan_white.png);}
+            .reference:before {content: url(/static/img/icons/reference_white.png);}
+        }
+    }
+
+
+}
diff --git a/src/catalogue/static/catalogue/css/exercise.css b/src/catalogue/static/catalogue/css/exercise.css
new file mode 100644 (file)
index 0000000..ce6f783
--- /dev/null
@@ -0,0 +1,231 @@
+@charset "UTF-8";
+.exercise img {
+  vertical-align: top; }
+.exercise .question-piece {
+  border-radius: 0.6875em;
+  padding: 0.5em 0.6875em; }
+.exercise .lista.punkt {
+  list-style: none;
+  margin: 0;
+  padding: 0; }
+.exercise .lista li {
+  margin: 0.3125em 0; }
+.exercise .question-piece.correct {
+  background-color: #16a487;
+  color: white; }
+.exercise .question-piece.incorrect {
+  background-color: #f00;
+  color: white; }
+.exercise .placeholder.dragover {
+  background: #ed7831 !important; }
+.exercise .remove {
+  float: right;
+  display: inline-block;
+  border-radius: 0.5em;
+  padding: 0.25em 0.5em;
+  margin: -0.25em -0.5em -0.25em 0.5em;
+  background: #ed7831;
+  color: white; }
+.exercise .buttons {
+  background: #5e6165;
+  border-radius: 0.5625em;
+  height: 1.875em;
+  line-height: 1.875em;
+  overflow: hidden;
+  color: white;
+  margin-top: 1.875em; }
+  .exercise .buttons input {
+    height: 100%;
+    border: 0;
+    background: #8e9093;
+    color: white;
+    text-transform: uppercase;
+    font-weight: bold; }
+  .exercise .buttons .message {
+    float: right;
+    padding: 0 1.25em;
+    background: red; }
+  .exercise .buttons .maxscore {
+    background: #16a487; }
+  .exercise .buttons input.check {
+    background: #ed7831; }
+
+.exercise .instruction, .exercise-wtem .instruction {
+  display: block;
+  margin: .3em;
+  color: green;
+  font-size: .9em; }
+.exercise .instruction:before, .exercise-wtem .instruction:before {
+  content: "☞ "; }
+
+.luki .question-piece {
+  background-color: #d4d6d8;
+  color: #363a3e;
+  cursor: pointer;
+  z-index: 2;
+  display: inline-block;
+  margin: 0.3125em;
+  z-index: 2;
+  max-width: 38em; }
+.luki .question-piece.disabled {
+  background-color: #eee;
+  color: #d4d6d8; }
+.luki .placeholder {
+  border-radius: 0.6875em;
+  padding: 0.5em 0.6875em;
+  display: inline-block;
+  margin: 0.3125em;
+  z-index: 2;
+  width: 4em;
+  background-color: #eee;
+  z-index: 1; }
+.luki .placeholder:after {
+  content: "\0000a0"; }
+
+.zastap .question-piece {
+  background-color: #d4d6d8;
+  color: #363a3e;
+  cursor: pointer;
+  z-index: 2;
+  display: inline-block;
+  margin: 0.3125em;
+  z-index: 2; }
+.zastap .question-piece.disabled {
+  background-color: #eee;
+  color: #d4d6d8; }
+.zastap .question-piece.placeholder {
+  background-color: inherit;
+  color: inherit;
+  cursor: inherit;
+  z-index: inherit;
+  display: inline;
+  margin: 0;
+  padding: 0;
+  z-index: inherit;
+  border-radius: 0; }
+
+.uporzadkuj .question-piece {
+  background-color: #d4d6d8;
+  color: #363a3e;
+  cursor: pointer;
+  z-index: 2; }
+.uporzadkuj .question-piece.disabled {
+  background-color: #eee;
+  color: #d4d6d8; }
+.uporzadkuj .lista {
+  list-style: none;
+  margin: 0;
+  padding: 0;
+  counter-reset: answer; }
+  .uporzadkuj .lista li {
+    counter-increment: answer;
+    padding-right: 3em;
+    background-image: url(/static/img/ornaments/draggable.png);
+    background-repeat: no-repeat;
+    background-position: 100% 50%; }
+  .uporzadkuj .lista li:before {
+    border-radius: 0.6875em;
+    padding: 0.5em 0.6875em;
+    background-color: #d4d6d8;
+    color: #363a3e;
+    cursor: pointer;
+    z-index: 2;
+    content: counter(answer);
+    float: left;
+    margin: -.5em 0 0 -3em; }
+  .uporzadkuj .lista li.ui-sortable-placeholder {
+    counter-increment: answer 0; }
+  .uporzadkuj .lista li.ui-sortable-helper:before {
+    content: none; }
+
+.przyporzadkuj .question-piece {
+  background-color: #d4d6d8;
+  color: #363a3e;
+  cursor: pointer;
+  z-index: 2;
+  width: 38.625em; }
+.przyporzadkuj .question-piece.short {
+  display: inline-block;
+  margin: .2em .1em;
+  width: auto; }
+.przyporzadkuj span.question-piece {
+  display: inline-block;
+  margin: .1em;
+  width: auto; }
+.przyporzadkuj .question-piece.disabled {
+  background-color: #eee;
+  color: #d4d6d8; }
+.przyporzadkuj .predicate {
+  list-style: none;
+  margin: 0;
+  padding: 0; }
+  .przyporzadkuj .predicate > li {
+    border-radius: 0.6875em;
+    padding: 0.5em 0.6875em;
+    display: inline-block;
+    background-color: #5e6165;
+    color: white;
+    width: 11.75em;
+    position: relative;
+    vertical-align: top; }
+    .przyporzadkuj .predicate > li .subjects {
+      list-style: none;
+      margin: 0;
+      padding: 0;
+      min-height: 2.8125em;
+      position: relative;
+      margin: 0.5em -0.6875em -0.5em -0.6875em;
+      padding: 0.5em 0.6875em; }
+      .przyporzadkuj .predicate > li .subjects li {
+        width: auto; }
+      .przyporzadkuj .predicate > li .subjects .placeholder {
+        border-radius: 0.6875em;
+        padding: 0.5em 0.6875em;
+        text-align: right;
+        position: relative;
+        padding: 0.5em 0.6875em;
+        margin: 0 -0.6875em; }
+      .przyporzadkuj .predicate > li .subjects .multiple {
+        position: absolute;
+        z-index: -1;
+        top: 0;
+        bottom: 0;
+        left: 0;
+        right: 0;
+        margin: 0; }
+      .przyporzadkuj .predicate > li .subjects .placeholder.dragover {
+        z-index: 1; }
+      .przyporzadkuj .predicate > li .subjects .placeholder:after {
+        content: "upuść tutaj";
+        text-style: italic; }
+.przyporzadkuj .subject {
+  list-style: none;
+  margin: 0;
+  padding: 0; }
+
+.prawdafalsz .question li.question-piece {
+  position: relative;
+  padding-left: 11em; }
+.prawdafalsz .question .buttons {
+  margin-top: 0;
+  top: 0;
+  left: 0;
+  position: absolute;
+  background-color: #d4d6d8;
+  color: #363a3e;
+  display: inline-block; }
+  .prawdafalsz .question .buttons a {
+    color: #363a3e;
+    text-transform: uppercase;
+    font-weight: bold;
+    display: inline-block;
+    padding: 0 0.6875em; }
+  .prawdafalsz .question .buttons a.chosen {
+    background: #ed7831;
+    color: white; }
+
+.wybor .question .lista {
+  list-style: none;
+  padding: 0; }
+  .wybor .question .lista li {
+    margin: 0; }
diff --git a/src/catalogue/static/catalogue/css/exercise.scss b/src/catalogue/static/catalogue/css/exercise.scss
new file mode 100755 (executable)
index 0000000..a9fc200
--- /dev/null
@@ -0,0 +1,320 @@
+$px: 0.0625em;
+$oranji: #ed7831;
+$ciemny: #363a3e;
+$zielony: #16a487;
+
+
+@mixin bubble {
+    border-radius: 11*$px;
+    padding: 8*$px 11*$px;
+}
+@mixin bubble-drag {
+    background-color: #d4d6d8;
+    color: #363a3e;
+    cursor: pointer;
+    z-index: 2;
+}
+@mixin bubble-drag-disabled {
+    background-color: #eee;
+    color: #d4d6d8;
+}
+@mixin un-bubble-drag {
+    background-color: inherit;
+    color: inherit;
+    cursor: inherit;
+    z-index: inherit;
+}
+
+@mixin bubble-inline {
+    display: inline-block;
+    margin: 5*$px;
+    z-index: 2;
+}
+@mixin un-bubble-inline {
+    display: inline;
+    margin: 0;
+    padding: 0;
+    z-index: inherit;
+    border-radius: 0;
+}
+@mixin list-plain {
+    list-style: none;
+    margin: 0;
+    padding: 0;
+}
+
+
+.exercise {
+    img {
+        vertical-align: top;
+    }
+
+    .question-piece {
+        @include bubble;
+    }
+    .lista.punkt {
+        @include list-plain;
+    }
+    .lista {
+        li {
+            margin: 5*$px 0;
+        }
+    }
+
+    .question-piece.correct {
+        background-color: #16a487;
+        color: white;
+    }
+    .question-piece.incorrect {
+        background-color: #f00;
+        color: white;
+    }
+    
+    .placeholder.dragover {
+         background: #ed7831 !important;
+    }
+
+    .remove {
+        float: right;
+        display: inline-block;
+        border-radius: 8*$px;
+        padding: 4*$px 8*$px;
+        margin: -4*$px -8*$px -.25em 8*$px;
+        background: #ed7831;
+        color: white;
+    }
+
+    .buttons {
+        background: #5e6165;
+        border-radius: 9*$px;
+        height: 30*$px;
+        line-height: 30*$px;
+        overflow: hidden;
+        color: white;
+        margin-top: 30*$px;
+
+        input {
+            height: 100%;
+            border: 0;
+            background: #8e9093;
+            color: white;
+            text-transform: uppercase;
+            font-weight: bold;
+        }
+        .message {
+            float: right;
+            padding: 0 20*$px;
+            background: red;
+        }
+        .maxscore {
+            background: #16a487;
+        }
+
+        input.check {
+            background: #ed7831;
+            
+        }
+    }
+}
+
+
+.exercise, .exercise-wtem {
+    .instruction {
+        display: block;
+        margin: .3em;
+        color: green;
+        font-size: .9em;
+    }
+    .instruction:before {
+        content: "☞ ";
+    }
+}
+
+
+.luki {
+    .question-piece {
+        @include bubble-drag;
+        @include bubble-inline;
+        max-width: 608*$px;
+    }
+    .question-piece.disabled {
+        @include bubble-drag-disabled;
+    }
+
+    .placeholder {
+        @include bubble;
+        @include bubble-inline;
+
+        width: 4em;
+        background-color: #eee;
+        z-index: 1;
+    }
+    .placeholder:after {
+        content: "\0000a0";
+    }
+}
+
+
+.zastap {
+    .question-piece {
+        @include bubble-drag;
+        @include bubble-inline;
+    }
+    .question-piece.disabled {
+        @include bubble-drag-disabled;
+    }
+    .question-piece.placeholder {
+        @include un-bubble-drag;
+        @include un-bubble-inline;
+    }
+}
+
+.uporzadkuj {
+    .question-piece {
+        @include bubble-drag;
+    }
+    .question-piece.disabled {
+        @include bubble-drag-disabled;
+    }
+    .lista {
+        @include list-plain;
+        counter-reset: answer;
+        li {
+            counter-increment: answer;
+            padding-right: 3em;
+            background-image: url(/static/img/ornaments/draggable.png);
+            background-repeat: no-repeat;
+            background-position: 100% 50%;
+        }
+        li:before {
+            @include bubble;
+            @include bubble-drag;
+            content: counter(answer);
+            float: left;
+            margin: -.5em 0 0 -3em;
+        }
+        li.ui-sortable-placeholder {
+            counter-increment: answer 0;
+        }
+        li.ui-sortable-helper:before {
+            content: none;
+        }
+    }
+}
+
+.przyporzadkuj {
+    .question-piece {
+        @include bubble-drag;
+        width: 618*$px;
+    }
+    .question-piece.short {
+        display: inline-block;
+        margin: .2em .1em;
+        width: auto;
+    }
+    span.question-piece {
+        display: inline-block;
+        margin: .1em;
+        width: auto;
+    }
+    .question-piece.disabled {
+        @include bubble-drag-disabled;
+    }
+    .predicate {
+        @include list-plain;
+
+        > li {
+            @include bubble;
+            display: inline-block;
+            background-color: #5e6165;
+            color: white;
+            width: 188*$px;
+            position: relative;
+            vertical-align: top;
+
+            .subjects {
+                @include list-plain;
+                min-height: 45*$px;
+                position: relative;
+                margin: 8*$px -11*$px -8*$px -11*$px;
+                padding: 8*$px 11*$px;
+
+                li {
+                    width: auto;
+                }
+
+                .placeholder {
+                    @include bubble;
+                    text-align: right;
+                    position:relative;
+                    padding: 8*$px 11*$px;
+                    margin: 0 -11*$px;
+                }
+                .multiple {
+                    position: absolute;
+                    z-index: -1;
+                    top: 0;
+                    bottom: 0;
+                    left: 0;
+                    right: 0;
+                    margin: 0;
+                }
+                
+                .placeholder.dragover {
+                    z-index: 1;
+                }
+                .placeholder:after {
+                    content: "upuść tutaj";
+                    text-style: italic;
+                }
+            }
+        }
+        .comment {
+        }
+    }
+    .subject {
+        @include list-plain;
+    }
+
+}
+
+
+.prawdafalsz .question {
+    li.question-piece {
+        position: relative;
+        padding-left: 11em;
+    }
+
+    .buttons {
+        margin-top: 0;
+        top: 0;
+        left: 0;
+        position: absolute;
+        
+        background-color: #d4d6d8;
+        color: #363a3e;
+        display: inline-block;
+
+        a {
+            color: #363a3e;
+            text-transform: uppercase;
+            font-weight: bold;
+            display: inline-block;
+            padding: 0 11*$px;
+        }
+        a.chosen {
+            background: #ed7831;
+            color: white;
+        }
+    }
+}
+
+.wybor .question {
+    .lista {
+        list-style: none;
+        padding: 0;
+        li {
+            margin: 0;
+        }
+    }
+}
diff --git a/src/catalogue/static/catalogue/css/layout.css b/src/catalogue/static/catalogue/css/layout.css
new file mode 100644 (file)
index 0000000..883d77b
--- /dev/null
@@ -0,0 +1,99 @@
+@charset "UTF-8";
+.box-button {
+  background-color: #ed7831;
+  border-radius: 0.9375em; }
+  .box-button .dl-button, .box-button .nice-button {
+    color: white;
+    padding: 1.0625em 0.75em 1.0625em 0.75em; }
+
+.dl-button, .nice-button {
+  color: #363a3e;
+  display: block;
+  font-weight: bold;
+  text-align: center;
+  text-transform: uppercase;
+  font-size: .9em; }
+
+.dl-button:after {
+  content: " ↓"; }
+
+#main-bar section.button {
+  margin-bottom: 1.0625em; }
+
+#sidebar {
+  position: absolute;
+  right: 0;
+  top: 0;
+  width: 13.75em;
+  color: #363a3e; }
+  #sidebar section {
+    margin-bottom: 1.0625em; }
+    #sidebar section h1 {
+      margin: 0; }
+    #sidebar section h1.realisation {
+      font-weight: normal; }
+  #sidebar .section {
+    border-top: 1px solid #c9ccce;
+    padding-top: 1.0625em; }
+  #sidebar .section-minor {
+    border-top: 1px solid #c9ccce;
+    padding-top: 1.0625em; }
+    #sidebar .section-minor h1 {
+      font-weight: normal;
+      font-size: 1em; }
+  #sidebar .section-micro {
+    font-size: .8em;
+    color: #888;
+    border-top: 1px solid #c9ccce;
+    padding-top: 1.0625em; }
+    #sidebar .section-micro h1 {
+      font-weight: normal;
+      font-size: 1em; }
+    #sidebar .section-micro .link-list a {
+      color: #888; }
+  #sidebar section:first-child {
+    border-top: 0;
+    padding-top: 0; }
+
+#main-bar {
+  width: 40em; }
+  #main-bar .top-link {
+    float: right; }
+  #main-bar .box {
+    background-color: #d4d6d8;
+    border-radius: 0.9375em;
+    padding: 1.0625em; }
+    #main-bar .box h1 {
+      font-size: 1em;
+      text-transform: uppercase; }
+    #main-bar .box p {
+      margin: 0; }
+    #main-bar .box .box-icon {
+      margin: -.2em 0 -.2em 1em;
+      float: right;
+      text-align: center; }
+
+.lesson-footer {
+  clear: both;
+  border-top: 1px solid #777;
+  margin-top: 2em;
+  padding-top: 1em; }
+  .lesson-footer .section-info {
+    text-align: center; }
+  .lesson-footer .previous-lesson {
+    float: left; }
+  .lesson-footer .next-lesson {
+    float: right; }
+
+ol.alpha {
+  counter-reset: list; }
+  ol.alpha > li {
+    list-style: none;
+    position: relative; }
+  ol.alpha > li:before {
+    counter-increment: list;
+    content: counter(list,lower-alpha) ") ";
+    position: absolute;
+    left: -1.4em; }
+
+/*# sourceMappingURL=layout.css.map */
diff --git a/src/catalogue/static/catalogue/css/layout.scss b/src/catalogue/static/catalogue/css/layout.scss
new file mode 100755 (executable)
index 0000000..a941469
--- /dev/null
@@ -0,0 +1,126 @@
+$px: .0625em;
+$new_black: #363a3e;
+
+.box-button {
+    background-color: #ed7831;
+    border-radius: 15*$px;
+    .dl-button, .nice-button {
+        color: white;
+        padding: 17*$px 12*$px 17*$px 12*$px;
+    }
+}
+.dl-button, .nice-button {
+    color: $new_black;
+    display: block;
+    font-weight: bold;
+    text-align: center;
+    text-transform: uppercase;
+    font-size: .9em;
+}
+.dl-button:after {
+    content: " ↓";
+}
+
+#main-bar section.button {
+    margin-bottom: 17*$px;
+}
+
+#sidebar {
+    position: absolute;
+    right: 0;
+    top: 0;
+    width: 220*$px;
+    color: $new_black;
+
+    section {
+        margin-bottom: 17*$px;
+        h1 {
+            margin: 0;
+        }
+        h1.realisation {
+            font-weight: normal;
+        }
+    }
+
+    .section {
+        border-top: 1px solid #c9ccce;
+        padding-top: 17*$px;
+    }
+    .section-minor {
+        border-top: 1px solid #c9ccce;
+        padding-top: 17*$px;
+        h1 {
+            font-weight: normal;
+            font-size: 1em;
+        }
+    }
+    .section-micro {
+        font-size: .8em;
+        color: #888;
+        border-top: 1px solid #c9ccce;
+        padding-top: 17*$px;
+        h1 {
+            font-weight: normal;
+            font-size: 1em;
+        }
+        .link-list a {
+            color: #888;
+        }
+    }
+    section:first-child {
+        border-top: 0;
+        padding-top: 0;
+    }
+}
+#main-bar {
+    width: 640*$px;
+
+    .top-link {
+        float:right;
+    }
+
+    .box {
+        background-color: #d4d6d8;
+        border-radius: 15*$px;
+        padding: 17*$px;
+        h1 {
+            font-size: 1em;
+            text-transform: uppercase;
+        }
+        p {
+            margin: 0;
+        }
+        .box-icon {
+            margin: -.2em 0 -.2em 1em;
+            float: right;
+            text-align: center;
+        }
+    }
+}
+
+.lesson-footer {
+    clear: both;
+    border-top: 1px solid #777;
+    margin-top: 2em;
+    padding-top: 1em;
+
+    .section-info {
+        text-align: center;
+    }
+    .previous-lesson {float: left;}
+    .next-lesson {float: right;}
+}
+
+ol.alpha {
+    counter-reset: list;
+    > li {
+        list-style: none;
+        position: relative;
+    }
+    > li:before {
+        counter-increment: list;
+        content: counter(list, lower-alpha) ") ";
+        position: absolute;
+        left: -1.4em;
+    }
+}
diff --git a/src/catalogue/static/catalogue/css/lesson.css b/src/catalogue/static/catalogue/css/lesson.css
new file mode 100644 (file)
index 0000000..fb7aa08
--- /dev/null
@@ -0,0 +1,262 @@
+/* =================================================== */
+/* = Common elements: headings, paragraphs and lines = */
+/* =================================================== */
+/*h1 {
+    font-size: 3em;
+    margin: 1.5em 0;
+    text-align: center;
+    line-height: 1.5em;
+    font-weight: bold;
+}
+
+h2 {
+    font-size: 2em;
+    margin: 1.5em 0 0;
+    font-weight: bold;
+    line-height: 1.5em;
+}
+
+h3 {
+    font-size: 1.5em;
+    margin: 1.5em 0 0;
+    font-weight: normal;
+    line-height: 1.5em;
+}
+
+h4 {
+    font-size: 1em;
+    margin: 1.5em 0 0;
+    line-height: 1.5em;
+}
+
+p {
+    margin: 0;
+}
+*/
+/* ======================== */
+/* = Footnotes and themes = */
+/* ======================== */
+.annotation {
+  font-style: normal;
+  font-weight: normal;
+  font-size: 12px;
+  padding-left: 2px;
+  position: relative;
+  top: -4px; }
+
+#footnotes {
+  margin-top: 3em; }
+
+#footnotes .annotation {
+  display: block;
+  float: left;
+  width: 2.5em;
+  clear: both; }
+
+#footnotes div {
+  margin: 1.5em 0 0 0; }
+
+#footnotes p, #footnotes ul {
+  margin-left: 2.5em;
+  font-size: 0.875em; }
+
+#footnotes .permalink {
+  font-size: .75em; }
+
+blockquote {
+  font-size: 0.875em; }
+
+/* ============= */
+/* = Numbering = */
+/* ============= */
+.verse, .paragraph {
+  position: relative; }
+
+.anchor {
+  position: absolute;
+  margin: -0.25em -0.5em;
+  left: -3em;
+  color: #777;
+  font-size: 12px;
+  width: 2em;
+  text-align: center;
+  padding: 0.25em 0.5em;
+  line-height: 1.5em; }
+
+.anchor:hover, #book-text .anchor:active {
+  color: #FFF;
+  background-color: #CCC; }
+
+/* =================== */
+/* = Custom elements = */
+/* =================== */
+span.author {
+  font-size: 0.5em;
+  display: block;
+  line-height: 1.5em;
+  margin-bottom: 0.25em; }
+
+span.collection {
+  font-size: 0.375em;
+  display: block;
+  line-height: 1.5em;
+  margin-bottom: -0.25em; }
+
+span.subtitle {
+  font-size: 0.5em;
+  display: block;
+  line-height: 1.5em;
+  margin-top: -0.25em; }
+
+span.translator {
+  font-size: 0.375em;
+  display: block;
+  line-height: 1.5em;
+  margin-top: 0.25em; }
+
+div.didaskalia {
+  font-style: italic;
+  margin: 0.5em 0 0 1.5em; }
+
+div.kwestia {
+  margin: 0.5em 0 0; }
+
+div.stanza {
+  margin: 1.5em 0 0; }
+
+div.kwestia div.stanza {
+  margin: 0; }
+
+p.paragraph {
+  text-align: justify;
+  margin: 1.5em 0 0; }
+
+p.motto {
+  text-align: justify;
+  font-style: italic;
+  margin: 1.5em 0 0; }
+
+p.motto_podpis {
+  font-size: 0.875em;
+  text-align: right; }
+
+div.fragment {
+  border-bottom: 0.1em solid #999;
+  padding-bottom: 1.5em; }
+
+div.note p, div.dedication p, div.note p.paragraph, div.dedication p.paragraph {
+  text-align: right;
+  font-style: italic; }
+
+hr.spacer {
+  height: 3em;
+  visibility: hidden; }
+
+hr.spacer-line {
+  margin: 1.5em 0;
+  border: none;
+  border-bottom: 0.1em solid #000; }
+
+p.spacer-asterisk {
+  padding: 0;
+  margin: 1.5em 0;
+  text-align: center; }
+
+div.person-list ol {
+  list-style: none;
+  padding: 0 0 0 1.5em; }
+
+p.place-and-time {
+  font-style: italic; }
+
+em.math, em.foreign-word, em.book-title, em.didaskalia {
+  font-style: italic; }
+
+em.author-emphasis {
+  letter-spacing: 0.1em; }
+
+em.person {
+  font-style: normal;
+  font-variant: small-caps; }
+
+.verse:after {
+  content: "\feff"; }
+
+table.framed {
+  border-collapse: collapse;
+}
+
+table.framed td, table.framed.th {
+  border: 1px #888 solid;
+}
+
+/* =================================== */
+/* = Hide some elements for printing = */
+/* =================================== */
+@media print {
+  #menu {
+    display: none; } }
+.activity {
+  clear: both; }
+
+.activity .text {
+  width: 27.5em;
+  margin-right: 20px;
+  float: left; }
+
+.activity .description p:first-child {
+  margin-top: 0; }
+
+.activity {
+  margin-top: 2em; }
+  .activity .act_counter {
+    float: left;
+    margin-right: .5em;
+    font-size: 2em; }
+  .activity .info {
+    float: right;
+    width: 8.4375em; }
+    .activity .info .infobox {
+      padding: 1em 0;
+      border-top: 1px solid #c9ccce; }
+      .activity .info .infobox h1 {
+        text-transform: uppercase;
+        font-weight: bold;
+        margin: 0 0 0.5em -2.1875em;
+        padding-left: 2.1875em;
+        line-height: 24px;
+        font-size: 1em; }
+      .activity .info .infobox p {
+        margin: 0; }
+    .activity .info .time h1 {
+      background: url(/static/img/icons/activity-time.png) 0 0 no-repeat; }
+    .activity .info .kind h1 {
+      background: url(/static/img/icons/activity-kind.png) 0 0 no-repeat; }
+    .activity .info .materials h1 {
+      background: url(/static/img/icons/activity-tools.png) 0 0 no-repeat; }
+
+.lista .paragraph {
+  margin: .3em 0; }
+.lista li {
+  margin: .75em 0; }
+
+.clearboth {
+  clear: both; }
+
+#book-text .caption {
+  margin: 1.5em; }
+  #book-text .caption p {
+    margin: 0; }
+
+/* utils */
+.clr {
+  clear: both; }
+
+#book-text .top-link {
+  margin-top: 1em; }
+
+.help {
+  font-size: .7em;
+  padding: 0 .5em;
+  color: #888;
+  vertical-align: super; }
diff --git a/src/catalogue/static/catalogue/css/lesson.scss b/src/catalogue/static/catalogue/css/lesson.scss
new file mode 100755 (executable)
index 0000000..d98f1a3
--- /dev/null
@@ -0,0 +1,327 @@
+$px: .0625em;
+
+/* =================================================== */
+/* = Common elements: headings, paragraphs and lines = */
+/* =================================================== */
+
+/*h1 {
+    font-size: 3em;
+    margin: 1.5em 0;
+    text-align: center;
+    line-height: 1.5em;
+    font-weight: bold;
+}
+
+h2 {
+    font-size: 2em;
+    margin: 1.5em 0 0;
+    font-weight: bold;
+    line-height: 1.5em;
+}
+
+h3 {
+    font-size: 1.5em;
+    margin: 1.5em 0 0;
+    font-weight: normal;
+    line-height: 1.5em;
+}
+
+h4 {
+    font-size: 1em;
+    margin: 1.5em 0 0;
+    line-height: 1.5em;
+}
+
+p {
+    margin: 0;
+}
+*/
+
+/* ======================== */
+/* = Footnotes and themes = */
+/* ======================== */
+
+.annotation {
+    font-style: normal;
+    font-weight: normal;
+    font-size: 12px;
+    padding-left: 2px;
+    position: relative;
+    top: -4px;
+}
+
+#footnotes {
+    margin-top: 3em;
+}
+
+#footnotes .annotation {
+    display: block;
+    float: left;
+    width: 2.5em;
+    clear: both;
+}
+
+#footnotes div {
+    margin: 1.5em 0 0 0;
+}
+
+#footnotes p, #footnotes ul {
+    margin-left: 2.5em;
+    font-size: 0.875em;
+}
+
+#footnotes .permalink {
+    font-size: .75em;
+}
+
+blockquote {
+    font-size: 0.875em;
+}
+
+/* ============= */
+/* = Numbering = */
+/* ============= */
+.verse, .paragraph {
+    position:relative;
+}
+.anchor {
+    position: absolute;
+    margin: -0.25em -0.5em;
+    left: -3em;
+    color: #777;
+    font-size: 12px;
+    width: 2em;
+    text-align: center;
+    padding: 0.25em 0.5em;
+    line-height: 1.5em;
+}
+
+.anchor:hover, #book-text .anchor:active {
+    color: #FFF;
+    background-color: #CCC;
+}
+
+/* =================== */
+/* = Custom elements = */
+/* =================== */
+span.author {
+    font-size: 0.5em;
+    display: block;
+    line-height: 1.5em;
+    margin-bottom: 0.25em;
+}
+
+span.collection {
+    font-size: 0.375em;
+    display: block;
+    line-height: 1.5em;
+    margin-bottom: -0.25em;
+}
+
+span.subtitle {
+    font-size: 0.5em;
+    display: block;
+    line-height: 1.5em;
+    margin-top: -0.25em;
+}
+
+span.translator {
+    font-size: 0.375em;
+    display: block;
+    line-height: 1.5em;
+    margin-top: 0.25em;
+}
+
+div.didaskalia {
+    font-style: italic;
+    margin: 0.5em 0 0 1.5em;
+}
+
+div.kwestia {
+    margin: 0.5em 0 0;
+}
+
+div.stanza {
+    margin: 1.5em 0 0;
+}
+
+div.kwestia div.stanza {
+    margin: 0;
+}
+
+p.paragraph {
+    text-align: justify;
+    margin: 1.5em 0 0;
+}
+
+p.motto {
+    text-align: justify;
+    font-style: italic;
+    margin: 1.5em 0 0;
+}
+
+p.motto_podpis {
+    font-size: 0.875em;
+    text-align: right;
+}
+
+div.fragment {
+    border-bottom: 0.1em solid #999;
+    padding-bottom: 1.5em;
+}
+
+div.note p, div.dedication p, div.note p.paragraph, div.dedication p.paragraph {
+    text-align: right;
+    font-style: italic;
+}
+
+hr.spacer {
+    height: 3em;
+    visibility: hidden;
+}
+
+hr.spacer-line {
+    margin: 1.5em 0;
+    border: none;
+    border-bottom: 0.1em solid #000;
+}
+
+p.spacer-asterisk {
+    padding: 0;
+    margin: 1.5em 0;
+    text-align: center;
+}
+
+div.person-list ol {
+    list-style: none;
+    padding: 0 0 0 1.5em;
+}
+
+p.place-and-time {
+    font-style: italic;
+}
+
+em.math, em.foreign-word, em.book-title, em.didaskalia {
+    font-style: italic;
+}
+
+em.author-emphasis {
+    letter-spacing: 0.1em;
+}
+
+em.person {
+    font-style: normal;
+    font-variant: small-caps;
+}
+
+.verse:after {
+    content: "\feff";
+}
+
+
+/* =================================== */
+/* = Hide some elements for printing = */
+/* =================================== */
+
+@media print {
+    #menu {display: none;}
+}
+
+
+
+.activity {
+ clear:both;
+}
+
+.activity .text {
+    width: 440*$px;
+    margin-right: 20px;
+    float: left;
+}
+
+.activity .description p:first-child {
+  margin-top: 0;
+}
+
+
+
+.activity {
+    margin-top: 2em;
+
+    .act_counter {
+        float: left;
+        margin-right: .5em;
+        font-size: 2em;
+    }
+
+    .info {
+        float: right;
+        width: 135*$px;
+
+        .infobox {
+            padding: 1em 0;
+            border-top: 1px solid #c9ccce;
+            h1 {
+                text-transform: uppercase;
+                font-weight: bold;
+                margin: 0 0 .5em -35*$px;
+                padding-left: 35*$px;
+                line-height: 24px;
+                font-size: 1em;
+            }
+            p {
+                margin: 0;
+            }
+
+        }
+        .time h1 {
+            background: url(/static/img/icons/activity-time.png) 0 0 no-repeat;
+        }
+        .kind h1 {
+            background: url(/static/img/icons/activity-kind.png) 0 0 no-repeat;
+        }
+        .materials h1 {
+            background: url(/static/img/icons/activity-tools.png) 0 0 no-repeat;
+        }
+    }
+}
+
+.lista {
+    .paragraph {
+        margin: .3em 0;
+    }
+    li {
+        margin: .75em 0;
+    }
+}
+
+
+.clearboth {
+ clear: both;
+}
+
+#book-text {
+    .caption {
+        margin: 1.5em;
+        p {
+            margin: 0;
+        }
+    }
+}
+
+/* utils */
+
+.clr {
+    clear: both;
+}
+
+#book-text .top-link {
+    margin-top: 1em;
+}
+
+.help {
+    font-size: .7em;
+    padding: 0 .5em;
+    color: #888;
+    vertical-align: super;
+}
diff --git a/src/catalogue/static/catalogue/css/section_list.css b/src/catalogue/static/catalogue/css/section_list.css
new file mode 100644 (file)
index 0000000..bd68dee
--- /dev/null
@@ -0,0 +1,58 @@
+#level-chooser-place {
+  min-height: 5.9375em;
+  margin-top: 2em; }
+  #level-chooser-place ul#level-chooser {
+    margin: 0;
+    padding: 1em 0 1em 8.75em;
+    background-color: white;
+    width: 31.25em;
+    z-index: 300;
+    position: relative;
+    text-transform: uppercase;
+    text-align: right; }
+    #level-chooser-place ul#level-chooser .home {
+      display: none;
+      position: absolute;
+      top: 1.5em;
+      left: 0; }
+      #level-chooser-place ul#level-chooser .home a {
+        background: none;
+        padding: 0; }
+        #level-chooser-place ul#level-chooser .home a img {
+          width: 7.5em; }
+    #level-chooser-place ul#level-chooser.fixed {
+      position: fixed;
+      top: 0;
+      border-bottom: 1px solid #c9ccce; }
+      #level-chooser-place ul#level-chooser.fixed .home {
+        display: block; }
+    #level-chooser-place ul#level-chooser li {
+      display: inline-block;
+      list-style: none;
+      max-width: 175px; }
+      #level-chooser-place ul#level-chooser li a {
+        display: table-cell;
+        padding: .5em 1em;
+        border-radius: 0.3125em;
+        background: #eee;
+        height: 2.625em;
+        vertical-align: middle; }
+        #level-chooser-place ul#level-chooser li a.active {
+          color: white;
+          background: #ED7831; }
+
+.level .link-list {
+  margin-left: 1em; }
+.level .level-toc {
+  overflow: hidden;
+  /* Because we're changing bg color lower. */ }
+  .level .level-toc.fixed {
+    position: fixed; }
+  .level .level-toc .link-list {
+    margin-left: 1em; }
+    .level .level-toc .link-list li {
+      margin-bottom: 0; }
+      .level .level-toc .link-list li.curriculumcourses {
+        margin: 10px -17px -17px;
+        padding: 10px 16px 16px;
+        background-color: #eee; }
diff --git a/src/catalogue/static/catalogue/css/section_list.scss b/src/catalogue/static/catalogue/css/section_list.scss
new file mode 100755 (executable)
index 0000000..fda2be3
--- /dev/null
@@ -0,0 +1,90 @@
+$px: 0.0625em;
+
+#level-chooser-place {
+    min-height: 95*$px;
+    margin-top: 2em;
+
+    ul#level-chooser {
+        margin: 0;
+        padding: 16*$px 0 16*$px 140*$px;
+        background-color: white;
+        width: 500*$px;
+        z-index: 300;
+        position: relative;
+        text-transform: uppercase;
+        text-align: right;
+
+        .home {
+            display: none;
+            position: absolute;
+            top: 1.5em;
+            left: 0;
+
+            a {
+                background: none;
+                padding: 0;
+                img {
+                    width: 120*$px;
+                }
+            }
+        }
+
+        &.fixed {
+            position: fixed;
+            top: 0;
+            border-bottom: 1px solid #c9ccce;
+
+            .home {
+                display: block;
+            }
+        }
+
+        li {
+            display: inline-block;
+            list-style: none;
+            max-width: 175px;
+
+            a {
+                display: table-cell;
+                padding: .5em 1em;
+                border-radius: 5*$px;
+                background: #eee;
+                height: 42*$px;
+                vertical-align: middle;
+
+                &.active {
+                    color: white;
+                    background: #ED7831;
+                }
+            }
+        }
+    }
+}
+
+.level {
+    .link-list {
+        margin-left: 1em;
+    }
+
+    .level-toc {
+        overflow: hidden; /* Because we're changing bg color lower. */
+
+        &.fixed {
+            position: fixed;
+        }
+
+        .link-list {
+            margin-left: 1em;
+
+            li {
+                margin-bottom: 0;
+
+                &.curriculumcourses {
+                    margin: 10px -17px -17px;
+                    padding: 10px 16px 16px;
+                    background-color: #eee;
+                }
+            }
+        }
+    }
+}
diff --git a/src/catalogue/static/catalogue/img/carousel-left.png b/src/catalogue/static/catalogue/img/carousel-left.png
new file mode 100644 (file)
index 0000000..3f6090b
Binary files /dev/null and b/src/catalogue/static/catalogue/img/carousel-left.png differ
diff --git a/src/catalogue/static/catalogue/img/carousel-right.png b/src/catalogue/static/catalogue/img/carousel-right.png
new file mode 100644 (file)
index 0000000..3987678
Binary files /dev/null and b/src/catalogue/static/catalogue/img/carousel-right.png differ
diff --git a/src/catalogue/static/catalogue/img/carousel/katarzyna-wlodarczyk.jpg b/src/catalogue/static/catalogue/img/carousel/katarzyna-wlodarczyk.jpg
new file mode 100644 (file)
index 0000000..93b81f2
Binary files /dev/null and b/src/catalogue/static/catalogue/img/carousel/katarzyna-wlodarczyk.jpg differ
diff --git a/src/catalogue/static/catalogue/js/carousel.js b/src/catalogue/static/catalogue/js/carousel.js
new file mode 100755 (executable)
index 0000000..b2484be
--- /dev/null
@@ -0,0 +1,27 @@
+(function($){
+$(function() {
+
+
+$("#catalogue-carousel-links").each(function() {
+    $slides = $(this); 
+
+    $slides.cycle({
+        fx: 'fade',
+        speed: 1000,
+        timeout: 5000,
+        pager: '#catalogue-carousel-switcher',
+        pagerAnchorBuilder: function() {},
+    });
+
+    $("#catalogue-carousel-switcher li").each(function(i, e) {
+        $("a", e).click(function(ev) {
+            ev.preventDefault();
+            $slides.cycle(i);
+        });
+    });
+
+});
+
+
+});
+})(jQuery);
diff --git a/src/catalogue/static/catalogue/js/edumed.js b/src/catalogue/static/catalogue/js/edumed.js
new file mode 100644 (file)
index 0000000..ec1eabc
--- /dev/null
@@ -0,0 +1,665 @@
+// Generated by CoffeeScript 1.4.0
+(function() {
+  var $, Binding, EduModule, Exercise, Luki, PrawdaFalsz, Przyporzadkuj, Uporzadkuj, Wybor, Zastap, exercise,
+    __hasProp = {}.hasOwnProperty,
+    __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
+
+  $ = jQuery;
+
+  Binding = (function() {
+
+    function Binding(handler, element) {
+      this.handler = handler;
+      this.element = element;
+      $(this.element).data(this.handler, this);
+    }
+
+    return Binding;
+
+  })();
+
+  EduModule = (function(_super) {
+
+    __extends(EduModule, _super);
+
+    function EduModule(element) {
+      EduModule.__super__.constructor.call(this, 'edumodule', element);
+    }
+
+    return EduModule;
+
+  })(Binding);
+
+  Exercise = (function(_super) {
+
+    __extends(Exercise, _super);
+
+    function Exercise(element) {
+      var _this = this;
+      Exercise.__super__.constructor.call(this, 'exercise', element);
+      $(this.element).data("exercise-html", $(this.element).html());
+      $(".check", this.element).click(function(ev) {
+        _this.check();
+        $(".retry", _this.element).show();
+        return $(".check", _this.element).hide();
+      });
+      $(".retry", this.element).click(function(ev) {
+        return _this.retry();
+      });
+      $('.solutions', this.element).click(function() {
+        _this.show_solutions();
+        return $(".comment", _this.element).show();
+      });
+      $('.reset', this.element).click(function() {
+        return _this.reset();
+      });
+    }
+
+    Exercise.prototype.retry = function() {
+      $(".correct, .incorrect", this.element).removeClass("correct incorrect");
+      $(".check", this.element).show();
+      return $(".retry", this.element).hide();
+    };
+
+    Exercise.prototype.reset = function() {
+      $(this.element).html($(this.element).data('exercise-html'));
+      return exercise(this.element);
+    };
+
+    Exercise.prototype.piece_correct = function(qpiece) {
+      return $(qpiece).removeClass('incorrect').addClass('correct');
+    };
+
+    Exercise.prototype.piece_incorrect = function(qpiece) {
+      return $(qpiece).removeClass('correct').addClass('incorrect');
+    };
+
+    Exercise.prototype.check = function() {
+      var score, scores,
+        _this = this;
+      scores = [];
+      $(".question", this.element).each(function(i, question) {
+        return scores.push(_this.check_question(question));
+      });
+      score = [0, 0, 0];
+      $.each(scores, function(i, s) {
+        score[0] += s[0];
+        score[1] += s[1];
+        return score[2] += s[2];
+      });
+      return this.show_score(score);
+    };
+
+    Exercise.prototype.show_solutions = function() {
+      var _this = this;
+      this.reset();
+      return $(".question", this.element).each(function(i, question) {
+        return _this.solve_question(question);
+      });
+    };
+
+    Exercise.prototype.get_value_list = function(elem, data_key, numbers) {
+      var vl;
+      vl = $(elem).attr("data-" + data_key).split(/[ ,]+/).map($.trim);
+      if (numbers) {
+        vl = vl.map(function(x) {
+          return parseInt(x);
+        });
+      }
+      return vl;
+    };
+
+    Exercise.prototype.get_value_optional_list = function(elem, data_key) {
+      var mandat, opt, v, vals, _i, _len;
+      vals = this.get_value_list(elem, data_key);
+      mandat = [];
+      opt = [];
+      for (_i = 0, _len = vals.length; _i < _len; _i++) {
+        v = vals[_i];
+        if (v.slice(-1) === "?") {
+          opt.push(v.slice(0, -1));
+        } else {
+          mandat.push(v);
+        }
+      }
+      return [mandat, opt];
+    };
+
+    Exercise.prototype.show_score = function(score) {
+      var $msg;
+      $msg = $(".message", this.element);
+      $msg.text("Wynik: " + score[0] + " / " + score[2]);
+      if (score[0] >= score[2] && score[1] === 0) {
+        return $msg.addClass("maxscore");
+      } else {
+        return $msg.removeClass("maxscore");
+      }
+    };
+
+    Exercise.prototype.draggable_equal = function($draggable1, $draggable2) {
+      return false;
+    };
+
+    Exercise.prototype.draggable_accept = function($draggable, $droppable) {
+      var d, dropped, _i, _len;
+      dropped = $droppable.closest("ul, ol").find(".draggable");
+      for (_i = 0, _len = dropped.length; _i < _len; _i++) {
+        d = dropped[_i];
+        if (this.draggable_equal($draggable, $(d))) {
+          return false;
+        }
+      }
+      return true;
+    };
+
+    Exercise.prototype.draggable_move = function($draggable, $placeholder, ismultiple) {
+      var $added,
+        _this = this;
+      $added = $draggable.clone();
+      $added.data("original", $draggable.get(0));
+      if (!ismultiple) {
+        $draggable.addClass('disabled').draggable('disable');
+      }
+      $placeholder.after($added);
+      if (!$placeholder.hasClass('multiple')) {
+        $placeholder.hide();
+      }
+      if ($added.is(".add-li")) {
+        $added.wrap("<li/>");
+      }
+      $added.append('<span class="remove">x</span><div class="clr"></div>');
+      return $('.remove', $added).click(function(ev) {
+        _this.retry();
+        if (!ismultiple) {
+          $($added.data('original')).removeClass('disabled').draggable('enable');
+        }
+        if ($added.is(".add-li")) {
+          $added = $added.closest('li');
+        }
+        $added.prev(".placeholder:not(.multiple)").show();
+        return $added.remove();
+      });
+    };
+
+    Exercise.prototype.dragging = function(ismultiple, issortable) {
+      var _this = this;
+      return $(".question", this.element).each(function(i, question) {
+        var draggable_opts, self;
+        draggable_opts = {
+          revert: 'invalid',
+          helper: 'clone',
+          start: _this.retry
+        };
+        $(".draggable", question).draggable(draggable_opts);
+        self = _this;
+        return $(".placeholder", question).droppable({
+          accept: function(draggable) {
+            var $draggable, is_accepted;
+            $draggable = $(draggable);
+            is_accepted = true;
+            if (!$draggable.is(".draggable")) {
+              is_accepted = false;
+            }
+            if (is_accepted) {
+              is_accepted = self.draggable_accept($draggable, $(this));
+            }
+            if (is_accepted) {
+              $(this).addClass('accepting');
+            } else {
+              $(this).removeClass('accepting');
+            }
+            return is_accepted;
+          },
+          drop: function(ev, ui) {
+            $(ev.target).removeClass('accepting dragover');
+            return _this.draggable_move($(ui.draggable), $(ev.target), ismultiple);
+          },
+          over: function(ev, ui) {
+            return $(ev.target).addClass('dragover');
+          },
+          out: function(ev, ui) {
+            return $(ev.target).removeClass('dragover');
+          }
+        });
+      });
+    };
+
+    return Exercise;
+
+  })(Binding);
+
+  Wybor = (function(_super) {
+
+    __extends(Wybor, _super);
+
+    function Wybor(element) {
+      Wybor.__super__.constructor.call(this, element);
+      $(".question-piece input", element).change(this.retry);
+    }
+
+    Wybor.prototype.check_question = function(question) {
+      var all = 0, bad = 0, good = 0, _this = this;
+      var single = $(question).closest('.exercise').attr('data-subtype') === 'single';
+
+      $(".question-piece", question).each(function(i, qpiece) {
+        var is_checked, should_be_checked;
+        should_be_checked = $(qpiece).attr('data-sol') === 'prawda';
+        is_checked = $("input", qpiece).is(":checked");
+        if (!single || should_be_checked)
+          all += 1;
+        if (single) {
+          if (is_checked) {
+            if (should_be_checked) {
+              good += 1;
+              return _this.piece_correct(qpiece);
+            } else {
+              bad += 1;
+              return _this.piece_incorrect(qpiece);
+            }
+          } else {
+            return $(qpiece).removeClass("correct,incorrect");
+          }
+        } else {
+          if (is_checked !== should_be_checked) {
+            bad += 1;
+            return _this.piece_incorrect(qpiece);
+          } else {
+            good += 1;
+            return _this.piece_correct(qpiece);
+          }
+        }
+      });
+      return [good, bad, all];
+    };
+
+    Wybor.prototype.solve_question = function(question) {
+      var solution,
+        _this = this;
+      return $(".question-piece", question).each(function(i, qpiece) {
+        var should_be_checked;
+        should_be_checked = $(qpiece).attr('data-sol') === 'prawda';
+        return $("input[type=checkbox],input[type=radio]", qpiece).prop('checked', should_be_checked);
+      });
+    };
+
+    return Wybor;
+
+  })(Exercise);
+
+  Uporzadkuj = (function(_super) {
+
+    __extends(Uporzadkuj, _super);
+
+    function Uporzadkuj(element) {
+      Uporzadkuj.__super__.constructor.call(this, element);
+      $('ol, ul', this.element).sortable({
+        items: "> li",
+        start: this.retry
+      });
+    }
+
+    Uporzadkuj.prototype.check_question = function(question) {
+      var all, bad, correct, pkt, pkts, positions, sorted, _i, _ref;
+      positions = this.get_value_list(question, 'original', true);
+      sorted = positions.sort(function(a, b) {
+        return a - b;
+      });
+      pkts = $('.question-piece', question);
+      correct = 0;
+      bad = 0;
+      all = 0;
+      for (pkt = _i = 0, _ref = pkts.length; 0 <= _ref ? _i < _ref : _i > _ref; pkt = 0 <= _ref ? ++_i : --_i) {
+        all += 1;
+        if (pkts.eq(pkt).data('pos') === sorted[pkt]) {
+          correct += 1;
+          this.piece_correct(pkts.eq(pkt));
+        } else {
+          bad += 1;
+          this.piece_incorrect(pkts.eq(pkt));
+        }
+      }
+      return [correct, bad, all];
+    };
+
+    Uporzadkuj.prototype.solve_question = function(question) {
+      var p, parent, pkts, _i, _len, _results;
+      pkts = $('.question-piece', question);
+      pkts.sort(function(a, b) {
+        return $(a).data('pos') - $(b).data('pos');
+      });
+      parent = pkts.eq(0).parent();
+      _results = [];
+      for (_i = 0, _len = pkts.length; _i < _len; _i++) {
+        p = pkts[_i];
+        _results.push(parent.append(p));
+      }
+      return _results;
+    };
+
+    return Uporzadkuj;
+
+  })(Exercise);
+
+  Luki = (function(_super) {
+
+    __extends(Luki, _super);
+
+    function Luki(element) {
+      Luki.__super__.constructor.call(this, element);
+      this.dragging(false, false);
+    }
+
+    Luki.prototype.check = function() {
+      var all, bad, correct,
+        _this = this;
+      all = $(".placeholder", this.element).length;
+      correct = 0;
+      bad = 0;
+      $(".placeholder + .question-piece", this.element).each(function(i, qpiece) {
+        var $placeholder;
+        $placeholder = $(qpiece).prev(".placeholder");
+        if ($placeholder.data('solution') === $(qpiece).data('no')) {
+          _this.piece_correct(qpiece);
+          return correct += 1;
+        } else {
+          bad += 1;
+          return _this.piece_incorrect(qpiece);
+        }
+      });
+      return this.show_score([correct, bad, all]);
+    };
+
+    Luki.prototype.solve_question = function(question) {
+      var _this = this;
+      return $(".placeholder", question).each(function(i, placeholder) {
+        var $qp;
+        $qp = $(".question-piece[data-no=" + $(placeholder).data('solution') + "]", question);
+        return _this.draggable_move($qp, $(placeholder), false);
+      });
+    };
+
+    return Luki;
+
+  })(Exercise);
+
+  Zastap = (function(_super) {
+
+    __extends(Zastap, _super);
+
+    function Zastap(element) {
+      var _this = this;
+      Zastap.__super__.constructor.call(this, element);
+      $(".paragraph", this.element).each(function(i, par) {
+        return _this.wrap_words($(par), $('<span class="placeholder zastap"/>'));
+      });
+      this.dragging(false, false);
+    }
+
+    Zastap.prototype.check = function() {
+      var all, bad, correct,
+        _this = this;
+      all = 0;
+      correct = 0;
+      bad = 0;
+      $(".paragraph", this.element).each(function(i, par) {
+        return $(".placeholder", par).each(function(j, qpiece) {
+          var $dragged, $qp;
+          $qp = $(qpiece);
+          $dragged = $qp.next(".draggable");
+          if ($qp.data("solution")) {
+            if ($dragged && $qp.data("solution") === $dragged.data("no")) {
+              _this.piece_correct($dragged);
+              correct += 1;
+            }
+            return all += 1;
+          }
+        });
+      });
+      return this.show_score([correct, bad, all]);
+    };
+
+    Zastap.prototype.show_solutions = function() {
+      var _this = this;
+      this.reset();
+      return $(".paragraph", this.element).each(function(i, par) {
+        return $(".placeholder[data-solution]", par).each(function(j, qpiece) {
+          var $dr, $qp;
+          $qp = $(qpiece);
+          $dr = $(".draggable[data-no=" + $qp.data('solution') + "]", _this.element);
+          return _this.draggable_move($dr, $qp, false);
+        });
+      });
+    };
+
+    Zastap.prototype.wrap_words = function(element, wrapper) {
+      var chld, i, ignore, insertWrapped, j, len, space, wordb, _i, _ref, _results;
+      ignore = /^[ \t.,:;()]+/;
+      insertWrapped = function(txt, elem) {
+        var nw;
+        nw = wrapper.clone();
+        return $(document.createTextNode(txt)).wrap(nw).parent().attr("data-original", txt).insertBefore(elem);
+      };
+      _results = [];
+      for (j = _i = _ref = element.get(0).childNodes.length - 1; _ref <= 0 ? _i <= 0 : _i >= 0; j = _ref <= 0 ? ++_i : --_i) {
+        chld = element.get(0).childNodes[j];
+        if (chld.nodeType === document.TEXT_NODE) {
+          len = chld.textContent.length;
+          wordb = 0;
+          i = 0;
+          while (i < len) {
+            space = ignore.exec(chld.textContent.substr(i));
+            if (space != null) {
+              if (wordb < i) {
+                insertWrapped(chld.textContent.substr(wordb, i - wordb), chld);
+              }
+              $(document.createTextNode(space[0])).insertBefore(chld);
+              i += space[0].length;
+              wordb = i;
+            } else {
+              i = i + 1;
+            }
+          }
+          if (wordb < len - 1) {
+            insertWrapped(chld.textContent.substr(wordb, len - 1 - wordb), chld);
+          }
+          _results.push($(chld).remove());
+        } else {
+          _results.push(void 0);
+        }
+      }
+      return _results;
+    };
+
+    return Zastap;
+
+  })(Exercise);
+
+  Przyporzadkuj = (function(_super) {
+
+    __extends(Przyporzadkuj, _super);
+
+    Przyporzadkuj.prototype.is_multiple = function() {
+      var qp, _i, _len, _ref;
+      _ref = $(".question-piece", this.element);
+      for (_i = 0, _len = _ref.length; _i < _len; _i++) {
+        qp = _ref[_i];
+        if ($(qp).attr('data-solution').split(/[ ,]+/).length > 1) {
+          return true;
+        }
+      }
+      return false;
+    };
+
+    function Przyporzadkuj(element) {
+      Przyporzadkuj.__super__.constructor.call(this, element);
+      this.multiple = this.is_multiple();
+      this.dragging(this.multiple, true);
+    }
+
+    Przyporzadkuj.prototype.draggable_equal = function(d1, d2) {
+      return d1.data("no") === d2.data("no");
+    };
+
+    Przyporzadkuj.prototype.check_question = function(question) {
+      var all, bad_count, count, mandatory, minimum, optional, pn, pred, qp, self, v, _i, _j, _len, _len1, _ref, _ref1;
+      minimum = $(question).data("minimum");
+      count = 0;
+      bad_count = 0;
+      all = 0;
+      if (!minimum) {
+        self = this;
+        $(".subject .question-piece", question).each(function(i, el) {
+          var mandatory, v;
+          v = self.get_value_optional_list(el, 'solution');
+          mandatory = v[0];
+          return all += mandatory.length;
+        });
+      }
+      _ref = $(".predicate [data-predicate]", question);
+      for (_i = 0, _len = _ref.length; _i < _len; _i++) {
+        pred = _ref[_i];
+        pn = $(pred).attr('data-predicate');
+        _ref1 = $(".question-piece", pred);
+        for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) {
+          qp = _ref1[_j];
+          v = this.get_value_optional_list(qp, 'solution');
+          mandatory = v[0];
+          optional = v[1];
+          if (mandatory.indexOf(pn) >= 0 || (minimum && optional.indexOf(pn) >= 0)) {
+            count += 1;
+            this.piece_correct(qp);
+          } else {
+            bad_count += 1;
+            this.piece_incorrect(qp);
+          }
+        }
+      }
+      return [count, bad_count, all];
+    };
+
+    Przyporzadkuj.prototype.solve_question = function(question) {
+      var $ph, $pr, draggables, m, mandatory, minimum, optional, qp, v, _i, _len, _ref, _results;
+      minimum = $(question).data("min");
+      _ref = $(".subject .question-piece", question);
+      _results = [];
+      for (_i = 0, _len = _ref.length; _i < _len; _i++) {
+        qp = _ref[_i];
+        v = this.get_value_optional_list(qp, 'solution');
+        mandatory = v[0];
+        optional = v[1];
+        if (minimum) {
+          draggables = mandatory.count(optional).slice(0, minimum);
+        } else {
+          draggables = mandatory;
+        }
+        _results.push((function() {
+          var _j, _len1, _results1;
+          _results1 = [];
+          for (_j = 0, _len1 = draggables.length; _j < _len1; _j++) {
+            m = draggables[_j];
+            $pr = $(".predicate [data-predicate=" + m + "]", question);
+            $ph = $pr.find(".placeholder:visible");
+            _results1.push(this.draggable_move($(qp), $ph.eq(0), this.multiple));
+          }
+          return _results1;
+        }).call(this));
+      }
+      return _results;
+    };
+
+    return Przyporzadkuj;
+
+  })(Exercise);
+
+  PrawdaFalsz = (function(_super) {
+
+    __extends(PrawdaFalsz, _super);
+
+    function PrawdaFalsz(element) {
+      var qp, _i, _len, _ref,
+        _this = this;
+      PrawdaFalsz.__super__.constructor.call(this, element);
+      _ref = $(".question-piece", this.element);
+      for (_i = 0, _len = _ref.length; _i < _len; _i++) {
+        qp = _ref[_i];
+        $(".true", qp).click(function(ev) {
+          ev.preventDefault();
+          _this.retry();
+          $(ev.target).closest(".question-piece").data("value", "true");
+          return $(ev.target).addClass('chosen').siblings('a').removeClass('chosen');
+        });
+        $(".false", qp).click(function(ev) {
+          ev.preventDefault();
+          _this.retry();
+          $(ev.target).closest(".question-piece").data("value", "false");
+          return $(ev.target).addClass('chosen').siblings('a').removeClass('chosen');
+        });
+      }
+    }
+
+    PrawdaFalsz.prototype.check_question = function() {
+      var all, bad, good, qp, _i, _len, _ref;
+      all = 0;
+      good = 0;
+      bad = 0;
+      _ref = $(".question-piece", this.element);
+      for (_i = 0, _len = _ref.length; _i < _len; _i++) {
+        qp = _ref[_i];
+        if ($(qp).data("solution").toString() === $(qp).data("value")) {
+          good += 1;
+          this.piece_correct(qp);
+        } else {
+          bad += 1;
+          this.piece_incorrect(qp);
+        }
+        all += 1;
+      }
+      return [good, bad, all];
+    };
+
+    PrawdaFalsz.prototype.show_solutions = function() {
+      var qp, _i, _len, _ref, _results;
+      this.reset();
+      _ref = $(".question-piece", this.element);
+      _results = [];
+      for (_i = 0, _len = _ref.length; _i < _len; _i++) {
+        qp = _ref[_i];
+        if ($(qp).data('solution') === true) {
+          _results.push($(".true", qp).click());
+        } else {
+          _results.push($(".false", qp).click());
+        }
+      }
+      return _results;
+    };
+
+    return PrawdaFalsz;
+
+  })(Exercise);
+
+  exercise = function(ele) {
+    var cls, es;
+    es = {
+      wybor: Wybor,
+      uporzadkuj: Uporzadkuj,
+      luki: Luki,
+      zastap: Zastap,
+      przyporzadkuj: Przyporzadkuj,
+      prawdafalsz: PrawdaFalsz
+    };
+    cls = es[$(ele).attr('data-type')];
+    return new cls(ele);
+  };
+
+  window.edumed = {
+    'EduModule': EduModule
+  };
+
+  $(document).ready(function() {
+    new EduModule($("#book-text"));
+    return $(".exercise").each(function(i, el) {
+      return exercise(this);
+    });
+  });
+
+}).call(this);
diff --git a/src/catalogue/static/catalogue/js/jquery-ui-1.10.0.custom.js b/src/catalogue/static/catalogue/js/jquery-ui-1.10.0.custom.js
new file mode 100644 (file)
index 0000000..d31460a
--- /dev/null
@@ -0,0 +1,5027 @@
+/*! jQuery UI - v1.10.0 - 2013-01-24
+* http://jqueryui.com
+* Includes: jquery.ui.core.js, jquery.ui.widget.js, jquery.ui.mouse.js, jquery.ui.draggable.js, jquery.ui.droppable.js, jquery.ui.selectable.js, jquery.ui.sortable.js, jquery.ui.effect.js
+* Copyright (c) 2013 jQuery Foundation and other contributors Licensed MIT */
+
+(function( $, undefined ) {
+
+var uuid = 0,
+       runiqueId = /^ui-id-\d+$/;
+
+// prevent duplicate loading
+// this is only a problem because we proxy existing functions
+// and we don't want to double proxy them
+$.ui = $.ui || {};
+if ( $.ui.version ) {
+       return;
+}
+
+$.extend( $.ui, {
+       version: "1.10.0",
+
+       keyCode: {
+               BACKSPACE: 8,
+               COMMA: 188,
+               DELETE: 46,
+               DOWN: 40,
+               END: 35,
+               ENTER: 13,
+               ESCAPE: 27,
+               HOME: 36,
+               LEFT: 37,
+               NUMPAD_ADD: 107,
+               NUMPAD_DECIMAL: 110,
+               NUMPAD_DIVIDE: 111,
+               NUMPAD_ENTER: 108,
+               NUMPAD_MULTIPLY: 106,
+               NUMPAD_SUBTRACT: 109,
+               PAGE_DOWN: 34,
+               PAGE_UP: 33,
+               PERIOD: 190,
+               RIGHT: 39,
+               SPACE: 32,
+               TAB: 9,
+               UP: 38
+       }
+});
+
+// plugins
+$.fn.extend({
+       _focus: $.fn.focus,
+       focus: function( delay, fn ) {
+               return typeof delay === "number" ?
+                       this.each(function() {
+                               var elem = this;
+                               setTimeout(function() {
+                                       $( elem ).focus();
+                                       if ( fn ) {
+                                               fn.call( elem );
+                                       }
+                               }, delay );
+                       }) :
+                       this._focus.apply( this, arguments );
+       },
+
+       scrollParent: function() {
+               var scrollParent;
+               if (($.ui.ie && (/(static|relative)/).test(this.css("position"))) || (/absolute/).test(this.css("position"))) {
+                       scrollParent = this.parents().filter(function() {
+                               return (/(relative|absolute|fixed)/).test($.css(this,"position")) && (/(auto|scroll)/).test($.css(this,"overflow")+$.css(this,"overflow-y")+$.css(this,"overflow-x"));
+                       }).eq(0);
+               } else {
+                       scrollParent = this.parents().filter(function() {
+                               return (/(auto|scroll)/).test($.css(this,"overflow")+$.css(this,"overflow-y")+$.css(this,"overflow-x"));
+                       }).eq(0);
+               }
+
+               return (/fixed/).test(this.css("position")) || !scrollParent.length ? $(document) : scrollParent;
+       },
+
+       zIndex: function( zIndex ) {
+               if ( zIndex !== undefined ) {
+                       return this.css( "zIndex", zIndex );
+               }
+
+               if ( this.length ) {
+                       var elem = $( this[ 0 ] ), position, value;
+                       while ( elem.length && elem[ 0 ] !== document ) {
+                               // Ignore z-index if position is set to a value where z-index is ignored by the browser
+                               // This makes behavior of this function consistent across browsers
+                               // WebKit always returns auto if the element is positioned
+                               position = elem.css( "position" );
+                               if ( position === "absolute" || position === "relative" || position === "fixed" ) {
+                                       // IE returns 0 when zIndex is not specified
+                                       // other browsers return a string
+                                       // we ignore the case of nested elements with an explicit value of 0
+                                       // <div style="z-index: -10;"><div style="z-index: 0;"></div></div>
+                                       value = parseInt( elem.css( "zIndex" ), 10 );
+                                       if ( !isNaN( value ) && value !== 0 ) {
+                                               return value;
+                                       }
+                               }
+                               elem = elem.parent();
+                       }
+               }
+
+               return 0;
+       },
+
+       uniqueId: function() {
+               return this.each(function() {
+                       if ( !this.id ) {
+                               this.id = "ui-id-" + (++uuid);
+                       }
+               });
+       },
+
+       removeUniqueId: function() {
+               return this.each(function() {
+                       if ( runiqueId.test( this.id ) ) {
+                               $( this ).removeAttr( "id" );
+                       }
+               });
+       }
+});
+
+// selectors
+function focusable( element, isTabIndexNotNaN ) {
+       var map, mapName, img,
+               nodeName = element.nodeName.toLowerCase();
+       if ( "area" === nodeName ) {
+               map = element.parentNode;
+               mapName = map.name;
+               if ( !element.href || !mapName || map.nodeName.toLowerCase() !== "map" ) {
+                       return false;
+               }
+               img = $( "img[usemap=#" + mapName + "]" )[0];
+               return !!img && visible( img );
+       }
+       return ( /input|select|textarea|button|object/.test( nodeName ) ?
+               !element.disabled :
+               "a" === nodeName ?
+                       element.href || isTabIndexNotNaN :
+                       isTabIndexNotNaN) &&
+               // the element and all of its ancestors must be visible
+               visible( element );
+}
+
+function visible( element ) {
+       return $.expr.filters.visible( element ) &&
+               !$( element ).parents().addBack().filter(function() {
+                       return $.css( this, "visibility" ) === "hidden";
+               }).length;
+}
+
+$.extend( $.expr[ ":" ], {
+       data: $.expr.createPseudo ?
+               $.expr.createPseudo(function( dataName ) {
+                       return function( elem ) {
+                               return !!$.data( elem, dataName );
+                       };
+               }) :
+               // support: jQuery <1.8
+               function( elem, i, match ) {
+                       return !!$.data( elem, match[ 3 ] );
+               },
+
+       focusable: function( element ) {
+               return focusable( element, !isNaN( $.attr( element, "tabindex" ) ) );
+       },
+
+       tabbable: function( element ) {
+               var tabIndex = $.attr( element, "tabindex" ),
+                       isTabIndexNaN = isNaN( tabIndex );
+               return ( isTabIndexNaN || tabIndex >= 0 ) && focusable( element, !isTabIndexNaN );
+       }
+});
+
+// support: jQuery <1.8
+if ( !$( "<a>" ).outerWidth( 1 ).jquery ) {
+       $.each( [ "Width", "Height" ], function( i, name ) {
+               var side = name === "Width" ? [ "Left", "Right" ] : [ "Top", "Bottom" ],
+                       type = name.toLowerCase(),
+                       orig = {
+                               innerWidth: $.fn.innerWidth,
+                               innerHeight: $.fn.innerHeight,
+                               outerWidth: $.fn.outerWidth,
+                               outerHeight: $.fn.outerHeight
+                       };
+
+               function reduce( elem, size, border, margin ) {
+                       $.each( side, function() {
+                               size -= parseFloat( $.css( elem, "padding" + this ) ) || 0;
+                               if ( border ) {
+                                       size -= parseFloat( $.css( elem, "border" + this + "Width" ) ) || 0;
+                               }
+                               if ( margin ) {
+                                       size -= parseFloat( $.css( elem, "margin" + this ) ) || 0;
+                               }
+                       });
+                       return size;
+               }
+
+               $.fn[ "inner" + name ] = function( size ) {
+                       if ( size === undefined ) {
+                               return orig[ "inner" + name ].call( this );
+                       }
+
+                       return this.each(function() {
+                               $( this ).css( type, reduce( this, size ) + "px" );
+                       });
+               };
+
+               $.fn[ "outer" + name] = function( size, margin ) {
+                       if ( typeof size !== "number" ) {
+                               return orig[ "outer" + name ].call( this, size );
+                       }
+
+                       return this.each(function() {
+                               $( this).css( type, reduce( this, size, true, margin ) + "px" );
+                       });
+               };
+       });
+}
+
+// support: jQuery <1.8
+if ( !$.fn.addBack ) {
+       $.fn.addBack = function( selector ) {
+               return this.add( selector == null ?
+                       this.prevObject : this.prevObject.filter( selector )
+               );
+       };
+}
+
+// support: jQuery 1.6.1, 1.6.2 (http://bugs.jquery.com/ticket/9413)
+if ( $( "<a>" ).data( "a-b", "a" ).removeData( "a-b" ).data( "a-b" ) ) {
+       $.fn.removeData = (function( removeData ) {
+               return function( key ) {
+                       if ( arguments.length ) {
+                               return removeData.call( this, $.camelCase( key ) );
+                       } else {
+                               return removeData.call( this );
+                       }
+               };
+       })( $.fn.removeData );
+}
+
+
+
+
+
+// deprecated
+$.ui.ie = !!/msie [\w.]+/.exec( navigator.userAgent.toLowerCase() );
+
+$.support.selectstart = "onselectstart" in document.createElement( "div" );
+$.fn.extend({
+       disableSelection: function() {
+               return this.bind( ( $.support.selectstart ? "selectstart" : "mousedown" ) +
+                       ".ui-disableSelection", function( event ) {
+                               event.preventDefault();
+                       });
+       },
+
+       enableSelection: function() {
+               return this.unbind( ".ui-disableSelection" );
+       }
+});
+
+$.extend( $.ui, {
+       // $.ui.plugin is deprecated.  Use the proxy pattern instead.
+       plugin: {
+               add: function( module, option, set ) {
+                       var i,
+                               proto = $.ui[ module ].prototype;
+                       for ( i in set ) {
+                               proto.plugins[ i ] = proto.plugins[ i ] || [];
+                               proto.plugins[ i ].push( [ option, set[ i ] ] );
+                       }
+               },
+               call: function( instance, name, args ) {
+                       var i,
+                               set = instance.plugins[ name ];
+                       if ( !set || !instance.element[ 0 ].parentNode || instance.element[ 0 ].parentNode.nodeType === 11 ) {
+                               return;
+                       }
+
+                       for ( i = 0; i < set.length; i++ ) {
+                               if ( instance.options[ set[ i ][ 0 ] ] ) {
+                                       set[ i ][ 1 ].apply( instance.element, args );
+                               }
+                       }
+               }
+       },
+
+       // only used by resizable
+       hasScroll: function( el, a ) {
+
+               //If overflow is hidden, the element might have extra content, but the user wants to hide it
+               if ( $( el ).css( "overflow" ) === "hidden") {
+                       return false;
+               }
+
+               var scroll = ( a && a === "left" ) ? "scrollLeft" : "scrollTop",
+                       has = false;
+
+               if ( el[ scroll ] > 0 ) {
+                       return true;
+               }
+
+               // TODO: determine which cases actually cause this to happen
+               // if the element doesn't have the scroll set, see if it's possible to
+               // set the scroll
+               el[ scroll ] = 1;
+               has = ( el[ scroll ] > 0 );
+               el[ scroll ] = 0;
+               return has;
+       }
+});
+
+})( jQuery );
+(function( $, undefined ) {
+
+var uuid = 0,
+       slice = Array.prototype.slice,
+       _cleanData = $.cleanData;
+$.cleanData = function( elems ) {
+       for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) {
+               try {
+                       $( elem ).triggerHandler( "remove" );
+               // http://bugs.jquery.com/ticket/8235
+               } catch( e ) {}
+       }
+       _cleanData( elems );
+};
+
+$.widget = function( name, base, prototype ) {
+       var fullName, existingConstructor, constructor, basePrototype,
+               // proxiedPrototype allows the provided prototype to remain unmodified
+               // so that it can be used as a mixin for multiple widgets (#8876)
+               proxiedPrototype = {},
+               namespace = name.split( "." )[ 0 ];
+
+       name = name.split( "." )[ 1 ];
+       fullName = namespace + "-" + name;
+
+       if ( !prototype ) {
+               prototype = base;
+               base = $.Widget;
+       }
+
+       // create selector for plugin
+       $.expr[ ":" ][ fullName.toLowerCase() ] = function( elem ) {
+               return !!$.data( elem, fullName );
+       };
+
+       $[ namespace ] = $[ namespace ] || {};
+       existingConstructor = $[ namespace ][ name ];
+       constructor = $[ namespace ][ name ] = function( options, element ) {
+               // allow instantiation without "new" keyword
+               if ( !this._createWidget ) {
+                       return new constructor( options, element );
+               }
+
+               // allow instantiation without initializing for simple inheritance
+               // must use "new" keyword (the code above always passes args)
+               if ( arguments.length ) {
+                       this._createWidget( options, element );
+               }
+       };
+       // extend with the existing constructor to carry over any static properties
+       $.extend( constructor, existingConstructor, {
+               version: prototype.version,
+               // copy the object used to create the prototype in case we need to
+               // redefine the widget later
+               _proto: $.extend( {}, prototype ),
+               // track widgets that inherit from this widget in case this widget is
+               // redefined after a widget inherits from it
+               _childConstructors: []
+       });
+
+       basePrototype = new base();
+       // we need to make the options hash a property directly on the new instance
+       // otherwise we'll modify the options hash on the prototype that we're
+       // inheriting from
+       basePrototype.options = $.widget.extend( {}, basePrototype.options );
+       $.each( prototype, function( prop, value ) {
+               if ( !$.isFunction( value ) ) {
+                       proxiedPrototype[ prop ] = value;
+                       return;
+               }
+               proxiedPrototype[ prop ] = (function() {
+                       var _super = function() {
+                                       return base.prototype[ prop ].apply( this, arguments );
+                               },
+                               _superApply = function( args ) {
+                                       return base.prototype[ prop ].apply( this, args );
+                               };
+                       return function() {
+                               var __super = this._super,
+                                       __superApply = this._superApply,
+                                       returnValue;
+
+                               this._super = _super;
+                               this._superApply = _superApply;
+
+                               returnValue = value.apply( this, arguments );
+
+                               this._super = __super;
+                               this._superApply = __superApply;
+
+                               return returnValue;
+                       };
+               })();
+       });
+       constructor.prototype = $.widget.extend( basePrototype, {
+               // TODO: remove support for widgetEventPrefix
+               // always use the name + a colon as the prefix, e.g., draggable:start
+               // don't prefix for widgets that aren't DOM-based
+               widgetEventPrefix: existingConstructor ? basePrototype.widgetEventPrefix : name
+       }, proxiedPrototype, {
+               constructor: constructor,
+               namespace: namespace,
+               widgetName: name,
+               widgetFullName: fullName
+       });
+
+       // If this widget is being redefined then we need to find all widgets that
+       // are inheriting from it and redefine all of them so that they inherit from
+       // the new version of this widget. We're essentially trying to replace one
+       // level in the prototype chain.
+       if ( existingConstructor ) {
+               $.each( existingConstructor._childConstructors, function( i, child ) {
+                       var childPrototype = child.prototype;
+
+                       // redefine the child widget using the same prototype that was
+                       // originally used, but inherit from the new version of the base
+                       $.widget( childPrototype.namespace + "." + childPrototype.widgetName, constructor, child._proto );
+               });
+               // remove the list of existing child constructors from the old constructor
+               // so the old child constructors can be garbage collected
+               delete existingConstructor._childConstructors;
+       } else {
+               base._childConstructors.push( constructor );
+       }
+
+       $.widget.bridge( name, constructor );
+};
+
+$.widget.extend = function( target ) {
+       var input = slice.call( arguments, 1 ),
+               inputIndex = 0,
+               inputLength = input.length,
+               key,
+               value;
+       for ( ; inputIndex < inputLength; inputIndex++ ) {
+               for ( key in input[ inputIndex ] ) {
+                       value = input[ inputIndex ][ key ];
+                       if ( input[ inputIndex ].hasOwnProperty( key ) && value !== undefined ) {
+                               // Clone objects
+                               if ( $.isPlainObject( value ) ) {
+                                       target[ key ] = $.isPlainObject( target[ key ] ) ?
+                                               $.widget.extend( {}, target[ key ], value ) :
+                                               // Don't extend strings, arrays, etc. with objects
+                                               $.widget.extend( {}, value );
+                               // Copy everything else by reference
+                               } else {
+                                       target[ key ] = value;
+                               }
+                       }
+               }
+       }
+       return target;
+};
+
+$.widget.bridge = function( name, object ) {
+       var fullName = object.prototype.widgetFullName || name;
+       $.fn[ name ] = function( options ) {
+               var isMethodCall = typeof options === "string",
+                       args = slice.call( arguments, 1 ),
+                       returnValue = this;
+
+               // allow multiple hashes to be passed on init
+               options = !isMethodCall && args.length ?
+                       $.widget.extend.apply( null, [ options ].concat(args) ) :
+                       options;
+
+               if ( isMethodCall ) {
+                       this.each(function() {
+                               var methodValue,
+                                       instance = $.data( this, fullName );
+                               if ( !instance ) {
+                                       return $.error( "cannot call methods on " + name + " prior to initialization; " +
+                                               "attempted to call method '" + options + "'" );
+                               }
+                               if ( !$.isFunction( instance[options] ) || options.charAt( 0 ) === "_" ) {
+                                       return $.error( "no such method '" + options + "' for " + name + " widget instance" );
+                               }
+                               methodValue = instance[ options ].apply( instance, args );
+                               if ( methodValue !== instance && methodValue !== undefined ) {
+                                       returnValue = methodValue && methodValue.jquery ?
+                                               returnValue.pushStack( methodValue.get() ) :
+                                               methodValue;
+                                       return false;
+                               }
+                       });
+               } else {
+                       this.each(function() {
+                               var instance = $.data( this, fullName );
+                               if ( instance ) {
+                                       instance.option( options || {} )._init();
+                               } else {
+                                       $.data( this, fullName, new object( options, this ) );
+                               }
+                       });
+               }
+
+               return returnValue;
+       };
+};
+
+$.Widget = function( /* options, element */ ) {};
+$.Widget._childConstructors = [];
+
+$.Widget.prototype = {
+       widgetName: "widget",
+       widgetEventPrefix: "",
+       defaultElement: "<div>",
+       options: {
+               disabled: false,
+
+               // callbacks
+               create: null
+       },
+       _createWidget: function( options, element ) {
+               element = $( element || this.defaultElement || this )[ 0 ];
+               this.element = $( element );
+               this.uuid = uuid++;
+               this.eventNamespace = "." + this.widgetName + this.uuid;
+               this.options = $.widget.extend( {},
+                       this.options,
+                       this._getCreateOptions(),
+                       options );
+
+               this.bindings = $();
+               this.hoverable = $();
+               this.focusable = $();
+
+               if ( element !== this ) {
+                       $.data( element, this.widgetFullName, this );
+                       this._on( true, this.element, {
+                               remove: function( event ) {
+                                       if ( event.target === element ) {
+                                               this.destroy();
+                                       }
+                               }
+                       });
+                       this.document = $( element.style ?
+                               // element within the document
+                               element.ownerDocument :
+                               // element is window or document
+                               element.document || element );
+                       this.window = $( this.document[0].defaultView || this.document[0].parentWindow );
+               }
+
+               this._create();
+               this._trigger( "create", null, this._getCreateEventData() );
+               this._init();
+       },
+       _getCreateOptions: $.noop,
+       _getCreateEventData: $.noop,
+       _create: $.noop,
+       _init: $.noop,
+
+       destroy: function() {
+               this._destroy();
+               // we can probably remove the unbind calls in 2.0
+               // all event bindings should go through this._on()
+               this.element
+                       .unbind( this.eventNamespace )
+                       // 1.9 BC for #7810
+                       // TODO remove dual storage
+                       .removeData( this.widgetName )
+                       .removeData( this.widgetFullName )
+                       // support: jquery <1.6.3
+                       // http://bugs.jquery.com/ticket/9413
+                       .removeData( $.camelCase( this.widgetFullName ) );
+               this.widget()
+                       .unbind( this.eventNamespace )
+                       .removeAttr( "aria-disabled" )
+                       .removeClass(
+                               this.widgetFullName + "-disabled " +
+                               "ui-state-disabled" );
+
+               // clean up events and states
+               this.bindings.unbind( this.eventNamespace );
+               this.hoverable.removeClass( "ui-state-hover" );
+               this.focusable.removeClass( "ui-state-focus" );
+       },
+       _destroy: $.noop,
+
+       widget: function() {
+               return this.element;
+       },
+
+       option: function( key, value ) {
+               var options = key,
+                       parts,
+                       curOption,
+                       i;
+
+               if ( arguments.length === 0 ) {
+                       // don't return a reference to the internal hash
+                       return $.widget.extend( {}, this.options );
+               }
+
+               if ( typeof key === "string" ) {
+                       // handle nested keys, e.g., "foo.bar" => { foo: { bar: ___ } }
+                       options = {};
+                       parts = key.split( "." );
+                       key = parts.shift();
+                       if ( parts.length ) {
+                               curOption = options[ key ] = $.widget.extend( {}, this.options[ key ] );
+                               for ( i = 0; i < parts.length - 1; i++ ) {
+                                       curOption[ parts[ i ] ] = curOption[ parts[ i ] ] || {};
+                                       curOption = curOption[ parts[ i ] ];
+                               }
+                               key = parts.pop();
+                               if ( value === undefined ) {
+                                       return curOption[ key ] === undefined ? null : curOption[ key ];
+                               }
+                               curOption[ key ] = value;
+                       } else {
+                               if ( value === undefined ) {
+                                       return this.options[ key ] === undefined ? null : this.options[ key ];
+                               }
+                               options[ key ] = value;
+                       }
+               }
+
+               this._setOptions( options );
+
+               return this;
+       },
+       _setOptions: function( options ) {
+               var key;
+
+               for ( key in options ) {
+                       this._setOption( key, options[ key ] );
+               }
+
+               return this;
+       },
+       _setOption: function( key, value ) {
+               this.options[ key ] = value;
+
+               if ( key === "disabled" ) {
+                       this.widget()
+                               .toggleClass( this.widgetFullName + "-disabled ui-state-disabled", !!value )
+                               .attr( "aria-disabled", value );
+                       this.hoverable.removeClass( "ui-state-hover" );
+                       this.focusable.removeClass( "ui-state-focus" );
+               }
+
+               return this;
+       },
+
+       enable: function() {
+               return this._setOption( "disabled", false );
+       },
+       disable: function() {
+               return this._setOption( "disabled", true );
+       },
+
+       _on: function( suppressDisabledCheck, element, handlers ) {
+               var delegateElement,
+                       instance = this;
+
+               // no suppressDisabledCheck flag, shuffle arguments
+               if ( typeof suppressDisabledCheck !== "boolean" ) {
+                       handlers = element;
+                       element = suppressDisabledCheck;
+                       suppressDisabledCheck = false;
+               }
+
+               // no element argument, shuffle and use this.element
+               if ( !handlers ) {
+                       handlers = element;
+                       element = this.element;
+                       delegateElement = this.widget();
+               } else {
+                       // accept selectors, DOM elements
+                       element = delegateElement = $( element );
+                       this.bindings = this.bindings.add( element );
+               }
+
+               $.each( handlers, function( event, handler ) {
+                       function handlerProxy() {
+                               // allow widgets to customize the disabled handling
+                               // - disabled as an array instead of boolean
+                               // - disabled class as method for disabling individual parts
+                               if ( !suppressDisabledCheck &&
+                                               ( instance.options.disabled === true ||
+                                                       $( this ).hasClass( "ui-state-disabled" ) ) ) {
+                                       return;
+                               }
+                               return ( typeof handler === "string" ? instance[ handler ] : handler )
+                                       .apply( instance, arguments );
+                       }
+
+                       // copy the guid so direct unbinding works
+                       if ( typeof handler !== "string" ) {
+                               handlerProxy.guid = handler.guid =
+                                       handler.guid || handlerProxy.guid || $.guid++;
+                       }
+
+                       var match = event.match( /^(\w+)\s*(.*)$/ ),
+                               eventName = match[1] + instance.eventNamespace,
+                               selector = match[2];
+                       if ( selector ) {
+                               delegateElement.delegate( selector, eventName, handlerProxy );
+                       } else {
+                               element.bind( eventName, handlerProxy );
+                       }
+               });
+       },
+
+       _off: function( element, eventName ) {
+               eventName = (eventName || "").split( " " ).join( this.eventNamespace + " " ) + this.eventNamespace;
+               element.unbind( eventName ).undelegate( eventName );
+       },
+
+       _delay: function( handler, delay ) {
+               function handlerProxy() {
+                       return ( typeof handler === "string" ? instance[ handler ] : handler )
+                               .apply( instance, arguments );
+               }
+               var instance = this;
+               return setTimeout( handlerProxy, delay || 0 );
+       },
+
+       _hoverable: function( element ) {
+               this.hoverable = this.hoverable.add( element );
+               this._on( element, {
+                       mouseenter: function( event ) {
+                               $( event.currentTarget ).addClass( "ui-state-hover" );
+                       },
+                       mouseleave: function( event ) {
+                               $( event.currentTarget ).removeClass( "ui-state-hover" );
+                       }
+               });
+       },
+
+       _focusable: function( element ) {
+               this.focusable = this.focusable.add( element );
+               this._on( element, {
+                       focusin: function( event ) {
+                               $( event.currentTarget ).addClass( "ui-state-focus" );
+                       },
+                       focusout: function( event ) {
+                               $( event.currentTarget ).removeClass( "ui-state-focus" );
+                       }
+               });
+       },
+
+       _trigger: function( type, event, data ) {
+               var prop, orig,
+                       callback = this.options[ type ];
+
+               data = data || {};
+               event = $.Event( event );
+               event.type = ( type === this.widgetEventPrefix ?
+                       type :
+                       this.widgetEventPrefix + type ).toLowerCase();
+               // the original event may come from any element
+               // so we need to reset the target on the new event
+               event.target = this.element[ 0 ];
+
+               // copy original event properties over to the new event
+               orig = event.originalEvent;
+               if ( orig ) {
+                       for ( prop in orig ) {
+                               if ( !( prop in event ) ) {
+                                       event[ prop ] = orig[ prop ];
+                               }
+                       }
+               }
+
+               this.element.trigger( event, data );
+               return !( $.isFunction( callback ) &&
+                       callback.apply( this.element[0], [ event ].concat( data ) ) === false ||
+                       event.isDefaultPrevented() );
+       }
+};
+
+$.each( { show: "fadeIn", hide: "fadeOut" }, function( method, defaultEffect ) {
+       $.Widget.prototype[ "_" + method ] = function( element, options, callback ) {
+               if ( typeof options === "string" ) {
+                       options = { effect: options };
+               }
+               var hasOptions,
+                       effectName = !options ?
+                               method :
+                               options === true || typeof options === "number" ?
+                                       defaultEffect :
+                                       options.effect || defaultEffect;
+               options = options || {};
+               if ( typeof options === "number" ) {
+                       options = { duration: options };
+               }
+               hasOptions = !$.isEmptyObject( options );
+               options.complete = callback;
+               if ( options.delay ) {
+                       element.delay( options.delay );
+               }
+               if ( hasOptions && $.effects && $.effects.effect[ effectName ] ) {
+                       element[ method ]( options );
+               } else if ( effectName !== method && element[ effectName ] ) {
+                       element[ effectName ]( options.duration, options.easing, callback );
+               } else {
+                       element.queue(function( next ) {
+                               $( this )[ method ]();
+                               if ( callback ) {
+                                       callback.call( element[ 0 ] );
+                               }
+                               next();
+                       });
+               }
+       };
+});
+
+})( jQuery );
+(function( $, undefined ) {
+
+var mouseHandled = false;
+$( document ).mouseup( function() {
+       mouseHandled = false;
+});
+
+$.widget("ui.mouse", {
+       version: "1.10.0",
+       options: {
+               cancel: "input,textarea,button,select,option",
+               distance: 1,
+               delay: 0
+       },
+       _mouseInit: function() {
+               var that = this;
+
+               this.element
+                       .bind("mousedown."+this.widgetName, function(event) {
+                               return that._mouseDown(event);
+                       })
+                       .bind("click."+this.widgetName, function(event) {
+                               if (true === $.data(event.target, that.widgetName + ".preventClickEvent")) {
+                                       $.removeData(event.target, that.widgetName + ".preventClickEvent");
+                                       event.stopImmediatePropagation();
+                                       return false;
+                               }
+                       });
+
+               this.started = false;
+       },
+
+       // TODO: make sure destroying one instance of mouse doesn't mess with
+       // other instances of mouse
+       _mouseDestroy: function() {
+               this.element.unbind("."+this.widgetName);
+               if ( this._mouseMoveDelegate ) {
+                       $(document)
+                               .unbind("mousemove."+this.widgetName, this._mouseMoveDelegate)
+                               .unbind("mouseup."+this.widgetName, this._mouseUpDelegate);
+               }
+       },
+
+       _mouseDown: function(event) {
+               // don't let more than one widget handle mouseStart
+               if( mouseHandled ) { return; }
+
+               // we may have missed mouseup (out of window)
+               (this._mouseStarted && this._mouseUp(event));
+
+               this._mouseDownEvent = event;
+
+               var that = this,
+                       btnIsLeft = (event.which === 1),
+                       // event.target.nodeName works around a bug in IE 8 with
+                       // disabled inputs (#7620)
+                       elIsCancel = (typeof this.options.cancel === "string" && event.target.nodeName ? $(event.target).closest(this.options.cancel).length : false);
+               if (!btnIsLeft || elIsCancel || !this._mouseCapture(event)) {
+                       return true;
+               }
+
+               this.mouseDelayMet = !this.options.delay;
+               if (!this.mouseDelayMet) {
+                       this._mouseDelayTimer = setTimeout(function() {
+                               that.mouseDelayMet = true;
+                       }, this.options.delay);
+               }
+
+               if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) {
+                       this._mouseStarted = (this._mouseStart(event) !== false);
+                       if (!this._mouseStarted) {
+                               event.preventDefault();
+                               return true;
+                       }
+               }
+
+               // Click event may never have fired (Gecko & Opera)
+               if (true === $.data(event.target, this.widgetName + ".preventClickEvent")) {
+                       $.removeData(event.target, this.widgetName + ".preventClickEvent");
+               }
+
+               // these delegates are required to keep context
+               this._mouseMoveDelegate = function(event) {
+                       return that._mouseMove(event);
+               };
+               this._mouseUpDelegate = function(event) {
+                       return that._mouseUp(event);
+               };
+               $(document)
+                       .bind("mousemove."+this.widgetName, this._mouseMoveDelegate)
+                       .bind("mouseup."+this.widgetName, this._mouseUpDelegate);
+
+               event.preventDefault();
+
+               mouseHandled = true;
+               return true;
+       },
+
+       _mouseMove: function(event) {
+               // IE mouseup check - mouseup happened when mouse was out of window
+               if ($.ui.ie && ( !document.documentMode || document.documentMode < 9 ) && !event.button) {
+                       return this._mouseUp(event);
+               }
+
+               if (this._mouseStarted) {
+                       this._mouseDrag(event);
+                       return event.preventDefault();
+               }
+
+               if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) {
+                       this._mouseStarted =
+                               (this._mouseStart(this._mouseDownEvent, event) !== false);
+                       (this._mouseStarted ? this._mouseDrag(event) : this._mouseUp(event));
+               }
+
+               return !this._mouseStarted;
+       },
+
+       _mouseUp: function(event) {
+               $(document)
+                       .unbind("mousemove."+this.widgetName, this._mouseMoveDelegate)
+                       .unbind("mouseup."+this.widgetName, this._mouseUpDelegate);
+
+               if (this._mouseStarted) {
+                       this._mouseStarted = false;
+
+                       if (event.target === this._mouseDownEvent.target) {
+                               $.data(event.target, this.widgetName + ".preventClickEvent", true);
+                       }
+
+                       this._mouseStop(event);
+               }
+
+               return false;
+       },
+
+       _mouseDistanceMet: function(event) {
+               return (Math.max(
+                               Math.abs(this._mouseDownEvent.pageX - event.pageX),
+                               Math.abs(this._mouseDownEvent.pageY - event.pageY)
+                       ) >= this.options.distance
+               );
+       },
+
+       _mouseDelayMet: function(/* event */) {
+               return this.mouseDelayMet;
+       },
+
+       // These are placeholder methods, to be overriden by extending plugin
+       _mouseStart: function(/* event */) {},
+       _mouseDrag: function(/* event */) {},
+       _mouseStop: function(/* event */) {},
+       _mouseCapture: function(/* event */) { return true; }
+});
+
+})(jQuery);
+(function( $, undefined ) {
+
+$.widget("ui.draggable", $.ui.mouse, {
+       version: "1.10.0",
+       widgetEventPrefix: "drag",
+       options: {
+               addClasses: true,
+               appendTo: "parent",
+               axis: false,
+               connectToSortable: false,
+               containment: false,
+               cursor: "auto",
+               cursorAt: false,
+               grid: false,
+               handle: false,
+               helper: "original",
+               iframeFix: false,
+               opacity: false,
+               refreshPositions: false,
+               revert: false,
+               revertDuration: 500,
+               scope: "default",
+               scroll: true,
+               scrollSensitivity: 20,
+               scrollSpeed: 20,
+               snap: false,
+               snapMode: "both",
+               snapTolerance: 20,
+               stack: false,
+               zIndex: false,
+
+               // callbacks
+               drag: null,
+               start: null,
+               stop: null
+       },
+       _create: function() {
+
+               if (this.options.helper === "original" && !(/^(?:r|a|f)/).test(this.element.css("position"))) {
+                       this.element[0].style.position = "relative";
+               }
+               if (this.options.addClasses){
+                       this.element.addClass("ui-draggable");
+               }
+               if (this.options.disabled){
+                       this.element.addClass("ui-draggable-disabled");
+               }
+
+               this._mouseInit();
+
+       },
+
+       _destroy: function() {
+               this.element.removeClass( "ui-draggable ui-draggable-dragging ui-draggable-disabled" );
+               this._mouseDestroy();
+       },
+
+       _mouseCapture: function(event) {
+
+               var o = this.options;
+
+               // among others, prevent a drag on a resizable-handle
+               if (this.helper || o.disabled || $(event.target).closest(".ui-resizable-handle").length > 0) {
+                       return false;
+               }
+
+               //Quit if we're not on a valid handle
+               this.handle = this._getHandle(event);
+               if (!this.handle) {
+                       return false;
+               }
+
+               $(o.iframeFix === true ? "iframe" : o.iframeFix).each(function() {
+                       $("<div class='ui-draggable-iframeFix' style='background: #fff;'></div>")
+                       .css({
+                               width: this.offsetWidth+"px", height: this.offsetHeight+"px",
+                               position: "absolute", opacity: "0.001", zIndex: 1000
+                       })
+                       .css($(this).offset())
+                       .appendTo("body");
+               });
+
+               return true;
+
+       },
+
+       _mouseStart: function(event) {
+
+               var o = this.options;
+
+               //Create and append the visible helper
+               this.helper = this._createHelper(event);
+
+               this.helper.addClass("ui-draggable-dragging");
+
+               //Cache the helper size
+               this._cacheHelperProportions();
+
+               //If ddmanager is used for droppables, set the global draggable
+               if($.ui.ddmanager) {
+                       $.ui.ddmanager.current = this;
+               }
+
+               /*
+                * - Position generation -
+                * This block generates everything position related - it's the core of draggables.
+                */
+
+               //Cache the margins of the original element
+               this._cacheMargins();
+
+               //Store the helper's css position
+               this.cssPosition = this.helper.css("position");
+               this.scrollParent = this.helper.scrollParent();
+
+               //The element's absolute position on the page minus margins
+               this.offset = this.positionAbs = this.element.offset();
+               this.offset = {
+                       top: this.offset.top - this.margins.top,
+                       left: this.offset.left - this.margins.left
+               };
+
+               $.extend(this.offset, {
+                       click: { //Where the click happened, relative to the element
+                               left: event.pageX - this.offset.left,
+                               top: event.pageY - this.offset.top
+                       },
+                       parent: this._getParentOffset(),
+                       relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper
+               });
+
+               //Generate the original position
+               this.originalPosition = this.position = this._generatePosition(event);
+               this.originalPageX = event.pageX;
+               this.originalPageY = event.pageY;
+
+               //Adjust the mouse offset relative to the helper if "cursorAt" is supplied
+               (o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt));
+
+               //Set a containment if given in the options
+               if(o.containment) {
+                       this._setContainment();
+               }
+
+               //Trigger event + callbacks
+               if(this._trigger("start", event) === false) {
+                       this._clear();
+                       return false;
+               }
+
+               //Recache the helper size
+               this._cacheHelperProportions();
+
+               //Prepare the droppable offsets
+               if ($.ui.ddmanager && !o.dropBehaviour) {
+                       $.ui.ddmanager.prepareOffsets(this, event);
+               }
+
+
+               this._mouseDrag(event, true); //Execute the drag once - this causes the helper not to be visible before getting its correct position
+
+               //If the ddmanager is used for droppables, inform the manager that dragging has started (see #5003)
+               if ( $.ui.ddmanager ) {
+                       $.ui.ddmanager.dragStart(this, event);
+               }
+
+               return true;
+       },
+
+       _mouseDrag: function(event, noPropagation) {
+
+               //Compute the helpers position
+               this.position = this._generatePosition(event);
+               this.positionAbs = this._convertPositionTo("absolute");
+
+               //Call plugins and callbacks and use the resulting position if something is returned
+               if (!noPropagation) {
+                       var ui = this._uiHash();
+                       if(this._trigger("drag", event, ui) === false) {
+                               this._mouseUp({});
+                               return false;
+                       }
+                       this.position = ui.position;
+               }
+
+               if(!this.options.axis || this.options.axis !== "y") {
+                       this.helper[0].style.left = this.position.left+"px";
+               }
+               if(!this.options.axis || this.options.axis !== "x") {
+                       this.helper[0].style.top = this.position.top+"px";
+               }
+               if($.ui.ddmanager) {
+                       $.ui.ddmanager.drag(this, event);
+               }
+
+               return false;
+       },
+
+       _mouseStop: function(event) {
+
+               //If we are using droppables, inform the manager about the drop
+               var element,
+                       that = this,
+                       elementInDom = false,
+                       dropped = false;
+               if ($.ui.ddmanager && !this.options.dropBehaviour) {
+                       dropped = $.ui.ddmanager.drop(this, event);
+               }
+
+               //if a drop comes from outside (a sortable)
+               if(this.dropped) {
+                       dropped = this.dropped;
+                       this.dropped = false;
+               }
+
+               //if the original element is no longer in the DOM don't bother to continue (see #8269)
+               element = this.element[0];
+               while ( element && (element = element.parentNode) ) {
+                       if (element === document ) {
+                               elementInDom = true;
+                       }
+               }
+               if ( !elementInDom && this.options.helper === "original" ) {
+                       return false;
+               }
+
+               if((this.options.revert === "invalid" && !dropped) || (this.options.revert === "valid" && dropped) || this.options.revert === true || ($.isFunction(this.options.revert) && this.options.revert.call(this.element, dropped))) {
+                       $(this.helper).animate(this.originalPosition, parseInt(this.options.revertDuration, 10), function() {
+                               if(that._trigger("stop", event) !== false) {
+                                       that._clear();
+                               }
+                       });
+               } else {
+                       if(this._trigger("stop", event) !== false) {
+                               this._clear();
+                       }
+               }
+
+               return false;
+       },
+
+       _mouseUp: function(event) {
+               //Remove frame helpers
+               $("div.ui-draggable-iframeFix").each(function() {
+                       this.parentNode.removeChild(this);
+               });
+
+               //If the ddmanager is used for droppables, inform the manager that dragging has stopped (see #5003)
+               if( $.ui.ddmanager ) {
+                       $.ui.ddmanager.dragStop(this, event);
+               }
+
+               return $.ui.mouse.prototype._mouseUp.call(this, event);
+       },
+
+       cancel: function() {
+
+               if(this.helper.is(".ui-draggable-dragging")) {
+                       this._mouseUp({});
+               } else {
+                       this._clear();
+               }
+
+               return this;
+
+       },
+
+       _getHandle: function(event) {
+
+               var handle = !this.options.handle || !$(this.options.handle, this.element).length ? true : false;
+               $(this.options.handle, this.element)
+                       .find("*")
+                       .addBack()
+                       .each(function() {
+                               if(this === event.target) {
+                                       handle = true;
+                               }
+                       });
+
+               return handle;
+
+       },
+
+       _createHelper: function(event) {
+
+               var o = this.options,
+                       helper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[0], [event])) : (o.helper === "clone" ? this.element.clone().removeAttr("id") : this.element);
+
+               if(!helper.parents("body").length) {
+                       helper.appendTo((o.appendTo === "parent" ? this.element[0].parentNode : o.appendTo));
+               }
+
+               if(helper[0] !== this.element[0] && !(/(fixed|absolute)/).test(helper.css("position"))) {
+                       helper.css("position", "absolute");
+               }
+
+               return helper;
+
+       },
+
+       _adjustOffsetFromHelper: function(obj) {
+               if (typeof obj === "string") {
+                       obj = obj.split(" ");
+               }
+               if ($.isArray(obj)) {
+                       obj = {left: +obj[0], top: +obj[1] || 0};
+               }
+               if ("left" in obj) {
+                       this.offset.click.left = obj.left + this.margins.left;
+               }
+               if ("right" in obj) {
+                       this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
+               }
+               if ("top" in obj) {
+                       this.offset.click.top = obj.top + this.margins.top;
+               }
+               if ("bottom" in obj) {
+                       this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
+               }
+       },
+
+       _getParentOffset: function() {
+
+               //Get the offsetParent and cache its position
+               this.offsetParent = this.helper.offsetParent();
+               var po = this.offsetParent.offset();
+
+               // This is a special case where we need to modify a offset calculated on start, since the following happened:
+               // 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent
+               // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that
+               //    the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag
+               if(this.cssPosition === "absolute" && this.scrollParent[0] !== document && $.contains(this.scrollParent[0], this.offsetParent[0])) {
+                       po.left += this.scrollParent.scrollLeft();
+                       po.top += this.scrollParent.scrollTop();
+               }
+
+               //This needs to be actually done for all browsers, since pageX/pageY includes this information
+               //Ugly IE fix
+               if((this.offsetParent[0] === document.body) ||
+                       (this.offsetParent[0].tagName && this.offsetParent[0].tagName.toLowerCase() === "html" && $.ui.ie)) {
+                       po = { top: 0, left: 0 };
+               }
+
+               return {
+                       top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"),10) || 0),
+                       left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"),10) || 0)
+               };
+
+       },
+
+       _getRelativeOffset: function() {
+
+               if(this.cssPosition === "relative") {
+                       var p = this.element.position();
+                       return {
+                               top: p.top - (parseInt(this.helper.css("top"),10) || 0) + this.scrollParent.scrollTop(),
+                               left: p.left - (parseInt(this.helper.css("left"),10) || 0) + this.scrollParent.scrollLeft()
+                       };
+               } else {
+                       return { top: 0, left: 0 };
+               }
+
+       },
+
+       _cacheMargins: function() {
+               this.margins = {
+                       left: (parseInt(this.element.css("marginLeft"),10) || 0),
+                       top: (parseInt(this.element.css("marginTop"),10) || 0),
+                       right: (parseInt(this.element.css("marginRight"),10) || 0),
+                       bottom: (parseInt(this.element.css("marginBottom"),10) || 0)
+               };
+       },
+
+       _cacheHelperProportions: function() {
+               this.helperProportions = {
+                       width: this.helper.outerWidth(),
+                       height: this.helper.outerHeight()
+               };
+       },
+
+       _setContainment: function() {
+
+               var over, c, ce,
+                       o = this.options;
+
+               if(o.containment === "parent") {
+                       o.containment = this.helper[0].parentNode;
+               }
+               if(o.containment === "document" || o.containment === "window") {
+                       this.containment = [
+                               o.containment === "document" ? 0 : $(window).scrollLeft() - this.offset.relative.left - this.offset.parent.left,
+                               o.containment === "document" ? 0 : $(window).scrollTop() - this.offset.relative.top - this.offset.parent.top,
+                               (o.containment === "document" ? 0 : $(window).scrollLeft()) + $(o.containment === "document" ? document : window).width() - this.helperProportions.width - this.margins.left,
+                               (o.containment === "document" ? 0 : $(window).scrollTop()) + ($(o.containment === "document" ? document : window).height() || document.body.parentNode.scrollHeight) - this.helperProportions.height - this.margins.top
+                       ];
+               }
+
+               if(!(/^(document|window|parent)$/).test(o.containment) && o.containment.constructor !== Array) {
+                       c = $(o.containment);
+                       ce = c[0];
+
+                       if(!ce) {
+                               return;
+                       }
+
+                       over = ($(ce).css("overflow") !== "hidden");
+
+                       this.containment = [
+                               (parseInt($(ce).css("borderLeftWidth"),10) || 0) + (parseInt($(ce).css("paddingLeft"),10) || 0),
+                               (parseInt($(ce).css("borderTopWidth"),10) || 0) + (parseInt($(ce).css("paddingTop"),10) || 0),
+                               (over ? Math.max(ce.scrollWidth,ce.offsetWidth) : ce.offsetWidth) - (parseInt($(ce).css("borderLeftWidth"),10) || 0) - (parseInt($(ce).css("paddingRight"),10) || 0) - this.helperProportions.width - this.margins.left - this.margins.right,
+                               (over ? Math.max(ce.scrollHeight,ce.offsetHeight) : ce.offsetHeight) - (parseInt($(ce).css("borderTopWidth"),10) || 0) - (parseInt($(ce).css("paddingBottom"),10) || 0) - this.helperProportions.height - this.margins.top  - this.margins.bottom
+                       ];
+                       this.relative_container = c;
+
+               } else if(o.containment.constructor === Array) {
+                       this.containment = o.containment;
+               }
+
+       },
+
+       _convertPositionTo: function(d, pos) {
+
+               if(!pos) {
+                       pos = this.position;
+               }
+
+               var mod = d === "absolute" ? 1 : -1,
+                       scroll = this.cssPosition === "absolute" && !(this.scrollParent[0] !== document && $.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName);
+
+               return {
+                       top: (
+                               pos.top +                                                                                                                               // The absolute mouse position
+                               this.offset.relative.top * mod +                                                                                // Only for relative positioned nodes: Relative offset from element to offset parent
+                               this.offset.parent.top * mod -                                                                          // The offsetParent's offset without borders (offset + border)
+                               ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod)
+                       ),
+                       left: (
+                               pos.left +                                                                                                                              // The absolute mouse position
+                               this.offset.relative.left * mod +                                                                               // Only for relative positioned nodes: Relative offset from element to offset parent
+                               this.offset.parent.left * mod   -                                                                               // The offsetParent's offset without borders (offset + border)
+                               ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ) * mod)
+                       )
+               };
+
+       },
+
+       _generatePosition: function(event) {
+
+               var containment, co, top, left,
+                       o = this.options,
+                       scroll = this.cssPosition === "absolute" && !(this.scrollParent[0] !== document && $.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent,
+                       scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName),
+                       pageX = event.pageX,
+                       pageY = event.pageY;
+
+               /*
+                * - Position constraining -
+                * Constrain the position to a mix of grid, containment.
+                */
+
+               if(this.originalPosition) { //If we are not dragging yet, we won't check for options
+                       if(this.containment) {
+                       if (this.relative_container){
+                               co = this.relative_container.offset();
+                               containment = [ this.containment[0] + co.left,
+                                       this.containment[1] + co.top,
+                                       this.containment[2] + co.left,
+                                       this.containment[3] + co.top ];
+                       }
+                       else {
+                               containment = this.containment;
+                       }
+
+                               if(event.pageX - this.offset.click.left < containment[0]) {
+                                       pageX = containment[0] + this.offset.click.left;
+                               }
+                               if(event.pageY - this.offset.click.top < containment[1]) {
+                                       pageY = containment[1] + this.offset.click.top;
+                               }
+                               if(event.pageX - this.offset.click.left > containment[2]) {
+                                       pageX = containment[2] + this.offset.click.left;
+                               }
+                               if(event.pageY - this.offset.click.top > containment[3]) {
+                                       pageY = containment[3] + this.offset.click.top;
+                               }
+                       }
+
+                       if(o.grid) {
+                               //Check for grid elements set to 0 to prevent divide by 0 error causing invalid argument errors in IE (see ticket #6950)
+                               top = o.grid[1] ? this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1] : this.originalPageY;
+                               pageY = containment ? ((top - this.offset.click.top >= containment[1] || top - this.offset.click.top > containment[3]) ? top : ((top - this.offset.click.top >= containment[1]) ? top - o.grid[1] : top + o.grid[1])) : top;
+
+                               left = o.grid[0] ? this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0] : this.originalPageX;
+                               pageX = containment ? ((left - this.offset.click.left >= containment[0] || left - this.offset.click.left > containment[2]) ? left : ((left - this.offset.click.left >= containment[0]) ? left - o.grid[0] : left + o.grid[0])) : left;
+                       }
+
+               }
+
+               return {
+                       top: (
+                               pageY -                                                                                                                                 // The absolute mouse position
+                               this.offset.click.top   -                                                                                               // Click offset (relative to the element)
+                               this.offset.relative.top -                                                                                              // Only for relative positioned nodes: Relative offset from element to offset parent
+                               this.offset.parent.top +                                                                                                // The offsetParent's offset without borders (offset + border)
+                               ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ))
+                       ),
+                       left: (
+                               pageX -                                                                                                                                 // The absolute mouse position
+                               this.offset.click.left -                                                                                                // Click offset (relative to the element)
+                               this.offset.relative.left -                                                                                             // Only for relative positioned nodes: Relative offset from element to offset parent
+                               this.offset.parent.left +                                                                                               // The offsetParent's offset without borders (offset + border)
+                               ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ))
+                       )
+               };
+
+       },
+
+       _clear: function() {
+               this.helper.removeClass("ui-draggable-dragging");
+               if(this.helper[0] !== this.element[0] && !this.cancelHelperRemoval) {
+                       this.helper.remove();
+               }
+               this.helper = null;
+               this.cancelHelperRemoval = false;
+       },
+
+       // From now on bulk stuff - mainly helpers
+
+       _trigger: function(type, event, ui) {
+               ui = ui || this._uiHash();
+               $.ui.plugin.call(this, type, [event, ui]);
+               //The absolute position has to be recalculated after plugins
+               if(type === "drag") {
+                       this.positionAbs = this._convertPositionTo("absolute");
+               }
+               return $.Widget.prototype._trigger.call(this, type, event, ui);
+       },
+
+       plugins: {},
+
+       _uiHash: function() {
+               return {
+                       helper: this.helper,
+                       position: this.position,
+                       originalPosition: this.originalPosition,
+                       offset: this.positionAbs
+               };
+       }
+
+});
+
+$.ui.plugin.add("draggable", "connectToSortable", {
+       start: function(event, ui) {
+
+               var inst = $(this).data("ui-draggable"), o = inst.options,
+                       uiSortable = $.extend({}, ui, { item: inst.element });
+               inst.sortables = [];
+               $(o.connectToSortable).each(function() {
+                       var sortable = $.data(this, "ui-sortable");
+                       if (sortable && !sortable.options.disabled) {
+                               inst.sortables.push({
+                                       instance: sortable,
+                                       shouldRevert: sortable.options.revert
+                               });
+                               sortable.refreshPositions();    // Call the sortable's refreshPositions at drag start to refresh the containerCache since the sortable container cache is used in drag and needs to be up to date (this will ensure it's initialised as well as being kept in step with any changes that might have happened on the page).
+                               sortable._trigger("activate", event, uiSortable);
+                       }
+               });
+
+       },
+       stop: function(event, ui) {
+
+               //If we are still over the sortable, we fake the stop event of the sortable, but also remove helper
+               var inst = $(this).data("ui-draggable"),
+                       uiSortable = $.extend({}, ui, { item: inst.element });
+
+               $.each(inst.sortables, function() {
+                       if(this.instance.isOver) {
+
+                               this.instance.isOver = 0;
+
+                               inst.cancelHelperRemoval = true; //Don't remove the helper in the draggable instance
+                               this.instance.cancelHelperRemoval = false; //Remove it in the sortable instance (so sortable plugins like revert still work)
+
+                               //The sortable revert is supported, and we have to set a temporary dropped variable on the draggable to support revert: "valid/invalid"
+                               if(this.shouldRevert) {
+                                       this.instance.options.revert = true;
+                               }
+
+                               //Trigger the stop of the sortable
+                               this.instance._mouseStop(event);
+
+                               this.instance.options.helper = this.instance.options._helper;
+
+                               //If the helper has been the original item, restore properties in the sortable
+                               if(inst.options.helper === "original") {
+                                       this.instance.currentItem.css({ top: "auto", left: "auto" });
+                               }
+
+                       } else {
+                               this.instance.cancelHelperRemoval = false; //Remove the helper in the sortable instance
+                               this.instance._trigger("deactivate", event, uiSortable);
+                       }
+
+               });
+
+       },
+       drag: function(event, ui) {
+
+               var inst = $(this).data("ui-draggable"), that = this;
+
+               $.each(inst.sortables, function() {
+
+                       var innermostIntersecting = false,
+                               thisSortable = this;
+
+                       //Copy over some variables to allow calling the sortable's native _intersectsWith
+                       this.instance.positionAbs = inst.positionAbs;
+                       this.instance.helperProportions = inst.helperProportions;
+                       this.instance.offset.click = inst.offset.click;
+
+                       if(this.instance._intersectsWith(this.instance.containerCache)) {
+                               innermostIntersecting = true;
+                               $.each(inst.sortables, function () {
+                                       this.instance.positionAbs = inst.positionAbs;
+                                       this.instance.helperProportions = inst.helperProportions;
+                                       this.instance.offset.click = inst.offset.click;
+                                       if (this !== thisSortable &&
+                                               this.instance._intersectsWith(this.instance.containerCache) &&
+                                               $.ui.contains(thisSortable.instance.element[0], this.instance.element[0])
+                                       ) {
+                                               innermostIntersecting = false;
+                                       }
+                                       return innermostIntersecting;
+                               });
+                       }
+
+
+                       if(innermostIntersecting) {
+                               //If it intersects, we use a little isOver variable and set it once, so our move-in stuff gets fired only once
+                               if(!this.instance.isOver) {
+
+                                       this.instance.isOver = 1;
+                                       //Now we fake the start of dragging for the sortable instance,
+                                       //by cloning the list group item, appending it to the sortable and using it as inst.currentItem
+                                       //We can then fire the start event of the sortable with our passed browser event, and our own helper (so it doesn't create a new one)
+                                       this.instance.currentItem = $(that).clone().removeAttr("id").appendTo(this.instance.element).data("ui-sortable-item", true);
+                                       this.instance.options._helper = this.instance.options.helper; //Store helper option to later restore it
+                                       this.instance.options.helper = function() { return ui.helper[0]; };
+
+                                       event.target = this.instance.currentItem[0];
+                                       this.instance._mouseCapture(event, true);
+                                       this.instance._mouseStart(event, true, true);
+
+                                       //Because the browser event is way off the new appended portlet, we modify a couple of variables to reflect the changes
+                                       this.instance.offset.click.top = inst.offset.click.top;
+                                       this.instance.offset.click.left = inst.offset.click.left;
+                                       this.instance.offset.parent.left -= inst.offset.parent.left - this.instance.offset.parent.left;
+                                       this.instance.offset.parent.top -= inst.offset.parent.top - this.instance.offset.parent.top;
+
+                                       inst._trigger("toSortable", event);
+                                       inst.dropped = this.instance.element; //draggable revert needs that
+                                       //hack so receive/update callbacks work (mostly)
+                                       inst.currentItem = inst.element;
+                                       this.instance.fromOutside = inst;
+
+                               }
+
+                               //Provided we did all the previous steps, we can fire the drag event of the sortable on every draggable drag, when it intersects with the sortable
+                               if(this.instance.currentItem) {
+                                       this.instance._mouseDrag(event);
+                               }
+
+                       } else {
+
+                               //If it doesn't intersect with the sortable, and it intersected before,
+                               //we fake the drag stop of the sortable, but make sure it doesn't remove the helper by using cancelHelperRemoval
+                               if(this.instance.isOver) {
+
+                                       this.instance.isOver = 0;
+                                       this.instance.cancelHelperRemoval = true;
+
+                                       //Prevent reverting on this forced stop
+                                       this.instance.options.revert = false;
+
+                                       // The out event needs to be triggered independently
+                                       this.instance._trigger("out", event, this.instance._uiHash(this.instance));
+
+                                       this.instance._mouseStop(event, true);
+                                       this.instance.options.helper = this.instance.options._helper;
+
+                                       //Now we remove our currentItem, the list group clone again, and the placeholder, and animate the helper back to it's original size
+                                       this.instance.currentItem.remove();
+                                       if(this.instance.placeholder) {
+                                               this.instance.placeholder.remove();
+                                       }
+
+                                       inst._trigger("fromSortable", event);
+                                       inst.dropped = false; //draggable revert needs that
+                               }
+
+                       }
+
+               });
+
+       }
+});
+
+$.ui.plugin.add("draggable", "cursor", {
+       start: function() {
+               var t = $("body"), o = $(this).data("ui-draggable").options;
+               if (t.css("cursor")) {
+                       o._cursor = t.css("cursor");
+               }
+               t.css("cursor", o.cursor);
+       },
+       stop: function() {
+               var o = $(this).data("ui-draggable").options;
+               if (o._cursor) {
+                       $("body").css("cursor", o._cursor);
+               }
+       }
+});
+
+$.ui.plugin.add("draggable", "opacity", {
+       start: function(event, ui) {
+               var t = $(ui.helper), o = $(this).data("ui-draggable").options;
+               if(t.css("opacity")) {
+                       o._opacity = t.css("opacity");
+               }
+               t.css("opacity", o.opacity);
+       },
+       stop: function(event, ui) {
+               var o = $(this).data("ui-draggable").options;
+               if(o._opacity) {
+                       $(ui.helper).css("opacity", o._opacity);
+               }
+       }
+});
+
+$.ui.plugin.add("draggable", "scroll", {
+       start: function() {
+               var i = $(this).data("ui-draggable");
+               if(i.scrollParent[0] !== document && i.scrollParent[0].tagName !== "HTML") {
+                       i.overflowOffset = i.scrollParent.offset();
+               }
+       },
+       drag: function( event ) {
+
+               var i = $(this).data("ui-draggable"), o = i.options, scrolled = false;
+
+               if(i.scrollParent[0] !== document && i.scrollParent[0].tagName !== "HTML") {
+
+                       if(!o.axis || o.axis !== "x") {
+                               if((i.overflowOffset.top + i.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity) {
+                                       i.scrollParent[0].scrollTop = scrolled = i.scrollParent[0].scrollTop + o.scrollSpeed;
+                               } else if(event.pageY - i.overflowOffset.top < o.scrollSensitivity) {
+                                       i.scrollParent[0].scrollTop = scrolled = i.scrollParent[0].scrollTop - o.scrollSpeed;
+                               }
+                       }
+
+                       if(!o.axis || o.axis !== "y") {
+                               if((i.overflowOffset.left + i.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity) {
+                                       i.scrollParent[0].scrollLeft = scrolled = i.scrollParent[0].scrollLeft + o.scrollSpeed;
+                               } else if(event.pageX - i.overflowOffset.left < o.scrollSensitivity) {
+                                       i.scrollParent[0].scrollLeft = scrolled = i.scrollParent[0].scrollLeft - o.scrollSpeed;
+                               }
+                       }
+
+               } else {
+
+                       if(!o.axis || o.axis !== "x") {
+                               if(event.pageY - $(document).scrollTop() < o.scrollSensitivity) {
+                                       scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed);
+                               } else if($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity) {
+                                       scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed);
+                               }
+                       }
+
+                       if(!o.axis || o.axis !== "y") {
+                               if(event.pageX - $(document).scrollLeft() < o.scrollSensitivity) {
+                                       scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed);
+                               } else if($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity) {
+                                       scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed);
+                               }
+                       }
+
+               }
+
+               if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour) {
+                       $.ui.ddmanager.prepareOffsets(i, event);
+               }
+
+       }
+});
+
+$.ui.plugin.add("draggable", "snap", {
+       start: function() {
+
+               var i = $(this).data("ui-draggable"),
+                       o = i.options;
+
+               i.snapElements = [];
+
+               $(o.snap.constructor !== String ? ( o.snap.items || ":data(ui-draggable)" ) : o.snap).each(function() {
+                       var $t = $(this),
+                               $o = $t.offset();
+                       if(this !== i.element[0]) {
+                               i.snapElements.push({
+                                       item: this,
+                                       width: $t.outerWidth(), height: $t.outerHeight(),
+                                       top: $o.top, left: $o.left
+                               });
+                       }
+               });
+
+       },
+       drag: function(event, ui) {
+
+               var ts, bs, ls, rs, l, r, t, b, i, first,
+                       inst = $(this).data("ui-draggable"),
+                       o = inst.options,
+                       d = o.snapTolerance,
+                       x1 = ui.offset.left, x2 = x1 + inst.helperProportions.width,
+                       y1 = ui.offset.top, y2 = y1 + inst.helperProportions.height;
+
+               for (i = inst.snapElements.length - 1; i >= 0; i--){
+
+                       l = inst.snapElements[i].left;
+                       r = l + inst.snapElements[i].width;
+                       t = inst.snapElements[i].top;
+                       b = t + inst.snapElements[i].height;
+
+                       //Yes, I know, this is insane ;)
+                       if(!((l-d < x1 && x1 < r+d && t-d < y1 && y1 < b+d) || (l-d < x1 && x1 < r+d && t-d < y2 && y2 < b+d) || (l-d < x2 && x2 < r+d && t-d < y1 && y1 < b+d) || (l-d < x2 && x2 < r+d && t-d < y2 && y2 < b+d))) {
+                               if(inst.snapElements[i].snapping) {
+                                       (inst.options.snap.release && inst.options.snap.release.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item })));
+                               }
+                               inst.snapElements[i].snapping = false;
+                               continue;
+                       }
+
+                       if(o.snapMode !== "inner") {
+                               ts = Math.abs(t - y2) <= d;
+                               bs = Math.abs(b - y1) <= d;
+                               ls = Math.abs(l - x2) <= d;
+                               rs = Math.abs(r - x1) <= d;
+                               if(ts) {
+                                       ui.position.top = inst._convertPositionTo("relative", { top: t - inst.helperProportions.height, left: 0 }).top - inst.margins.top;
+                               }
+                               if(bs) {
+                                       ui.position.top = inst._convertPositionTo("relative", { top: b, left: 0 }).top - inst.margins.top;
+                               }
+                               if(ls) {
+                                       ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l - inst.helperProportions.width }).left - inst.margins.left;
+                               }
+                               if(rs) {
+                                       ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r }).left - inst.margins.left;
+                               }
+                       }
+
+                       first = (ts || bs || ls || rs);
+
+                       if(o.snapMode !== "outer") {
+                               ts = Math.abs(t - y1) <= d;
+                               bs = Math.abs(b - y2) <= d;
+                               ls = Math.abs(l - x1) <= d;
+                               rs = Math.abs(r - x2) <= d;
+                               if(ts) {
+                                       ui.position.top = inst._convertPositionTo("relative", { top: t, left: 0 }).top - inst.margins.top;
+                               }
+                               if(bs) {
+                                       ui.position.top = inst._convertPositionTo("relative", { top: b - inst.helperProportions.height, left: 0 }).top - inst.margins.top;
+                               }
+                               if(ls) {
+                                       ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l }).left - inst.margins.left;
+                               }
+                               if(rs) {
+                                       ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r - inst.helperProportions.width }).left - inst.margins.left;
+                               }
+                       }
+
+                       if(!inst.snapElements[i].snapping && (ts || bs || ls || rs || first)) {
+                               (inst.options.snap.snap && inst.options.snap.snap.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item })));
+                       }
+                       inst.snapElements[i].snapping = (ts || bs || ls || rs || first);
+
+               }
+
+       }
+});
+
+$.ui.plugin.add("draggable", "stack", {
+       start: function() {
+
+               var min,
+                       o = $(this).data("ui-draggable").options,
+                       group = $.makeArray($(o.stack)).sort(function(a,b) {
+                               return (parseInt($(a).css("zIndex"),10) || 0) - (parseInt($(b).css("zIndex"),10) || 0);
+                       });
+
+               if (!group.length) { return; }
+
+               min = parseInt(group[0].style.zIndex, 10) || 0;
+               $(group).each(function(i) {
+                       this.style.zIndex = min + i;
+               });
+
+               this[0].style.zIndex = min + group.length;
+
+       }
+});
+
+$.ui.plugin.add("draggable", "zIndex", {
+       start: function(event, ui) {
+               var t = $(ui.helper), o = $(this).data("ui-draggable").options;
+               if(t.css("zIndex")) {
+                       o._zIndex = t.css("zIndex");
+               }
+               t.css("zIndex", o.zIndex);
+       },
+       stop: function(event, ui) {
+               var o = $(this).data("ui-draggable").options;
+               if(o._zIndex) {
+                       $(ui.helper).css("zIndex", o._zIndex);
+               }
+       }
+});
+
+})(jQuery);
+(function( $, undefined ) {
+
+function isOverAxis( x, reference, size ) {
+       return ( x > reference ) && ( x < ( reference + size ) );
+}
+
+$.widget("ui.droppable", {
+       version: "1.10.0",
+       widgetEventPrefix: "drop",
+       options: {
+               accept: "*",
+               activeClass: false,
+               addClasses: true,
+               greedy: false,
+               hoverClass: false,
+               scope: "default",
+               tolerance: "intersect",
+
+               // callbacks
+               activate: null,
+               deactivate: null,
+               drop: null,
+               out: null,
+               over: null
+       },
+       _create: function() {
+
+               var o = this.options,
+                       accept = o.accept;
+
+               this.isover = false;
+               this.isout = true;
+
+               this.accept = $.isFunction(accept) ? accept : function(d) {
+                       return d.is(accept);
+               };
+
+               //Store the droppable's proportions
+               this.proportions = { width: this.element[0].offsetWidth, height: this.element[0].offsetHeight };
+
+               // Add the reference and positions to the manager
+               $.ui.ddmanager.droppables[o.scope] = $.ui.ddmanager.droppables[o.scope] || [];
+               $.ui.ddmanager.droppables[o.scope].push(this);
+
+               (o.addClasses && this.element.addClass("ui-droppable"));
+
+       },
+
+       _destroy: function() {
+               var i = 0,
+                       drop = $.ui.ddmanager.droppables[this.options.scope];
+
+               for ( ; i < drop.length; i++ ) {
+                       if ( drop[i] === this ) {
+                               drop.splice(i, 1);
+                       }
+               }
+
+               this.element.removeClass("ui-droppable ui-droppable-disabled");
+       },
+
+       _setOption: function(key, value) {
+
+               if(key === "accept") {
+                       this.accept = $.isFunction(value) ? value : function(d) {
+                               return d.is(value);
+                       };
+               }
+               $.Widget.prototype._setOption.apply(this, arguments);
+       },
+
+       _activate: function(event) {
+               var draggable = $.ui.ddmanager.current;
+               if(this.options.activeClass) {
+                       this.element.addClass(this.options.activeClass);
+               }
+               if(draggable){
+                       this._trigger("activate", event, this.ui(draggable));
+               }
+       },
+
+       _deactivate: function(event) {
+               var draggable = $.ui.ddmanager.current;
+               if(this.options.activeClass) {
+                       this.element.removeClass(this.options.activeClass);
+               }
+               if(draggable){
+                       this._trigger("deactivate", event, this.ui(draggable));
+               }
+       },
+
+       _over: function(event) {
+
+               var draggable = $.ui.ddmanager.current;
+
+               // Bail if draggable and droppable are same element
+               if (!draggable || (draggable.currentItem || draggable.element)[0] === this.element[0]) {
+                       return;
+               }
+
+               if (this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
+                       if(this.options.hoverClass) {
+                               this.element.addClass(this.options.hoverClass);
+                       }
+                       this._trigger("over", event, this.ui(draggable));
+               }
+
+       },
+
+       _out: function(event) {
+
+               var draggable = $.ui.ddmanager.current;
+
+               // Bail if draggable and droppable are same element
+               if (!draggable || (draggable.currentItem || draggable.element)[0] === this.element[0]) {
+                       return;
+               }
+
+               if (this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
+                       if(this.options.hoverClass) {
+                               this.element.removeClass(this.options.hoverClass);
+                       }
+                       this._trigger("out", event, this.ui(draggable));
+               }
+
+       },
+
+       _drop: function(event,custom) {
+
+               var draggable = custom || $.ui.ddmanager.current,
+                       childrenIntersection = false;
+
+               // Bail if draggable and droppable are same element
+               if (!draggable || (draggable.currentItem || draggable.element)[0] === this.element[0]) {
+                       return false;
+               }
+
+               this.element.find(":data(ui-droppable)").not(".ui-draggable-dragging").each(function() {
+                       var inst = $.data(this, "ui-droppable");
+                       if(
+                               inst.options.greedy &&
+                               !inst.options.disabled &&
+                               inst.options.scope === draggable.options.scope &&
+                               inst.accept.call(inst.element[0], (draggable.currentItem || draggable.element)) &&
+                               $.ui.intersect(draggable, $.extend(inst, { offset: inst.element.offset() }), inst.options.tolerance)
+                       ) { childrenIntersection = true; return false; }
+               });
+               if(childrenIntersection) {
+                       return false;
+               }
+
+               if(this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
+                       if(this.options.activeClass) {
+                               this.element.removeClass(this.options.activeClass);
+                       }
+                       if(this.options.hoverClass) {
+                               this.element.removeClass(this.options.hoverClass);
+                       }
+                       this._trigger("drop", event, this.ui(draggable));
+                       return this.element;
+               }
+
+               return false;
+
+       },
+
+       ui: function(c) {
+               return {
+                       draggable: (c.currentItem || c.element),
+                       helper: c.helper,
+                       position: c.position,
+                       offset: c.positionAbs
+               };
+       }
+
+});
+
+$.ui.intersect = function(draggable, droppable, toleranceMode) {
+
+       if (!droppable.offset) {
+               return false;
+       }
+
+       var draggableLeft, draggableTop,
+               x1 = (draggable.positionAbs || draggable.position.absolute).left, x2 = x1 + draggable.helperProportions.width,
+               y1 = (draggable.positionAbs || draggable.position.absolute).top, y2 = y1 + draggable.helperProportions.height,
+               l = droppable.offset.left, r = l + droppable.proportions.width,
+               t = droppable.offset.top, b = t + droppable.proportions.height;
+
+       switch (toleranceMode) {
+               case "fit":
+                       return (l <= x1 && x2 <= r && t <= y1 && y2 <= b);
+               case "intersect":
+                       return (l < x1 + (draggable.helperProportions.width / 2) && // Right Half
+                               x2 - (draggable.helperProportions.width / 2) < r && // Left Half
+                               t < y1 + (draggable.helperProportions.height / 2) && // Bottom Half
+                               y2 - (draggable.helperProportions.height / 2) < b ); // Top Half
+               case "pointer":
+                       draggableLeft = ((draggable.positionAbs || draggable.position.absolute).left + (draggable.clickOffset || draggable.offset.click).left);
+                       draggableTop = ((draggable.positionAbs || draggable.position.absolute).top + (draggable.clickOffset || draggable.offset.click).top);
+                       return isOverAxis( draggableTop, t, droppable.proportions.height ) && isOverAxis( draggableLeft, l, droppable.proportions.width );
+               case "touch":
+                       return (
+                               (y1 >= t && y1 <= b) || // Top edge touching
+                               (y2 >= t && y2 <= b) || // Bottom edge touching
+                               (y1 < t && y2 > b)              // Surrounded vertically
+                       ) && (
+                               (x1 >= l && x1 <= r) || // Left edge touching
+                               (x2 >= l && x2 <= r) || // Right edge touching
+                               (x1 < l && x2 > r)              // Surrounded horizontally
+                       );
+               default:
+                       return false;
+               }
+
+};
+
+/*
+       This manager tracks offsets of draggables and droppables
+*/
+$.ui.ddmanager = {
+       current: null,
+       droppables: { "default": [] },
+       prepareOffsets: function(t, event) {
+
+               var i, j,
+                       m = $.ui.ddmanager.droppables[t.options.scope] || [],
+                       type = event ? event.type : null, // workaround for #2317
+                       list = (t.currentItem || t.element).find(":data(ui-droppable)").addBack();
+
+               droppablesLoop: for (i = 0; i < m.length; i++) {
+
+                       //No disabled and non-accepted
+                       if(m[i].options.disabled || (t && !m[i].accept.call(m[i].element[0],(t.currentItem || t.element)))) {
+                               continue;
+                       }
+
+                       // Filter out elements in the current dragged item
+                       for (j=0; j < list.length; j++) {
+                               if(list[j] === m[i].element[0]) {
+                                       m[i].proportions.height = 0;
+                                       continue droppablesLoop;
+                               }
+                       }
+
+                       m[i].visible = m[i].element.css("display") !== "none";
+                       if(!m[i].visible) {
+                               continue;
+                       }
+
+                       //Activate the droppable if used directly from draggables
+                       if(type === "mousedown") {
+                               m[i]._activate.call(m[i], event);
+                       }
+
+                       m[i].offset = m[i].element.offset();
+                       m[i].proportions = { width: m[i].element[0].offsetWidth, height: m[i].element[0].offsetHeight };
+
+               }
+
+       },
+       drop: function(draggable, event) {
+
+               var dropped = false;
+               $.each($.ui.ddmanager.droppables[draggable.options.scope] || [], function() {
+
+                       if(!this.options) {
+                               return;
+                       }
+                       if (!this.options.disabled && this.visible && $.ui.intersect(draggable, this, this.options.tolerance)) {
+                               dropped = this._drop.call(this, event) || dropped;
+                       }
+
+                       if (!this.options.disabled && this.visible && this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
+                               this.isout = true;
+                               this.isover = false;
+                               this._deactivate.call(this, event);
+                       }
+
+               });
+               return dropped;
+
+       },
+       dragStart: function( draggable, event ) {
+               //Listen for scrolling so that if the dragging causes scrolling the position of the droppables can be recalculated (see #5003)
+               draggable.element.parentsUntil( "body" ).bind( "scroll.droppable", function() {
+                       if( !draggable.options.refreshPositions ) {
+                               $.ui.ddmanager.prepareOffsets( draggable, event );
+                       }
+               });
+       },
+       drag: function(draggable, event) {
+
+               //If you have a highly dynamic page, you might try this option. It renders positions every time you move the mouse.
+               if(draggable.options.refreshPositions) {
+                       $.ui.ddmanager.prepareOffsets(draggable, event);
+               }
+
+               //Run through all droppables and check their positions based on specific tolerance options
+               $.each($.ui.ddmanager.droppables[draggable.options.scope] || [], function() {
+
+                       if(this.options.disabled || this.greedyChild || !this.visible) {
+                               return;
+                       }
+
+                       var parentInstance, scope, parent,
+                               intersects = $.ui.intersect(draggable, this, this.options.tolerance),
+                               c = !intersects && this.isover ? "isout" : (intersects && !this.isover ? "isover" : null);
+                       if(!c) {
+                               return;
+                       }
+
+                       if (this.options.greedy) {
+                               // find droppable parents with same scope
+                               scope = this.options.scope;
+                               parent = this.element.parents(":data(ui-droppable)").filter(function () {
+                                       return $.data(this, "ui-droppable").options.scope === scope;
+                               });
+
+                               if (parent.length) {
+                                       parentInstance = $.data(parent[0], "ui-droppable");
+                                       parentInstance.greedyChild = (c === "isover");
+                               }
+                       }
+
+                       // we just moved into a greedy child
+                       if (parentInstance && c === "isover") {
+                               parentInstance.isover = false;
+                               parentInstance.isout = true;
+                               parentInstance._out.call(parentInstance, event);
+                       }
+
+                       this[c] = true;
+                       this[c === "isout" ? "isover" : "isout"] = false;
+                       this[c === "isover" ? "_over" : "_out"].call(this, event);
+
+                       // we just moved out of a greedy child
+                       if (parentInstance && c === "isout") {
+                               parentInstance.isout = false;
+                               parentInstance.isover = true;
+                               parentInstance._over.call(parentInstance, event);
+                       }
+               });
+
+       },
+       dragStop: function( draggable, event ) {
+               draggable.element.parentsUntil( "body" ).unbind( "scroll.droppable" );
+               //Call prepareOffsets one final time since IE does not fire return scroll events when overflow was caused by drag (see #5003)
+               if( !draggable.options.refreshPositions ) {
+                       $.ui.ddmanager.prepareOffsets( draggable, event );
+               }
+       }
+};
+
+})(jQuery);
+(function( $, undefined ) {
+
+$.widget("ui.selectable", $.ui.mouse, {
+       version: "1.10.0",
+       options: {
+               appendTo: "body",
+               autoRefresh: true,
+               distance: 0,
+               filter: "*",
+               tolerance: "touch",
+
+               // callbacks
+               selected: null,
+               selecting: null,
+               start: null,
+               stop: null,
+               unselected: null,
+               unselecting: null
+       },
+       _create: function() {
+               var selectees,
+                       that = this;
+
+               this.element.addClass("ui-selectable");
+
+               this.dragged = false;
+
+               // cache selectee children based on filter
+               this.refresh = function() {
+                       selectees = $(that.options.filter, that.element[0]);
+                       selectees.addClass("ui-selectee");
+                       selectees.each(function() {
+                               var $this = $(this),
+                                       pos = $this.offset();
+                               $.data(this, "selectable-item", {
+                                       element: this,
+                                       $element: $this,
+                                       left: pos.left,
+                                       top: pos.top,
+                                       right: pos.left + $this.outerWidth(),
+                                       bottom: pos.top + $this.outerHeight(),
+                                       startselected: false,
+                                       selected: $this.hasClass("ui-selected"),
+                                       selecting: $this.hasClass("ui-selecting"),
+                                       unselecting: $this.hasClass("ui-unselecting")
+                               });
+                       });
+               };
+               this.refresh();
+
+               this.selectees = selectees.addClass("ui-selectee");
+
+               this._mouseInit();
+
+               this.helper = $("<div class='ui-selectable-helper'></div>");
+       },
+
+       _destroy: function() {
+               this.selectees
+                       .removeClass("ui-selectee")
+                       .removeData("selectable-item");
+               this.element
+                       .removeClass("ui-selectable ui-selectable-disabled");
+               this._mouseDestroy();
+       },
+
+       _mouseStart: function(event) {
+               var that = this,
+                       options = this.options;
+
+               this.opos = [event.pageX, event.pageY];
+
+               if (this.options.disabled) {
+                       return;
+               }
+
+               this.selectees = $(options.filter, this.element[0]);
+
+               this._trigger("start", event);
+
+               $(options.appendTo).append(this.helper);
+               // position helper (lasso)
+               this.helper.css({
+                       "left": event.pageX,
+                       "top": event.pageY,
+                       "width": 0,
+                       "height": 0
+               });
+
+               if (options.autoRefresh) {
+                       this.refresh();
+               }
+
+               this.selectees.filter(".ui-selected").each(function() {
+                       var selectee = $.data(this, "selectable-item");
+                       selectee.startselected = true;
+                       if (!event.metaKey && !event.ctrlKey) {
+                               selectee.$element.removeClass("ui-selected");
+                               selectee.selected = false;
+                               selectee.$element.addClass("ui-unselecting");
+                               selectee.unselecting = true;
+                               // selectable UNSELECTING callback
+                               that._trigger("unselecting", event, {
+                                       unselecting: selectee.element
+                               });
+                       }
+               });
+
+               $(event.target).parents().addBack().each(function() {
+                       var doSelect,
+                               selectee = $.data(this, "selectable-item");
+                       if (selectee) {
+                               doSelect = (!event.metaKey && !event.ctrlKey) || !selectee.$element.hasClass("ui-selected");
+                               selectee.$element
+                                       .removeClass(doSelect ? "ui-unselecting" : "ui-selected")
+                                       .addClass(doSelect ? "ui-selecting" : "ui-unselecting");
+                               selectee.unselecting = !doSelect;
+                               selectee.selecting = doSelect;
+                               selectee.selected = doSelect;
+                               // selectable (UN)SELECTING callback
+                               if (doSelect) {
+                                       that._trigger("selecting", event, {
+                                               selecting: selectee.element
+                                       });
+                               } else {
+                                       that._trigger("unselecting", event, {
+                                               unselecting: selectee.element
+                                       });
+                               }
+                               return false;
+                       }
+               });
+
+       },
+
+       _mouseDrag: function(event) {
+
+               this.dragged = true;
+
+               if (this.options.disabled) {
+                       return;
+               }
+
+               var tmp,
+                       that = this,
+                       options = this.options,
+                       x1 = this.opos[0],
+                       y1 = this.opos[1],
+                       x2 = event.pageX,
+                       y2 = event.pageY;
+
+               if (x1 > x2) { tmp = x2; x2 = x1; x1 = tmp; }
+               if (y1 > y2) { tmp = y2; y2 = y1; y1 = tmp; }
+               this.helper.css({left: x1, top: y1, width: x2-x1, height: y2-y1});
+
+               this.selectees.each(function() {
+                       var selectee = $.data(this, "selectable-item"),
+                               hit = false;
+
+                       //prevent helper from being selected if appendTo: selectable
+                       if (!selectee || selectee.element === that.element[0]) {
+                               return;
+                       }
+
+                       if (options.tolerance === "touch") {
+                               hit = ( !(selectee.left > x2 || selectee.right < x1 || selectee.top > y2 || selectee.bottom < y1) );
+                       } else if (options.tolerance === "fit") {
+                               hit = (selectee.left > x1 && selectee.right < x2 && selectee.top > y1 && selectee.bottom < y2);
+                       }
+
+                       if (hit) {
+                               // SELECT
+                               if (selectee.selected) {
+                                       selectee.$element.removeClass("ui-selected");
+                                       selectee.selected = false;
+                               }
+                               if (selectee.unselecting) {
+                                       selectee.$element.removeClass("ui-unselecting");
+                                       selectee.unselecting = false;
+                               }
+                               if (!selectee.selecting) {
+                                       selectee.$element.addClass("ui-selecting");
+                                       selectee.selecting = true;
+                                       // selectable SELECTING callback
+                                       that._trigger("selecting", event, {
+                                               selecting: selectee.element
+                                       });
+                               }
+                       } else {
+                               // UNSELECT
+                               if (selectee.selecting) {
+                                       if ((event.metaKey || event.ctrlKey) && selectee.startselected) {
+                                               selectee.$element.removeClass("ui-selecting");
+                                               selectee.selecting = false;
+                                               selectee.$element.addClass("ui-selected");
+                                               selectee.selected = true;
+                                       } else {
+                                               selectee.$element.removeClass("ui-selecting");
+                                               selectee.selecting = false;
+                                               if (selectee.startselected) {
+                                                       selectee.$element.addClass("ui-unselecting");
+                                                       selectee.unselecting = true;
+                                               }
+                                               // selectable UNSELECTING callback
+                                               that._trigger("unselecting", event, {
+                                                       unselecting: selectee.element
+                                               });
+                                       }
+                               }
+                               if (selectee.selected) {
+                                       if (!event.metaKey && !event.ctrlKey && !selectee.startselected) {
+                                               selectee.$element.removeClass("ui-selected");
+                                               selectee.selected = false;
+
+                                               selectee.$element.addClass("ui-unselecting");
+                                               selectee.unselecting = true;
+                                               // selectable UNSELECTING callback
+                                               that._trigger("unselecting", event, {
+                                                       unselecting: selectee.element
+                                               });
+                                       }
+                               }
+                       }
+               });
+
+               return false;
+       },
+
+       _mouseStop: function(event) {
+               var that = this;
+
+               this.dragged = false;
+
+               $(".ui-unselecting", this.element[0]).each(function() {
+                       var selectee = $.data(this, "selectable-item");
+                       selectee.$element.removeClass("ui-unselecting");
+                       selectee.unselecting = false;
+                       selectee.startselected = false;
+                       that._trigger("unselected", event, {
+                               unselected: selectee.element
+                       });
+               });
+               $(".ui-selecting", this.element[0]).each(function() {
+                       var selectee = $.data(this, "selectable-item");
+                       selectee.$element.removeClass("ui-selecting").addClass("ui-selected");
+                       selectee.selecting = false;
+                       selectee.selected = true;
+                       selectee.startselected = true;
+                       that._trigger("selected", event, {
+                               selected: selectee.element
+                       });
+               });
+               this._trigger("stop", event);
+
+               this.helper.remove();
+
+               return false;
+       }
+
+});
+
+})(jQuery);
+(function( $, undefined ) {
+
+/*jshint loopfunc: true */
+
+function isOverAxis( x, reference, size ) {
+       return ( x > reference ) && ( x < ( reference + size ) );
+}
+
+$.widget("ui.sortable", $.ui.mouse, {
+       version: "1.10.0",
+       widgetEventPrefix: "sort",
+       ready: false,
+       options: {
+               appendTo: "parent",
+               axis: false,
+               connectWith: false,
+               containment: false,
+               cursor: "auto",
+               cursorAt: false,
+               dropOnEmpty: true,
+               forcePlaceholderSize: false,
+               forceHelperSize: false,
+               grid: false,
+               handle: false,
+               helper: "original",
+               items: "> *",
+               opacity: false,
+               placeholder: false,
+               revert: false,
+               scroll: true,
+               scrollSensitivity: 20,
+               scrollSpeed: 20,
+               scope: "default",
+               tolerance: "intersect",
+               zIndex: 1000,
+
+               // callbacks
+               activate: null,
+               beforeStop: null,
+               change: null,
+               deactivate: null,
+               out: null,
+               over: null,
+               receive: null,
+               remove: null,
+               sort: null,
+               start: null,
+               stop: null,
+               update: null
+       },
+       _create: function() {
+
+               var o = this.options;
+               this.containerCache = {};
+               this.element.addClass("ui-sortable");
+
+               //Get the items
+               this.refresh();
+
+               //Let's determine if the items are being displayed horizontally
+               this.floating = this.items.length ? o.axis === "x" || (/left|right/).test(this.items[0].item.css("float")) || (/inline|table-cell/).test(this.items[0].item.css("display")) : false;
+
+               //Let's determine the parent's offset
+               this.offset = this.element.offset();
+
+               //Initialize mouse events for interaction
+               this._mouseInit();
+
+               //We're ready to go
+               this.ready = true;
+
+       },
+
+       _destroy: function() {
+               this.element
+                       .removeClass("ui-sortable ui-sortable-disabled");
+               this._mouseDestroy();
+
+               for ( var i = this.items.length - 1; i >= 0; i-- ) {
+                       this.items[i].item.removeData(this.widgetName + "-item");
+               }
+
+               return this;
+       },
+
+       _setOption: function(key, value){
+               if ( key === "disabled" ) {
+                       this.options[ key ] = value;
+
+                       this.widget().toggleClass( "ui-sortable-disabled", !!value );
+               } else {
+                       // Don't call widget base _setOption for disable as it adds ui-state-disabled class
+                       $.Widget.prototype._setOption.apply(this, arguments);
+               }
+       },
+
+       _mouseCapture: function(event, overrideHandle) {
+               var currentItem = null,
+                       validHandle = false,
+                       that = this;
+
+               if (this.reverting) {
+                       return false;
+               }
+
+               if(this.options.disabled || this.options.type === "static") {
+                       return false;
+               }
+
+               //We have to refresh the items data once first
+               this._refreshItems(event);
+
+               //Find out if the clicked node (or one of its parents) is a actual item in this.items
+               $(event.target).parents().each(function() {
+                       if($.data(this, that.widgetName + "-item") === that) {
+                               currentItem = $(this);
+                               return false;
+                       }
+               });
+               if($.data(event.target, that.widgetName + "-item") === that) {
+                       currentItem = $(event.target);
+               }
+
+               if(!currentItem) {
+                       return false;
+               }
+               if(this.options.handle && !overrideHandle) {
+                       $(this.options.handle, currentItem).find("*").addBack().each(function() {
+                               if(this === event.target) {
+                                       validHandle = true;
+                               }
+                       });
+                       if(!validHandle) {
+                               return false;
+                       }
+               }
+
+               this.currentItem = currentItem;
+               this._removeCurrentsFromItems();
+               return true;
+
+       },
+
+       _mouseStart: function(event, overrideHandle, noActivation) {
+
+               var i,
+                       o = this.options;
+
+               this.currentContainer = this;
+
+               //We only need to call refreshPositions, because the refreshItems call has been moved to mouseCapture
+               this.refreshPositions();
+
+               //Create and append the visible helper
+               this.helper = this._createHelper(event);
+
+               //Cache the helper size
+               this._cacheHelperProportions();
+
+               /*
+                * - Position generation -
+                * This block generates everything position related - it's the core of draggables.
+                */
+
+               //Cache the margins of the original element
+               this._cacheMargins();
+
+               //Get the next scrolling parent
+               this.scrollParent = this.helper.scrollParent();
+
+               //The element's absolute position on the page minus margins
+               this.offset = this.currentItem.offset();
+               this.offset = {
+                       top: this.offset.top - this.margins.top,
+                       left: this.offset.left - this.margins.left
+               };
+
+               $.extend(this.offset, {
+                       click: { //Where the click happened, relative to the element
+                               left: event.pageX - this.offset.left,
+                               top: event.pageY - this.offset.top
+                       },
+                       parent: this._getParentOffset(),
+                       relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper
+               });
+
+               // Only after we got the offset, we can change the helper's position to absolute
+               // TODO: Still need to figure out a way to make relative sorting possible
+               this.helper.css("position", "absolute");
+               this.cssPosition = this.helper.css("position");
+
+               //Generate the original position
+               this.originalPosition = this._generatePosition(event);
+               this.originalPageX = event.pageX;
+               this.originalPageY = event.pageY;
+
+               //Adjust the mouse offset relative to the helper if "cursorAt" is supplied
+               (o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt));
+
+               //Cache the former DOM position
+               this.domPosition = { prev: this.currentItem.prev()[0], parent: this.currentItem.parent()[0] };
+
+               //If the helper is not the original, hide the original so it's not playing any role during the drag, won't cause anything bad this way
+               if(this.helper[0] !== this.currentItem[0]) {
+                       this.currentItem.hide();
+               }
+
+               //Create the placeholder
+               this._createPlaceholder();
+
+               //Set a containment if given in the options
+               if(o.containment) {
+                       this._setContainment();
+               }
+
+               if(o.cursor) { // cursor option
+                       if ($("body").css("cursor")) {
+                               this._storedCursor = $("body").css("cursor");
+                       }
+                       $("body").css("cursor", o.cursor);
+               }
+
+               if(o.opacity) { // opacity option
+                       if (this.helper.css("opacity")) {
+                               this._storedOpacity = this.helper.css("opacity");
+                       }
+                       this.helper.css("opacity", o.opacity);
+               }
+
+               if(o.zIndex) { // zIndex option
+                       if (this.helper.css("zIndex")) {
+                               this._storedZIndex = this.helper.css("zIndex");
+                       }
+                       this.helper.css("zIndex", o.zIndex);
+               }
+
+               //Prepare scrolling
+               if(this.scrollParent[0] !== document && this.scrollParent[0].tagName !== "HTML") {
+                       this.overflowOffset = this.scrollParent.offset();
+               }
+
+               //Call callbacks
+               this._trigger("start", event, this._uiHash());
+
+               //Recache the helper size
+               if(!this._preserveHelperProportions) {
+                       this._cacheHelperProportions();
+               }
+
+
+               //Post "activate" events to possible containers
+               if( !noActivation ) {
+                       for ( i = this.containers.length - 1; i >= 0; i-- ) {
+                               this.containers[ i ]._trigger( "activate", event, this._uiHash( this ) );
+                       }
+               }
+
+               //Prepare possible droppables
+               if($.ui.ddmanager) {
+                       $.ui.ddmanager.current = this;
+               }
+
+               if ($.ui.ddmanager && !o.dropBehaviour) {
+                       $.ui.ddmanager.prepareOffsets(this, event);
+               }
+
+               this.dragging = true;
+
+               this.helper.addClass("ui-sortable-helper");
+               this._mouseDrag(event); //Execute the drag once - this causes the helper not to be visible before getting its correct position
+               return true;
+
+       },
+
+       _mouseDrag: function(event) {
+               var i, item, itemElement, intersection,
+                       o = this.options,
+                       scrolled = false;
+
+               //Compute the helpers position
+               this.position = this._generatePosition(event);
+               this.positionAbs = this._convertPositionTo("absolute");
+
+               if (!this.lastPositionAbs) {
+                       this.lastPositionAbs = this.positionAbs;
+               }
+
+               //Do scrolling
+               if(this.options.scroll) {
+                       if(this.scrollParent[0] !== document && this.scrollParent[0].tagName !== "HTML") {
+
+                               if((this.overflowOffset.top + this.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity) {
+                                       this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop + o.scrollSpeed;
+                               } else if(event.pageY - this.overflowOffset.top < o.scrollSensitivity) {
+                                       this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop - o.scrollSpeed;
+                               }
+
+                               if((this.overflowOffset.left + this.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity) {
+                                       this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft + o.scrollSpeed;
+                               } else if(event.pageX - this.overflowOffset.left < o.scrollSensitivity) {
+                                       this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft - o.scrollSpeed;
+                               }
+
+                       } else {
+
+                               if(event.pageY - $(document).scrollTop() < o.scrollSensitivity) {
+                                       scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed);
+                               } else if($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity) {
+                                       scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed);
+                               }
+
+                               if(event.pageX - $(document).scrollLeft() < o.scrollSensitivity) {
+                                       scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed);
+                               } else if($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity) {
+                                       scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed);
+                               }
+
+                       }
+
+                       if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour) {
+                               $.ui.ddmanager.prepareOffsets(this, event);
+                       }
+               }
+
+               //Regenerate the absolute position used for position checks
+               this.positionAbs = this._convertPositionTo("absolute");
+
+               //Set the helper position
+               if(!this.options.axis || this.options.axis !== "y") {
+                       this.helper[0].style.left = this.position.left+"px";
+               }
+               if(!this.options.axis || this.options.axis !== "x") {
+                       this.helper[0].style.top = this.position.top+"px";
+               }
+
+               //Rearrange
+               for (i = this.items.length - 1; i >= 0; i--) {
+
+                       //Cache variables and intersection, continue if no intersection
+                       item = this.items[i];
+                       itemElement = item.item[0];
+                       intersection = this._intersectsWithPointer(item);
+                       if (!intersection) {
+                               continue;
+                       }
+
+                       // Only put the placeholder inside the current Container, skip all
+                       // items form other containers. This works because when moving
+                       // an item from one container to another the
+                       // currentContainer is switched before the placeholder is moved.
+                       //
+                       // Without this moving items in "sub-sortables" can cause the placeholder to jitter
+                       // beetween the outer and inner container.
+                       if (item.instance !== this.currentContainer) {
+                               continue;
+                       }
+
+                       // cannot intersect with itself
+                       // no useless actions that have been done before
+                       // no action if the item moved is the parent of the item checked
+                       if (itemElement !== this.currentItem[0] &&
+                               this.placeholder[intersection === 1 ? "next" : "prev"]()[0] !== itemElement &&
+                               !$.contains(this.placeholder[0], itemElement) &&
+                               (this.options.type === "semi-dynamic" ? !$.contains(this.element[0], itemElement) : true)
+                       ) {
+
+                               this.direction = intersection === 1 ? "down" : "up";
+
+                               if (this.options.tolerance === "pointer" || this._intersectsWithSides(item)) {
+                                       this._rearrange(event, item);
+                               } else {
+                                       break;
+                               }
+
+                               this._trigger("change", event, this._uiHash());
+                               break;
+                       }
+               }
+
+               //Post events to containers
+               this._contactContainers(event);
+
+               //Interconnect with droppables
+               if($.ui.ddmanager) {
+                       $.ui.ddmanager.drag(this, event);
+               }
+
+               //Call callbacks
+               this._trigger("sort", event, this._uiHash());
+
+               this.lastPositionAbs = this.positionAbs;
+               return false;
+
+       },
+
+       _mouseStop: function(event, noPropagation) {
+
+               if(!event) {
+                       return;
+               }
+
+               //If we are using droppables, inform the manager about the drop
+               if ($.ui.ddmanager && !this.options.dropBehaviour) {
+                       $.ui.ddmanager.drop(this, event);
+               }
+
+               if(this.options.revert) {
+                       var that = this,
+                               cur = this.placeholder.offset();
+
+                       this.reverting = true;
+
+                       $(this.helper).animate({
+                               left: cur.left - this.offset.parent.left - this.margins.left + (this.offsetParent[0] === document.body ? 0 : this.offsetParent[0].scrollLeft),
+                               top: cur.top - this.offset.parent.top - this.margins.top + (this.offsetParent[0] === document.body ? 0 : this.offsetParent[0].scrollTop)
+                       }, parseInt(this.options.revert, 10) || 500, function() {
+                               that._clear(event);
+                       });
+               } else {
+                       this._clear(event, noPropagation);
+               }
+
+               return false;
+
+       },
+
+       cancel: function() {
+
+               if(this.dragging) {
+
+                       this._mouseUp({ target: null });
+
+                       if(this.options.helper === "original") {
+                               this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper");
+                       } else {
+                               this.currentItem.show();
+                       }
+
+                       //Post deactivating events to containers
+                       for (var i = this.containers.length - 1; i >= 0; i--){
+                               this.containers[i]._trigger("deactivate", null, this._uiHash(this));
+                               if(this.containers[i].containerCache.over) {
+                                       this.containers[i]._trigger("out", null, this._uiHash(this));
+                                       this.containers[i].containerCache.over = 0;
+                               }
+                       }
+
+               }
+
+               if (this.placeholder) {
+                       //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node!
+                       if(this.placeholder[0].parentNode) {
+                               this.placeholder[0].parentNode.removeChild(this.placeholder[0]);
+                       }
+                       if(this.options.helper !== "original" && this.helper && this.helper[0].parentNode) {
+                               this.helper.remove();
+                       }
+
+                       $.extend(this, {
+                               helper: null,
+                               dragging: false,
+                               reverting: false,
+                               _noFinalSort: null
+                       });
+
+                       if(this.domPosition.prev) {
+                               $(this.domPosition.prev).after(this.currentItem);
+                       } else {
+                               $(this.domPosition.parent).prepend(this.currentItem);
+                       }
+               }
+
+               return this;
+
+       },
+
+       serialize: function(o) {
+
+               var items = this._getItemsAsjQuery(o && o.connected),
+                       str = [];
+               o = o || {};
+
+               $(items).each(function() {
+                       var res = ($(o.item || this).attr(o.attribute || "id") || "").match(o.expression || (/(.+)[\-=_](.+)/));
+                       if (res) {
+                               str.push((o.key || res[1]+"[]")+"="+(o.key && o.expression ? res[1] : res[2]));
+                       }
+               });
+
+               if(!str.length && o.key) {
+                       str.push(o.key + "=");
+               }
+
+               return str.join("&");
+
+       },
+
+       toArray: function(o) {
+
+               var items = this._getItemsAsjQuery(o && o.connected),
+                       ret = [];
+
+               o = o || {};
+
+               items.each(function() { ret.push($(o.item || this).attr(o.attribute || "id") || ""); });
+               return ret;
+
+       },
+
+       /* Be careful with the following core functions */
+       _intersectsWith: function(item) {
+
+               var x1 = this.positionAbs.left,
+                       x2 = x1 + this.helperProportions.width,
+                       y1 = this.positionAbs.top,
+                       y2 = y1 + this.helperProportions.height,
+                       l = item.left,
+                       r = l + item.width,
+                       t = item.top,
+                       b = t + item.height,
+                       dyClick = this.offset.click.top,
+                       dxClick = this.offset.click.left,
+                       isOverElement = (y1 + dyClick) > t && (y1 + dyClick) < b && (x1 + dxClick) > l && (x1 + dxClick) < r;
+
+               if ( this.options.tolerance === "pointer" ||
+                       this.options.forcePointerForContainers ||
+                       (this.options.tolerance !== "pointer" && this.helperProportions[this.floating ? "width" : "height"] > item[this.floating ? "width" : "height"])
+               ) {
+                       return isOverElement;
+               } else {
+
+                       return (l < x1 + (this.helperProportions.width / 2) && // Right Half
+                               x2 - (this.helperProportions.width / 2) < r && // Left Half
+                               t < y1 + (this.helperProportions.height / 2) && // Bottom Half
+                               y2 - (this.helperProportions.height / 2) < b ); // Top Half
+
+               }
+       },
+
+       _intersectsWithPointer: function(item) {
+
+               var isOverElementHeight = (this.options.axis === "x") || isOverAxis(this.positionAbs.top + this.offset.click.top, item.top, item.height),
+                       isOverElementWidth = (this.options.axis === "y") || isOverAxis(this.positionAbs.left + this.offset.click.left, item.left, item.width),
+                       isOverElement = isOverElementHeight && isOverElementWidth,
+                       verticalDirection = this._getDragVerticalDirection(),
+                       horizontalDirection = this._getDragHorizontalDirection();
+
+               if (!isOverElement) {
+                       return false;
+               }
+
+               return this.floating ?
+                       ( ((horizontalDirection && horizontalDirection === "right") || verticalDirection === "down") ? 2 : 1 )
+                       : ( verticalDirection && (verticalDirection === "down" ? 2 : 1) );
+
+       },
+
+       _intersectsWithSides: function(item) {
+
+               var isOverBottomHalf = isOverAxis(this.positionAbs.top + this.offset.click.top, item.top + (item.height/2), item.height),
+                       isOverRightHalf = isOverAxis(this.positionAbs.left + this.offset.click.left, item.left + (item.width/2), item.width),
+                       verticalDirection = this._getDragVerticalDirection(),
+                       horizontalDirection = this._getDragHorizontalDirection();
+
+               if (this.floating && horizontalDirection) {
+                       return ((horizontalDirection === "right" && isOverRightHalf) || (horizontalDirection === "left" && !isOverRightHalf));
+               } else {
+                       return verticalDirection && ((verticalDirection === "down" && isOverBottomHalf) || (verticalDirection === "up" && !isOverBottomHalf));
+               }
+
+       },
+
+       _getDragVerticalDirection: function() {
+               var delta = this.positionAbs.top - this.lastPositionAbs.top;
+               return delta !== 0 && (delta > 0 ? "down" : "up");
+       },
+
+       _getDragHorizontalDirection: function() {
+               var delta = this.positionAbs.left - this.lastPositionAbs.left;
+               return delta !== 0 && (delta > 0 ? "right" : "left");
+       },
+
+       refresh: function(event) {
+               this._refreshItems(event);
+               this.refreshPositions();
+               return this;
+       },
+
+       _connectWith: function() {
+               var options = this.options;
+               return options.connectWith.constructor === String ? [options.connectWith] : options.connectWith;
+       },
+
+       _getItemsAsjQuery: function(connected) {
+
+               var i, j, cur, inst,
+                       items = [],
+                       queries = [],
+                       connectWith = this._connectWith();
+
+               if(connectWith && connected) {
+                       for (i = connectWith.length - 1; i >= 0; i--){
+                               cur = $(connectWith[i]);
+                               for ( j = cur.length - 1; j >= 0; j--){
+                                       inst = $.data(cur[j], this.widgetFullName);
+                                       if(inst && inst !== this && !inst.options.disabled) {
+                                               queries.push([$.isFunction(inst.options.items) ? inst.options.items.call(inst.element) : $(inst.options.items, inst.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"), inst]);
+                                       }
+                               }
+                       }
+               }
+
+               queries.push([$.isFunction(this.options.items) ? this.options.items.call(this.element, null, { options: this.options, item: this.currentItem }) : $(this.options.items, this.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"), this]);
+
+               for (i = queries.length - 1; i >= 0; i--){
+                       queries[i][0].each(function() {
+                               items.push(this);
+                       });
+               }
+
+               return $(items);
+
+       },
+
+       _removeCurrentsFromItems: function() {
+
+               var list = this.currentItem.find(":data(" + this.widgetName + "-item)");
+
+               this.items = $.grep(this.items, function (item) {
+                       for (var j=0; j < list.length; j++) {
+                               if(list[j] === item.item[0]) {
+                                       return false;
+                               }
+                       }
+                       return true;
+               });
+
+       },
+
+       _refreshItems: function(event) {
+
+               this.items = [];
+               this.containers = [this];
+
+               var i, j, cur, inst, targetData, _queries, item, queriesLength,
+                       items = this.items,
+                       queries = [[$.isFunction(this.options.items) ? this.options.items.call(this.element[0], event, { item: this.currentItem }) : $(this.options.items, this.element), this]],
+                       connectWith = this._connectWith();
+
+               if(connectWith && this.ready) { //Shouldn't be run the first time through due to massive slow-down
+                       for (i = connectWith.length - 1; i >= 0; i--){
+                               cur = $(connectWith[i]);
+                               for (j = cur.length - 1; j >= 0; j--){
+                                       inst = $.data(cur[j], this.widgetFullName);
+                                       if(inst && inst !== this && !inst.options.disabled) {
+                                               queries.push([$.isFunction(inst.options.items) ? inst.options.items.call(inst.element[0], event, { item: this.currentItem }) : $(inst.options.items, inst.element), inst]);
+                                               this.containers.push(inst);
+                                       }
+                               }
+                       }
+               }
+
+               for (i = queries.length - 1; i >= 0; i--) {
+                       targetData = queries[i][1];
+                       _queries = queries[i][0];
+
+                       for (j=0, queriesLength = _queries.length; j < queriesLength; j++) {
+                               item = $(_queries[j]);
+
+                               item.data(this.widgetName + "-item", targetData); // Data for target checking (mouse manager)
+
+                               items.push({
+                                       item: item,
+                                       instance: targetData,
+                                       width: 0, height: 0,
+                                       left: 0, top: 0
+                               });
+                       }
+               }
+
+       },
+
+       refreshPositions: function(fast) {
+
+               //This has to be redone because due to the item being moved out/into the offsetParent, the offsetParent's position will change
+               if(this.offsetParent && this.helper) {
+                       this.offset.parent = this._getParentOffset();
+               }
+
+               var i, item, t, p;
+
+               for (i = this.items.length - 1; i >= 0; i--){
+                       item = this.items[i];
+
+                       //We ignore calculating positions of all connected containers when we're not over them
+                       if(item.instance !== this.currentContainer && this.currentContainer && item.item[0] !== this.currentItem[0]) {
+                               continue;
+                       }
+
+                       t = this.options.toleranceElement ? $(this.options.toleranceElement, item.item) : item.item;
+
+                       if (!fast) {
+                               item.width = t.outerWidth();
+                               item.height = t.outerHeight();
+                       }
+
+                       p = t.offset();
+                       item.left = p.left;
+                       item.top = p.top;
+               }
+
+               if(this.options.custom && this.options.custom.refreshContainers) {
+                       this.options.custom.refreshContainers.call(this);
+               } else {
+                       for (i = this.containers.length - 1; i >= 0; i--){
+                               p = this.containers[i].element.offset();
+                               this.containers[i].containerCache.left = p.left;
+                               this.containers[i].containerCache.top = p.top;
+                               this.containers[i].containerCache.width = this.containers[i].element.outerWidth();
+                               this.containers[i].containerCache.height = this.containers[i].element.outerHeight();
+                       }
+               }
+
+               return this;
+       },
+
+       _createPlaceholder: function(that) {
+               that = that || this;
+               var className,
+                       o = that.options;
+
+               if(!o.placeholder || o.placeholder.constructor === String) {
+                       className = o.placeholder;
+                       o.placeholder = {
+                               element: function() {
+
+                                       var el = $(document.createElement(that.currentItem[0].nodeName))
+                                               .addClass(className || that.currentItem[0].className+" ui-sortable-placeholder")
+                                               .removeClass("ui-sortable-helper")[0];
+
+                                       if(!className) {
+                                               el.style.visibility = "hidden";
+                                       }
+
+                                       return el;
+                               },
+                               update: function(container, p) {
+
+                                       // 1. If a className is set as 'placeholder option, we don't force sizes - the class is responsible for that
+                                       // 2. The option 'forcePlaceholderSize can be enabled to force it even if a class name is specified
+                                       if(className && !o.forcePlaceholderSize) {
+                                               return;
+                                       }
+
+                                       //If the element doesn't have a actual height by itself (without styles coming from a stylesheet), it receives the inline height from the dragged item
+                                       if(!p.height()) { p.height(that.currentItem.innerHeight() - parseInt(that.currentItem.css("paddingTop")||0, 10) - parseInt(that.currentItem.css("paddingBottom")||0, 10)); }
+                                       if(!p.width()) { p.width(that.currentItem.innerWidth() - parseInt(that.currentItem.css("paddingLeft")||0, 10) - parseInt(that.currentItem.css("paddingRight")||0, 10)); }
+                               }
+                       };
+               }
+
+               //Create the placeholder
+               that.placeholder = $(o.placeholder.element.call(that.element, that.currentItem));
+
+               //Append it after the actual current item
+               that.currentItem.after(that.placeholder);
+
+               //Update the size of the placeholder (TODO: Logic to fuzzy, see line 316/317)
+               o.placeholder.update(that, that.placeholder);
+
+       },
+
+       _contactContainers: function(event) {
+               var i, j, dist, itemWithLeastDistance, posProperty, sizeProperty, base, cur, nearBottom,
+                       innermostContainer = null,
+                       innermostIndex = null;
+
+               // get innermost container that intersects with item
+               for (i = this.containers.length - 1; i >= 0; i--) {
+
+                       // never consider a container that's located within the item itself
+                       if($.contains(this.currentItem[0], this.containers[i].element[0])) {
+                               continue;
+                       }
+
+                       if(this._intersectsWith(this.containers[i].containerCache)) {
+
+                               // if we've already found a container and it's more "inner" than this, then continue
+                               if(innermostContainer && $.contains(this.containers[i].element[0], innermostContainer.element[0])) {
+                                       continue;
+                               }
+
+                               innermostContainer = this.containers[i];
+                               innermostIndex = i;
+
+                       } else {
+                               // container doesn't intersect. trigger "out" event if necessary
+                               if(this.containers[i].containerCache.over) {
+                                       this.containers[i]._trigger("out", event, this._uiHash(this));
+                                       this.containers[i].containerCache.over = 0;
+                               }
+                       }
+
+               }
+
+               // if no intersecting containers found, return
+               if(!innermostContainer) {
+                       return;
+               }
+
+               // move the item into the container if it's not there already
+               if(this.containers.length === 1) {
+                       this.containers[innermostIndex]._trigger("over", event, this._uiHash(this));
+                       this.containers[innermostIndex].containerCache.over = 1;
+               } else {
+
+                       //When entering a new container, we will find the item with the least distance and append our item near it
+                       dist = 10000;
+                       itemWithLeastDistance = null;
+                       posProperty = this.containers[innermostIndex].floating ? "left" : "top";
+                       sizeProperty = this.containers[innermostIndex].floating ? "width" : "height";
+                       base = this.positionAbs[posProperty] + this.offset.click[posProperty];
+                       for (j = this.items.length - 1; j >= 0; j--) {
+                               if(!$.contains(this.containers[innermostIndex].element[0], this.items[j].item[0])) {
+                                       continue;
+                               }
+                               if(this.items[j].item[0] === this.currentItem[0]) {
+                                       continue;
+                               }
+                               cur = this.items[j].item.offset()[posProperty];
+                               nearBottom = false;
+                               if(Math.abs(cur - base) > Math.abs(cur + this.items[j][sizeProperty] - base)){
+                                       nearBottom = true;
+                                       cur += this.items[j][sizeProperty];
+                               }
+
+                               if(Math.abs(cur - base) < dist) {
+                                       dist = Math.abs(cur - base); itemWithLeastDistance = this.items[j];
+                                       this.direction = nearBottom ? "up": "down";
+                               }
+                       }
+
+                       //Check if dropOnEmpty is enabled
+                       if(!itemWithLeastDistance && !this.options.dropOnEmpty) {
+                               return;
+                       }
+
+                       this.currentContainer = this.containers[innermostIndex];
+                       itemWithLeastDistance ? this._rearrange(event, itemWithLeastDistance, null, true) : this._rearrange(event, null, this.containers[innermostIndex].element, true);
+                       this._trigger("change", event, this._uiHash());
+                       this.containers[innermostIndex]._trigger("change", event, this._uiHash(this));
+
+                       //Update the placeholder
+                       this.options.placeholder.update(this.currentContainer, this.placeholder);
+
+                       this.containers[innermostIndex]._trigger("over", event, this._uiHash(this));
+                       this.containers[innermostIndex].containerCache.over = 1;
+               }
+
+
+       },
+
+       _createHelper: function(event) {
+
+               var o = this.options,
+                       helper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[0], [event, this.currentItem])) : (o.helper === "clone" ? this.currentItem.clone() : this.currentItem);
+
+               //Add the helper to the DOM if that didn't happen already
+               if(!helper.parents("body").length) {
+                       $(o.appendTo !== "parent" ? o.appendTo : this.currentItem[0].parentNode)[0].appendChild(helper[0]);
+               }
+
+               if(helper[0] === this.currentItem[0]) {
+                       this._storedCSS = { width: this.currentItem[0].style.width, height: this.currentItem[0].style.height, position: this.currentItem.css("position"), top: this.currentItem.css("top"), left: this.currentItem.css("left") };
+               }
+
+               if(!helper[0].style.width || o.forceHelperSize) {
+                       helper.width(this.currentItem.width());
+               }
+               if(!helper[0].style.height || o.forceHelperSize) {
+                       helper.height(this.currentItem.height());
+               }
+
+               return helper;
+
+       },
+
+       _adjustOffsetFromHelper: function(obj) {
+               if (typeof obj === "string") {
+                       obj = obj.split(" ");
+               }
+               if ($.isArray(obj)) {
+                       obj = {left: +obj[0], top: +obj[1] || 0};
+               }
+               if ("left" in obj) {
+                       this.offset.click.left = obj.left + this.margins.left;
+               }
+               if ("right" in obj) {
+                       this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
+               }
+               if ("top" in obj) {
+                       this.offset.click.top = obj.top + this.margins.top;
+               }
+               if ("bottom" in obj) {
+                       this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
+               }
+       },
+
+       _getParentOffset: function() {
+
+
+               //Get the offsetParent and cache its position
+               this.offsetParent = this.helper.offsetParent();
+               var po = this.offsetParent.offset();
+
+               // This is a special case where we need to modify a offset calculated on start, since the following happened:
+               // 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent
+               // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that
+               //    the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag
+               if(this.cssPosition === "absolute" && this.scrollParent[0] !== document && $.contains(this.scrollParent[0], this.offsetParent[0])) {
+                       po.left += this.scrollParent.scrollLeft();
+                       po.top += this.scrollParent.scrollTop();
+               }
+
+               // This needs to be actually done for all browsers, since pageX/pageY includes this information
+               // with an ugly IE fix
+               if( this.offsetParent[0] === document.body || (this.offsetParent[0].tagName && this.offsetParent[0].tagName.toLowerCase() === "html" && $.ui.ie)) {
+                       po = { top: 0, left: 0 };
+               }
+
+               return {
+                       top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"),10) || 0),
+                       left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"),10) || 0)
+               };
+
+       },
+
+       _getRelativeOffset: function() {
+
+               if(this.cssPosition === "relative") {
+                       var p = this.currentItem.position();
+                       return {
+                               top: p.top - (parseInt(this.helper.css("top"),10) || 0) + this.scrollParent.scrollTop(),
+                               left: p.left - (parseInt(this.helper.css("left"),10) || 0) + this.scrollParent.scrollLeft()
+                       };
+               } else {
+                       return { top: 0, left: 0 };
+               }
+
+       },
+
+       _cacheMargins: function() {
+               this.margins = {
+                       left: (parseInt(this.currentItem.css("marginLeft"),10) || 0),
+                       top: (parseInt(this.currentItem.css("marginTop"),10) || 0)
+               };
+       },
+
+       _cacheHelperProportions: function() {
+               this.helperProportions = {
+                       width: this.helper.outerWidth(),
+                       height: this.helper.outerHeight()
+               };
+       },
+
+       _setContainment: function() {
+
+               var ce, co, over,
+                       o = this.options;
+               if(o.containment === "parent") {
+                       o.containment = this.helper[0].parentNode;
+               }
+               if(o.containment === "document" || o.containment === "window") {
+                       this.containment = [
+                               0 - this.offset.relative.left - this.offset.parent.left,
+                               0 - this.offset.relative.top - this.offset.parent.top,
+                               $(o.containment === "document" ? document : window).width() - this.helperProportions.width - this.margins.left,
+                               ($(o.containment === "document" ? document : window).height() || document.body.parentNode.scrollHeight) - this.helperProportions.height - this.margins.top
+                       ];
+               }
+
+               if(!(/^(document|window|parent)$/).test(o.containment)) {
+                       ce = $(o.containment)[0];
+                       co = $(o.containment).offset();
+                       over = ($(ce).css("overflow") !== "hidden");
+
+                       this.containment = [
+                               co.left + (parseInt($(ce).css("borderLeftWidth"),10) || 0) + (parseInt($(ce).css("paddingLeft"),10) || 0) - this.margins.left,
+                               co.top + (parseInt($(ce).css("borderTopWidth"),10) || 0) + (parseInt($(ce).css("paddingTop"),10) || 0) - this.margins.top,
+                               co.left+(over ? Math.max(ce.scrollWidth,ce.offsetWidth) : ce.offsetWidth) - (parseInt($(ce).css("borderLeftWidth"),10) || 0) - (parseInt($(ce).css("paddingRight"),10) || 0) - this.helperProportions.width - this.margins.left,
+                               co.top+(over ? Math.max(ce.scrollHeight,ce.offsetHeight) : ce.offsetHeight) - (parseInt($(ce).css("borderTopWidth"),10) || 0) - (parseInt($(ce).css("paddingBottom"),10) || 0) - this.helperProportions.height - this.margins.top
+                       ];
+               }
+
+       },
+
+       _convertPositionTo: function(d, pos) {
+
+               if(!pos) {
+                       pos = this.position;
+               }
+               var mod = d === "absolute" ? 1 : -1,
+                       scroll = this.cssPosition === "absolute" && !(this.scrollParent[0] !== document && $.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent,
+                       scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName);
+
+               return {
+                       top: (
+                               pos.top +                                                                                                                               // The absolute mouse position
+                               this.offset.relative.top * mod +                                                                                // Only for relative positioned nodes: Relative offset from element to offset parent
+                               this.offset.parent.top * mod -                                                                                  // The offsetParent's offset without borders (offset + border)
+                               ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod)
+                       ),
+                       left: (
+                               pos.left +                                                                                                                              // The absolute mouse position
+                               this.offset.relative.left * mod +                                                                               // Only for relative positioned nodes: Relative offset from element to offset parent
+                               this.offset.parent.left * mod   -                                                                               // The offsetParent's offset without borders (offset + border)
+                               ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ) * mod)
+                       )
+               };
+
+       },
+
+       _generatePosition: function(event) {
+
+               var top, left,
+                       o = this.options,
+                       pageX = event.pageX,
+                       pageY = event.pageY,
+                       scroll = this.cssPosition === "absolute" && !(this.scrollParent[0] !== document && $.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName);
+
+               // This is another very weird special case that only happens for relative elements:
+               // 1. If the css position is relative
+               // 2. and the scroll parent is the document or similar to the offset parent
+               // we have to refresh the relative offset during the scroll so there are no jumps
+               if(this.cssPosition === "relative" && !(this.scrollParent[0] !== document && this.scrollParent[0] !== this.offsetParent[0])) {
+                       this.offset.relative = this._getRelativeOffset();
+               }
+
+               /*
+                * - Position constraining -
+                * Constrain the position to a mix of grid, containment.
+                */
+
+               if(this.originalPosition) { //If we are not dragging yet, we won't check for options
+
+                       if(this.containment) {
+                               if(event.pageX - this.offset.click.left < this.containment[0]) {
+                                       pageX = this.containment[0] + this.offset.click.left;
+                               }
+                               if(event.pageY - this.offset.click.top < this.containment[1]) {
+                                       pageY = this.containment[1] + this.offset.click.top;
+                               }
+                               if(event.pageX - this.offset.click.left > this.containment[2]) {
+                                       pageX = this.containment[2] + this.offset.click.left;
+                               }
+                               if(event.pageY - this.offset.click.top > this.containment[3]) {
+                                       pageY = this.containment[3] + this.offset.click.top;
+                               }
+                       }
+
+                       if(o.grid) {
+                               top = this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1];
+                               pageY = this.containment ? ( (top - this.offset.click.top >= this.containment[1] && top - this.offset.click.top <= this.containment[3]) ? top : ((top - this.offset.click.top >= this.containment[1]) ? top - o.grid[1] : top + o.grid[1])) : top;
+
+                               left = this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0];
+                               pageX = this.containment ? ( (left - this.offset.click.left >= this.containment[0] && left - this.offset.click.left <= this.containment[2]) ? left : ((left - this.offset.click.left >= this.containment[0]) ? left - o.grid[0] : left + o.grid[0])) : left;
+                       }
+
+               }
+
+               return {
+                       top: (
+                               pageY -                                                                                                                         // The absolute mouse position
+                               this.offset.click.top -                                                                                                 // Click offset (relative to the element)
+                               this.offset.relative.top        -                                                                                       // Only for relative positioned nodes: Relative offset from element to offset parent
+                               this.offset.parent.top +                                                                                                // The offsetParent's offset without borders (offset + border)
+                               ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ))
+                       ),
+                       left: (
+                               pageX -                                                                                                                         // The absolute mouse position
+                               this.offset.click.left -                                                                                                // Click offset (relative to the element)
+                               this.offset.relative.left       -                                                                                       // Only for relative positioned nodes: Relative offset from element to offset parent
+                               this.offset.parent.left +                                                                                               // The offsetParent's offset without borders (offset + border)
+                               ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ))
+                       )
+               };
+
+       },
+
+       _rearrange: function(event, i, a, hardRefresh) {
+
+               a ? a[0].appendChild(this.placeholder[0]) : i.item[0].parentNode.insertBefore(this.placeholder[0], (this.direction === "down" ? i.item[0] : i.item[0].nextSibling));
+
+               //Various things done here to improve the performance:
+               // 1. we create a setTimeout, that calls refreshPositions
+               // 2. on the instance, we have a counter variable, that get's higher after every append
+               // 3. on the local scope, we copy the counter variable, and check in the timeout, if it's still the same
+               // 4. this lets only the last addition to the timeout stack through
+               this.counter = this.counter ? ++this.counter : 1;
+               var counter = this.counter;
+
+               this._delay(function() {
+                       if(counter === this.counter) {
+                               this.refreshPositions(!hardRefresh); //Precompute after each DOM insertion, NOT on mousemove
+                       }
+               });
+
+       },
+
+       _clear: function(event, noPropagation) {
+
+               this.reverting = false;
+               // We delay all events that have to be triggered to after the point where the placeholder has been removed and
+               // everything else normalized again
+               var i,
+                       delayedTriggers = [];
+
+               // We first have to update the dom position of the actual currentItem
+               // Note: don't do it if the current item is already removed (by a user), or it gets reappended (see #4088)
+               if(!this._noFinalSort && this.currentItem.parent().length) {
+                       this.placeholder.before(this.currentItem);
+               }
+               this._noFinalSort = null;
+
+               if(this.helper[0] === this.currentItem[0]) {
+                       for(i in this._storedCSS) {
+                               if(this._storedCSS[i] === "auto" || this._storedCSS[i] === "static") {
+                                       this._storedCSS[i] = "";
+                               }
+                       }
+                       this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper");
+               } else {
+                       this.currentItem.show();
+               }
+
+               if(this.fromOutside && !noPropagation) {
+                       delayedTriggers.push(function(event) { this._trigger("receive", event, this._uiHash(this.fromOutside)); });
+               }
+               if((this.fromOutside || this.domPosition.prev !== this.currentItem.prev().not(".ui-sortable-helper")[0] || this.domPosition.parent !== this.currentItem.parent()[0]) && !noPropagation) {
+                       delayedTriggers.push(function(event) { this._trigger("update", event, this._uiHash()); }); //Trigger update callback if the DOM position has changed
+               }
+
+               // Check if the items Container has Changed and trigger appropriate
+               // events.
+               if (this !== this.currentContainer) {
+                       if(!noPropagation) {
+                               delayedTriggers.push(function(event) { this._trigger("remove", event, this._uiHash()); });
+                               delayedTriggers.push((function(c) { return function(event) { c._trigger("receive", event, this._uiHash(this)); };  }).call(this, this.currentContainer));
+                               delayedTriggers.push((function(c) { return function(event) { c._trigger("update", event, this._uiHash(this));  }; }).call(this, this.currentContainer));
+                       }
+               }
+
+
+               //Post events to containers
+               for (i = this.containers.length - 1; i >= 0; i--){
+                       if(!noPropagation) {
+                               delayedTriggers.push((function(c) { return function(event) { c._trigger("deactivate", event, this._uiHash(this)); };  }).call(this, this.containers[i]));
+                       }
+                       if(this.containers[i].containerCache.over) {
+                               delayedTriggers.push((function(c) { return function(event) { c._trigger("out", event, this._uiHash(this)); };  }).call(this, this.containers[i]));
+                               this.containers[i].containerCache.over = 0;
+                       }
+               }
+
+               //Do what was originally in plugins
+               if(this._storedCursor) {
+                       $("body").css("cursor", this._storedCursor);
+               }
+               if(this._storedOpacity) {
+                       this.helper.css("opacity", this._storedOpacity);
+               }
+               if(this._storedZIndex) {
+                       this.helper.css("zIndex", this._storedZIndex === "auto" ? "" : this._storedZIndex);
+               }
+
+               this.dragging = false;
+               if(this.cancelHelperRemoval) {
+                       if(!noPropagation) {
+                               this._trigger("beforeStop", event, this._uiHash());
+                               for (i=0; i < delayedTriggers.length; i++) {
+                                       delayedTriggers[i].call(this, event);
+                               } //Trigger all delayed events
+                               this._trigger("stop", event, this._uiHash());
+                       }
+
+                       this.fromOutside = false;
+                       return false;
+               }
+
+               if(!noPropagation) {
+                       this._trigger("beforeStop", event, this._uiHash());
+               }
+
+               //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node!
+               this.placeholder[0].parentNode.removeChild(this.placeholder[0]);
+
+               if(this.helper[0] !== this.currentItem[0]) {
+                       this.helper.remove();
+               }
+               this.helper = null;
+
+               if(!noPropagation) {
+                       for (i=0; i < delayedTriggers.length; i++) {
+                               delayedTriggers[i].call(this, event);
+                       } //Trigger all delayed events
+                       this._trigger("stop", event, this._uiHash());
+               }
+
+               this.fromOutside = false;
+               return true;
+
+       },
+
+       _trigger: function() {
+               if ($.Widget.prototype._trigger.apply(this, arguments) === false) {
+                       this.cancel();
+               }
+       },
+
+       _uiHash: function(_inst) {
+               var inst = _inst || this;
+               return {
+                       helper: inst.helper,
+                       placeholder: inst.placeholder || $([]),
+                       position: inst.position,
+                       originalPosition: inst.originalPosition,
+                       offset: inst.positionAbs,
+                       item: inst.currentItem,
+                       sender: _inst ? _inst.element : null
+               };
+       }
+
+});
+
+})(jQuery);
+;(jQuery.effects || (function($, undefined) {
+
+var dataSpace = "ui-effects-";
+
+$.effects = {
+       effect: {}
+};
+
+/*!
+ * jQuery Color Animations v2.1.2
+ * https://github.com/jquery/jquery-color
+ *
+ * Copyright 2013 jQuery Foundation and other contributors
+ * Released under the MIT license.
+ * http://jquery.org/license
+ *
+ * Date: Wed Jan 16 08:47:09 2013 -0600
+ */
+(function( jQuery, undefined ) {
+
+       var stepHooks = "backgroundColor borderBottomColor borderLeftColor borderRightColor borderTopColor color columnRuleColor outlineColor textDecorationColor textEmphasisColor",
+
+       // plusequals test for += 100 -= 100
+       rplusequals = /^([\-+])=\s*(\d+\.?\d*)/,
+       // a set of RE's that can match strings and generate color tuples.
+       stringParsers = [{
+                       re: /rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,
+                       parse: function( execResult ) {
+                               return [
+                                       execResult[ 1 ],
+                                       execResult[ 2 ],
+                                       execResult[ 3 ],
+                                       execResult[ 4 ]
+                               ];
+                       }
+               }, {
+                       re: /rgba?\(\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,
+                       parse: function( execResult ) {
+                               return [
+                                       execResult[ 1 ] * 2.55,
+                                       execResult[ 2 ] * 2.55,
+                                       execResult[ 3 ] * 2.55,
+                                       execResult[ 4 ]
+                               ];
+                       }
+               }, {
+                       // this regex ignores A-F because it's compared against an already lowercased string
+                       re: /#([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})/,
+                       parse: function( execResult ) {
+                               return [
+                                       parseInt( execResult[ 1 ], 16 ),
+                                       parseInt( execResult[ 2 ], 16 ),
+                                       parseInt( execResult[ 3 ], 16 )
+                               ];
+                       }
+               }, {
+                       // this regex ignores A-F because it's compared against an already lowercased string
+                       re: /#([a-f0-9])([a-f0-9])([a-f0-9])/,
+                       parse: function( execResult ) {
+                               return [
+                                       parseInt( execResult[ 1 ] + execResult[ 1 ], 16 ),
+                                       parseInt( execResult[ 2 ] + execResult[ 2 ], 16 ),
+                                       parseInt( execResult[ 3 ] + execResult[ 3 ], 16 )
+                               ];
+                       }
+               }, {
+                       re: /hsla?\(\s*(\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,
+                       space: "hsla",
+                       parse: function( execResult ) {
+                               return [
+                                       execResult[ 1 ],
+                                       execResult[ 2 ] / 100,
+                                       execResult[ 3 ] / 100,
+                                       execResult[ 4 ]
+                               ];
+                       }
+               }],
+
+       // jQuery.Color( )
+       color = jQuery.Color = function( color, green, blue, alpha ) {
+               return new jQuery.Color.fn.parse( color, green, blue, alpha );
+       },
+       spaces = {
+               rgba: {
+                       props: {
+                               red: {
+                                       idx: 0,
+                                       type: "byte"
+                               },
+                               green: {
+                                       idx: 1,
+                                       type: "byte"
+                               },
+                               blue: {
+                                       idx: 2,
+                                       type: "byte"
+                               }
+                       }
+               },
+
+               hsla: {
+                       props: {
+                               hue: {
+                                       idx: 0,
+                                       type: "degrees"
+                               },
+                               saturation: {
+                                       idx: 1,
+                                       type: "percent"
+                               },
+                               lightness: {
+                                       idx: 2,
+                                       type: "percent"
+                               }
+                       }
+               }
+       },
+       propTypes = {
+               "byte": {
+                       floor: true,
+                       max: 255
+               },
+               "percent": {
+                       max: 1
+               },
+               "degrees": {
+                       mod: 360,
+                       floor: true
+               }
+       },
+       support = color.support = {},
+
+       // element for support tests
+       supportElem = jQuery( "<p>" )[ 0 ],
+
+       // colors = jQuery.Color.names
+       colors,
+
+       // local aliases of functions called often
+       each = jQuery.each;
+
+// determine rgba support immediately
+supportElem.style.cssText = "background-color:rgba(1,1,1,.5)";
+support.rgba = supportElem.style.backgroundColor.indexOf( "rgba" ) > -1;
+
+// define cache name and alpha properties
+// for rgba and hsla spaces
+each( spaces, function( spaceName, space ) {
+       space.cache = "_" + spaceName;
+       space.props.alpha = {
+               idx: 3,
+               type: "percent",
+               def: 1
+       };
+});
+
+function clamp( value, prop, allowEmpty ) {
+       var type = propTypes[ prop.type ] || {};
+
+       if ( value == null ) {
+               return (allowEmpty || !prop.def) ? null : prop.def;
+       }
+
+       // ~~ is an short way of doing floor for positive numbers
+       value = type.floor ? ~~value : parseFloat( value );
+
+       // IE will pass in empty strings as value for alpha,
+       // which will hit this case
+       if ( isNaN( value ) ) {
+               return prop.def;
+       }
+
+       if ( type.mod ) {
+               // we add mod before modding to make sure that negatives values
+               // get converted properly: -10 -> 350
+               return (value + type.mod) % type.mod;
+       }
+
+       // for now all property types without mod have min and max
+       return 0 > value ? 0 : type.max < value ? type.max : value;
+}
+
+function stringParse( string ) {
+       var inst = color(),
+               rgba = inst._rgba = [];
+
+       string = string.toLowerCase();
+
+       each( stringParsers, function( i, parser ) {
+               var parsed,
+                       match = parser.re.exec( string ),
+                       values = match && parser.parse( match ),
+                       spaceName = parser.space || "rgba";
+
+               if ( values ) {
+                       parsed = inst[ spaceName ]( values );
+
+                       // if this was an rgba parse the assignment might happen twice
+                       // oh well....
+                       inst[ spaces[ spaceName ].cache ] = parsed[ spaces[ spaceName ].cache ];
+                       rgba = inst._rgba = parsed._rgba;
+
+                       // exit each( stringParsers ) here because we matched
+                       return false;
+               }
+       });
+
+       // Found a stringParser that handled it
+       if ( rgba.length ) {
+
+               // if this came from a parsed string, force "transparent" when alpha is 0
+               // chrome, (and maybe others) return "transparent" as rgba(0,0,0,0)
+               if ( rgba.join() === "0,0,0,0" ) {
+                       jQuery.extend( rgba, colors.transparent );
+               }
+               return inst;
+       }
+
+       // named colors
+       return colors[ string ];
+}
+
+color.fn = jQuery.extend( color.prototype, {
+       parse: function( red, green, blue, alpha ) {
+               if ( red === undefined ) {
+                       this._rgba = [ null, null, null, null ];
+                       return this;
+               }
+               if ( red.jquery || red.nodeType ) {
+                       red = jQuery( red ).css( green );
+                       green = undefined;
+               }
+
+               var inst = this,
+                       type = jQuery.type( red ),
+                       rgba = this._rgba = [];
+
+               // more than 1 argument specified - assume ( red, green, blue, alpha )
+               if ( green !== undefined ) {
+                       red = [ red, green, blue, alpha ];
+                       type = "array";
+               }
+
+               if ( type === "string" ) {
+                       return this.parse( stringParse( red ) || colors._default );
+               }
+
+               if ( type === "array" ) {
+                       each( spaces.rgba.props, function( key, prop ) {
+                               rgba[ prop.idx ] = clamp( red[ prop.idx ], prop );
+                       });
+                       return this;
+               }
+
+               if ( type === "object" ) {
+                       if ( red instanceof color ) {
+                               each( spaces, function( spaceName, space ) {
+                                       if ( red[ space.cache ] ) {
+                                               inst[ space.cache ] = red[ space.cache ].slice();
+                                       }
+                               });
+                       } else {
+                               each( spaces, function( spaceName, space ) {
+                                       var cache = space.cache;
+                                       each( space.props, function( key, prop ) {
+
+                                               // if the cache doesn't exist, and we know how to convert
+                                               if ( !inst[ cache ] && space.to ) {
+
+                                                       // if the value was null, we don't need to copy it
+                                                       // if the key was alpha, we don't need to copy it either
+                                                       if ( key === "alpha" || red[ key ] == null ) {
+                                                               return;
+                                                       }
+                                                       inst[ cache ] = space.to( inst._rgba );
+                                               }
+
+                                               // this is the only case where we allow nulls for ALL properties.
+                                               // call clamp with alwaysAllowEmpty
+                                               inst[ cache ][ prop.idx ] = clamp( red[ key ], prop, true );
+                                       });
+
+                                       // everything defined but alpha?
+                                       if ( inst[ cache ] && jQuery.inArray( null, inst[ cache ].slice( 0, 3 ) ) < 0 ) {
+                                               // use the default of 1
+                                               inst[ cache ][ 3 ] = 1;
+                                               if ( space.from ) {
+                                                       inst._rgba = space.from( inst[ cache ] );
+                                               }
+                                       }
+                               });
+                       }
+                       return this;
+               }
+       },
+       is: function( compare ) {
+               var is = color( compare ),
+                       same = true,
+                       inst = this;
+
+               each( spaces, function( _, space ) {
+                       var localCache,
+                               isCache = is[ space.cache ];
+                       if (isCache) {
+                               localCache = inst[ space.cache ] || space.to && space.to( inst._rgba ) || [];
+                               each( space.props, function( _, prop ) {
+                                       if ( isCache[ prop.idx ] != null ) {
+                                               same = ( isCache[ prop.idx ] === localCache[ prop.idx ] );
+                                               return same;
+                                       }
+                               });
+                       }
+                       return same;
+               });
+               return same;
+       },
+       _space: function() {
+               var used = [],
+                       inst = this;
+               each( spaces, function( spaceName, space ) {
+                       if ( inst[ space.cache ] ) {
+                               used.push( spaceName );
+                       }
+               });
+               return used.pop();
+       },
+       transition: function( other, distance ) {
+               var end = color( other ),
+                       spaceName = end._space(),
+                       space = spaces[ spaceName ],
+                       startColor = this.alpha() === 0 ? color( "transparent" ) : this,
+                       start = startColor[ space.cache ] || space.to( startColor._rgba ),
+                       result = start.slice();
+
+               end = end[ space.cache ];
+               each( space.props, function( key, prop ) {
+                       var index = prop.idx,
+                               startValue = start[ index ],
+                               endValue = end[ index ],
+                               type = propTypes[ prop.type ] || {};
+
+                       // if null, don't override start value
+                       if ( endValue === null ) {
+                               return;
+                       }
+                       // if null - use end
+                       if ( startValue === null ) {
+                               result[ index ] = endValue;
+                       } else {
+                               if ( type.mod ) {
+                                       if ( endValue - startValue > type.mod / 2 ) {
+                                               startValue += type.mod;
+                                       } else if ( startValue - endValue > type.mod / 2 ) {
+                                               startValue -= type.mod;
+                                       }
+                               }
+                               result[ index ] = clamp( ( endValue - startValue ) * distance + startValue, prop );
+                       }
+               });
+               return this[ spaceName ]( result );
+       },
+       blend: function( opaque ) {
+               // if we are already opaque - return ourself
+               if ( this._rgba[ 3 ] === 1 ) {
+                       return this;
+               }
+
+               var rgb = this._rgba.slice(),
+                       a = rgb.pop(),
+                       blend = color( opaque )._rgba;
+
+               return color( jQuery.map( rgb, function( v, i ) {
+                       return ( 1 - a ) * blend[ i ] + a * v;
+               }));
+       },
+       toRgbaString: function() {
+               var prefix = "rgba(",
+                       rgba = jQuery.map( this._rgba, function( v, i ) {
+                               return v == null ? ( i > 2 ? 1 : 0 ) : v;
+                       });
+
+               if ( rgba[ 3 ] === 1 ) {
+                       rgba.pop();
+                       prefix = "rgb(";
+               }
+
+               return prefix + rgba.join() + ")";
+       },
+       toHslaString: function() {
+               var prefix = "hsla(",
+                       hsla = jQuery.map( this.hsla(), function( v, i ) {
+                               if ( v == null ) {
+                                       v = i > 2 ? 1 : 0;
+                               }
+
+                               // catch 1 and 2
+                               if ( i && i < 3 ) {
+                                       v = Math.round( v * 100 ) + "%";
+                               }
+                               return v;
+                       });
+
+               if ( hsla[ 3 ] === 1 ) {
+                       hsla.pop();
+                       prefix = "hsl(";
+               }
+               return prefix + hsla.join() + ")";
+       },
+       toHexString: function( includeAlpha ) {
+               var rgba = this._rgba.slice(),
+                       alpha = rgba.pop();
+
+               if ( includeAlpha ) {
+                       rgba.push( ~~( alpha * 255 ) );
+               }
+
+               return "#" + jQuery.map( rgba, function( v ) {
+
+                       // default to 0 when nulls exist
+                       v = ( v || 0 ).toString( 16 );
+                       return v.length === 1 ? "0" + v : v;
+               }).join("");
+       },
+       toString: function() {
+               return this._rgba[ 3 ] === 0 ? "transparent" : this.toRgbaString();
+       }
+});
+color.fn.parse.prototype = color.fn;
+
+// hsla conversions adapted from:
+// https://code.google.com/p/maashaack/source/browse/packages/graphics/trunk/src/graphics/colors/HUE2RGB.as?r=5021
+
+function hue2rgb( p, q, h ) {
+       h = ( h + 1 ) % 1;
+       if ( h * 6 < 1 ) {
+               return p + (q - p) * h * 6;
+       }
+       if ( h * 2 < 1) {
+               return q;
+       }
+       if ( h * 3 < 2 ) {
+               return p + (q - p) * ((2/3) - h) * 6;
+       }
+       return p;
+}
+
+spaces.hsla.to = function ( rgba ) {
+       if ( rgba[ 0 ] == null || rgba[ 1 ] == null || rgba[ 2 ] == null ) {
+               return [ null, null, null, rgba[ 3 ] ];
+       }
+       var r = rgba[ 0 ] / 255,
+               g = rgba[ 1 ] / 255,
+               b = rgba[ 2 ] / 255,
+               a = rgba[ 3 ],
+               max = Math.max( r, g, b ),
+               min = Math.min( r, g, b ),
+               diff = max - min,
+               add = max + min,
+               l = add * 0.5,
+               h, s;
+
+       if ( min === max ) {
+               h = 0;
+       } else if ( r === max ) {
+               h = ( 60 * ( g - b ) / diff ) + 360;
+       } else if ( g === max ) {
+               h = ( 60 * ( b - r ) / diff ) + 120;
+       } else {
+               h = ( 60 * ( r - g ) / diff ) + 240;
+       }
+
+       // chroma (diff) == 0 means greyscale which, by definition, saturation = 0%
+       // otherwise, saturation is based on the ratio of chroma (diff) to lightness (add)
+       if ( diff === 0 ) {
+               s = 0;
+       } else if ( l <= 0.5 ) {
+               s = diff / add;
+       } else {
+               s = diff / ( 2 - add );
+       }
+       return [ Math.round(h) % 360, s, l, a == null ? 1 : a ];
+};
+
+spaces.hsla.from = function ( hsla ) {
+       if ( hsla[ 0 ] == null || hsla[ 1 ] == null || hsla[ 2 ] == null ) {
+               return [ null, null, null, hsla[ 3 ] ];
+       }
+       var h = hsla[ 0 ] / 360,
+               s = hsla[ 1 ],
+               l = hsla[ 2 ],
+               a = hsla[ 3 ],
+               q = l <= 0.5 ? l * ( 1 + s ) : l + s - l * s,
+               p = 2 * l - q;
+
+       return [
+               Math.round( hue2rgb( p, q, h + ( 1 / 3 ) ) * 255 ),
+               Math.round( hue2rgb( p, q, h ) * 255 ),
+               Math.round( hue2rgb( p, q, h - ( 1 / 3 ) ) * 255 ),
+               a
+       ];
+};
+
+
+each( spaces, function( spaceName, space ) {
+       var props = space.props,
+               cache = space.cache,
+               to = space.to,
+               from = space.from;
+
+       // makes rgba() and hsla()
+       color.fn[ spaceName ] = function( value ) {
+
+               // generate a cache for this space if it doesn't exist
+               if ( to && !this[ cache ] ) {
+                       this[ cache ] = to( this._rgba );
+               }
+               if ( value === undefined ) {
+                       return this[ cache ].slice();
+               }
+
+               var ret,
+                       type = jQuery.type( value ),
+                       arr = ( type === "array" || type === "object" ) ? value : arguments,
+                       local = this[ cache ].slice();
+
+               each( props, function( key, prop ) {
+                       var val = arr[ type === "object" ? key : prop.idx ];
+                       if ( val == null ) {
+                               val = local[ prop.idx ];
+                       }
+                       local[ prop.idx ] = clamp( val, prop );
+               });
+
+               if ( from ) {
+                       ret = color( from( local ) );
+                       ret[ cache ] = local;
+                       return ret;
+               } else {
+                       return color( local );
+               }
+       };
+
+       // makes red() green() blue() alpha() hue() saturation() lightness()
+       each( props, function( key, prop ) {
+               // alpha is included in more than one space
+               if ( color.fn[ key ] ) {
+                       return;
+               }
+               color.fn[ key ] = function( value ) {
+                       var vtype = jQuery.type( value ),
+                               fn = ( key === "alpha" ? ( this._hsla ? "hsla" : "rgba" ) : spaceName ),
+                               local = this[ fn ](),
+                               cur = local[ prop.idx ],
+                               match;
+
+                       if ( vtype === "undefined" ) {
+                               return cur;
+                       }
+
+                       if ( vtype === "function" ) {
+                               value = value.call( this, cur );
+                               vtype = jQuery.type( value );
+                       }
+                       if ( value == null && prop.empty ) {
+                               return this;
+                       }
+                       if ( vtype === "string" ) {
+                               match = rplusequals.exec( value );
+                               if ( match ) {
+                                       value = cur + parseFloat( match[ 2 ] ) * ( match[ 1 ] === "+" ? 1 : -1 );
+                               }
+                       }
+                       local[ prop.idx ] = value;
+                       return this[ fn ]( local );
+               };
+       });
+});
+
+// add cssHook and .fx.step function for each named hook.
+// accept a space separated string of properties
+color.hook = function( hook ) {
+       var hooks = hook.split( " " );
+       each( hooks, function( i, hook ) {
+               jQuery.cssHooks[ hook ] = {
+                       set: function( elem, value ) {
+                               var parsed, curElem,
+                                       backgroundColor = "";
+
+                               if ( value !== "transparent" && ( jQuery.type( value ) !== "string" || ( parsed = stringParse( value ) ) ) ) {
+                                       value = color( parsed || value );
+                                       if ( !support.rgba && value._rgba[ 3 ] !== 1 ) {
+                                               curElem = hook === "backgroundColor" ? elem.parentNode : elem;
+                                               while (
+                                                       (backgroundColor === "" || backgroundColor === "transparent") &&
+                                                       curElem && curElem.style
+                                               ) {
+                                                       try {
+                                                               backgroundColor = jQuery.css( curElem, "backgroundColor" );
+                                                               curElem = curElem.parentNode;
+                                                       } catch ( e ) {
+                                                       }
+                                               }
+
+                                               value = value.blend( backgroundColor && backgroundColor !== "transparent" ?
+                                                       backgroundColor :
+                                                       "_default" );
+                                       }
+
+                                       value = value.toRgbaString();
+                               }
+                               try {
+                                       elem.style[ hook ] = value;
+                               } catch( e ) {
+                                       // wrapped to prevent IE from throwing errors on "invalid" values like 'auto' or 'inherit'
+                               }
+                       }
+               };
+               jQuery.fx.step[ hook ] = function( fx ) {
+                       if ( !fx.colorInit ) {
+                               fx.start = color( fx.elem, hook );
+                               fx.end = color( fx.end );
+                               fx.colorInit = true;
+                       }
+                       jQuery.cssHooks[ hook ].set( fx.elem, fx.start.transition( fx.end, fx.pos ) );
+               };
+       });
+
+};
+
+color.hook( stepHooks );
+
+jQuery.cssHooks.borderColor = {
+       expand: function( value ) {
+               var expanded = {};
+
+               each( [ "Top", "Right", "Bottom", "Left" ], function( i, part ) {
+                       expanded[ "border" + part + "Color" ] = value;
+               });
+               return expanded;
+       }
+};
+
+// Basic color names only.
+// Usage of any of the other color names requires adding yourself or including
+// jquery.color.svg-names.js.
+colors = jQuery.Color.names = {
+       // 4.1. Basic color keywords
+       aqua: "#00ffff",
+       black: "#000000",
+       blue: "#0000ff",
+       fuchsia: "#ff00ff",
+       gray: "#808080",
+       green: "#008000",
+       lime: "#00ff00",
+       maroon: "#800000",
+       navy: "#000080",
+       olive: "#808000",
+       purple: "#800080",
+       red: "#ff0000",
+       silver: "#c0c0c0",
+       teal: "#008080",
+       white: "#ffffff",
+       yellow: "#ffff00",
+
+       // 4.2.3. "transparent" color keyword
+       transparent: [ null, null, null, 0 ],
+
+       _default: "#ffffff"
+};
+
+})( jQuery );
+
+
+/******************************************************************************/
+/****************************** CLASS ANIMATIONS ******************************/
+/******************************************************************************/
+(function() {
+
+var classAnimationActions = [ "add", "remove", "toggle" ],
+       shorthandStyles = {
+               border: 1,
+               borderBottom: 1,
+               borderColor: 1,
+               borderLeft: 1,
+               borderRight: 1,
+               borderTop: 1,
+               borderWidth: 1,
+               margin: 1,
+               padding: 1
+       };
+
+$.each([ "borderLeftStyle", "borderRightStyle", "borderBottomStyle", "borderTopStyle" ], function( _, prop ) {
+       $.fx.step[ prop ] = function( fx ) {
+               if ( fx.end !== "none" && !fx.setAttr || fx.pos === 1 && !fx.setAttr ) {
+                       jQuery.style( fx.elem, prop, fx.end );
+                       fx.setAttr = true;
+               }
+       };
+});
+
+function getElementStyles( elem ) {
+       var key, len,
+               style = elem.ownerDocument.defaultView ?
+                       elem.ownerDocument.defaultView.getComputedStyle( elem, null ) :
+                       elem.currentStyle,
+               styles = {};
+
+       if ( style && style.length && style[ 0 ] && style[ style[ 0 ] ] ) {
+               len = style.length;
+               while ( len-- ) {
+                       key = style[ len ];
+                       if ( typeof style[ key ] === "string" ) {
+                               styles[ $.camelCase( key ) ] = style[ key ];
+                       }
+               }
+       // support: Opera, IE <9
+       } else {
+               for ( key in style ) {
+                       if ( typeof style[ key ] === "string" ) {
+                               styles[ key ] = style[ key ];
+                       }
+               }
+       }
+
+       return styles;
+}
+
+
+function styleDifference( oldStyle, newStyle ) {
+       var diff = {},
+               name, value;
+
+       for ( name in newStyle ) {
+               value = newStyle[ name ];
+               if ( oldStyle[ name ] !== value ) {
+                       if ( !shorthandStyles[ name ] ) {
+                               if ( $.fx.step[ name ] || !isNaN( parseFloat( value ) ) ) {
+                                       diff[ name ] = value;
+                               }
+                       }
+               }
+       }
+
+       return diff;
+}
+
+// support: jQuery <1.8
+if ( !$.fn.addBack ) {
+       $.fn.addBack = function( selector ) {
+               return this.add( selector == null ?
+                       this.prevObject : this.prevObject.filter( selector )
+               );
+       };
+}
+
+$.effects.animateClass = function( value, duration, easing, callback ) {
+       var o = $.speed( duration, easing, callback );
+
+       return this.queue( function() {
+               var animated = $( this ),
+                       baseClass = animated.attr( "class" ) || "",
+                       applyClassChange,
+                       allAnimations = o.children ? animated.find( "*" ).addBack() : animated;
+
+               // map the animated objects to store the original styles.
+               allAnimations = allAnimations.map(function() {
+                       var el = $( this );
+                       return {
+                               el: el,
+                               start: getElementStyles( this )
+                       };
+               });
+
+               // apply class change
+               applyClassChange = function() {
+                       $.each( classAnimationActions, function(i, action) {
+                               if ( value[ action ] ) {
+                                       animated[ action + "Class" ]( value[ action ] );
+                               }
+                       });
+               };
+               applyClassChange();
+
+               // map all animated objects again - calculate new styles and diff
+               allAnimations = allAnimations.map(function() {
+                       this.end = getElementStyles( this.el[ 0 ] );
+                       this.diff = styleDifference( this.start, this.end );
+                       return this;
+               });
+
+               // apply original class
+               animated.attr( "class", baseClass );
+
+               // map all animated objects again - this time collecting a promise
+               allAnimations = allAnimations.map(function() {
+                       var styleInfo = this,
+                               dfd = $.Deferred(),
+                               opts = $.extend({}, o, {
+                                       queue: false,
+                                       complete: function() {
+                                               dfd.resolve( styleInfo );
+                                       }
+                               });
+
+                       this.el.animate( this.diff, opts );
+                       return dfd.promise();
+               });
+
+               // once all animations have completed:
+               $.when.apply( $, allAnimations.get() ).done(function() {
+
+                       // set the final class
+                       applyClassChange();
+
+                       // for each animated element,
+                       // clear all css properties that were animated
+                       $.each( arguments, function() {
+                               var el = this.el;
+                               $.each( this.diff, function(key) {
+                                       el.css( key, "" );
+                               });
+                       });
+
+                       // this is guarnteed to be there if you use jQuery.speed()
+                       // it also handles dequeuing the next anim...
+                       o.complete.call( animated[ 0 ] );
+               });
+       });
+};
+
+$.fn.extend({
+       _addClass: $.fn.addClass,
+       addClass: function( classNames, speed, easing, callback ) {
+               return speed ?
+                       $.effects.animateClass.call( this,
+                               { add: classNames }, speed, easing, callback ) :
+                       this._addClass( classNames );
+       },
+
+       _removeClass: $.fn.removeClass,
+       removeClass: function( classNames, speed, easing, callback ) {
+               return speed ?
+                       $.effects.animateClass.call( this,
+                               { remove: classNames }, speed, easing, callback ) :
+                       this._removeClass( classNames );
+       },
+
+       _toggleClass: $.fn.toggleClass,
+       toggleClass: function( classNames, force, speed, easing, callback ) {
+               if ( typeof force === "boolean" || force === undefined ) {
+                       if ( !speed ) {
+                               // without speed parameter
+                               return this._toggleClass( classNames, force );
+                       } else {
+                               return $.effects.animateClass.call( this,
+                                       (force ? { add: classNames } : { remove: classNames }),
+                                       speed, easing, callback );
+                       }
+               } else {
+                       // without force parameter
+                       return $.effects.animateClass.call( this,
+                               { toggle: classNames }, force, speed, easing );
+               }
+       },
+
+       switchClass: function( remove, add, speed, easing, callback) {
+               return $.effects.animateClass.call( this, {
+                       add: add,
+                       remove: remove
+               }, speed, easing, callback );
+       }
+});
+
+})();
+
+/******************************************************************************/
+/*********************************** EFFECTS **********************************/
+/******************************************************************************/
+
+(function() {
+
+$.extend( $.effects, {
+       version: "1.10.0",
+
+       // Saves a set of properties in a data storage
+       save: function( element, set ) {
+               for( var i=0; i < set.length; i++ ) {
+                       if ( set[ i ] !== null ) {
+                               element.data( dataSpace + set[ i ], element[ 0 ].style[ set[ i ] ] );
+                       }
+               }
+       },
+
+       // Restores a set of previously saved properties from a data storage
+       restore: function( element, set ) {
+               var val, i;
+               for( i=0; i < set.length; i++ ) {
+                       if ( set[ i ] !== null ) {
+                               val = element.data( dataSpace + set[ i ] );
+                               // support: jQuery 1.6.2
+                               // http://bugs.jquery.com/ticket/9917
+                               // jQuery 1.6.2 incorrectly returns undefined for any falsy value.
+                               // We can't differentiate between "" and 0 here, so we just assume
+                               // empty string since it's likely to be a more common value...
+                               if ( val === undefined ) {
+                                       val = "";
+                               }
+                               element.css( set[ i ], val );
+                       }
+               }
+       },
+
+       setMode: function( el, mode ) {
+               if (mode === "toggle") {
+                       mode = el.is( ":hidden" ) ? "show" : "hide";
+               }
+               return mode;
+       },
+
+       // Translates a [top,left] array into a baseline value
+       // this should be a little more flexible in the future to handle a string & hash
+       getBaseline: function( origin, original ) {
+               var y, x;
+               switch ( origin[ 0 ] ) {
+                       case "top": y = 0; break;
+                       case "middle": y = 0.5; break;
+                       case "bottom": y = 1; break;
+                       default: y = origin[ 0 ] / original.height;
+               }
+               switch ( origin[ 1 ] ) {
+                       case "left": x = 0; break;
+                       case "center": x = 0.5; break;
+                       case "right": x = 1; break;
+                       default: x = origin[ 1 ] / original.width;
+               }
+               return {
+                       x: x,
+                       y: y
+               };
+       },
+
+       // Wraps the element around a wrapper that copies position properties
+       createWrapper: function( element ) {
+
+               // if the element is already wrapped, return it
+               if ( element.parent().is( ".ui-effects-wrapper" )) {
+                       return element.parent();
+               }
+
+               // wrap the element
+               var props = {
+                               width: element.outerWidth(true),
+                               height: element.outerHeight(true),
+                               "float": element.css( "float" )
+                       },
+                       wrapper = $( "<div></div>" )
+                               .addClass( "ui-effects-wrapper" )
+                               .css({
+                                       fontSize: "100%",
+                                       background: "transparent",
+                                       border: "none",
+                                       margin: 0,
+                                       padding: 0
+                               }),
+                       // Store the size in case width/height are defined in % - Fixes #5245
+                       size = {
+                               width: element.width(),
+                               height: element.height()
+                       },
+                       active = document.activeElement;
+
+               // support: Firefox
+               // Firefox incorrectly exposes anonymous content
+               // https://bugzilla.mozilla.org/show_bug.cgi?id=561664
+               try {
+                       active.id;
+               } catch( e ) {
+                       active = document.body;
+               }
+
+               element.wrap( wrapper );
+
+               // Fixes #7595 - Elements lose focus when wrapped.
+               if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) {
+                       $( active ).focus();
+               }
+
+               wrapper = element.parent(); //Hotfix for jQuery 1.4 since some change in wrap() seems to actually lose the reference to the wrapped element
+
+               // transfer positioning properties to the wrapper
+               if ( element.css( "position" ) === "static" ) {
+                       wrapper.css({ position: "relative" });
+                       element.css({ position: "relative" });
+               } else {
+                       $.extend( props, {
+                               position: element.css( "position" ),
+                               zIndex: element.css( "z-index" )
+                       });
+                       $.each([ "top", "left", "bottom", "right" ], function(i, pos) {
+                               props[ pos ] = element.css( pos );
+                               if ( isNaN( parseInt( props[ pos ], 10 ) ) ) {
+                                       props[ pos ] = "auto";
+                               }
+                       });
+                       element.css({
+                               position: "relative",
+                               top: 0,
+                               left: 0,
+                               right: "auto",
+                               bottom: "auto"
+                       });
+               }
+               element.css(size);
+
+               return wrapper.css( props ).show();
+       },
+
+       removeWrapper: function( element ) {
+               var active = document.activeElement;
+
+               if ( element.parent().is( ".ui-effects-wrapper" ) ) {
+                       element.parent().replaceWith( element );
+
+                       // Fixes #7595 - Elements lose focus when wrapped.
+                       if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) {
+                               $( active ).focus();
+                       }
+               }
+
+
+               return element;
+       },
+
+       setTransition: function( element, list, factor, value ) {
+               value = value || {};
+               $.each( list, function( i, x ) {
+                       var unit = element.cssUnit( x );
+                       if ( unit[ 0 ] > 0 ) {
+                               value[ x ] = unit[ 0 ] * factor + unit[ 1 ];
+                       }
+               });
+               return value;
+       }
+});
+
+// return an effect options object for the given parameters:
+function _normalizeArguments( effect, options, speed, callback ) {
+
+       // allow passing all options as the first parameter
+       if ( $.isPlainObject( effect ) ) {
+               options = effect;
+               effect = effect.effect;
+       }
+
+       // convert to an object
+       effect = { effect: effect };
+
+       // catch (effect, null, ...)
+       if ( options == null ) {
+               options = {};
+       }
+
+       // catch (effect, callback)
+       if ( $.isFunction( options ) ) {
+               callback = options;
+               speed = null;
+               options = {};
+       }
+
+       // catch (effect, speed, ?)
+       if ( typeof options === "number" || $.fx.speeds[ options ] ) {
+               callback = speed;
+               speed = options;
+               options = {};
+       }
+
+       // catch (effect, options, callback)
+       if ( $.isFunction( speed ) ) {
+               callback = speed;
+               speed = null;
+       }
+
+       // add options to effect
+       if ( options ) {
+               $.extend( effect, options );
+       }
+
+       speed = speed || options.duration;
+       effect.duration = $.fx.off ? 0 :
+               typeof speed === "number" ? speed :
+               speed in $.fx.speeds ? $.fx.speeds[ speed ] :
+               $.fx.speeds._default;
+
+       effect.complete = callback || options.complete;
+
+       return effect;
+}
+
+function standardSpeed( speed ) {
+       // valid standard speeds
+       if ( !speed || typeof speed === "number" || $.fx.speeds[ speed ] ) {
+               return true;
+       }
+
+       // invalid strings - treat as "normal" speed
+       return typeof speed === "string" && !$.effects.effect[ speed ];
+}
+
+$.fn.extend({
+       effect: function( /* effect, options, speed, callback */ ) {
+               var args = _normalizeArguments.apply( this, arguments ),
+                       mode = args.mode,
+                       queue = args.queue,
+                       effectMethod = $.effects.effect[ args.effect ];
+
+               if ( $.fx.off || !effectMethod ) {
+                       // delegate to the original method (e.g., .show()) if possible
+                       if ( mode ) {
+                               return this[ mode ]( args.duration, args.complete );
+                       } else {
+                               return this.each( function() {
+                                       if ( args.complete ) {
+                                               args.complete.call( this );
+                                       }
+                               });
+                       }
+               }
+
+               function run( next ) {
+                       var elem = $( this ),
+                               complete = args.complete,
+                               mode = args.mode;
+
+                       function done() {
+                               if ( $.isFunction( complete ) ) {
+                                       complete.call( elem[0] );
+                               }
+                               if ( $.isFunction( next ) ) {
+                                       next();
+                               }
+                       }
+
+                       // if the element is hiddden and mode is hide,
+                       // or element is visible and mode is show
+                       if ( elem.is( ":hidden" ) ? mode === "hide" : mode === "show" ) {
+                               done();
+                       } else {
+                               effectMethod.call( elem[0], args, done );
+                       }
+               }
+
+               return queue === false ? this.each( run ) : this.queue( queue || "fx", run );
+       },
+
+       _show: $.fn.show,
+       show: function( speed ) {
+               if ( standardSpeed( speed ) ) {
+                       return this._show.apply( this, arguments );
+               } else {
+                       var args = _normalizeArguments.apply( this, arguments );
+                       args.mode = "show";
+                       return this.effect.call( this, args );
+               }
+       },
+
+       _hide: $.fn.hide,
+       hide: function( speed ) {
+               if ( standardSpeed( speed ) ) {
+                       return this._hide.apply( this, arguments );
+               } else {
+                       var args = _normalizeArguments.apply( this, arguments );
+                       args.mode = "hide";
+                       return this.effect.call( this, args );
+               }
+       },
+
+       // jQuery core overloads toggle and creates _toggle
+       __toggle: $.fn.toggle,
+       toggle: function( speed ) {
+               if ( standardSpeed( speed ) || typeof speed === "boolean" || $.isFunction( speed ) ) {
+                       return this.__toggle.apply( this, arguments );
+               } else {
+                       var args = _normalizeArguments.apply( this, arguments );
+                       args.mode = "toggle";
+                       return this.effect.call( this, args );
+               }
+       },
+
+       // helper functions
+       cssUnit: function(key) {
+               var style = this.css( key ),
+                       val = [];
+
+               $.each( [ "em", "px", "%", "pt" ], function( i, unit ) {
+                       if ( style.indexOf( unit ) > 0 ) {
+                               val = [ parseFloat( style ), unit ];
+                       }
+               });
+               return val;
+       }
+});
+
+})();
+
+/******************************************************************************/
+/*********************************** EASING ***********************************/
+/******************************************************************************/
+
+(function() {
+
+// based on easing equations from Robert Penner (http://www.robertpenner.com/easing)
+
+var baseEasings = {};
+
+$.each( [ "Quad", "Cubic", "Quart", "Quint", "Expo" ], function( i, name ) {
+       baseEasings[ name ] = function( p ) {
+               return Math.pow( p, i + 2 );
+       };
+});
+
+$.extend( baseEasings, {
+       Sine: function ( p ) {
+               return 1 - Math.cos( p * Math.PI / 2 );
+       },
+       Circ: function ( p ) {
+               return 1 - Math.sqrt( 1 - p * p );
+       },
+       Elastic: function( p ) {
+               return p === 0 || p === 1 ? p :
+                       -Math.pow( 2, 8 * (p - 1) ) * Math.sin( ( (p - 1) * 80 - 7.5 ) * Math.PI / 15 );
+       },
+       Back: function( p ) {
+               return p * p * ( 3 * p - 2 );
+       },
+       Bounce: function ( p ) {
+               var pow2,
+                       bounce = 4;
+
+               while ( p < ( ( pow2 = Math.pow( 2, --bounce ) ) - 1 ) / 11 ) {}
+               return 1 / Math.pow( 4, 3 - bounce ) - 7.5625 * Math.pow( ( pow2 * 3 - 2 ) / 22 - p, 2 );
+       }
+});
+
+$.each( baseEasings, function( name, easeIn ) {
+       $.easing[ "easeIn" + name ] = easeIn;
+       $.easing[ "easeOut" + name ] = function( p ) {
+               return 1 - easeIn( 1 - p );
+       };
+       $.easing[ "easeInOut" + name ] = function( p ) {
+               return p < 0.5 ?
+                       easeIn( p * 2 ) / 2 :
+                       1 - easeIn( p * -2 + 2 ) / 2;
+       };
+});
+
+})();
+
+})(jQuery));
diff --git a/src/catalogue/static/catalogue/js/jquery.cycle.all.js b/src/catalogue/static/catalogue/js/jquery.cycle.all.js
new file mode 100644 (file)
index 0000000..666afda
--- /dev/null
@@ -0,0 +1,1538 @@
+/*!
+ * jQuery Cycle Plugin (with Transition Definitions)
+ * Examples and documentation at: http://jquery.malsup.com/cycle/
+ * Copyright (c) 2007-2012 M. Alsup
+ * Version: 2.9999.81 (15-JAN-2013)
+ * Dual licensed under the MIT and GPL licenses.
+ * http://jquery.malsup.com/license.html
+ * Requires: jQuery v1.7.1 or later
+ */
+;(function($, undefined) {
+"use strict";
+
+var ver = '2.9999.81';
+
+function debug(s) {
+       if ($.fn.cycle.debug)
+               log(s);
+}              
+function log() {
+       if (window.console && console.log)
+               console.log('[cycle] ' + Array.prototype.join.call(arguments,' '));
+}
+$.expr[':'].paused = function(el) {
+       return el.cyclePause;
+};
+
+
+// the options arg can be...
+//   a number  - indicates an immediate transition should occur to the given slide index
+//   a string  - 'pause', 'resume', 'toggle', 'next', 'prev', 'stop', 'destroy' or the name of a transition effect (ie, 'fade', 'zoom', etc)
+//   an object - properties to control the slideshow
+//
+// the arg2 arg can be...
+//   the name of an fx (only used in conjunction with a numeric value for 'options')
+//   the value true (only used in first arg == 'resume') and indicates
+//      that the resume should occur immediately (not wait for next timeout)
+
+$.fn.cycle = function(options, arg2) {
+       var o = { s: this.selector, c: this.context };
+
+       // in 1.3+ we can fix mistakes with the ready state
+       if (this.length === 0 && options != 'stop') {
+               if (!$.isReady && o.s) {
+                       log('DOM not ready, queuing slideshow');
+                       $(function() {
+                               $(o.s,o.c).cycle(options,arg2);
+                       });
+                       return this;
+               }
+               // is your DOM ready?  http://docs.jquery.com/Tutorials:Introducing_$(document).ready()
+               log('terminating; zero elements found by selector' + ($.isReady ? '' : ' (DOM not ready)'));
+               return this;
+       }
+
+       // iterate the matched nodeset
+       return this.each(function() {
+               var opts = handleArguments(this, options, arg2);
+               if (opts === false)
+                       return;
+
+               opts.updateActivePagerLink = opts.updateActivePagerLink || $.fn.cycle.updateActivePagerLink;
+               
+               // stop existing slideshow for this container (if there is one)
+               if (this.cycleTimeout)
+                       clearTimeout(this.cycleTimeout);
+               this.cycleTimeout = this.cyclePause = 0;
+               this.cycleStop = 0; // issue #108
+
+               var $cont = $(this);
+               var $slides = opts.slideExpr ? $(opts.slideExpr, this) : $cont.children();
+               var els = $slides.get();
+
+               if (els.length < 2) {
+                       log('terminating; too few slides: ' + els.length);
+                       return;
+               }
+
+               var opts2 = buildOptions($cont, $slides, els, opts, o);
+               if (opts2 === false)
+                       return;
+
+               var startTime = opts2.continuous ? 10 : getTimeout(els[opts2.currSlide], els[opts2.nextSlide], opts2, !opts2.backwards);
+
+               // if it's an auto slideshow, kick it off
+               if (startTime) {
+                       startTime += (opts2.delay || 0);
+                       if (startTime < 10)
+                               startTime = 10;
+                       debug('first timeout: ' + startTime);
+                       this.cycleTimeout = setTimeout(function(){go(els,opts2,0,!opts.backwards);}, startTime);
+               }
+       });
+};
+
+function triggerPause(cont, byHover, onPager) {
+       var opts = $(cont).data('cycle.opts');
+       if (!opts)
+               return;
+       var paused = !!cont.cyclePause;
+       if (paused && opts.paused)
+               opts.paused(cont, opts, byHover, onPager);
+       else if (!paused && opts.resumed)
+               opts.resumed(cont, opts, byHover, onPager);
+}
+
+// process the args that were passed to the plugin fn
+function handleArguments(cont, options, arg2) {
+       if (cont.cycleStop === undefined)
+               cont.cycleStop = 0;
+       if (options === undefined || options === null)
+               options = {};
+       if (options.constructor == String) {
+               switch(options) {
+               case 'destroy':
+               case 'stop':
+                       var opts = $(cont).data('cycle.opts');
+                       if (!opts)
+                               return false;
+                       cont.cycleStop++; // callbacks look for change
+                       if (cont.cycleTimeout)
+                               clearTimeout(cont.cycleTimeout);
+                       cont.cycleTimeout = 0;
+                       if (opts.elements)
+                               $(opts.elements).stop();
+                       $(cont).removeData('cycle.opts');
+                       if (options == 'destroy')
+                               destroy(cont, opts);
+                       return false;
+               case 'toggle':
+                       cont.cyclePause = (cont.cyclePause === 1) ? 0 : 1;
+                       checkInstantResume(cont.cyclePause, arg2, cont);
+                       triggerPause(cont);
+                       return false;
+               case 'pause':
+                       cont.cyclePause = 1;
+                       triggerPause(cont);
+                       return false;
+               case 'resume':
+                       cont.cyclePause = 0;
+                       checkInstantResume(false, arg2, cont);
+                       triggerPause(cont);
+                       return false;
+               case 'prev':
+               case 'next':
+                       opts = $(cont).data('cycle.opts');
+                       if (!opts) {
+                               log('options not found, "prev/next" ignored');
+                               return false;
+                       }
+                       $.fn.cycle[options](opts);
+                       return false;
+               default:
+                       options = { fx: options };
+               }
+               return options;
+       }
+       else if (options.constructor == Number) {
+               // go to the requested slide
+               var num = options;
+               options = $(cont).data('cycle.opts');
+               if (!options) {
+                       log('options not found, can not advance slide');
+                       return false;
+               }
+               if (num < 0 || num >= options.elements.length) {
+                       log('invalid slide index: ' + num);
+                       return false;
+               }
+               options.nextSlide = num;
+               if (cont.cycleTimeout) {
+                       clearTimeout(cont.cycleTimeout);
+                       cont.cycleTimeout = 0;
+               }
+               if (typeof arg2 == 'string')
+                       options.oneTimeFx = arg2;
+               go(options.elements, options, 1, num >= options.currSlide);
+               return false;
+       }
+       return options;
+       
+       function checkInstantResume(isPaused, arg2, cont) {
+               if (!isPaused && arg2 === true) { // resume now!
+                       var options = $(cont).data('cycle.opts');
+                       if (!options) {
+                               log('options not found, can not resume');
+                               return false;
+                       }
+                       if (cont.cycleTimeout) {
+                               clearTimeout(cont.cycleTimeout);
+                               cont.cycleTimeout = 0;
+                       }
+                       go(options.elements, options, 1, !options.backwards);
+               }
+       }
+}
+
+function removeFilter(el, opts) {
+       if (!$.support.opacity && opts.cleartype && el.style.filter) {
+               try { el.style.removeAttribute('filter'); }
+               catch(smother) {} // handle old opera versions
+       }
+}
+
+// unbind event handlers
+function destroy(cont, opts) {
+       if (opts.next)
+               $(opts.next).unbind(opts.prevNextEvent);
+       if (opts.prev)
+               $(opts.prev).unbind(opts.prevNextEvent);
+       
+       if (opts.pager || opts.pagerAnchorBuilder)
+               $.each(opts.pagerAnchors || [], function() {
+                       this.unbind().remove();
+               });
+       opts.pagerAnchors = null;
+       $(cont).unbind('mouseenter.cycle mouseleave.cycle');
+       if (opts.destroy) // callback
+               opts.destroy(opts);
+}
+
+// one-time initialization
+function buildOptions($cont, $slides, els, options, o) {
+       var startingSlideSpecified;
+       // support metadata plugin (v1.0 and v2.0)
+       var opts = $.extend({}, $.fn.cycle.defaults, options || {}, $.metadata ? $cont.metadata() : $.meta ? $cont.data() : {});
+       var meta = $.isFunction($cont.data) ? $cont.data(opts.metaAttr) : null;
+       if (meta)
+               opts = $.extend(opts, meta);
+       if (opts.autostop)
+               opts.countdown = opts.autostopCount || els.length;
+
+       var cont = $cont[0];
+       $cont.data('cycle.opts', opts);
+       opts.$cont = $cont;
+       opts.stopCount = cont.cycleStop;
+       opts.elements = els;
+       opts.before = opts.before ? [opts.before] : [];
+       opts.after = opts.after ? [opts.after] : [];
+
+       // push some after callbacks
+       if (!$.support.opacity && opts.cleartype)
+               opts.after.push(function() { removeFilter(this, opts); });
+       if (opts.continuous)
+               opts.after.push(function() { go(els,opts,0,!opts.backwards); });
+
+       saveOriginalOpts(opts);
+
+       // clearType corrections
+       if (!$.support.opacity && opts.cleartype && !opts.cleartypeNoBg)
+               clearTypeFix($slides);
+
+       // container requires non-static position so that slides can be position within
+       if ($cont.css('position') == 'static')
+               $cont.css('position', 'relative');
+       if (opts.width)
+               $cont.width(opts.width);
+       if (opts.height && opts.height != 'auto')
+               $cont.height(opts.height);
+
+       if (opts.startingSlide !== undefined) {
+               opts.startingSlide = parseInt(opts.startingSlide,10);
+               if (opts.startingSlide >= els.length || opts.startSlide < 0)
+                       opts.startingSlide = 0; // catch bogus input
+               else 
+                       startingSlideSpecified = true;
+       }
+       else if (opts.backwards)
+               opts.startingSlide = els.length - 1;
+       else
+               opts.startingSlide = 0;
+
+       // if random, mix up the slide array
+       if (opts.random) {
+               opts.randomMap = [];
+               for (var i = 0; i < els.length; i++)
+                       opts.randomMap.push(i);
+               opts.randomMap.sort(function(a,b) {return Math.random() - 0.5;});
+               if (startingSlideSpecified) {
+                       // try to find the specified starting slide and if found set start slide index in the map accordingly
+                       for ( var cnt = 0; cnt < els.length; cnt++ ) {
+                               if ( opts.startingSlide == opts.randomMap[cnt] ) {
+                                       opts.randomIndex = cnt;
+                               }
+                       }
+               }
+               else {
+                       opts.randomIndex = 1;
+                       opts.startingSlide = opts.randomMap[1];
+               }
+       }
+       else if (opts.startingSlide >= els.length)
+               opts.startingSlide = 0; // catch bogus input
+       opts.currSlide = opts.startingSlide || 0;
+       var first = opts.startingSlide;
+
+       // set position and zIndex on all the slides
+       $slides.css({position: 'absolute', top:0, left:0}).hide().each(function(i) {
+               var z;
+               if (opts.backwards)
+                       z = first ? i <= first ? els.length + (i-first) : first-i : els.length-i;
+               else
+                       z = first ? i >= first ? els.length - (i-first) : first-i : els.length-i;
+               $(this).css('z-index', z);
+       });
+
+       // make sure first slide is visible
+       $(els[first]).css('opacity',1).show(); // opacity bit needed to handle restart use case
+       removeFilter(els[first], opts);
+
+       // stretch slides
+       if (opts.fit) {
+               if (!opts.aspect) {
+               if (opts.width)
+                   $slides.width(opts.width);
+               if (opts.height && opts.height != 'auto')
+                   $slides.height(opts.height);
+               } else {
+                       $slides.each(function(){
+                               var $slide = $(this);
+                               var ratio = (opts.aspect === true) ? $slide.width()/$slide.height() : opts.aspect;
+                               if( opts.width && $slide.width() != opts.width ) {
+                                       $slide.width( opts.width );
+                                       $slide.height( opts.width / ratio );
+                               }
+
+                               if( opts.height && $slide.height() < opts.height ) {
+                                       $slide.height( opts.height );
+                                       $slide.width( opts.height * ratio );
+                               }
+                       });
+               }
+       }
+
+       if (opts.center && ((!opts.fit) || opts.aspect)) {
+               $slides.each(function(){
+                       var $slide = $(this);
+                       $slide.css({
+                               "margin-left": opts.width ?
+                                       ((opts.width - $slide.width()) / 2) + "px" :
+                                       0,
+                               "margin-top": opts.height ?
+                                       ((opts.height - $slide.height()) / 2) + "px" :
+                                       0
+                       });
+               });
+       }
+
+       if (opts.center && !opts.fit && !opts.slideResize) {
+               $slides.each(function(){
+                       var $slide = $(this);
+                       $slide.css({
+                               "margin-left": opts.width ? ((opts.width - $slide.width()) / 2) + "px" : 0,
+                               "margin-top": opts.height ? ((opts.height - $slide.height()) / 2) + "px" : 0
+                       });
+               });
+       }
+               
+       // stretch container
+       var reshape = (opts.containerResize || opts.containerResizeHeight) && !$cont.innerHeight();
+       if (reshape) { // do this only if container has no size http://tinyurl.com/da2oa9
+               var maxw = 0, maxh = 0;
+               for(var j=0; j < els.length; j++) {
+                       var $e = $(els[j]), e = $e[0], w = $e.outerWidth(), h = $e.outerHeight();
+                       if (!w) w = e.offsetWidth || e.width || $e.attr('width');
+                       if (!h) h = e.offsetHeight || e.height || $e.attr('height');
+                       maxw = w > maxw ? w : maxw;
+                       maxh = h > maxh ? h : maxh;
+               }
+               if (opts.containerResize && maxw > 0 && maxh > 0)
+                       $cont.css({width:maxw+'px',height:maxh+'px'});
+               if (opts.containerResizeHeight && maxh > 0)
+                       $cont.css({height:maxh+'px'});
+       }
+
+       var pauseFlag = false;  // https://github.com/malsup/cycle/issues/44
+       if (opts.pause)
+               $cont.bind('mouseenter.cycle', function(){
+                       pauseFlag = true;
+                       this.cyclePause++;
+                       triggerPause(cont, true);
+               }).bind('mouseleave.cycle', function(){
+                               if (pauseFlag)
+                                       this.cyclePause--;
+                               triggerPause(cont, true);
+               });
+
+       if (supportMultiTransitions(opts) === false)
+               return false;
+
+       // apparently a lot of people use image slideshows without height/width attributes on the images.
+       // Cycle 2.50+ requires the sizing info for every slide; this block tries to deal with that.
+       var requeue = false;
+       options.requeueAttempts = options.requeueAttempts || 0;
+       $slides.each(function() {
+               // try to get height/width of each slide
+               var $el = $(this);
+               this.cycleH = (opts.fit && opts.height) ? opts.height : ($el.height() || this.offsetHeight || this.height || $el.attr('height') || 0);
+               this.cycleW = (opts.fit && opts.width) ? opts.width : ($el.width() || this.offsetWidth || this.width || $el.attr('width') || 0);
+
+               if ( $el.is('img') ) {
+                       var loading = (this.cycleH === 0 && this.cycleW === 0 && !this.complete);
+                       // don't requeue for images that are still loading but have a valid size
+                       if (loading) {
+                               if (o.s && opts.requeueOnImageNotLoaded && ++options.requeueAttempts < 100) { // track retry count so we don't loop forever
+                                       log(options.requeueAttempts,' - img slide not loaded, requeuing slideshow: ', this.src, this.cycleW, this.cycleH);
+                                       setTimeout(function() {$(o.s,o.c).cycle(options);}, opts.requeueTimeout);
+                                       requeue = true;
+                                       return false; // break each loop
+                               }
+                               else {
+                                       log('could not determine size of image: '+this.src, this.cycleW, this.cycleH);
+                               }
+                       }
+               }
+               return true;
+       });
+
+       if (requeue)
+               return false;
+
+       opts.cssBefore = opts.cssBefore || {};
+       opts.cssAfter = opts.cssAfter || {};
+       opts.cssFirst = opts.cssFirst || {};
+       opts.animIn = opts.animIn || {};
+       opts.animOut = opts.animOut || {};
+
+       $slides.not(':eq('+first+')').css(opts.cssBefore);
+       $($slides[first]).css(opts.cssFirst);
+
+       if (opts.timeout) {
+               opts.timeout = parseInt(opts.timeout,10);
+               // ensure that timeout and speed settings are sane
+               if (opts.speed.constructor == String)
+                       opts.speed = $.fx.speeds[opts.speed] || parseInt(opts.speed,10);
+               if (!opts.sync)
+                       opts.speed = opts.speed / 2;
+               
+               var buffer = opts.fx == 'none' ? 0 : opts.fx == 'shuffle' ? 500 : 250;
+               while((opts.timeout - opts.speed) < buffer) // sanitize timeout
+                       opts.timeout += opts.speed;
+       }
+       if (opts.easing)
+               opts.easeIn = opts.easeOut = opts.easing;
+       if (!opts.speedIn)
+               opts.speedIn = opts.speed;
+       if (!opts.speedOut)
+               opts.speedOut = opts.speed;
+
+       opts.slideCount = els.length;
+       opts.currSlide = opts.lastSlide = first;
+       if (opts.random) {
+               if (++opts.randomIndex == els.length)
+                       opts.randomIndex = 0;
+               opts.nextSlide = opts.randomMap[opts.randomIndex];
+       }
+       else if (opts.backwards)
+               opts.nextSlide = opts.startingSlide === 0 ? (els.length-1) : opts.startingSlide-1;
+       else
+               opts.nextSlide = opts.startingSlide >= (els.length-1) ? 0 : opts.startingSlide+1;
+
+       // run transition init fn
+       if (!opts.multiFx) {
+               var init = $.fn.cycle.transitions[opts.fx];
+               if ($.isFunction(init))
+                       init($cont, $slides, opts);
+               else if (opts.fx != 'custom' && !opts.multiFx) {
+                       log('unknown transition: ' + opts.fx,'; slideshow terminating');
+                       return false;
+               }
+       }
+
+       // fire artificial events
+       var e0 = $slides[first];
+       if (!opts.skipInitializationCallbacks) {
+               if (opts.before.length)
+                       opts.before[0].apply(e0, [e0, e0, opts, true]);
+               if (opts.after.length)
+                       opts.after[0].apply(e0, [e0, e0, opts, true]);
+       }
+       if (opts.next)
+               $(opts.next).bind(opts.prevNextEvent,function(){return advance(opts,1);});
+       if (opts.prev)
+               $(opts.prev).bind(opts.prevNextEvent,function(){return advance(opts,0);});
+       if (opts.pager || opts.pagerAnchorBuilder)
+               buildPager(els,opts);
+
+       exposeAddSlide(opts, els);
+
+       return opts;
+}
+
+// save off original opts so we can restore after clearing state
+function saveOriginalOpts(opts) {
+       opts.original = { before: [], after: [] };
+       opts.original.cssBefore = $.extend({}, opts.cssBefore);
+       opts.original.cssAfter  = $.extend({}, opts.cssAfter);
+       opts.original.animIn    = $.extend({}, opts.animIn);
+       opts.original.animOut   = $.extend({}, opts.animOut);
+       $.each(opts.before, function() { opts.original.before.push(this); });
+       $.each(opts.after,  function() { opts.original.after.push(this); });
+}
+
+function supportMultiTransitions(opts) {
+       var i, tx, txs = $.fn.cycle.transitions;
+       // look for multiple effects
+       if (opts.fx.indexOf(',') > 0) {
+               opts.multiFx = true;
+               opts.fxs = opts.fx.replace(/\s*/g,'').split(',');
+               // discard any bogus effect names
+               for (i=0; i < opts.fxs.length; i++) {
+                       var fx = opts.fxs[i];
+                       tx = txs[fx];
+                       if (!tx || !txs.hasOwnProperty(fx) || !$.isFunction(tx)) {
+                               log('discarding unknown transition: ',fx);
+                               opts.fxs.splice(i,1);
+                               i--;
+                       }
+               }
+               // if we have an empty list then we threw everything away!
+               if (!opts.fxs.length) {
+                       log('No valid transitions named; slideshow terminating.');
+                       return false;
+               }
+       }
+       else if (opts.fx == 'all') {  // auto-gen the list of transitions
+               opts.multiFx = true;
+               opts.fxs = [];
+               for (var p in txs) {
+                       if (txs.hasOwnProperty(p)) {
+                               tx = txs[p];
+                               if (txs.hasOwnProperty(p) && $.isFunction(tx))
+                                       opts.fxs.push(p);
+                       }
+               }
+       }
+       if (opts.multiFx && opts.randomizeEffects) {
+               // munge the fxs array to make effect selection random
+               var r1 = Math.floor(Math.random() * 20) + 30;
+               for (i = 0; i < r1; i++) {
+                       var r2 = Math.floor(Math.random() * opts.fxs.length);
+                       opts.fxs.push(opts.fxs.splice(r2,1)[0]);
+               }
+               debug('randomized fx sequence: ',opts.fxs);
+       }
+       return true;
+}
+
+// provide a mechanism for adding slides after the slideshow has started
+function exposeAddSlide(opts, els) {
+       opts.addSlide = function(newSlide, prepend) {
+               var $s = $(newSlide), s = $s[0];
+               if (!opts.autostopCount)
+                       opts.countdown++;
+               els[prepend?'unshift':'push'](s);
+               if (opts.els)
+                       opts.els[prepend?'unshift':'push'](s); // shuffle needs this
+               opts.slideCount = els.length;
+
+               // add the slide to the random map and resort
+               if (opts.random) {
+                       opts.randomMap.push(opts.slideCount-1);
+                       opts.randomMap.sort(function(a,b) {return Math.random() - 0.5;});
+               }
+
+               $s.css('position','absolute');
+               $s[prepend?'prependTo':'appendTo'](opts.$cont);
+
+               if (prepend) {
+                       opts.currSlide++;
+                       opts.nextSlide++;
+               }
+
+               if (!$.support.opacity && opts.cleartype && !opts.cleartypeNoBg)
+                       clearTypeFix($s);
+
+               if (opts.fit && opts.width)
+                       $s.width(opts.width);
+               if (opts.fit && opts.height && opts.height != 'auto')
+                       $s.height(opts.height);
+               s.cycleH = (opts.fit && opts.height) ? opts.height : $s.height();
+               s.cycleW = (opts.fit && opts.width) ? opts.width : $s.width();
+
+               $s.css(opts.cssBefore);
+
+               if (opts.pager || opts.pagerAnchorBuilder)
+                       $.fn.cycle.createPagerAnchor(els.length-1, s, $(opts.pager), els, opts);
+
+               if ($.isFunction(opts.onAddSlide))
+                       opts.onAddSlide($s);
+               else
+                       $s.hide(); // default behavior
+       };
+}
+
+// reset internal state; we do this on every pass in order to support multiple effects
+$.fn.cycle.resetState = function(opts, fx) {
+       fx = fx || opts.fx;
+       opts.before = []; opts.after = [];
+       opts.cssBefore = $.extend({}, opts.original.cssBefore);
+       opts.cssAfter  = $.extend({}, opts.original.cssAfter);
+       opts.animIn     = $.extend({}, opts.original.animIn);
+       opts.animOut   = $.extend({}, opts.original.animOut);
+       opts.fxFn = null;
+       $.each(opts.original.before, function() { opts.before.push(this); });
+       $.each(opts.original.after,  function() { opts.after.push(this); });
+
+       // re-init
+       var init = $.fn.cycle.transitions[fx];
+       if ($.isFunction(init))
+               init(opts.$cont, $(opts.elements), opts);
+};
+
+// this is the main engine fn, it handles the timeouts, callbacks and slide index mgmt
+function go(els, opts, manual, fwd) {
+       var p = opts.$cont[0], curr = els[opts.currSlide], next = els[opts.nextSlide];
+
+       // opts.busy is true if we're in the middle of an animation
+       if (manual && opts.busy && opts.manualTrump) {
+               // let manual transitions requests trump active ones
+               debug('manualTrump in go(), stopping active transition');
+               $(els).stop(true,true);
+               opts.busy = 0;
+               clearTimeout(p.cycleTimeout);
+       }
+
+       // don't begin another timeout-based transition if there is one active
+       if (opts.busy) {
+               debug('transition active, ignoring new tx request');
+               return;
+       }
+
+
+       // stop cycling if we have an outstanding stop request
+       if (p.cycleStop != opts.stopCount || p.cycleTimeout === 0 && !manual)
+               return;
+
+       // check to see if we should stop cycling based on autostop options
+       if (!manual && !p.cyclePause && !opts.bounce &&
+               ((opts.autostop && (--opts.countdown <= 0)) ||
+               (opts.nowrap && !opts.random && opts.nextSlide < opts.currSlide))) {
+               if (opts.end)
+                       opts.end(opts);
+               return;
+       }
+
+       // if slideshow is paused, only transition on a manual trigger
+       var changed = false;
+       if ((manual || !p.cyclePause) && (opts.nextSlide != opts.currSlide)) {
+               changed = true;
+               var fx = opts.fx;
+               // keep trying to get the slide size if we don't have it yet
+               curr.cycleH = curr.cycleH || $(curr).height();
+               curr.cycleW = curr.cycleW || $(curr).width();
+               next.cycleH = next.cycleH || $(next).height();
+               next.cycleW = next.cycleW || $(next).width();
+
+               // support multiple transition types
+               if (opts.multiFx) {
+                       if (fwd && (opts.lastFx === undefined || ++opts.lastFx >= opts.fxs.length))
+                               opts.lastFx = 0;
+                       else if (!fwd && (opts.lastFx === undefined || --opts.lastFx < 0))
+                               opts.lastFx = opts.fxs.length - 1;
+                       fx = opts.fxs[opts.lastFx];
+               }
+
+               // one-time fx overrides apply to:  $('div').cycle(3,'zoom');
+               if (opts.oneTimeFx) {
+                       fx = opts.oneTimeFx;
+                       opts.oneTimeFx = null;
+               }
+
+               $.fn.cycle.resetState(opts, fx);
+
+               // run the before callbacks
+               if (opts.before.length)
+                       $.each(opts.before, function(i,o) {
+                               if (p.cycleStop != opts.stopCount) return;
+                               o.apply(next, [curr, next, opts, fwd]);
+                       });
+
+               // stage the after callacks
+               var after = function() {
+                       opts.busy = 0;
+                       $.each(opts.after, function(i,o) {
+                               if (p.cycleStop != opts.stopCount) return;
+                               o.apply(next, [curr, next, opts, fwd]);
+                       });
+                       if (!p.cycleStop) {
+                               // queue next transition
+                               queueNext();
+                       }
+               };
+
+               debug('tx firing('+fx+'); currSlide: ' + opts.currSlide + '; nextSlide: ' + opts.nextSlide);
+               
+               // get ready to perform the transition
+               opts.busy = 1;
+               if (opts.fxFn) // fx function provided?
+                       opts.fxFn(curr, next, opts, after, fwd, manual && opts.fastOnEvent);
+               else if ($.isFunction($.fn.cycle[opts.fx])) // fx plugin ?
+                       $.fn.cycle[opts.fx](curr, next, opts, after, fwd, manual && opts.fastOnEvent);
+               else
+                       $.fn.cycle.custom(curr, next, opts, after, fwd, manual && opts.fastOnEvent);
+       }
+       else {
+               queueNext();
+       }
+
+       if (changed || opts.nextSlide == opts.currSlide) {
+               // calculate the next slide
+               var roll;
+               opts.lastSlide = opts.currSlide;
+               if (opts.random) {
+                       opts.currSlide = opts.nextSlide;
+                       if (++opts.randomIndex == els.length) {
+                               opts.randomIndex = 0;
+                               opts.randomMap.sort(function(a,b) {return Math.random() - 0.5;});
+                       }
+                       opts.nextSlide = opts.randomMap[opts.randomIndex];
+                       if (opts.nextSlide == opts.currSlide)
+                               opts.nextSlide = (opts.currSlide == opts.slideCount - 1) ? 0 : opts.currSlide + 1;
+               }
+               else if (opts.backwards) {
+                       roll = (opts.nextSlide - 1) < 0;
+                       if (roll && opts.bounce) {
+                               opts.backwards = !opts.backwards;
+                               opts.nextSlide = 1;
+                               opts.currSlide = 0;
+                       }
+                       else {
+                               opts.nextSlide = roll ? (els.length-1) : opts.nextSlide-1;
+                               opts.currSlide = roll ? 0 : opts.nextSlide+1;
+                       }
+               }
+               else { // sequence
+                       roll = (opts.nextSlide + 1) == els.length;
+                       if (roll && opts.bounce) {
+                               opts.backwards = !opts.backwards;
+                               opts.nextSlide = els.length-2;
+                               opts.currSlide = els.length-1;
+                       }
+                       else {
+                               opts.nextSlide = roll ? 0 : opts.nextSlide+1;
+                               opts.currSlide = roll ? els.length-1 : opts.nextSlide-1;
+                       }
+               }
+       }
+       if (changed && opts.pager)
+               opts.updateActivePagerLink(opts.pager, opts.currSlide, opts.activePagerClass);
+       
+       function queueNext() {
+               // stage the next transition
+               var ms = 0, timeout = opts.timeout;
+               if (opts.timeout && !opts.continuous) {
+                       ms = getTimeout(els[opts.currSlide], els[opts.nextSlide], opts, fwd);
+         if (opts.fx == 'shuffle')
+            ms -= opts.speedOut;
+      }
+               else if (opts.continuous && p.cyclePause) // continuous shows work off an after callback, not this timer logic
+                       ms = 10;
+               if (ms > 0)
+                       p.cycleTimeout = setTimeout(function(){ go(els, opts, 0, !opts.backwards); }, ms);
+       }
+}
+
+// invoked after transition
+$.fn.cycle.updateActivePagerLink = function(pager, currSlide, clsName) {
+   $(pager).each(function() {
+       $(this).children().removeClass(clsName).eq(currSlide).addClass(clsName);
+   });
+};
+
+// calculate timeout value for current transition
+function getTimeout(curr, next, opts, fwd) {
+       if (opts.timeoutFn) {
+               // call user provided calc fn
+               var t = opts.timeoutFn.call(curr,curr,next,opts,fwd);
+               while (opts.fx != 'none' && (t - opts.speed) < 250) // sanitize timeout
+                       t += opts.speed;
+               debug('calculated timeout: ' + t + '; speed: ' + opts.speed);
+               if (t !== false)
+                       return t;
+       }
+       return opts.timeout;
+}
+
+// expose next/prev function, caller must pass in state
+$.fn.cycle.next = function(opts) { advance(opts,1); };
+$.fn.cycle.prev = function(opts) { advance(opts,0);};
+
+// advance slide forward or back
+function advance(opts, moveForward) {
+       var val = moveForward ? 1 : -1;
+       var els = opts.elements;
+       var p = opts.$cont[0], timeout = p.cycleTimeout;
+       if (timeout) {
+               clearTimeout(timeout);
+               p.cycleTimeout = 0;
+       }
+       if (opts.random && val < 0) {
+               // move back to the previously display slide
+               opts.randomIndex--;
+               if (--opts.randomIndex == -2)
+                       opts.randomIndex = els.length-2;
+               else if (opts.randomIndex == -1)
+                       opts.randomIndex = els.length-1;
+               opts.nextSlide = opts.randomMap[opts.randomIndex];
+       }
+       else if (opts.random) {
+               opts.nextSlide = opts.randomMap[opts.randomIndex];
+       }
+       else {
+               opts.nextSlide = opts.currSlide + val;
+               if (opts.nextSlide < 0) {
+                       if (opts.nowrap) return false;
+                       opts.nextSlide = els.length - 1;
+               }
+               else if (opts.nextSlide >= els.length) {
+                       if (opts.nowrap) return false;
+                       opts.nextSlide = 0;
+               }
+       }
+
+       var cb = opts.onPrevNextEvent || opts.prevNextClick; // prevNextClick is deprecated
+       if ($.isFunction(cb))
+               cb(val > 0, opts.nextSlide, els[opts.nextSlide]);
+       go(els, opts, 1, moveForward);
+       return false;
+}
+
+function buildPager(els, opts) {
+       var $p = $(opts.pager);
+       $.each(els, function(i,o) {
+               $.fn.cycle.createPagerAnchor(i,o,$p,els,opts);
+       });
+       opts.updateActivePagerLink(opts.pager, opts.startingSlide, opts.activePagerClass);
+}
+
+$.fn.cycle.createPagerAnchor = function(i, el, $p, els, opts) {
+       var a;
+       if ($.isFunction(opts.pagerAnchorBuilder)) {
+               a = opts.pagerAnchorBuilder(i,el);
+               debug('pagerAnchorBuilder('+i+', el) returned: ' + a);
+       }
+       else
+               a = '<a href="#">'+(i+1)+'</a>';
+               
+       if (!a)
+               return;
+       var $a = $(a);
+       // don't reparent if anchor is in the dom
+       if ($a.parents('body').length === 0) {
+               var arr = [];
+               if ($p.length > 1) {
+                       $p.each(function() {
+                               var $clone = $a.clone(true);
+                               $(this).append($clone);
+                               arr.push($clone[0]);
+                       });
+                       $a = $(arr);
+               }
+               else {
+                       $a.appendTo($p);
+               }
+       }
+
+       opts.pagerAnchors =  opts.pagerAnchors || [];
+       opts.pagerAnchors.push($a);
+       
+       var pagerFn = function(e) {
+               e.preventDefault();
+               opts.nextSlide = i;
+               var p = opts.$cont[0], timeout = p.cycleTimeout;
+               if (timeout) {
+                       clearTimeout(timeout);
+                       p.cycleTimeout = 0;
+               }
+               var cb = opts.onPagerEvent || opts.pagerClick; // pagerClick is deprecated
+               if ($.isFunction(cb))
+                       cb(opts.nextSlide, els[opts.nextSlide]);
+               go(els,opts,1,opts.currSlide < i); // trigger the trans
+//             return false; // <== allow bubble
+       };
+       
+       if ( /mouseenter|mouseover/i.test(opts.pagerEvent) ) {
+               $a.hover(pagerFn, function(){/* no-op */} );
+       }
+       else {
+               $a.bind(opts.pagerEvent, pagerFn);
+       }
+       
+       if ( ! /^click/.test(opts.pagerEvent) && !opts.allowPagerClickBubble)
+               $a.bind('click.cycle', function(){return false;}); // suppress click
+       
+       var cont = opts.$cont[0];
+       var pauseFlag = false; // https://github.com/malsup/cycle/issues/44
+       if (opts.pauseOnPagerHover) {
+               $a.hover(
+                       function() { 
+                               pauseFlag = true;
+                               cont.cyclePause++; 
+                               triggerPause(cont,true,true);
+                       }, function() { 
+                               if (pauseFlag)
+                                       cont.cyclePause--; 
+                               triggerPause(cont,true,true);
+                       } 
+               );
+       }
+};
+
+// helper fn to calculate the number of slides between the current and the next
+$.fn.cycle.hopsFromLast = function(opts, fwd) {
+       var hops, l = opts.lastSlide, c = opts.currSlide;
+       if (fwd)
+               hops = c > l ? c - l : opts.slideCount - l;
+       else
+               hops = c < l ? l - c : l + opts.slideCount - c;
+       return hops;
+};
+
+// fix clearType problems in ie6 by setting an explicit bg color
+// (otherwise text slides look horrible during a fade transition)
+function clearTypeFix($slides) {
+       debug('applying clearType background-color hack');
+       function hex(s) {
+               s = parseInt(s,10).toString(16);
+               return s.length < 2 ? '0'+s : s;
+       }
+       function getBg(e) {
+               for ( ; e && e.nodeName.toLowerCase() != 'html'; e = e.parentNode) {
+                       var v = $.css(e,'background-color');
+                       if (v && v.indexOf('rgb') >= 0 ) {
+                               var rgb = v.match(/\d+/g);
+                               return '#'+ hex(rgb[0]) + hex(rgb[1]) + hex(rgb[2]);
+                       }
+                       if (v && v != 'transparent')
+                               return v;
+               }
+               return '#ffffff';
+       }
+       $slides.each(function() { $(this).css('background-color', getBg(this)); });
+}
+
+// reset common props before the next transition
+$.fn.cycle.commonReset = function(curr,next,opts,w,h,rev) {
+       $(opts.elements).not(curr).hide();
+       if (typeof opts.cssBefore.opacity == 'undefined')
+               opts.cssBefore.opacity = 1;
+       opts.cssBefore.display = 'block';
+       if (opts.slideResize && w !== false && next.cycleW > 0)
+               opts.cssBefore.width = next.cycleW;
+       if (opts.slideResize && h !== false && next.cycleH > 0)
+               opts.cssBefore.height = next.cycleH;
+       opts.cssAfter = opts.cssAfter || {};
+       opts.cssAfter.display = 'none';
+       $(curr).css('zIndex',opts.slideCount + (rev === true ? 1 : 0));
+       $(next).css('zIndex',opts.slideCount + (rev === true ? 0 : 1));
+};
+
+// the actual fn for effecting a transition
+$.fn.cycle.custom = function(curr, next, opts, cb, fwd, speedOverride) {
+       var $l = $(curr), $n = $(next);
+       var speedIn = opts.speedIn, speedOut = opts.speedOut, easeIn = opts.easeIn, easeOut = opts.easeOut;
+       $n.css(opts.cssBefore);
+       if (speedOverride) {
+               if (typeof speedOverride == 'number')
+                       speedIn = speedOut = speedOverride;
+               else
+                       speedIn = speedOut = 1;
+               easeIn = easeOut = null;
+       }
+       var fn = function() {
+               $n.animate(opts.animIn, speedIn, easeIn, function() {
+                       cb();
+               });
+       };
+       $l.animate(opts.animOut, speedOut, easeOut, function() {
+               $l.css(opts.cssAfter);
+               if (!opts.sync) 
+                       fn();
+       });
+       if (opts.sync) fn();
+};
+
+// transition definitions - only fade is defined here, transition pack defines the rest
+$.fn.cycle.transitions = {
+       fade: function($cont, $slides, opts) {
+               $slides.not(':eq('+opts.currSlide+')').css('opacity',0);
+               opts.before.push(function(curr,next,opts) {
+                       $.fn.cycle.commonReset(curr,next,opts);
+                       opts.cssBefore.opacity = 0;
+               });
+               opts.animIn        = { opacity: 1 };
+               opts.animOut   = { opacity: 0 };
+               opts.cssBefore = { top: 0, left: 0 };
+       }
+};
+
+$.fn.cycle.ver = function() { return ver; };
+
+// override these globally if you like (they are all optional)
+$.fn.cycle.defaults = {
+    activePagerClass: 'activeSlide', // class name used for the active pager link
+    after:            null,     // transition callback (scope set to element that was shown):  function(currSlideElement, nextSlideElement, options, forwardFlag)
+    allowPagerClickBubble: false, // allows or prevents click event on pager anchors from bubbling
+    animIn:           null,     // properties that define how the slide animates in
+    animOut:          null,     // properties that define how the slide animates out
+    aspect:           false,    // preserve aspect ratio during fit resizing, cropping if necessary (must be used with fit option)
+    autostop:         0,        // true to end slideshow after X transitions (where X == slide count)
+    autostopCount:    0,        // number of transitions (optionally used with autostop to define X)
+    backwards:        false,    // true to start slideshow at last slide and move backwards through the stack
+    before:           null,     // transition callback (scope set to element to be shown):     function(currSlideElement, nextSlideElement, options, forwardFlag)
+    center:           null,     // set to true to have cycle add top/left margin to each slide (use with width and height options)
+    cleartype:        !$.support.opacity,  // true if clearType corrections should be applied (for IE)
+    cleartypeNoBg:    false,    // set to true to disable extra cleartype fixing (leave false to force background color setting on slides)
+    containerResize:  1,        // resize container to fit largest slide
+    containerResizeHeight:  0,  // resize containers height to fit the largest slide but leave the width dynamic
+    continuous:       0,        // true to start next transition immediately after current one completes
+    cssAfter:         null,     // properties that defined the state of the slide after transitioning out
+    cssBefore:        null,     // properties that define the initial state of the slide before transitioning in
+    delay:            0,        // additional delay (in ms) for first transition (hint: can be negative)
+    easeIn:           null,     // easing for "in" transition
+    easeOut:          null,     // easing for "out" transition
+    easing:           null,     // easing method for both in and out transitions
+    end:              null,     // callback invoked when the slideshow terminates (use with autostop or nowrap options): function(options)
+    fastOnEvent:      0,        // force fast transitions when triggered manually (via pager or prev/next); value == time in ms
+    fit:              0,        // force slides to fit container
+    fx:               'fade',   // name of transition effect (or comma separated names, ex: 'fade,scrollUp,shuffle')
+    fxFn:             null,     // function used to control the transition: function(currSlideElement, nextSlideElement, options, afterCalback, forwardFlag)
+    height:           'auto',   // container height (if the 'fit' option is true, the slides will be set to this height as well)
+    manualTrump:      true,     // causes manual transition to stop an active transition instead of being ignored
+    metaAttr:         'cycle',  // data- attribute that holds the option data for the slideshow
+    next:             null,     // element, jQuery object, or jQuery selector string for the element to use as event trigger for next slide
+    nowrap:           0,        // true to prevent slideshow from wrapping
+    onPagerEvent:     null,     // callback fn for pager events: function(zeroBasedSlideIndex, slideElement)
+    onPrevNextEvent:  null,     // callback fn for prev/next events: function(isNext, zeroBasedSlideIndex, slideElement)
+    pager:            null,     // element, jQuery object, or jQuery selector string for the element to use as pager container
+    pagerAnchorBuilder: null,   // callback fn for building anchor links:  function(index, DOMelement)
+    pagerEvent:       'click.cycle', // name of event which drives the pager navigation
+    pause:            0,        // true to enable "pause on hover"
+    pauseOnPagerHover: 0,       // true to pause when hovering over pager link
+    prev:             null,     // element, jQuery object, or jQuery selector string for the element to use as event trigger for previous slide
+    prevNextEvent:    'click.cycle',// event which drives the manual transition to the previous or next slide
+    random:           0,        // true for random, false for sequence (not applicable to shuffle fx)
+    randomizeEffects: 1,        // valid when multiple effects are used; true to make the effect sequence random
+    requeueOnImageNotLoaded: true, // requeue the slideshow if any image slides are not yet loaded
+    requeueTimeout:   250,      // ms delay for requeue
+    rev:              0,        // causes animations to transition in reverse (for effects that support it such as scrollHorz/scrollVert/shuffle)
+    shuffle:          null,     // coords for shuffle animation, ex: { top:15, left: 200 }
+    skipInitializationCallbacks: false, // set to true to disable the first before/after callback that occurs prior to any transition
+    slideExpr:        null,     // expression for selecting slides (if something other than all children is required)
+    slideResize:      1,        // force slide width/height to fixed size before every transition
+    speed:            1000,     // speed of the transition (any valid fx speed value)
+    speedIn:          null,     // speed of the 'in' transition
+    speedOut:         null,     // speed of the 'out' transition
+    startingSlide:    undefined,// zero-based index of the first slide to be displayed
+    sync:             1,        // true if in/out transitions should occur simultaneously
+    timeout:          4000,     // milliseconds between slide transitions (0 to disable auto advance)
+    timeoutFn:        null,     // callback for determining per-slide timeout value:  function(currSlideElement, nextSlideElement, options, forwardFlag)
+    updateActivePagerLink: null,// callback fn invoked to update the active pager link (adds/removes activePagerClass style)
+    width:            null      // container width (if the 'fit' option is true, the slides will be set to this width as well)
+};
+
+})(jQuery);
+
+
+/*!
+ * jQuery Cycle Plugin Transition Definitions
+ * This script is a plugin for the jQuery Cycle Plugin
+ * Examples and documentation at: http://malsup.com/jquery/cycle/
+ * Copyright (c) 2007-2010 M. Alsup
+ * Version:     2.73
+ * Dual licensed under the MIT and GPL licenses:
+ * http://www.opensource.org/licenses/mit-license.php
+ * http://www.gnu.org/licenses/gpl.html
+ */
+(function($) {
+"use strict";
+
+//
+// These functions define slide initialization and properties for the named
+// transitions. To save file size feel free to remove any of these that you
+// don't need.
+//
+$.fn.cycle.transitions.none = function($cont, $slides, opts) {
+       opts.fxFn = function(curr,next,opts,after){
+               $(next).show();
+               $(curr).hide();
+               after();
+       };
+};
+
+// not a cross-fade, fadeout only fades out the top slide
+$.fn.cycle.transitions.fadeout = function($cont, $slides, opts) {
+       $slides.not(':eq('+opts.currSlide+')').css({ display: 'block', 'opacity': 1 });
+       opts.before.push(function(curr,next,opts,w,h,rev) {
+               $(curr).css('zIndex',opts.slideCount + (rev !== true ? 1 : 0));
+               $(next).css('zIndex',opts.slideCount + (rev !== true ? 0 : 1));
+       });
+       opts.animIn.opacity = 1;
+       opts.animOut.opacity = 0;
+       opts.cssBefore.opacity = 1;
+       opts.cssBefore.display = 'block';
+       opts.cssAfter.zIndex = 0;
+};
+
+// scrollUp/Down/Left/Right
+$.fn.cycle.transitions.scrollUp = function($cont, $slides, opts) {
+       $cont.css('overflow','hidden');
+       opts.before.push($.fn.cycle.commonReset);
+       var h = $cont.height();
+       opts.cssBefore.top = h;
+       opts.cssBefore.left = 0;
+       opts.cssFirst.top = 0;
+       opts.animIn.top = 0;
+       opts.animOut.top = -h;
+};
+$.fn.cycle.transitions.scrollDown = function($cont, $slides, opts) {
+       $cont.css('overflow','hidden');
+       opts.before.push($.fn.cycle.commonReset);
+       var h = $cont.height();
+       opts.cssFirst.top = 0;
+       opts.cssBefore.top = -h;
+       opts.cssBefore.left = 0;
+       opts.animIn.top = 0;
+       opts.animOut.top = h;
+};
+$.fn.cycle.transitions.scrollLeft = function($cont, $slides, opts) {
+       $cont.css('overflow','hidden');
+       opts.before.push($.fn.cycle.commonReset);
+       var w = $cont.width();
+       opts.cssFirst.left = 0;
+       opts.cssBefore.left = w;
+       opts.cssBefore.top = 0;
+       opts.animIn.left = 0;
+       opts.animOut.left = 0-w;
+};
+$.fn.cycle.transitions.scrollRight = function($cont, $slides, opts) {
+       $cont.css('overflow','hidden');
+       opts.before.push($.fn.cycle.commonReset);
+       var w = $cont.width();
+       opts.cssFirst.left = 0;
+       opts.cssBefore.left = -w;
+       opts.cssBefore.top = 0;
+       opts.animIn.left = 0;
+       opts.animOut.left = w;
+};
+$.fn.cycle.transitions.scrollHorz = function($cont, $slides, opts) {
+       $cont.css('overflow','hidden').width();
+       opts.before.push(function(curr, next, opts, fwd) {
+               if (opts.rev)
+                       fwd = !fwd;
+               $.fn.cycle.commonReset(curr,next,opts);
+               opts.cssBefore.left = fwd ? (next.cycleW-1) : (1-next.cycleW);
+               opts.animOut.left = fwd ? -curr.cycleW : curr.cycleW;
+       });
+       opts.cssFirst.left = 0;
+       opts.cssBefore.top = 0;
+       opts.animIn.left = 0;
+       opts.animOut.top = 0;
+};
+$.fn.cycle.transitions.scrollVert = function($cont, $slides, opts) {
+       $cont.css('overflow','hidden');
+       opts.before.push(function(curr, next, opts, fwd) {
+               if (opts.rev)
+                       fwd = !fwd;
+               $.fn.cycle.commonReset(curr,next,opts);
+               opts.cssBefore.top = fwd ? (1-next.cycleH) : (next.cycleH-1);
+               opts.animOut.top = fwd ? curr.cycleH : -curr.cycleH;
+       });
+       opts.cssFirst.top = 0;
+       opts.cssBefore.left = 0;
+       opts.animIn.top = 0;
+       opts.animOut.left = 0;
+};
+
+// slideX/slideY
+$.fn.cycle.transitions.slideX = function($cont, $slides, opts) {
+       opts.before.push(function(curr, next, opts) {
+               $(opts.elements).not(curr).hide();
+               $.fn.cycle.commonReset(curr,next,opts,false,true);
+               opts.animIn.width = next.cycleW;
+       });
+       opts.cssBefore.left = 0;
+       opts.cssBefore.top = 0;
+       opts.cssBefore.width = 0;
+       opts.animIn.width = 'show';
+       opts.animOut.width = 0;
+};
+$.fn.cycle.transitions.slideY = function($cont, $slides, opts) {
+       opts.before.push(function(curr, next, opts) {
+               $(opts.elements).not(curr).hide();
+               $.fn.cycle.commonReset(curr,next,opts,true,false);
+               opts.animIn.height = next.cycleH;
+       });
+       opts.cssBefore.left = 0;
+       opts.cssBefore.top = 0;
+       opts.cssBefore.height = 0;
+       opts.animIn.height = 'show';
+       opts.animOut.height = 0;
+};
+
+// shuffle
+$.fn.cycle.transitions.shuffle = function($cont, $slides, opts) {
+       var i, w = $cont.css('overflow', 'visible').width();
+       $slides.css({left: 0, top: 0});
+       opts.before.push(function(curr,next,opts) {
+               $.fn.cycle.commonReset(curr,next,opts,true,true,true);
+       });
+       // only adjust speed once!
+       if (!opts.speedAdjusted) {
+               opts.speed = opts.speed / 2; // shuffle has 2 transitions
+               opts.speedAdjusted = true;
+       }
+       opts.random = 0;
+       opts.shuffle = opts.shuffle || {left:-w, top:15};
+       opts.els = [];
+       for (i=0; i < $slides.length; i++)
+               opts.els.push($slides[i]);
+
+       for (i=0; i < opts.currSlide; i++)
+               opts.els.push(opts.els.shift());
+
+       // custom transition fn (hat tip to Benjamin Sterling for this bit of sweetness!)
+       opts.fxFn = function(curr, next, opts, cb, fwd) {
+               if (opts.rev)
+                       fwd = !fwd;
+               var $el = fwd ? $(curr) : $(next);
+               $(next).css(opts.cssBefore);
+               var count = opts.slideCount;
+               $el.animate(opts.shuffle, opts.speedIn, opts.easeIn, function() {
+                       var hops = $.fn.cycle.hopsFromLast(opts, fwd);
+                       for (var k=0; k < hops; k++) {
+                               if (fwd)
+                                       opts.els.push(opts.els.shift());
+                               else
+                                       opts.els.unshift(opts.els.pop());
+                       }
+                       if (fwd) {
+                               for (var i=0, len=opts.els.length; i < len; i++)
+                                       $(opts.els[i]).css('z-index', len-i+count);
+                       }
+                       else {
+                               var z = $(curr).css('z-index');
+                               $el.css('z-index', parseInt(z,10)+1+count);
+                       }
+                       $el.animate({left:0, top:0}, opts.speedOut, opts.easeOut, function() {
+                               $(fwd ? this : curr).hide();
+                               if (cb) cb();
+                       });
+               });
+       };
+       $.extend(opts.cssBefore, { display: 'block', opacity: 1, top: 0, left: 0 });
+};
+
+// turnUp/Down/Left/Right
+$.fn.cycle.transitions.turnUp = function($cont, $slides, opts) {
+       opts.before.push(function(curr, next, opts) {
+               $.fn.cycle.commonReset(curr,next,opts,true,false);
+               opts.cssBefore.top = next.cycleH;
+               opts.animIn.height = next.cycleH;
+               opts.animOut.width = next.cycleW;
+       });
+       opts.cssFirst.top = 0;
+       opts.cssBefore.left = 0;
+       opts.cssBefore.height = 0;
+       opts.animIn.top = 0;
+       opts.animOut.height = 0;
+};
+$.fn.cycle.transitions.turnDown = function($cont, $slides, opts) {
+       opts.before.push(function(curr, next, opts) {
+               $.fn.cycle.commonReset(curr,next,opts,true,false);
+               opts.animIn.height = next.cycleH;
+               opts.animOut.top   = curr.cycleH;
+       });
+       opts.cssFirst.top = 0;
+       opts.cssBefore.left = 0;
+       opts.cssBefore.top = 0;
+       opts.cssBefore.height = 0;
+       opts.animOut.height = 0;
+};
+$.fn.cycle.transitions.turnLeft = function($cont, $slides, opts) {
+       opts.before.push(function(curr, next, opts) {
+               $.fn.cycle.commonReset(curr,next,opts,false,true);
+               opts.cssBefore.left = next.cycleW;
+               opts.animIn.width = next.cycleW;
+       });
+       opts.cssBefore.top = 0;
+       opts.cssBefore.width = 0;
+       opts.animIn.left = 0;
+       opts.animOut.width = 0;
+};
+$.fn.cycle.transitions.turnRight = function($cont, $slides, opts) {
+       opts.before.push(function(curr, next, opts) {
+               $.fn.cycle.commonReset(curr,next,opts,false,true);
+               opts.animIn.width = next.cycleW;
+               opts.animOut.left = curr.cycleW;
+       });
+       $.extend(opts.cssBefore, { top: 0, left: 0, width: 0 });
+       opts.animIn.left = 0;
+       opts.animOut.width = 0;
+};
+
+// zoom
+$.fn.cycle.transitions.zoom = function($cont, $slides, opts) {
+       opts.before.push(function(curr, next, opts) {
+               $.fn.cycle.commonReset(curr,next,opts,false,false,true);
+               opts.cssBefore.top = next.cycleH/2;
+               opts.cssBefore.left = next.cycleW/2;
+               $.extend(opts.animIn, { top: 0, left: 0, width: next.cycleW, height: next.cycleH });
+               $.extend(opts.animOut, { width: 0, height: 0, top: curr.cycleH/2, left: curr.cycleW/2 });
+       });
+       opts.cssFirst.top = 0;
+       opts.cssFirst.left = 0;
+       opts.cssBefore.width = 0;
+       opts.cssBefore.height = 0;
+};
+
+// fadeZoom
+$.fn.cycle.transitions.fadeZoom = function($cont, $slides, opts) {
+       opts.before.push(function(curr, next, opts) {
+               $.fn.cycle.commonReset(curr,next,opts,false,false);
+               opts.cssBefore.left = next.cycleW/2;
+               opts.cssBefore.top = next.cycleH/2;
+               $.extend(opts.animIn, { top: 0, left: 0, width: next.cycleW, height: next.cycleH });
+       });
+       opts.cssBefore.width = 0;
+       opts.cssBefore.height = 0;
+       opts.animOut.opacity = 0;
+};
+
+// blindX
+$.fn.cycle.transitions.blindX = function($cont, $slides, opts) {
+       var w = $cont.css('overflow','hidden').width();
+       opts.before.push(function(curr, next, opts) {
+               $.fn.cycle.commonReset(curr,next,opts);
+               opts.animIn.width = next.cycleW;
+               opts.animOut.left   = curr.cycleW;
+       });
+       opts.cssBefore.left = w;
+       opts.cssBefore.top = 0;
+       opts.animIn.left = 0;
+       opts.animOut.left = w;
+};
+// blindY
+$.fn.cycle.transitions.blindY = function($cont, $slides, opts) {
+       var h = $cont.css('overflow','hidden').height();
+       opts.before.push(function(curr, next, opts) {
+               $.fn.cycle.commonReset(curr,next,opts);
+               opts.animIn.height = next.cycleH;
+               opts.animOut.top   = curr.cycleH;
+       });
+       opts.cssBefore.top = h;
+       opts.cssBefore.left = 0;
+       opts.animIn.top = 0;
+       opts.animOut.top = h;
+};
+// blindZ
+$.fn.cycle.transitions.blindZ = function($cont, $slides, opts) {
+       var h = $cont.css('overflow','hidden').height();
+       var w = $cont.width();
+       opts.before.push(function(curr, next, opts) {
+               $.fn.cycle.commonReset(curr,next,opts);
+               opts.animIn.height = next.cycleH;
+               opts.animOut.top   = curr.cycleH;
+       });
+       opts.cssBefore.top = h;
+       opts.cssBefore.left = w;
+       opts.animIn.top = 0;
+       opts.animIn.left = 0;
+       opts.animOut.top = h;
+       opts.animOut.left = w;
+};
+
+// growX - grow horizontally from centered 0 width
+$.fn.cycle.transitions.growX = function($cont, $slides, opts) {
+       opts.before.push(function(curr, next, opts) {
+               $.fn.cycle.commonReset(curr,next,opts,false,true);
+               opts.cssBefore.left = this.cycleW/2;
+               opts.animIn.left = 0;
+               opts.animIn.width = this.cycleW;
+               opts.animOut.left = 0;
+       });
+       opts.cssBefore.top = 0;
+       opts.cssBefore.width = 0;
+};
+// growY - grow vertically from centered 0 height
+$.fn.cycle.transitions.growY = function($cont, $slides, opts) {
+       opts.before.push(function(curr, next, opts) {
+               $.fn.cycle.commonReset(curr,next,opts,true,false);
+               opts.cssBefore.top = this.cycleH/2;
+               opts.animIn.top = 0;
+               opts.animIn.height = this.cycleH;
+               opts.animOut.top = 0;
+       });
+       opts.cssBefore.height = 0;
+       opts.cssBefore.left = 0;
+};
+
+// curtainX - squeeze in both edges horizontally
+$.fn.cycle.transitions.curtainX = function($cont, $slides, opts) {
+       opts.before.push(function(curr, next, opts) {
+               $.fn.cycle.commonReset(curr,next,opts,false,true,true);
+               opts.cssBefore.left = next.cycleW/2;
+               opts.animIn.left = 0;
+               opts.animIn.width = this.cycleW;
+               opts.animOut.left = curr.cycleW/2;
+               opts.animOut.width = 0;
+       });
+       opts.cssBefore.top = 0;
+       opts.cssBefore.width = 0;
+};
+// curtainY - squeeze in both edges vertically
+$.fn.cycle.transitions.curtainY = function($cont, $slides, opts) {
+       opts.before.push(function(curr, next, opts) {
+               $.fn.cycle.commonReset(curr,next,opts,true,false,true);
+               opts.cssBefore.top = next.cycleH/2;
+               opts.animIn.top = 0;
+               opts.animIn.height = next.cycleH;
+               opts.animOut.top = curr.cycleH/2;
+               opts.animOut.height = 0;
+       });
+       opts.cssBefore.height = 0;
+       opts.cssBefore.left = 0;
+};
+
+// cover - curr slide covered by next slide
+$.fn.cycle.transitions.cover = function($cont, $slides, opts) {
+       var d = opts.direction || 'left';
+       var w = $cont.css('overflow','hidden').width();
+       var h = $cont.height();
+       opts.before.push(function(curr, next, opts) {
+               $.fn.cycle.commonReset(curr,next,opts);
+               opts.cssAfter.display = '';
+               if (d == 'right')
+                       opts.cssBefore.left = -w;
+               else if (d == 'up')
+                       opts.cssBefore.top = h;
+               else if (d == 'down')
+                       opts.cssBefore.top = -h;
+               else
+                       opts.cssBefore.left = w;
+       });
+       opts.animIn.left = 0;
+       opts.animIn.top = 0;
+       opts.cssBefore.top = 0;
+       opts.cssBefore.left = 0;
+};
+
+// uncover - curr slide moves off next slide
+$.fn.cycle.transitions.uncover = function($cont, $slides, opts) {
+       var d = opts.direction || 'left';
+       var w = $cont.css('overflow','hidden').width();
+       var h = $cont.height();
+       opts.before.push(function(curr, next, opts) {
+               $.fn.cycle.commonReset(curr,next,opts,true,true,true);
+               if (d == 'right')
+                       opts.animOut.left = w;
+               else if (d == 'up')
+                       opts.animOut.top = -h;
+               else if (d == 'down')
+                       opts.animOut.top = h;
+               else
+                       opts.animOut.left = -w;
+       });
+       opts.animIn.left = 0;
+       opts.animIn.top = 0;
+       opts.cssBefore.top = 0;
+       opts.cssBefore.left = 0;
+};
+
+// toss - move top slide and fade away
+$.fn.cycle.transitions.toss = function($cont, $slides, opts) {
+       var w = $cont.css('overflow','visible').width();
+       var h = $cont.height();
+       opts.before.push(function(curr, next, opts) {
+               $.fn.cycle.commonReset(curr,next,opts,true,true,true);
+               // provide default toss settings if animOut not provided
+               if (!opts.animOut.left && !opts.animOut.top)
+                       $.extend(opts.animOut, { left: w*2, top: -h/2, opacity: 0 });
+               else
+                       opts.animOut.opacity = 0;
+       });
+       opts.cssBefore.left = 0;
+       opts.cssBefore.top = 0;
+       opts.animIn.left = 0;
+};
+
+// wipe - clip animation
+$.fn.cycle.transitions.wipe = function($cont, $slides, opts) {
+       var w = $cont.css('overflow','hidden').width();
+       var h = $cont.height();
+       opts.cssBefore = opts.cssBefore || {};
+       var clip;
+       if (opts.clip) {
+               if (/l2r/.test(opts.clip))
+                       clip = 'rect(0px 0px '+h+'px 0px)';
+               else if (/r2l/.test(opts.clip))
+                       clip = 'rect(0px '+w+'px '+h+'px '+w+'px)';
+               else if (/t2b/.test(opts.clip))
+                       clip = 'rect(0px '+w+'px 0px 0px)';
+               else if (/b2t/.test(opts.clip))
+                       clip = 'rect('+h+'px '+w+'px '+h+'px 0px)';
+               else if (/zoom/.test(opts.clip)) {
+                       var top = parseInt(h/2,10);
+                       var left = parseInt(w/2,10);
+                       clip = 'rect('+top+'px '+left+'px '+top+'px '+left+'px)';
+               }
+       }
+
+       opts.cssBefore.clip = opts.cssBefore.clip || clip || 'rect(0px 0px 0px 0px)';
+
+       var d = opts.cssBefore.clip.match(/(\d+)/g);
+       var t = parseInt(d[0],10), r = parseInt(d[1],10), b = parseInt(d[2],10), l = parseInt(d[3],10);
+
+       opts.before.push(function(curr, next, opts) {
+               if (curr == next) return;
+               var $curr = $(curr), $next = $(next);
+               $.fn.cycle.commonReset(curr,next,opts,true,true,false);
+               opts.cssAfter.display = 'block';
+
+               var step = 1, count = parseInt((opts.speedIn / 13),10) - 1;
+               (function f() {
+                       var tt = t ? t - parseInt(step * (t/count),10) : 0;
+                       var ll = l ? l - parseInt(step * (l/count),10) : 0;
+                       var bb = b < h ? b + parseInt(step * ((h-b)/count || 1),10) : h;
+                       var rr = r < w ? r + parseInt(step * ((w-r)/count || 1),10) : w;
+                       $next.css({ clip: 'rect('+tt+'px '+rr+'px '+bb+'px '+ll+'px)' });
+                       (step++ <= count) ? setTimeout(f, 13) : $curr.css('display', 'none');
+               })();
+       });
+       $.extend(opts.cssBefore, { display: 'block', opacity: 1, top: 0, left: 0 });
+       opts.animIn        = { left: 0 };
+       opts.animOut   = { left: 0 };
+};
+
+})(jQuery);
diff --git a/src/catalogue/static/catalogue/js/lesson-list.js b/src/catalogue/static/catalogue/js/lesson-list.js
new file mode 100644 (file)
index 0000000..62bbb65
--- /dev/null
@@ -0,0 +1,60 @@
+(function($){
+$(function() {
+
+
+function scrollTo(thing) {
+    $('html, body').scrollTop($(thing).offset().top - $('#level-chooser').outerHeight());
+}
+
+function updateView() {
+    var scrolltop = $(window).scrollTop();
+
+    $('#level-chooser-place').each(function(i, el){
+        if (scrolltop > $(el).offset().top) {
+            $("#level-chooser").addClass("fixed");
+        }
+        else {
+            $("#level-chooser").removeClass("fixed");
+        }
+    });
+
+    $('.level-toc').each(function(i, el) {
+        var $sect = $($(el).parent());
+        var menu_top = $('#level-chooser').outerHeight();
+        var menu_scrolltop = scrolltop + menu_top;
+
+        if (menu_scrolltop + 2 >= $sect.offset().top && 
+                menu_scrolltop < $sect.offset().top + $sect.outerHeight()) {
+            $(el).addClass("fixed").css("top", Math.min(
+                menu_top, 
+                - scrolltop + $sect.offset().top + $sect.outerHeight() - $(el).outerHeight()
+            ));
+            $("#level-chooser a[href='#" + $sect.attr('id') + "']").addClass('active');
+        }
+        else {
+            $(el).removeClass("fixed");
+            $("#level-chooser a[href='#" + $sect.attr('id') + "']").removeClass('active');
+        }
+    });
+}
+
+
+
+$("#level-chooser a, .level-toc a").click(function(ev) {
+    ev.preventDefault();
+    scrollTo($(this).attr('href'));
+});
+
+
+
+
+
+updateView();
+$(document).scroll(updateView);
+if (window.location.hash) {
+    scrollTo(window.location.hash);
+}
+
+
+});
+})(jQuery);
diff --git a/src/catalogue/static/catalogue/js/lesson.js b/src/catalogue/static/catalogue/js/lesson.js
new file mode 100755 (executable)
index 0000000..080eb45
--- /dev/null
@@ -0,0 +1,12 @@
+(function($){
+$(function() {
+
+
+$('a.image').colorbox({
+    maxWidth: '100%',
+    maxHeight: '100%',
+});
+
+
+});
+})($);
diff --git a/src/catalogue/templates/catalogue/latest_blog_posts.html b/src/catalogue/templates/catalogue/latest_blog_posts.html
new file mode 100755 (executable)
index 0000000..e9eb109
--- /dev/null
@@ -0,0 +1,5 @@
+<ol class="link-list">
+{% for post in posts %}
+    <li><a href="{{ post.link }}">{{ post.title }}</a></li>
+{% endfor %}
+</ol>
diff --git a/src/catalogue/templates/catalogue/lesson/added-var/lesson_detail.html b/src/catalogue/templates/catalogue/lesson/added-var/lesson_detail.html
new file mode 100644 (file)
index 0000000..a40c999
--- /dev/null
@@ -0,0 +1,31 @@
+{% extends "catalogue/lesson/lesson_detail.html" %}
+{% load static from staticfiles %}
+
+{% block lesson-info %}
+<section class="box">
+    <div class="box-icon"><img src="/static/img/icons/activity-time.png"><br>45m</div>
+
+    {% include "catalogue/lesson/box-icons.html" %}
+
+    <p>Ta lekcja jest częścią tematu
+    <a href="{% url 'catalogue_lessons' %}#{{ object.level.slug }}_varsaviana"><strong>Edukacja varsavianistyczna</strong></a>
+    na poziomie {{ object.level|lower }}.
+    </p>
+    <div style="clear: right"></div>
+</section>
+
+{% endblock %}
+
+
+{% block sidebar-top %}
+<div class="buttons" style="padding-bottom: 1em; border-bottom: 1px solid red;">
+
+{% if object.package %}
+    <section class="box-button"><a href="{{ object.package.url }}" class="dl-button">Pobierz całą lekcję</a></section>
+{% endif %}
+{% if object.student_package %}
+    <section><a href="{{ object.student_package.url }}" class="dl-button">Pobierz lekcję w wersji dla ucznia</a></section>
+{% endif %}
+
+</div>
+{% endblock %}
diff --git a/src/catalogue/templates/catalogue/lesson/added/lesson_detail.html b/src/catalogue/templates/catalogue/lesson/added/lesson_detail.html
new file mode 100644 (file)
index 0000000..62ec0a4
--- /dev/null
@@ -0,0 +1,31 @@
+{% extends "catalogue/lesson/lesson_detail.html" %}
+{% load static from staticfiles %}
+
+{% block lesson-info %}
+<section class="box">
+    <div class="box-icon"><img src="/static/img/icons/activity-time.png"><br>45m</div>
+
+    {% include "catalogue/lesson/box-icons.html" %}
+
+    <p>Ta lekcja jest częścią tematu
+    <a href="{% url 'catalogue_lessons' %}#{{ object.level.slug }}_filmowa"><strong>Edukacja filmowa</strong></a>
+    na poziomie {{ object.level|lower }}.
+    </p>
+    <div style="clear: right"></div>
+</section>
+
+{% endblock %}
+
+
+{% block sidebar-top %}
+<div class="buttons" style="padding-bottom: 1em; border-bottom: 1px solid red;">
+
+{% if object.package %}
+    <section class="box-button"><a href="{{ object.package.url }}" class="dl-button">Pobierz całą lekcję</a></section>
+{% endif %}
+{% if object.student_package %}
+    <section><a href="{{ object.student_package.url }}" class="dl-button">Pobierz lekcję w wersji dla ucznia</a></section>
+{% endif %}
+
+</div>
+{% endblock %}
diff --git a/src/catalogue/templates/catalogue/lesson/appendix/lesson_detail.html b/src/catalogue/templates/catalogue/lesson/appendix/lesson_detail.html
new file mode 100755 (executable)
index 0000000..98b6e3b
--- /dev/null
@@ -0,0 +1,11 @@
+{% extends "catalogue/lesson/lesson_detail.html" %}
+
+{% block lesson-info %}
+{% endblock %}
+
+
+{% block suggest-link %}
+<a href="{% url 'contact_form' 'sugestie' %}?temat={{ object.title|urlencode }}">
+    Zgłoś swoją uwagę na temat tej strony.
+</a>
+{% endblock %}
diff --git a/src/catalogue/templates/catalogue/lesson/box-icons.html b/src/catalogue/templates/catalogue/lesson/box-icons.html
new file mode 100644 (file)
index 0000000..2963698
--- /dev/null
@@ -0,0 +1,18 @@
+{% load static from staticfiles %}
+{% if object.requires_internet %}
+<div class="box-icon"><img src="{% static 'img/icons/internet_black.png' %}"
+        title="Wymaga dostępu do Internetu"
+        alt="Wymaga dostępu do Internetu"
+    ><br>Internet</div>
+{% else %}
+<div class="box-icon"><img src="{% static 'img/icons/nointernet_black.png' %}"
+        title="Nie wymaga dostępu do Internetu"
+        alt="Nie wymaga dostępu do Internetu"
+        ><br>Bez Internetu</div>
+{% endif %}
+{% if publisher %}
+<div class="box-icon"><img src="{{ publisher.logo.url }}"
+        title="{{ publisher.name }}"
+        alt="{{ publisher.name }}"
+    ></div>
+{% endif %}
diff --git a/src/catalogue/templates/catalogue/lesson/course/lesson_detail.html b/src/catalogue/templates/catalogue/lesson/course/lesson_detail.html
new file mode 100755 (executable)
index 0000000..38ef906
--- /dev/null
@@ -0,0 +1,31 @@
+{% extends "catalogue/lesson/lesson_detail.html" %}
+{% load static from staticfiles %}
+
+{% block lesson-info %}
+<section class="box">
+    <div class="box-icon"><img src="/static/img/icons/activity-time.png"><br>45m</div>
+
+    {% include "catalogue/lesson/box-icons.html" %}
+
+    <p>Ta lekcja jest częścią tematu
+    <a href="{% url 'catalogue_lessons' %}#{{ object.level.slug }}_{{ object.section.slug }}"><strong>{{ object.section }}</strong></a>
+    na poziomie {{ object.level|lower }}.
+    </p>
+    <div style="clear: right"></div>
+</section>
+
+{% endblock %}
+
+
+{% block sidebar-top %}
+<div class="buttons" style="padding-bottom: 1em; border-bottom: 1px solid red;">
+
+{% if object.package %}
+    <section class="box-button"><a href="{{ object.package.url }}" class="dl-button">Pobierz całą lekcję</a></section>
+{% endif %}
+{% if object.student_package %}
+    <section><a href="{{ object.student_package.url }}" class="dl-button">Pobierz lekcję w wersji dla ucznia</a></section>
+{% endif %}
+
+</div>
+{% endblock %}
diff --git a/src/catalogue/templates/catalogue/lesson/lesson_detail.html b/src/catalogue/templates/catalogue/lesson/lesson_detail.html
new file mode 100755 (executable)
index 0000000..2493a77
--- /dev/null
@@ -0,0 +1,143 @@
+{% extends "base.html" %}
+{% load lesson_link lesson_nav person_list from catalogue_tags %}
+{% load competence curriculum url_for_level from curriculum_tags %}
+
+
+{% block title %}{{ object }}{% endblock %}
+
+{% block body %}
+    <!--h1>{{ object }}</h1-->
+
+<aside id="sidebar">
+    {% block sidebar-top %}{% endblock %}
+
+    <section class="section">
+        {% lesson_nav object %}
+    </section>
+
+    {% if object.dc.relations %}
+    <section class="section-minor">
+        <h1>Powiązane lekcje</h1>
+        <ul class="link-list link-list-colored">
+        {% for uri in object.dc.relations %}
+            <li>{% lesson_link uri %}</li>
+        {% endfor %}
+        </ul>
+    </section>
+    {% endif %}
+
+    {% if object.dc.competences %}
+    <section class="section-minor">
+        <h1>Kompetencje:</h1>
+        <ul class="plain">
+        {% competence object.dc.competences object.level %}
+        </ul>
+    </section>
+    {% endif %}
+
+    {% if object.dc.curriculum %}
+    <section class="section-minor">
+        <h1>Podstawa programowa:</h1>
+        <ul class="plain">
+        {% curriculum object.dc.curriculum %}
+        </ul>
+    </section>
+    {% endif %}
+
+    {% if object.dc.curriculum_new %}
+    <section class="section-minor">
+        <h1>Nowa podstawa programowa:</h1>
+        <ul class="plain">
+        {% curriculum object.dc.curriculum_new new=True %}
+        </ul>
+    </section>
+    {% endif %}
+
+    <section class="section-micro">
+        <h1>Informacje:</h1>
+        <p>
+        {% if object.dc.authors_textbook %}
+        Tekst: {{ object.dc.authors_textbook|person_list }}<br/>
+        {% endif %}
+        {% if object.dc.authors_scenario %}
+        Scenariusz: {{ object.dc.authors_scenario|person_list }}<br/>
+        {% endif %}
+        {% if object.dc.authors_expert %}
+        Konsultacja merytoryczna: {{ object.dc.authors_expert|person_list }}<br/>
+        {% endif %}
+        {% if object.dc.authors_methodologist %}
+        Konsultacja metodyczna: {{ object.dc.authors_methodologist|person_list }}<br/>
+        {% endif %}
+        Licencja: <a href="{{ object.dc.license }}">{{ object.dc.license_description }}</a>.</p>
+    </section>
+
+    <section class="section-micro">
+        <h1>Narzędzia:</h1>
+        <ul class="link-list">
+            <li><a href="{{ object.xml_file.url }}">źródłowy plik XML</a></li>
+            <!--li><a href="{{ object.dc.about }}">lekcja na Platformie Redakcyjnej</a></li-->
+        </ul>
+    </section>
+
+    <section class="section-micro">
+        <p>{{ object.dc.description }}</p>
+    </section>
+
+</aside>
+
+<div id="main-bar">
+
+{% block lesson-info %}
+{% endblock %}
+
+{{ object.html_file.read|safe }}
+
+
+<a class="top-link" href="#">wróć na górę</a>
+<footer class="lesson-footer">
+
+{% if object.section %}
+
+<p class="section-info"><a href="{{ object.section.get_absolute_url }}">Temat: {{ object.section }}</a>
+<br/>(<a href="{% url 'catalogue_lessons' %}">spis wszystkich lekcji</a>)</p>
+
+<p>
+{% with object.get_previous as previous %}
+    {% if previous %}
+        <a class="previous-lesson" href="{{ previous.get_absolute_url }}">&larr; {{ previous }}</a>
+    {% endif %}
+{% endwith %}
+
+{% with object.get_next as next %}
+    {% if next %}
+        <a class="next-lesson" href="{{ next.get_absolute_url }}">{{ next }} &rarr;</a>
+    {% endif %}
+{% endwith %}
+</p>
+{% endif %}
+
+<div class="clr"></div>
+
+<p class="section-info">
+    {% block suggest-link %}
+    <a href="{% url 'contact_form' 'sugestie' %}?temat={{ 'Lekcja: '|add:object.title|urlencode }}">
+        Zgłoś swoją uwagę na temat tej lekcji.
+    </a>
+    {% endblock %}
+</p>
+
+</footer>
+
+
+{% if request.user.is_authenticated and object.forum_topics.all.count %}
+    <h2>Na forum</h2>
+    <ul>
+    {% for forum_topic in object.forum_topics.all %}
+        <li><a href="{{forum_topic.pybb_topic.get_absolute_url}}">{{forum_topic.pybb_topic.name}}</a></li>
+    {% endfor %}
+    </ul>
+{% endif %}
+
+</div>
+
+{% endblock %}
diff --git a/src/catalogue/templates/catalogue/lesson/project/lesson_detail.html b/src/catalogue/templates/catalogue/lesson/project/lesson_detail.html
new file mode 100755 (executable)
index 0000000..7a17251
--- /dev/null
@@ -0,0 +1,28 @@
+{% extends "catalogue/lesson/lesson_detail.html" %}
+
+{% block lesson-info %}
+<section class="box">
+    {% if publisher %}
+    <div class="box-icon"><img src="{{ publisher.logo.url }}"
+            title="{{ publisher.name }}"
+            alt="{{ publisher.name }}"
+        ></div>
+    {% endif %}
+
+    <p>To jest <a href="{% url 'info' 'metoda-projektowa' %}">projekt</a> 
+    na poziomie
+    <a href="{% url 'catalogue_lessons' %}#{{ object.level.slug }}">{{ object.level|lower }}</a>.
+    </p>
+</section>
+{% endblock %}
+
+
+
+{% block sidebar-top %}
+
+
+{% if object.package %}
+    <section class="box-button"><a href="{{ object.package.url }}" class="dl-button">Pobierz cały projekt</a></section>
+{% endif %}
+
+{% endblock %}
diff --git a/src/catalogue/templates/catalogue/lesson/synthetic/lesson_detail.html b/src/catalogue/templates/catalogue/lesson/synthetic/lesson_detail.html
new file mode 100755 (executable)
index 0000000..df60c9f
--- /dev/null
@@ -0,0 +1,25 @@
+{% extends "catalogue/lesson/lesson_detail.html" %}
+
+{% block lesson-info %}
+<section class="box">
+    <div class="box-icon"><img src="/static/img/icons/activity-time.png"><br>45m</div>
+
+    {% include "catalogue/lesson/box-icons.html" %}
+
+    <p>Ta lekcja jest częścią skróconego kursu na poziomie {{ object.level|lower }}.
+        Zobacz też <a href="{% url 'catalogue_lessons' %}#{{ object.level.slug }}_pelny">pełny kurs</a>.
+    </p>
+    <div style="clear: right"></div>
+</section>
+{% endblock %}
+
+{% block sidebar-top %}
+
+{% if object.package %}
+    <section class="box-button"><a href="{{ object.package.url }}" class="dl-button">Pobierz całą lekcję</a></section>
+{% endif %}
+{% if object.student_package %}
+    <section><a href="{{ object.student_package.url }}" class="dl-button">Pobierz lekcję w wersji dla ucznia</a></section>
+{% endif %}
+
+{% endblock %}
diff --git a/src/catalogue/templates/catalogue/lesson_list.html b/src/catalogue/templates/catalogue/lesson_list.html
new file mode 100755 (executable)
index 0000000..d89b547
--- /dev/null
@@ -0,0 +1,47 @@
+{% extends "base.html" %}
+{% load catalogue_tags %}
+{% load static from staticfiles %}
+{% load course_boxes course_boxes_toc from curriculum_tags %}
+{% load chunk from chunks %}
+
+{% block title %}Lekcje{% endblock %}
+
+{% block body %}
+    <h1>Lekcje</h1>
+
+<aside id="sidebar">
+    <section class="section-minor">
+        <h1>Zebrane dla wszystkich tematów</h1>
+        <ul class="link-list">
+            {% for lesson in appendix %}
+                <li><a href="{{ lesson.get_absolute_url }}">{{ lesson }}</a></li>
+            {% endfor %}
+            <li><a href="{% url 'info' 'infografiki' %}">Infografiki</a></li>
+        </ul>
+    </section>
+    {% chunk 'lesson_list_sidebar' %}
+</aside>
+
+<div id="main-bar">
+    <div class="box">
+    {% chunk 'levels_disclaimer' %}
+    </div>
+
+    <div id="level-chooser-place">
+        <ul id="level-chooser">
+            <li class="home"><a href="#body"><img src="{% static 'img/logo.png' %}" /></a></li>
+            {% for object in object_list %}
+                <li><a href="#{{ object.slug }}">{{ object }}</a></li>
+            {% endfor %}
+        </ul>
+    </div>
+
+
+
+    {% for level in object_list %}
+        {% level_box level %}
+    {% endfor %}
+</div>
+
+
+{% endblock %}
diff --git a/src/catalogue/templates/catalogue/section_detail.html b/src/catalogue/templates/catalogue/section_detail.html
new file mode 100755 (executable)
index 0000000..01889ee
--- /dev/null
@@ -0,0 +1,11 @@
+{% extends "base.html" %}
+{% load catalogue_tags %}
+
+{% block title %}{{ object }}{% endblock %}
+
+{% block body %}
+    <h1>{{ object }}</h1>
+    {% section_box object %}
+    
+
+{% endblock %}
diff --git a/src/catalogue/templates/catalogue/snippets/carousel.html b/src/catalogue/templates/catalogue/snippets/carousel.html
new file mode 100755 (executable)
index 0000000..bb31eae
--- /dev/null
@@ -0,0 +1,27 @@
+{% load thumbnail %}
+{% url 'catalogue_lessons' as lessons %}
+<section id="catalogue-carousel">
+    <ul id="catalogue-carousel-links">
+        {% for section in object_list %}
+        <li style="{% if section.pic %}{% thumbnail section.pic '460x235' crop='center' as th %}background-image: url('{{ th.url }}');{% endthumbnail %}{% endif %}">
+            <a href="{{ lessons }}#gimnazjum_{{ section.slug }}" class="catalogue-carousel-link">
+                <div class="catalogue-carousel-note">
+                    <div>
+                        <p>
+                        <strong>{{ section }}</strong>
+                        {{ section.summary }}
+                        <span class="more">zobacz &rarr;</span>
+                        </p>
+                    </div>
+                </div>
+            </a>
+            <a class="attribution" href="{{ section.pic_src }}">fot. {{ section.pic_attribution }}</a>
+        </li>    
+        {% endfor %}
+    </ul>
+    <ul id="catalogue-carousel-switcher">
+        {% for section in object_list %}
+            <li><a href="{{ section.get_absolute_url }}">{{ section }}</a></li>
+        {% endfor %}
+    </ul>
+</section>
diff --git a/src/catalogue/templates/catalogue/snippets/lesson_link.html b/src/catalogue/templates/catalogue/snippets/lesson_link.html
new file mode 100755 (executable)
index 0000000..749b4e1
--- /dev/null
@@ -0,0 +1 @@
+{% if lesson %}<a href="{{ lesson.get_absolute_url }}">{{ lesson }}</a>{% endif %}
diff --git a/src/catalogue/templates/catalogue/snippets/lesson_nav.html b/src/catalogue/templates/catalogue/snippets/lesson_nav.html
new file mode 100755 (executable)
index 0000000..0e64225
--- /dev/null
@@ -0,0 +1,27 @@
+<h1>
+{% if root %}
+    <a href="{{ root.get_absolute_url }}">{{ root }}, <br>{{ lesson.level }}</a>
+{% elif lesson.type == 'synthetic' %}
+    <a href="{% url 'catalogue_lessons' %}">Kurs skrócony, <br>{{ lesson.level }}</a>
+{% elif lesson.type == 'project' %}
+    <a href="{% url 'catalogue_lessons' %}">Projekty, <br>{{ lesson.level }}</a>
+{% elif lesson.type == 'added' %}
+    <a href="{% url 'catalogue_lessons' %}#liceum_filmowa">Edukacja filmowa</a>
+{% elif lesson.type == 'added-var' %}
+    <a href="{% url 'catalogue_lessons' %}#liceum_varsaviana">Edukacja varsavianistyczna</a>
+{% else %}
+    <a href="{% url 'catalogue_lessons' %}">Inne</a>
+{% endif %}
+</h1>
+
+<ul>
+{% for item in siblings %}
+    <li>
+    {% if item == lesson %}
+        <strong>{{ item }}</strong>
+    {% else %}
+        <a href="{{ item.get_absolute_url }}">{{ item }}</a>
+    {% endif %}
+    </li>
+{% endfor %}
+</ul>
diff --git a/src/catalogue/templates/catalogue/snippets/lesson_or_stub.html b/src/catalogue/templates/catalogue/snippets/lesson_or_stub.html
new file mode 100644 (file)
index 0000000..5bb2614
--- /dev/null
@@ -0,0 +1,9 @@
+{% if lesson.slug %}
+    <a href="{{ lesson.get_absolute_url }}" title="{{ lesson.description }}">
+{% endif %}
+{{ lesson }}
+{% if lesson.slug %}
+    </a>
+{% else %}
+(w przygotowaniu)
+{% endif %}
diff --git a/src/catalogue/templates/catalogue/snippets/level_box.html b/src/catalogue/templates/catalogue/snippets/level_box.html
new file mode 100755 (executable)
index 0000000..3155cce
--- /dev/null
@@ -0,0 +1,176 @@
+<section id="{{ level.slug }}" class="level" style="margin-left: 20em">
+
+    <section class="box level-toc" style="float: left; margin-left: -20em; width: 15em;">
+        <strong><a href="#{{ level.slug }}">{{ level }}</a></strong>
+        <ul  class="link-list"  style="list-style: none; padding: 0; margin: 0;">
+            {% if lessons.synthetic %}
+            <li><a href="#{{ level.slug }}_skrocony">Skrócony kurs</a></li>
+            {% endif %}
+            {% if lessons.course %}
+            <li><a href="#{{ level.slug }}_pelny">Pełny kurs</a>
+                <ul style="list-style: none; padding: 0 0 0 1em; margin: 0;">
+                {% for section in lessons.course %}
+                        <li><a href="#{{ level.slug }}_{{ section.slug}}">{{ section }}</a></li>
+                {% endfor %}
+                </ul>
+            </li>
+            {% endif %}
+            {% if lessons.project %}
+            <li><a href="#{{ level.slug }}_projekty">Projekty</a></li>
+            {% endif %}
+            {% if lessons.appendix %}
+            <li><a href="#{{ level.slug }}_pozostale">Pozostałe materiały</a></li>
+            {% endif %}
+
+            {% if courses %}
+            <li class="curriculumcourses"><a href="#{{ level.slug }}_podstawa">Według postawy programowej</a>
+                <ul style="list-style: none; padding: 0 0 0 1em; margin: 0;">
+                {% for course, lessons in courses %}
+                        <li><a href="#{{ level.slug }}_{{ course.slug}}">{{ course }}</a></li>
+                {% endfor %}
+                </ul>
+            </li>
+            {% endif %}
+
+            {% if added %}
+            <li class="curriculumcourses"><a href="#{{ level.slug }}_inne">Inne</a>
+                <ul style="list-style: none; padding: 0 0 0 1em; margin: 0;">
+                {% for item in added %}
+                    <li><a href="#{{ level.slug }}_{{ item.slug }}">{{ item.title }}</a></li>
+                {% endfor %}
+                </ul>
+            </li>
+            {% endif %}
+
+        </ul>
+
+
+    </section>
+
+
+
+    <h1>{{ level }}</h1>
+
+    <section class="box-button button"><a href="{{ level.package.url }}" class="dl-button">Pobierz wszystkie lekcje</a></section>
+    <section class="button"><a href="{{ level.student_package.url }}" class="dl-button">Pobierz wszystkie lekcje w&nbsp;wersji dla ucznia</a></section>
+
+    {% if lessons.synthetic %}
+    <section id="{{ level.slug }}_skrocony">
+        <h1>Skrócony kurs</h1>
+
+        <p>Masz kilka godzin? Przeprowadź po jednej lekcji przeglądowej z każdego tematu.</p>
+
+        <ul class="link-list">
+            {% for lesson in lessons.synthetic %}
+                <li>{% include "catalogue/snippets/lesson_or_stub.html" %}</li>
+            {% endfor %}
+        </ul>
+    </section>
+    {% endif %}
+
+
+    {% if lessons.course %}
+    <section id="{{ level.slug }}_pelny">
+        <h1>Pełny kurs</h1>
+
+        <p>Masz więcej czasu? Zrealizuj kompletny program edukacji medialnej.</p>
+
+        {% for section, s_lessons in lessons.course.items %}
+            <section id="{{ level.slug }}_{{ section.slug}}">
+                <h1>{{ section }}</h1>
+
+                <ul class="link-list">
+                    {% for lesson in s_lessons %}
+                        <li>{% include "catalogue/snippets/lesson_or_stub.html" %}</li>
+                    {% endfor %}
+                </ul>
+            </section>
+        {% endfor %}
+
+    </section>
+    {% endif %}
+
+
+    {% if lessons.project %}
+    <section id="{{ level.slug }}_projekty">
+        <h1>Projekty</h1>
+
+        <p>Masz 4-6 tygodni? Zrealizuj jeden z projektów ze swoimi uczniami.</p>
+
+        <ul class="link-list">
+            {% for lesson in lessons.project %}
+                <li>{% include "catalogue/snippets/lesson_or_stub.html" %}</li>
+            {% endfor %}
+        </ul>
+    </section>
+    {% endif %}
+
+
+    {% if courses %}
+    <section id="{{ level.slug }}_podstawa">
+        <h1>Według podstawy programowej</h1>
+
+        {% for course, lessons in courses %}
+        <section id="{{ level.slug}}_{{ course.slug }}">
+            <h1>{{ course }}</h1>
+
+            {% if lessons.synthetic %}
+            <section>
+                <h1>Z kursu skróconego</h1>
+                <ul class="link-list">
+                    {% for lesson in lessons.synthetic %}
+                        <li>{% include "catalogue/snippets/lesson_or_stub.html" %}</li>
+                    {% endfor %}
+                </ul>
+            </section>
+            {% endif %}
+
+            {% if lessons.course %}
+            <section>
+                <h1>Z kursu pełnego</h1>
+                <ul class="link-list">
+                    {% for lesson in lessons.course %}
+                        <li>{% include "catalogue/snippets/lesson_or_stub.html" %}</li>
+                    {% endfor %}
+                </ul>
+            </section>
+            {% endif %}
+
+            {% if lessons.project %}
+            <section>
+                <h1>Projekty</h1>
+                <ul class="link-list">
+                    {% for lesson in lessons.project %}
+                        <li>{% include "catalogue/snippets/lesson_or_stub.html" %}</li>
+                    {% endfor %}
+                </ul>
+            </section>
+            {% endif %}
+
+        </section>
+        {% endfor %}
+        
+    </section>
+    {% endif %}
+
+
+    {% if added %}
+    <section id="{{ level.slug }}_inne">
+        <h1>Inne</h1>
+
+        {% for item in added %}
+        <section id="{{ level.slug }}_{{ item.slug }}">
+            <h1>{{ item.title }}</h1>
+
+            <ul class="link-list">
+                {% for lesson in item.lessons %}
+                    <li><a href="{{ lesson.get_absolute_url }}" title="{{ lesson.description }}">{{ lesson }}</a></li>
+                {% endfor %}
+            </ul>
+        </section>
+        {% endfor %}
+    </section>
+    {% endif %}
+
+
+</section>
diff --git a/src/catalogue/templates/catalogue/snippets/levels_main.html b/src/catalogue/templates/catalogue/snippets/levels_main.html
new file mode 100644 (file)
index 0000000..54ceed9
--- /dev/null
@@ -0,0 +1,36 @@
+{% load i18n %}
+<style type="text/css">
+#main-sections ul li {width: {{ section_width }}px;}
+#main-sections ul li a {width: {{ section_width|add:"-10" }}px;}
+.levelth {width: {{ section_width }}px;}
+</style>
+{% url 'catalogue_lessons' as les %}
+<ul class="section-buttons">
+{% for level in object_list %}
+<li class="box{{ level.pk }}">
+    <a href="{{ les }}#{{ level.slug }}">
+    <span class="in-box">
+    <span class="name">{{ level }}</span>
+    {% if level.length_synthetic %}{{ level.length_synthetic }} lub {% endif %}{{ level.length_course }} godzin
+    </span>
+    </a>
+</li>
+{% endfor %}
+<li class="box6">
+    <a href="{{ les }}#liceum_filmowa">
+    <span class="in-box">
+    <span class="name">Edukacja filmowa</span>
+    8 godzin
+    </span>
+    </a>
+</li>
+<li class="box7">
+    <a href="{{ les }}#liceum_varsaviana">
+    <span class="in-box">
+    <span class="name">Edukacja varsavianistyczna</span>
+    10 godzin
+    </span>
+    </a>
+</li>
+
+</ul>
diff --git a/src/catalogue/templates/search/indexes/catalogue/lesson_text.txt b/src/catalogue/templates/search/indexes/catalogue/lesson_text.txt
new file mode 100755 (executable)
index 0000000..ab6feff
--- /dev/null
@@ -0,0 +1 @@
+{{ object.html_file.read|striptags }}
diff --git a/src/catalogue/templatetags/__init__.py b/src/catalogue/templatetags/__init__.py
new file mode 100755 (executable)
index 0000000..e69de29
diff --git a/src/catalogue/templatetags/catalogue_tags.py b/src/catalogue/templatetags/catalogue_tags.py
new file mode 100755 (executable)
index 0000000..b74224d
--- /dev/null
@@ -0,0 +1,173 @@
+# -*- coding: utf-8 -*-
+from collections import defaultdict
+from django import template
+from django.utils.datastructures import SortedDict
+from ..models import Lesson, Section
+from curriculum.models import Level, CurriculumCourse
+from librarian.dcparser import WLURI, Person
+
+register = template.Library()
+
+
+@register.inclusion_tag("catalogue/snippets/carousel.html")
+def catalogue_carousel():
+    return {
+        "object_list": Section.objects.all()
+    }
+
+
+@register.inclusion_tag("catalogue/snippets/levels_main.html")
+def catalogue_levels_main():
+    object_list = Level.objects.exclude(lesson=None)
+    c = object_list.count()
+    return {
+        'object_list': object_list,
+        # 'section_width': (700 - 20 * (c - 1)) / c,
+        'section_width': (700 - 20 * 2) / 3
+    }
+
+
+@register.inclusion_tag("catalogue/snippets/level_box.html")
+def level_box(level):
+    lessons = {'synthetic': [], 'course': SortedDict(), 'project': []}
+    by_course = defaultdict(lambda: defaultdict(list))
+
+    lesson_lists = [alist for alist in [
+        list(level.lesson_set.exclude(type='appendix').order_by('section__order', 'order')),
+        list(level.lessonstub_set.all())
+    ] if alist]
+
+    while lesson_lists:
+        min_index, min_list = min(enumerate(lesson_lists), key=lambda x: x[1][0].order)
+        lesson = min_list.pop(0)
+        if not min_list:
+            lesson_lists.pop(min_index)
+
+        if lesson.type == 'course':
+            if lesson.section not in lessons['course']:
+                lessons['course'][lesson.section] = []
+            lessons['course'][lesson.section].append(lesson)
+        elif lesson.type.startswith('added'):
+            continue
+        else:
+            lessons[lesson.type].append(lesson)
+
+        if hasattr(lesson, 'curriculum_courses'):
+            for course in lesson.curriculum_courses.all():
+                by_course[course][lesson.type].append(lesson)
+
+    courses = [(course, by_course[course])
+               for course in CurriculumCourse.objects.filter(lesson__level=level).distinct()]
+
+    added = []
+    if level.slug == 'liceum':
+        added.append({
+            'slug': 'filmowa',
+            'title': u'Edukacja filmowa',
+            'lessons': [
+                Lesson.objects.get(slug=s) for s in [
+                    'film-co-to-wlasciwie-jest',
+                    'scenariusz-scenopis-i-srodki-realizacyjne',
+                    'kompozycja-obrazu-filmowego',
+                    'praca-kamery-kadr-kat',
+                    'montaz-materialu-filmowego',
+                    'swiatlo-i-dzwiek-w-filmie',
+                    'scenografia-charakteryzacja-kostiumy-i-aktorzy',
+                    'narracja-w-filmie-tekst-i-fabula',
+                ]
+            ],
+        })
+        added.append({
+            'slug': 'varsaviana',
+            'title': u'Edukacja varsavianistyczna',
+            'lessons': [
+                Lesson.objects.get(slug=s) for s in [
+                    'czego-prus-w-lalce-o-zydach-nie-powiedzial',
+                    'jak-zmienila-sie-warszawa-o-dworcu-dawniej-i-dzis',
+                    'o-gwarze-praskiej',
+                    'poznaj-i-pokaz-prage',
+                    'praga-trzech-religii',
+                    'sladami-zydow-w-warszawie',
+                    'tajemnice-palacu-saskiego',
+                    'warszawa-przedwojenne-miasto-neonow',
+                    'warszawski-barok',
+                    'ziemianska-jako-soczewka-swiata-lat-miedzywojennych',
+                ]
+            ],
+        })
+
+    return {
+        "level": level,
+        "lessons": lessons,
+        "courses": courses,
+        "added": added,
+    }
+
+
+@register.inclusion_tag("catalogue/snippets/lesson_nav.html")
+def lesson_nav(lesson):
+    if lesson.type == 'course':
+        root = lesson.section
+        siblings = Lesson.objects.filter(type='course', level=lesson.level, section=root)
+    elif lesson.type == 'appendix':
+        root = None
+        siblings = Lesson.objects.filter(type=lesson.type)
+    elif lesson.type == 'added':
+        root = None
+        siblings = [
+                Lesson.objects.get(slug=s) for s in [
+                    'film-co-to-wlasciwie-jest',
+                    'scenariusz-scenopis-i-srodki-realizacyjne',
+                    'kompozycja-obrazu-filmowego',
+                    'praca-kamery-kadr-kat',
+                    'montaz-materialu-filmowego',
+                    'swiatlo-i-dzwiek-w-filmie',
+                    'scenografia-charakteryzacja-kostiumy-i-aktorzy',
+                    'narracja-w-filmie-tekst-i-fabula',
+                ]
+            ]
+    else:
+        root = None
+        siblings = Lesson.objects.filter(type=lesson.type, level=lesson.level)
+    return {
+        "lesson": lesson,
+        "root": root,
+        "siblings": siblings,
+    }
+
+
+@register.inclusion_tag("catalogue/snippets/lesson_link.html")
+def lesson_link(uri):
+    try:
+        return {'lesson': Lesson.objects.get(slug=WLURI(uri).slug)}
+    except Lesson.DoesNotExist:
+        return {}
+
+
+@register.filter
+def person_list(persons):
+    return u", ".join(Person.from_text(p).readable() for p in persons)
+
+
+# FIXME: Move to fnpdjango
+import feedparser
+import datetime
+
+
+@register.inclusion_tag('catalogue/latest_blog_posts.html')
+def latest_blog_posts(feed_url, posts_to_show=5):
+    try:
+        feed = feedparser.parse(str(feed_url))
+        posts = []
+        for i in range(posts_to_show):
+            pub_date = feed['entries'][i].updated_parsed
+            published = datetime.date(pub_date[0], pub_date[1], pub_date[2])
+            posts.append({
+                'title': feed['entries'][i].title,
+                'summary': feed['entries'][i].summary,
+                'link': feed['entries'][i].link,
+                'date': published,
+                })
+        return {'posts': posts}
+    except:
+        return {'posts': []}
diff --git a/src/catalogue/tests.py b/src/catalogue/tests.py
new file mode 100644 (file)
index 0000000..b967c44
--- /dev/null
@@ -0,0 +1,17 @@
+# -*- coding: utf-8 -*-
+"""
+This file demonstrates writing tests using the unittest module. These will pass
+when you run "manage.py test".
+
+Replace this with more appropriate tests for your application.
+"""
+
+from django.test import TestCase
+
+
+class SimpleTest(TestCase):
+    def test_basic_addition(self):
+        """
+        Tests that 1 + 1 always equals 2.
+        """
+        self.assertEqual(1 + 1, 2)
diff --git a/src/catalogue/urls.py b/src/catalogue/urls.py
new file mode 100755 (executable)
index 0000000..f2a8b08
--- /dev/null
@@ -0,0 +1,13 @@
+# -*- coding: utf-8 -*-
+from django.conf.urls import patterns, url
+from .views import LessonListView, LessonView
+
+urlpatterns = patterns(
+    '',
+    url(r'^$',
+        LessonListView.as_view(),
+        name="catalogue_lessons"),
+    url(r'^(?P<slug>[^/]+)/$',
+        LessonView.as_view(),
+        name="catalogue_lesson"),
+)
diff --git a/src/catalogue/views.py b/src/catalogue/views.py
new file mode 100644 (file)
index 0000000..4f9d78c
--- /dev/null
@@ -0,0 +1,35 @@
+# -*- coding: utf-8 -*-
+from django.views.generic import DetailView, ListView
+
+from curriculum.models import Level
+from publishers.models import Publisher
+from .models import Lesson
+
+
+class LessonListView(ListView):
+    queryset = Level.objects.exclude(lesson=None)
+    template_name = "catalogue/lesson_list.html"
+
+    def get_context_data(self, **kwargs):
+        context = super(LessonListView, self).get_context_data(**kwargs)
+        context['appendix'] = Lesson.objects.filter(type='appendix')
+        return context
+
+
+class LessonView(DetailView):
+    model = Lesson
+
+    def get_template_names(self):
+        return [
+            'catalogue/lesson/%s/lesson_detail.html' % self.object.type,
+            'catalogue/lesson/lesson_detail.html',
+        ]
+
+    def get_context_data(self, **kwargs):
+        context = super(LessonView, self).get_context_data(**kwargs)
+        try:
+            context['publisher'] = Publisher.objects.get(
+                name=context['object'].dc.get('publisher', '').strip())
+        except (Publisher.DoesNotExist, Publisher.MultipleObjectsReturned):
+            pass
+        return context
diff --git a/src/chunks/__init__.py b/src/chunks/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/src/chunks/admin.py b/src/chunks/admin.py
new file mode 100644 (file)
index 0000000..5bdbddc
--- /dev/null
@@ -0,0 +1,18 @@
+# -*- coding: utf-8 -*-
+from django.contrib import admin
+
+from chunks.models import Chunk, Attachment
+
+
+class ChunkAdmin(admin.ModelAdmin):
+    list_display = ('key', 'description',)
+    search_fields = ('key', 'content',)
+
+admin.site.register(Chunk, ChunkAdmin)
+
+
+class AttachmentAdmin(admin.ModelAdmin):
+    list_display = ('key',)
+    search_fields = ('key',)
+
+admin.site.register(Attachment, AttachmentAdmin)
diff --git a/src/chunks/fixtures/chunks.json b/src/chunks/fixtures/chunks.json
new file mode 100644 (file)
index 0000000..0d26270
--- /dev/null
@@ -0,0 +1,41 @@
+[
+    {
+        "pk": "document-list", 
+        "model": "chunks.chunk", 
+        "fields": {
+            "content": "        <p>Zasoby szkolnej biblioteki internetowej Wolne Lektury oraz jej funkcjonalno\u015bci wykorzystywane s\u0105 przez nauczycieli i nauczycielki podczas pracy w szkole. Poni\u017cej znajduj\u0105 si\u0119 materia\u0142y edukacyjne \u2013 scenariusze lekcji, tematy wypracowa\u0144 i inne \u2013 stworzone przez pedagog\u00f3w, kt\u00f3rzy w swojej codziennej pracy w szkole wykorzystuj\u0105 przygotowane przez nas narz\u0119dzia i opracowane merytorycznie teksty.</p>\r\n\r\n<ol>\r\n<li><strong>Scenariusze lekcji</strong>\r\n\r\n <ul>\r\n  <li><a href=\"/materialy/kot-w-literaturze-scenariusz-lekcji/\" data-hash=\"#kot-w-literaturze-scenariusz-lekcji\">Scenariusz lekcji. Kot w literaturze.</a> <a class='download-doc' href=\"/media/lessons/document/wolnelektury-kot-scenariusz.doc\">Pobierz dokument</a></li>\r\n  <li><a href=\"/materialy/lekcja-multimedialna-danse-macabre/\" data-hash=\"#lekcja-multimedialna-danse-macabre\">Lekcja multimedialna - Motyw danse macabre wyst\u0119puj\u0105cy w tekstach kultury. </a><a class='download-doc' href=\"/media/lessons/document/wolnelektury-lekcja.multimedialna-danse.macabre_.ppt\">Pobierz prezentacj\u0119</a></li>\r\n  <li><a href=\"/materialy/lekcja-multimedialna-sonet/\" data-hash=\"#lekcja-multimedialna-sonet\">R\u00f3\u017cnorodno\u015b\u0107 tematyczna  sonetu.</a><a class='download-doc' href=\"/media/lessons/document/wolnelektury-lekcja.multimedialna-sonet.ppt\">Pobierz dokument</a></li>\r\n  <li><a href=\"/materialy/slowacki-czesc-i/\" data-hash=\"#slowacki-czesc-i\">\u201eBo to jest wieszcza najja\u015bniejsza chwa\u0142a\u2026\u201d Juliusz S\u0142owacki - cz\u0142owiek i poeta</a> <a class='download-doc' href=\"/media/lessons/document/wolnelektury-slowacki01.ppt\">Pobierz prezentacj\u0119</a></li>\r\n  <li><a href=\"/materialy/usmiech-i-lzy-wieszcza/\" data-hash=\"#usmiech-i-lzy-wieszcza\">U\u015bmiech  i \u0142zy wieszcza czyli S\u0142owacki p\u00f3\u0142 \u017cartem,  p\u00f3\u0142 serio.</a> <a class='download-doc' href=\"/media/lessons/document/wolnelektury-usmiech.i.lzy.wieszcza.ppt\">Pobierz prezentacj\u0119</a></li>\r\n\r\n</ul>\r\n</li>\r\n\r\n<li><a href=\"/materialy/przyklady-zadan/\" data-hash=\"#przyklady-zadan\">Przyk\u0142ady zada\u0144 do opracowania przez zespo\u0142y uczni\u00f3w</a> <a class='download-doc' href=\"/media/lessons/document/wolnelektury-przyklady.zadan.doc\">Pobierz dokument</a></li>\r\n<li><a href=\"/materialy/tematy-wypracowan/\" data-hash=\"#tematy-wypracowan\">Tematy wypracowa\u0144</a> <a class='download-doc' href=\"/media/lessons/document/wolne.lektury-tematy.wypracowan.doc\">Pobierz dokument</a></li>\r\n<li><a href=\"/materialy/repetytorium-maturalne/\" data-hash=\"#repetytorium-maturalne\">Repetytorium maturalne.</a> <a class='download-doc' href=\"/media/lessons/document/wolnelektury-repetytorium.maturalne.ppt\">Pobierz prezentacj\u0119</a></li>\r\n\r\n</ol>\r\n</p>\r\n\r\n<p>Zach\u0119camy wszystkich nauczycieli i wszystkie nauczycielki do tworzenia materia\u0142\u00f3w edukacyjnych i publikowania ich na naszej stronie! Warto zapozna\u0107 si\u0119 z <a href=\"/materialy/tworzenie-scenariuszy-lekcji/\" data-hash=\"#tworzenie-scenariuszy-lekcji\">instrukcj\u0105 dotycz\u0105c\u0105 pisania scenariuszy lekcji</a> i <a href=\"/materialy/schemat-scenariusza-lekcji/\" data-hash=\"#schemat-scenariusza-lekcji\">schematem przyk\u0142adowego scenariusza lekcji</a>, a gotowe materia\u0142y przes\u0142a\u0107 na adres <a href=\"mailto:fundacja@nowoczesnapolska.org.pl\">fundacja@nowoczesnapolska.org.pl</a>.</p>", 
+            "description": ""
+        }
+    }, 
+    {
+        "pk": "footer-map", 
+        "model": "chunks.chunk", 
+        "fields": {
+            "content": "<AREA SHAPE=\"rect\" COORDS=\"104,83,261,101\" HREF=\"http://edukacja.gazeta.pl\" ALT=\"GazetaEdukacja.pl - matura, testy, egzaminy, studia\" TITLE=\"GazetaEdukacja.pl - matura, testy, egzaminy, studia\"><AREA SHAPE=\"rect\" COORDS=\"539,38,656,73\" ALT=\"Kurier Wile\u0144ski\" HREF=\"http://www.kurierwilenski.lt/\"><AREA SHAPE=\"rect\" COORDS=\"687,81,789,116\" ALT=\"Radio znad Wilii\" HREF=\"http://www.znadwilii.lt\"><AREA SHAPE=\"rect\" COORDS=\"376,34,520,75\" ALT=\"Ministerstwo Edukacji Narodowej\" HREF=\"http://www.men.gov.pl/\"><AREA SHAPE=\"rect\" COORDS=\"761,59,822,77\" ALT=\"Biblioteka Analiz\" HREF=\"http://www.rynek-ksiazki.pl/\"><AREA SHAPE=\"rect\" COORDS=\"734,55,759,76\" ALT=\"Przekr\u00f3j\" HREF=\"http://www.przekroj.pl/\"><AREA SHAPE=\"rect\" COORDS=\"695,55,732,76\" ALT=\"TVP Kultura\" HREF=\"http://www.tvp.pl/tvpkultura/\"><AREA SHAPE=\"rect\" COORDS=\"762,35,821,59\" ALT=\"Elle\" HREF=\"http://elle.interia.pl/\"><AREA SHAPE=\"rect\" COORDS=\"659,55,693,77\" ALT=\"Radio TOK.FM\" HREF=\"http://www.tok.fm/\"><AREA SHAPE=\"rect\" COORDS=\"658,35,760,53\" ALT=\"Tygodnik Powszechny\" HREF=\"http://tygodnik.onet.pl/\"><AREA SHAPE=\"rect\" COORDS=\"265,35,366,74\" ALT=\"Ministerstwo Kultury i Dziedzictwa Narodowego\" HREF=\"http://www.mkidn.gov.pl/\"><AREA SHAPE=\"rect\" COORDS=\"222,29,261,83\" ALT=\"Biblioteka Narodowa\" HREF=\"http://www.bn.org.pl/\"><AREA SHAPE=\"rect\" COORDS=\"188,58,217,81\" ALT=\"PZL\" HREF=\"http://www.pzl.pl/\"><AREA SHAPE=\"rect\" COORDS=\"162,32,218,56\" ALT=\"eo Networks - administracja, zarz\u0105dzanie serwerami, technologie Sun,\r\nlinux, bsd, unix, solaris\" HREF=\"http://eo.pl/\"><AREA SHAPE=\"rect\" COORDS=\"104,61,184,76\" ALT=\"Kancelaria Prawna Grynhoff Wo\u017any Mali\u0144ski Sp\u00f3\u0142ka komandytowa\" HREF=\"http://www.gww.pl/\"><AREA SHAPE=\"rect\" COORDS=\"104,35,160,60\" ALT=\"Information is art\" HREF=\"http://www.informationisart.com/\"><AREA SHAPE=\"rect\" COORDS=\"15,39,98,75\" ALT=\"Fundacja Nowoczesna Polska\" HREF=\"http://nowoczesnapolska.org.pl/\"><AREA SHAPE=\"default\" COORDS=\"0,0,860,120\" NOHREF>", 
+            "description": ""
+        }
+    }, 
+    {
+        "pk": "site-description", 
+        "model": "chunks.chunk", 
+        "fields": {
+            "content": "", 
+            "description": ""
+        }
+    }, 
+    {
+        "pk": "top-message", 
+        "model": "chunks.chunk", 
+        "fields": {
+            "content": "", 
+            "description": ""
+        }
+    }, 
+    {
+        "pk": "footer-img", 
+        "model": "chunks.attachment", 
+        "fields": {
+            "attachment": "chunks/attachment/footer.png"
+        }
+    }
+]
diff --git a/src/chunks/locale/de/LC_MESSAGES/django.mo b/src/chunks/locale/de/LC_MESSAGES/django.mo
new file mode 100644 (file)
index 0000000..be5f8ae
Binary files /dev/null and b/src/chunks/locale/de/LC_MESSAGES/django.mo differ
diff --git a/src/chunks/locale/de/LC_MESSAGES/django.po b/src/chunks/locale/de/LC_MESSAGES/django.po
new file mode 100644 (file)
index 0000000..7fbf84e
--- /dev/null
@@ -0,0 +1,74 @@
+# 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: 2012-07-19 11:39+0200\n"
+"PO-Revision-Date: 2012-04-11 22:56+0100\n"
+"Last-Translator: Kamil <kjaklukowski@gmail.com>\n"
+"Language-Team: \n"
+"Language: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#: models.py:11 models.py:33
+msgid "key"
+msgstr "Schlüssel"
+
+#: models.py:11
+msgid "A unique name for this chunk of content"
+msgstr "Die einzigartige Bezeichnung für dieses Chunk von Inhalten"
+
+#: models.py:12
+msgid "description"
+msgstr "Beschreibung"
+
+#: models.py:13
+msgid "content"
+msgstr "Inhalt"
+
+#: models.py:17
+msgid "chunk"
+msgstr "Chunk"
+
+#: models.py:18
+msgid "chunks"
+msgstr "Chunks"
+
+#: models.py:33
+msgid "A unique name for this attachment"
+msgstr "Die einzigartige Bezeichnung für diese Beilage"
+
+#: models.py:38
+msgid "attachment"
+msgstr "Beilage"
+
+#: models.py:38
+msgid "attachments"
+msgstr "Beilagen"
+
+#~ msgid "title"
+#~ msgstr "Titel"
+
+#~ msgid "slug"
+#~ msgstr "Slug"
+
+#~ msgid "file"
+#~ msgstr "Datei"
+
+#~ msgid "author"
+#~ msgstr "Autor"
+
+#~ msgid "slideshare ID"
+#~ msgstr "Dia-ID"
+
+#~ msgid "HTML"
+#~ msgstr "HTML"
+
+#~ msgid "document"
+#~ msgstr "Dokument"
diff --git a/src/chunks/locale/en/LC_MESSAGES/django.mo b/src/chunks/locale/en/LC_MESSAGES/django.mo
new file mode 100644 (file)
index 0000000..a81e430
Binary files /dev/null and b/src/chunks/locale/en/LC_MESSAGES/django.mo differ
diff --git a/src/chunks/locale/en/LC_MESSAGES/django.po b/src/chunks/locale/en/LC_MESSAGES/django.po
new file mode 100644 (file)
index 0000000..e81d48a
--- /dev/null
@@ -0,0 +1,53 @@
+# 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: 2012-07-19 11:39+0200\n"
+"PO-Revision-Date: 2012-03-04 20:05+0100\n"
+"Last-Translator: xxx <xxx>\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"
+
+#: models.py:11 models.py:33
+msgid "key"
+msgstr "key"
+
+#: models.py:11
+msgid "A unique name for this chunk of content"
+msgstr "A unique name for this piece of content"
+
+#: models.py:12
+msgid "description"
+msgstr "description"
+
+#: models.py:13
+msgid "content"
+msgstr "content"
+
+#: models.py:17
+msgid "chunk"
+msgstr "piece"
+
+#: models.py:18
+msgid "chunks"
+msgstr "pieces"
+
+#: models.py:33
+msgid "A unique name for this attachment"
+msgstr "A unique name for this attachment"
+
+#: models.py:38
+msgid "attachment"
+msgstr "attachment"
+
+#: models.py:38
+msgid "attachments"
+msgstr "attachments"
diff --git a/src/chunks/locale/es/LC_MESSAGES/django.mo b/src/chunks/locale/es/LC_MESSAGES/django.mo
new file mode 100644 (file)
index 0000000..83f03fb
Binary files /dev/null and b/src/chunks/locale/es/LC_MESSAGES/django.mo differ
diff --git a/src/chunks/locale/es/LC_MESSAGES/django.po b/src/chunks/locale/es/LC_MESSAGES/django.po
new file mode 100644 (file)
index 0000000..4130ea1
--- /dev/null
@@ -0,0 +1,53 @@
+# 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: 2012-07-19 11:39+0200\n"
+"PO-Revision-Date: 2012-02-18 13:02+0100\n"
+"Last-Translator: Anna Jopp <aniajopp@gmail.com>\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"
+
+#: models.py:11 models.py:33
+msgid "key"
+msgstr "clave"
+
+#: models.py:11
+msgid "A unique name for this chunk of content"
+msgstr "El nombre único para este elemento del contenido"
+
+#: models.py:12
+msgid "description"
+msgstr "descripción"
+
+#: models.py:13
+msgid "content"
+msgstr "contenido"
+
+#: models.py:17
+msgid "chunk"
+msgstr "elemento"
+
+#: models.py:18
+msgid "chunks"
+msgstr "elementos"
+
+#: models.py:33
+msgid "A unique name for this attachment"
+msgstr "El nombre único para este archivo adjunto"
+
+#: models.py:38
+msgid "attachment"
+msgstr "archivo adjunto"
+
+#: models.py:38
+msgid "attachments"
+msgstr "archivos adjuntos"
diff --git a/src/chunks/locale/fr/LC_MESSAGES/django.mo b/src/chunks/locale/fr/LC_MESSAGES/django.mo
new file mode 100644 (file)
index 0000000..1ef6af2
Binary files /dev/null and b/src/chunks/locale/fr/LC_MESSAGES/django.mo differ
diff --git a/src/chunks/locale/fr/LC_MESSAGES/django.po b/src/chunks/locale/fr/LC_MESSAGES/django.po
new file mode 100644 (file)
index 0000000..150a92c
--- /dev/null
@@ -0,0 +1,53 @@
+# 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: 2012-07-19 11:39+0200\n"
+"PO-Revision-Date: 2012-02-22 20:52+0100\n"
+"Last-Translator: Ela Janota <amarillis5@wp.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"
+
+#: models.py:11 models.py:33
+msgid "key"
+msgstr "clé"
+
+#: models.py:11
+msgid "A unique name for this chunk of content"
+msgstr "Un nom unique pour ce fragment du contenu"
+
+#: models.py:12
+msgid "description"
+msgstr "description"
+
+#: models.py:13
+msgid "content"
+msgstr "contenu"
+
+#: models.py:17
+msgid "chunk"
+msgstr "fragment"
+
+#: models.py:18
+msgid "chunks"
+msgstr "fragments"
+
+#: models.py:33
+msgid "A unique name for this attachment"
+msgstr "Un nom unique pour cette pièce jointe"
+
+#: models.py:38
+msgid "attachment"
+msgstr "pièce jointe"
+
+#: models.py:38
+msgid "attachments"
+msgstr "pièces jointes"
diff --git a/src/chunks/locale/it/LC_MESSAGES/django.mo b/src/chunks/locale/it/LC_MESSAGES/django.mo
new file mode 100644 (file)
index 0000000..a07410f
Binary files /dev/null and b/src/chunks/locale/it/LC_MESSAGES/django.mo differ
diff --git a/src/chunks/locale/it/LC_MESSAGES/django.po b/src/chunks/locale/it/LC_MESSAGES/django.po
new file mode 100644 (file)
index 0000000..4598d53
--- /dev/null
@@ -0,0 +1,54 @@
+# 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: 2012-07-19 11:39+0200\n"
+"PO-Revision-Date: 2012-02-21 16:52+0100\n"
+"Last-Translator: xxx\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=2; plural=(n != 1)\n"
+
+#: models.py:11 models.py:33
+msgid "key"
+msgstr "Chiave"
+
+#: models.py:11
+msgid "A unique name for this chunk of content"
+msgstr "un nome unico per questo allegato"
+
+#: models.py:12
+msgid "description"
+msgstr "descrizione"
+
+#: models.py:13
+msgid "content"
+msgstr "contenuto"
+
+#: models.py:17
+msgid "chunk"
+msgstr "blocco"
+
+#: models.py:18
+msgid "chunks"
+msgstr "blocchi"
+
+#: models.py:33
+msgid "A unique name for this attachment"
+msgstr "Un nome unico per questo allegato"
+
+#: models.py:38
+msgid "attachment"
+msgstr "allegato"
+
+#: models.py:38
+msgid "attachments"
+msgstr "allegati"
diff --git a/src/chunks/locale/jp/LC_MESSAGES/django.mo b/src/chunks/locale/jp/LC_MESSAGES/django.mo
new file mode 100644 (file)
index 0000000..ad2faa7
Binary files /dev/null and b/src/chunks/locale/jp/LC_MESSAGES/django.mo differ
diff --git a/src/chunks/locale/jp/LC_MESSAGES/django.po b/src/chunks/locale/jp/LC_MESSAGES/django.po
new file mode 100644 (file)
index 0000000..dcc303c
--- /dev/null
@@ -0,0 +1,54 @@
+# 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.
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: PACKAGE VERSION\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2012-07-19 11:39+0200\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: FULL NAME <EMAIL@ADDRESS>\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"
+
+#: models.py:11 models.py:33
+msgid "key"
+msgstr ""
+
+#: models.py:11
+msgid "A unique name for this chunk of content"
+msgstr ""
+
+#: models.py:12
+msgid "description"
+msgstr ""
+
+#: models.py:13
+msgid "content"
+msgstr ""
+
+#: models.py:17
+msgid "chunk"
+msgstr ""
+
+#: models.py:18
+msgid "chunks"
+msgstr ""
+
+#: models.py:33
+msgid "A unique name for this attachment"
+msgstr ""
+
+#: models.py:38
+msgid "attachment"
+msgstr ""
+
+#: models.py:38
+msgid "attachments"
+msgstr ""
diff --git a/src/chunks/locale/lt/LC_MESSAGES/django.mo b/src/chunks/locale/lt/LC_MESSAGES/django.mo
new file mode 100644 (file)
index 0000000..6131fd5
Binary files /dev/null and b/src/chunks/locale/lt/LC_MESSAGES/django.mo differ
diff --git a/src/chunks/locale/lt/LC_MESSAGES/django.po b/src/chunks/locale/lt/LC_MESSAGES/django.po
new file mode 100644 (file)
index 0000000..a78804a
--- /dev/null
@@ -0,0 +1,54 @@
+# 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: 2012-07-19 11:39+0200\n"
+"PO-Revision-Date: 2012-03-01 16:13+0100\n"
+"Last-Translator: Aneta\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"
+"X-Translated-Using: django-rosetta 0.5.3\n"
+
+#: models.py:11 models.py:33
+msgid "key"
+msgstr "raktas"
+
+#: models.py:11
+msgid "A unique name for this chunk of content"
+msgstr "Unikalus šio turinio gabalo pavadnimas"
+
+#: models.py:12
+msgid "description"
+msgstr "aprašymas"
+
+#: models.py:13
+msgid "content"
+msgstr "turinys"
+
+#: models.py:17
+msgid "chunk"
+msgstr "gabalas"
+
+#: models.py:18
+msgid "chunks"
+msgstr "gabalai"
+
+#: models.py:33
+msgid "A unique name for this attachment"
+msgstr "Unikalus šio priedo pavadnimas"
+
+#: models.py:38
+msgid "attachment"
+msgstr "priedas"
+
+#: models.py:38
+msgid "attachments"
+msgstr "priedai"
diff --git a/src/chunks/locale/pl/LC_MESSAGES/django.mo b/src/chunks/locale/pl/LC_MESSAGES/django.mo
new file mode 100644 (file)
index 0000000..a26b41c
Binary files /dev/null and b/src/chunks/locale/pl/LC_MESSAGES/django.mo differ
diff --git a/src/chunks/locale/pl/LC_MESSAGES/django.po b/src/chunks/locale/pl/LC_MESSAGES/django.po
new file mode 100644 (file)
index 0000000..c562232
--- /dev/null
@@ -0,0 +1,54 @@
+# 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: 2012-07-19 11:39+0200\n"
+"PO-Revision-Date: 2010-05-19 16:19\n"
+"Last-Translator: <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"
+"X-Translated-Using: django-rosetta 0.5.3\n"
+
+#: models.py:11 models.py:33
+msgid "key"
+msgstr "klucz"
+
+#: models.py:11
+msgid "A unique name for this chunk of content"
+msgstr "Unikalna nazwa dla tego kawałka treści"
+
+#: models.py:12
+msgid "description"
+msgstr "opis"
+
+#: models.py:13
+msgid "content"
+msgstr "zawartość"
+
+#: models.py:17
+msgid "chunk"
+msgstr "kawałek"
+
+#: models.py:18
+msgid "chunks"
+msgstr "kawałki"
+
+#: models.py:33
+msgid "A unique name for this attachment"
+msgstr "Unikalna nazwa dla tego załącznika"
+
+#: models.py:38
+msgid "attachment"
+msgstr "załącznik"
+
+#: models.py:38
+msgid "attachments"
+msgstr "załączniki"
diff --git a/src/chunks/locale/ru/LC_MESSAGES/django.mo b/src/chunks/locale/ru/LC_MESSAGES/django.mo
new file mode 100644 (file)
index 0000000..e1d650c
Binary files /dev/null and b/src/chunks/locale/ru/LC_MESSAGES/django.mo differ
diff --git a/src/chunks/locale/ru/LC_MESSAGES/django.po b/src/chunks/locale/ru/LC_MESSAGES/django.po
new file mode 100644 (file)
index 0000000..593521f
--- /dev/null
@@ -0,0 +1,53 @@
+# 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: 2012-07-19 11:39+0200\n"
+"PO-Revision-Date: 2012-03-04 22:10+0100\n"
+"Last-Translator: xxx <xxx>\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"
+
+#: models.py:11 models.py:33
+msgid "key"
+msgstr "ключ"
+
+#: models.py:11
+msgid "A unique name for this chunk of content"
+msgstr "Уникальное имя для этого фрагмента содержания"
+
+#: models.py:12
+msgid "description"
+msgstr "описание"
+
+#: models.py:13
+msgid "content"
+msgstr "содержание"
+
+#: models.py:17
+msgid "chunk"
+msgstr "фрагмент"
+
+#: models.py:18
+msgid "chunks"
+msgstr "фрагменты"
+
+#: models.py:33
+msgid "A unique name for this attachment"
+msgstr "Уникальное имя для этого приложения"
+
+#: models.py:38
+msgid "attachment"
+msgstr "приложение"
+
+#: models.py:38
+msgid "attachments"
+msgstr "приложения"
diff --git a/src/chunks/locale/uk/LC_MESSAGES/django.mo b/src/chunks/locale/uk/LC_MESSAGES/django.mo
new file mode 100644 (file)
index 0000000..7c5388e
Binary files /dev/null and b/src/chunks/locale/uk/LC_MESSAGES/django.mo differ
diff --git a/src/chunks/locale/uk/LC_MESSAGES/django.po b/src/chunks/locale/uk/LC_MESSAGES/django.po
new file mode 100644 (file)
index 0000000..edb9b06
--- /dev/null
@@ -0,0 +1,53 @@
+# 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: 2012-07-19 11:39+0200\n"
+"PO-Revision-Date: 2012-03-04 17:29+0100\n"
+"Last-Translator: xxx <xxx>\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"
+
+#: models.py:11 models.py:33
+msgid "key"
+msgstr "ключ"
+
+#: models.py:11
+msgid "A unique name for this chunk of content"
+msgstr "Унікальна назва для цієї частини змісту"
+
+#: models.py:12
+msgid "description"
+msgstr "опис"
+
+#: models.py:13
+msgid "content"
+msgstr "зміст"
+
+#: models.py:17
+msgid "chunk"
+msgstr "частина"
+
+#: models.py:18
+msgid "chunks"
+msgstr "частини"
+
+#: models.py:33
+msgid "A unique name for this attachment"
+msgstr "Унікальна назва для цього додатку"
+
+#: models.py:38
+msgid "attachment"
+msgstr "додаток"
+
+#: models.py:38
+msgid "attachments"
+msgstr "додатки"
diff --git a/src/chunks/models.py b/src/chunks/models.py
new file mode 100644 (file)
index 0000000..5cd007d
--- /dev/null
@@ -0,0 +1,43 @@
+# -*- coding: utf-8 -*-
+from django.core.cache import cache
+from django.db import models
+from django.utils.translation import ugettext_lazy as _
+
+
+class Chunk(models.Model):
+    """
+    A Chunk is a piece of content associated with a unique key that can be inserted into
+    any template with the use of a special template tag.
+    """
+    key = models.CharField(
+        _('key'), help_text=_('A unique name for this chunk of content'), primary_key=True, max_length=255)
+    description = models.CharField(_('description'), blank=True, max_length=255)
+    content = models.TextField(_('content'), blank=True)
+
+    class Meta:
+        ordering = ('key',)
+        verbose_name = _('chunk')
+        verbose_name_plural = _('chunks')
+
+    def __unicode__(self):
+        return self.key
+
+    def cache_key(self):
+        return 'chunk_' + self.key
+
+    def save(self, *args, **kwargs):
+        ret = super(Chunk, self).save(*args, **kwargs)
+        cache.delete(self.cache_key())
+        return ret
+
+
+class Attachment(models.Model):
+    key = models.CharField(_('key'), help_text=_('A unique name for this attachment'), primary_key=True, max_length=255)
+    attachment = models.FileField(upload_to='chunks/attachment')
+
+    class Meta:
+        ordering = ('key',)
+        verbose_name, verbose_name_plural = _('attachment'), _('attachments')
+
+    def __unicode__(self):
+        return self.key
diff --git a/src/chunks/templatetags/__init__.py b/src/chunks/templatetags/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/src/chunks/templatetags/chunks.py b/src/chunks/templatetags/chunks.py
new file mode 100644 (file)
index 0000000..968d284
--- /dev/null
@@ -0,0 +1,36 @@
+# -*- coding: utf-8 -*-
+from django import template
+from django.core.cache import cache
+from ..models import Chunk, Attachment
+
+
+register = template.Library()
+
+
+@register.simple_tag
+def chunk(key, cache_time=0):
+    try:
+        cache_key = 'chunk_' + key
+        c = cache.get(cache_key)
+        if c is None:
+            c = Chunk.objects.get(key=key)
+            cache.set(cache_key, c, int(cache_time))
+        content = c.content
+    except Chunk.DoesNotExist:
+        n = Chunk(key=key)
+        n.save()
+        return ''
+    return content
+
+
+@register.simple_tag
+def attachment(key, cache_time=0):
+    try:
+        cache_key = 'attachment_' + key
+        c = cache.get(cache_key)
+        if c is None:
+            c = Attachment.objects.get(key=key)
+            cache.set(cache_key, c, int(cache_time))
+        return c.attachment.url
+    except Attachment.DoesNotExist:
+        return ''
diff --git a/src/comment/__init__.py b/src/comment/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/src/comment/admin.py b/src/comment/admin.py
new file mode 100644 (file)
index 0000000..7c9ce9a
--- /dev/null
@@ -0,0 +1,10 @@
+# -*- coding: utf-8 -*-
+from django.contrib import admin
+
+from .models import CommentDocument
+
+
+class CommentDocumentAdmin(admin.ModelAdmin):
+    prepopulated_fields = {"slug": ("name",)}
+
+admin.site.register(CommentDocument, CommentDocumentAdmin)
diff --git a/src/comment/locale/pl/LC_MESSAGES/django.mo b/src/comment/locale/pl/LC_MESSAGES/django.mo
new file mode 100644 (file)
index 0000000..b3595bd
Binary files /dev/null and b/src/comment/locale/pl/LC_MESSAGES/django.mo differ
diff --git a/src/comment/locale/pl/LC_MESSAGES/django.po b/src/comment/locale/pl/LC_MESSAGES/django.po
new file mode 100644 (file)
index 0000000..94594a8
--- /dev/null
@@ -0,0 +1,84 @@
+# 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.
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: PACKAGE VERSION\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2013-12-05 09:48+0100\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: FULL NAME <EMAIL@ADDRESS>\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"
+
+#: templates/comment/commentdocument_list.html:7
+#, python-format
+msgid ""
+"\n"
+"    Take part in the consultation by filling in <a href=\"%(form_href)s"
+"\">the form</a> or comment on specific competencies in different thematic "
+"fields\n"
+"    "
+msgstr ""
+"\n"
+" Weź udział w konsultacjach wypełniając <a href=\"%(form_href)s\">ten "
+"formularz</a> lub skomentuj szczegółowo kompetencje w poszczególnych "
+"obszarach tematycznych\n"
+"    "
+
+#: templates/comment/commentdocument_list.html:17
+msgid ""
+"\n"
+"        <p>To insert comments in a selected thematic field you need to "
+"register.</p>\n"
+"\n"
+"        <p>How to do it?</p>\n"
+"        <ol>\n"
+"            <li>Click on a selected link from the list of the thematic "
+"fields.</li>\n"
+"            <li>Choose \"Register\" option.</li>\n"
+"            <li>Enter your data.</li>\n"
+"            <li>Check your email for the message confirming the registration "
+"and click on the link included.</li>\n"
+"            <li>Enter your username and password.</li>\n"
+"            <li>Go back to the consultation page. Choose one of the fields, "
+"log in and share your comments.</li>\n"
+"        </ol>\n"
+"\n"
+"        <p>How to add a comment?</p>\n"
+"        <ol>\n"
+"            <li>Highlight a fragment of the text.</li>\n"
+"            <li>Click on a yellow \"comment\" button on the left.</li>\n"
+"            <li>Type in a subject and content of your comment.</li>\n"
+"            <li>Save your comment.</li>\n"
+"        </ol>\n"
+"    "
+msgstr ""
+"\n"
+"        <p>Aby wprowadzić szczegółowe komentarze w poszczególnych obszarach tematycznych konieczna jest rejestracja.</p>"
+"        <p>Jak to zrobić?</p>"
+"        <ol>"
+"            <li>Kliknij w dowolny link z listy obszarów tematycznych.</li>"
+"            <li>Wybierz opcję \"Register\" (Zarejestruj się).</li>"
+"            <li>Wprowadź swoje dane (adres e-mail, imię, nazwisko). Kliknij zielony przycisk \"Register\".</li>"
+"            <li>Na Twoje konto e-mail zostanie wysłana wiadomość potwierdzająca rejestrację. Kliknij w podany w niej link, aby aktywować swoje konto.</li>"
+"            <li>Wprowadź nazwę użytkownika i hasło. Potwierdź zielonym przyciskiem.</li>"
+"            <li>Wejdź ponownie na stronę http://katalog.edukacjamedialna.edu.pl/wez-udzial/. Wybierz interesujący Cię obszar tematyczny, zaloguj się i podziel się swoimi uwagami.</li>"
+"        </ol>"
+"        "
+"        <p>Jak dodać komentarz?</p>"
+"        <ol>"
+"            <li>Zaznacz dowolny fragment tekstu.</li>"
+"            <li>Wciśnij żółty przycisk \"comment\" po lewej stronie.</li>"
+"            <li>W polu \"subject\" wpisz temat uwagi, a w polu \"content\" jej treść.</li>"
+"            <li>Zapisz swój komentarz przyciskiem \"save\".</li>"
+"        </ol>"
+"    "
\ No newline at end of file
diff --git a/src/comment/migrations/0001_initial.py b/src/comment/migrations/0001_initial.py
new file mode 100644 (file)
index 0000000..9bf33a5
--- /dev/null
@@ -0,0 +1,38 @@
+# -*- coding: utf-8 -*-
+import datetime
+from south.db import db
+from south.v2 import SchemaMigration
+from django.db import models
+
+
+class Migration(SchemaMigration):
+
+    def forwards(self, orm):
+        # Adding model 'CommentDocument'
+        db.create_table(u'comment_commentdocument', (
+            (u'id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
+            ('name', self.gf('django.db.models.fields.CharField')(unique=True, max_length=255)),
+            ('slug', self.gf('django.db.models.fields.SlugField')(unique=True, max_length=255)),
+            ('comment_id', self.gf('django.db.models.fields.CharField')(unique=True, max_length=255)),
+            ('order', self.gf('django.db.models.fields.IntegerField')()),
+        ))
+        db.send_create_signal(u'comment', ['CommentDocument'])
+
+
+    def backwards(self, orm):
+        # Deleting model 'CommentDocument'
+        db.delete_table(u'comment_commentdocument')
+
+
+    models = {
+        u'comment.commentdocument': {
+            'Meta': {'ordering': "['order']", 'object_name': 'CommentDocument'},
+            'comment_id': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'}),
+            'order': ('django.db.models.fields.IntegerField', [], {}),
+            'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '255'})
+        }
+    }
+
+    complete_apps = ['comment']
\ No newline at end of file
diff --git a/src/comment/migrations/0002_auto__add_field_commentdocument_language_code.py b/src/comment/migrations/0002_auto__add_field_commentdocument_language_code.py
new file mode 100644 (file)
index 0000000..686f568
--- /dev/null
@@ -0,0 +1,34 @@
+# -*- coding: utf-8 -*-
+import datetime
+from south.db import db
+from south.v2 import SchemaMigration
+from django.db import models
+
+
+class Migration(SchemaMigration):
+
+    def forwards(self, orm):
+        # Adding field 'CommentDocument.language_code'
+        db.add_column(u'comment_commentdocument', 'language_code',
+                      self.gf('django.db.models.fields.CharField')(default='pl', max_length=2),
+                      keep_default=False)
+
+
+    def backwards(self, orm):
+        # Deleting field 'CommentDocument.language_code'
+        db.delete_column(u'comment_commentdocument', 'language_code')
+
+
+    models = {
+        u'comment.commentdocument': {
+            'Meta': {'ordering': "['order']", 'object_name': 'CommentDocument'},
+            'comment_id': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'language_code': ('django.db.models.fields.CharField', [], {'default': "'pl'", 'max_length': '2'}),
+            'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'}),
+            'order': ('django.db.models.fields.IntegerField', [], {}),
+            'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '255'})
+        }
+    }
+
+    complete_apps = ['comment']
\ No newline at end of file
diff --git a/src/comment/migrations/__init__.py b/src/comment/migrations/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/src/comment/models.py b/src/comment/models.py
new file mode 100644 (file)
index 0000000..38c43d1
--- /dev/null
@@ -0,0 +1,20 @@
+# -*- coding: utf-8 -*-
+from django.db import models
+from django.core.urlresolvers import reverse
+
+
+class CommentDocument(models.Model):
+    name = models.CharField(max_length=255, unique=True)
+    slug = models.SlugField(max_length=255, unique=True)
+    comment_id = models.CharField(max_length=255, unique=True)
+    order = models.IntegerField()
+    language_code = models.CharField(max_length=2, default='pl')
+
+    class Meta:
+        ordering = ['order']
+
+    def __unicode__(self):
+        return self.name
+
+    def get_absolute_url(self):
+        return reverse('comment_document', kwargs={'slug': self.slug})
diff --git a/src/comment/templates/comment/commentdocument_detail.html b/src/comment/templates/comment/commentdocument_detail.html
new file mode 100644 (file)
index 0000000..2ab214b
--- /dev/null
@@ -0,0 +1,9 @@
+{% extends "base_mil.html" %}
+
+{% block body %}
+
+    <h1>{{object.name}}</h1>
+
+    <iframe  frameborder="0" src="{{comment_url}}/text/{{object.comment_id}}/comments_frame/?" style="height: 600px; width: 99.9%; position: relative; top: 0px;"></iframe>
+
+{% endblock %}
\ No newline at end of file
diff --git a/src/comment/templates/comment/commentdocument_list.html b/src/comment/templates/comment/commentdocument_list.html
new file mode 100644 (file)
index 0000000..0a13f63
--- /dev/null
@@ -0,0 +1,39 @@
+{% extends "base_mil.html" %}
+{% load i18n %}
+
+
+{% block body %}
+
+    <p>{% blocktrans with href=form_href %}
+    Take part in the consultation by filling in <a href="{{form_href}}">the form</a> or comment on specific competencies in different thematic fields
+    {% endblocktrans %}:</p>
+
+    <ol>
+    {% for document in object_list %}
+        <li><a href="{{document.get_absolute_url}}">{{document.name}}</a></li>
+    {% endfor %}
+    </ol>
+
+    {% blocktrans %}
+        <p>To insert comments in a selected thematic field you need to register.</p>
+
+        <p>How to do it?</p>
+        <ol>
+            <li>Click on a selected link from the list of the thematic fields.</li>
+            <li>Choose "Register" option.</li>
+            <li>Enter your data.</li>
+            <li>Check your email for the message confirming the registration and click on the link included.</li>
+            <li>Enter your username and password.</li>
+            <li>Go back to the consultation page. Choose one of the fields, log in and share your comments.</li>
+        </ol>
+
+        <p>How to add a comment?</p>
+        <ol>
+            <li>Highlight a fragment of the text.</li>
+            <li>Click on a yellow "comment" button on the left.</li>
+            <li>Type in a subject and content of your comment.</li>
+            <li>Save your comment.</li>
+        </ol>
+    {% endblocktrans %}
+
+{% endblock %}
\ No newline at end of file
diff --git a/src/comment/urls.py b/src/comment/urls.py
new file mode 100644 (file)
index 0000000..ef48089
--- /dev/null
@@ -0,0 +1,11 @@
+# -*- coding: utf-8 -*-
+from django.conf.urls import patterns, url
+
+from .views import CommentDocumentList, CommentDocument
+
+
+urlpatterns = patterns(
+    '',
+    url('^$', CommentDocumentList.as_view(), name='comment_document_index'),
+    url('^(?P<slug>[^/]+)/$', CommentDocument.as_view(), name='comment_document')
+)
diff --git a/src/comment/views.py b/src/comment/views.py
new file mode 100644 (file)
index 0000000..40db4b0
--- /dev/null
@@ -0,0 +1,29 @@
+# -*- coding: utf-8 -*-
+from django.views.generic import ListView, DetailView
+from django.conf import settings
+from django.utils.translation import get_language
+
+from django.core.urlresolvers import reverse
+
+from .models import CommentDocument as CommentDocumentModel
+
+
+class CommentDocumentList(ListView):
+    model = CommentDocumentModel
+
+    def get_queryset(self):
+        return super(CommentDocumentList, self).get_queryset().filter(language_code=get_language())
+
+    def get_context_data(self, **kwargs):
+        context = super(CommentDocumentList, self).get_context_data(**kwargs)
+        context['form_href'] = reverse('contact_form', kwargs={'form_tag': 'mil'})
+        return context
+
+
+class CommentDocument(DetailView):
+    model = CommentDocumentModel
+
+    def get_context_data(self, **kwargs):
+        context = super(CommentDocument, self).get_context_data(**kwargs)
+        context['comment_url'] = settings.COMMENT_URL
+        return context
\ No newline at end of file
diff --git a/src/contact/__init__.py b/src/contact/__init__.py
new file mode 100644 (file)
index 0000000..3bce2e3
--- /dev/null
@@ -0,0 +1,53 @@
+# -*- coding: utf-8 -*-
+"""
+Generic app for creating contact forms.
+
+0. Add 'contact' to your INSTALLED_APPS and include 'contact.urls' somewhere
+in your urls.py, like: 
+    url(r'^contact/', 
+        include('contact.urls'))
+
+1. Migrate.
+
+2. Create somewhere in your project a module with some subclasses of
+contact.forms.ContactForm, specyfing form_tag and some fields in each.
+
+3. Set CONTACT_FORMS_MODULE in your settings to point to the module.
+
+4. Link to the form with {% url 'contact_form' form_tag %}.
+
+5. Optionally override some templates in form-specific template directories
+(/contact/<form_tag>/...).
+
+6. Receive submitted forms by email and read them in admin.
+
+
+Example:
+========
+
+settings.py:
+    CONTACT_FORMS_MODULE = 'myproject.contact_forms'
+
+myproject/contact_forms.py:
+    from django import forms
+    from contact.forms import ContactForm
+    from django.utils.translation import ugettext_lazy as _
+
+    class RegistrationForm(ContactForm):
+        form_tag = 'register'
+        name = forms.CharField(label=_('Name'), max_length=128)
+        presentation = forms.FileField(label=_('Presentation'))
+
+some_template.html:
+    {% url 'contact:form' 'register' %}
+
+"""
+
+from fnpdjango.utils.app import AppSettings
+
+
+class Settings(AppSettings):
+    FORMS_MODULE = "contact_forms"
+
+
+app_settings = Settings('CONTACT')
diff --git a/src/contact/admin.py b/src/contact/admin.py
new file mode 100644 (file)
index 0000000..22d3593
--- /dev/null
@@ -0,0 +1,177 @@
+# -*- coding: utf-8 -*-
+import csv
+import json
+
+from django.contrib import admin
+from django.utils.translation import ugettext as _
+from django.utils.safestring import mark_safe
+from django.conf.urls import patterns, url
+from django.http import HttpResponse, Http404
+
+from edumed.utils import UnicodeCSVWriter
+from .forms import contact_forms, admin_list_width
+from .models import Contact
+
+
+class ContactAdminMeta(admin.ModelAdmin.__class__):
+    def __getattr__(cls, name):
+        if name.startswith('admin_list_'):
+            return lambda self: ""
+        raise AttributeError(name)
+
+
+class ContactAdmin(admin.ModelAdmin):
+    __metaclass__ = ContactAdminMeta
+    date_hierarchy = 'created_at'
+    list_display = ['created_at', 'contact', 'form_tag'] + \
+        ["admin_list_%d" % i for i in range(admin_list_width)]
+    fields = ['form_tag', 'created_at', 'contact', 'ip']
+    readonly_fields = ['form_tag', 'created_at', 'contact', 'ip']
+    list_filter = ['form_tag']
+
+    @staticmethod
+    def admin_list(obj, nr):
+        try:
+            field_name = contact_forms[obj.form_tag].admin_list[nr]
+        except BaseException:
+            return ''
+        else:
+            return Contact.pretty_print(obj.body.get(field_name, ''), for_html=True)
+
+    def __getattr__(self, name):
+        if name.startswith('admin_list_'):
+            nr = int(name[len('admin_list_'):])
+            return lambda obj: self.admin_list(obj, nr)
+        raise AttributeError(name)
+
+    def change_view(self, request, object_id, form_url='', extra_context=None):
+        if object_id:
+            try:
+                instance = Contact.objects.get(pk=object_id)
+                assert isinstance(instance.body, dict)
+            except (Contact.DoesNotExist, AssertionError):
+                pass
+            else:
+                # Create readonly fields from the body JSON.
+                attachments = list(instance.attachment_set.all())
+                body_keys = instance.body.keys() + [a.tag for a in attachments]
+
+                # Find the original form.
+                try:
+                    orig_fields = contact_forms[instance.form_tag]().fields
+                except KeyError:
+                    orig_fields = {}
+
+                # Try to preserve the original order.
+                orig_keys = list(orig_fields.keys())
+                admin_keys = [key for key in orig_keys if key in body_keys] + \
+                             [key for key in body_keys if key not in orig_keys]
+                admin_fields = ['body__%s' % key for key in admin_keys]
+
+                self.readonly_fields.extend(admin_fields)
+
+                self.fieldsets = [
+                    (None, {'fields': self.fields}),
+                    (_('Body'), {'fields': admin_fields}),
+                ]
+
+                # Create field getters for fields and attachments.
+                def attach_getter(key, value):
+                    def f(self):
+                        return value
+                    f.short_description = orig_fields[key].label if key in orig_fields else _(key)
+                    setattr(self, "body__%s" % key, f)
+
+                for k, v in instance.body.items():
+                    attach_getter(k, Contact.pretty_print(v, for_html=True))
+
+                download_link = "<a href='%(url)s'>%(url)s</a>"
+                for attachment in attachments:
+                    link = mark_safe(download_link % {
+                            'url': attachment.get_absolute_url()})
+                    attach_getter(attachment.tag, link)
+        return super(ContactAdmin, self).change_view(
+            request, object_id, form_url=form_url, extra_context=extra_context)
+
+    def changelist_view(self, request, extra_context=None):
+        context = dict()
+        if 'form_tag' in request.GET:
+            form = contact_forms.get(request.GET['form_tag'])
+            context['extract_types'] = [
+                {'slug': 'all', 'label': _('all')},
+                {'slug': 'contacts', 'label': _('contacts')}]
+            context['extract_types'] += [type for type in getattr(form, 'extract_types', [])]
+        return super(ContactAdmin, self).changelist_view(request, extra_context=context)
+
+    def get_urls(self):
+        # urls = super(ContactAdmin, self).get_urls()
+        return patterns(
+            '',
+            url(r'^extract/(?P<form_tag>[\w-]+)/(?P<extract_type_slug>[\w-]+)/$',
+                self.admin_site.admin_view(extract_view), name='contact_extract')
+        ) + super(ContactAdmin, self).get_urls()
+
+
+def extract_view(request, form_tag, extract_type_slug):
+    contacts_by_spec = dict()
+    form = contact_forms.get(form_tag)
+    if form is None and extract_type_slug not in ('contacts', 'all'):
+        raise Http404
+
+    q = Contact.objects.filter(form_tag=form_tag)
+    at_year = request.GET.get('created_at__year')
+    at_month = request.GET.get('created_at__month')
+    if at_year:
+        q = q.filter(created_at__year=at_year)
+        if at_month:
+            q = q.filter(created_at__month=at_month)
+
+    # Segregate contacts by body key sets
+    if form:
+        orig_keys = list(form().fields.keys())
+    else:
+        orig_keys = []
+    for contact in q.all():
+        if extract_type_slug == 'contacts':
+            keys = ['contact']
+        elif extract_type_slug == 'all':
+            keys = contact.body.keys() + ['contact']
+            keys = [key for key in orig_keys if key in keys] + [key for key in keys if key not in orig_keys]
+        else:
+            keys = form.get_extract_fields(contact, extract_type_slug)
+        contacts_by_spec.setdefault(tuple(keys), []).append(contact)
+
+    response = HttpResponse(content_type='text/csv')
+    csv_writer = UnicodeCSVWriter(response)
+
+    # Generate list for each body key set
+    for keys, contacts in contacts_by_spec.items():
+        csv_writer.writerow(keys)
+        for contact in contacts:
+            if extract_type_slug == 'contacts':
+                records = [dict(contact=contact.contact)]
+            elif extract_type_slug == 'all':
+                records = [dict(contact=contact.contact, **contact.body)]
+            else:
+                records = form.get_extract_records(keys, contact, extract_type_slug)
+
+            for record in records:
+                for key in keys:
+                    if key not in record:
+                        record[key] = ''
+                    if isinstance(record[key], basestring):
+                        pass
+                    elif isinstance(record[key], bool):
+                        record[key] = 'tak' if record[key] else 'nie'
+                    elif isinstance(record[key], (list, tuple)) and all(isinstance(v, basestring) for v in record[key]):
+                        record[key] = ', '.join(record[key])
+                    else:
+                        record[key] = json.dumps(record[key])
+
+                csv_writer.writerow([record[key] for key in keys])
+        csv_writer.writerow([])
+
+    response['Content-Disposition'] = 'attachment; filename="kontakt.csv"'
+    return response
+
+admin.site.register(Contact, ContactAdmin)
diff --git a/src/contact/fields.py b/src/contact/fields.py
new file mode 100644 (file)
index 0000000..67fc71b
--- /dev/null
@@ -0,0 +1,10 @@
+# -*- coding: utf-8 -*-
+from django import forms
+from .widgets import HeaderWidget
+
+
+class HeaderField(forms.CharField):
+    def __init__(self, required=False, widget=None, *args, **kwargs):
+        if widget is None:
+            widget = HeaderWidget
+        super(HeaderField, self).__init__(required=required, widget=widget, *args, **kwargs)
diff --git a/src/contact/forms.py b/src/contact/forms.py
new file mode 100644 (file)
index 0000000..059f9e8
--- /dev/null
@@ -0,0 +1,192 @@
+# -*- coding: utf-8 -*-
+import os
+
+from django.contrib.sites.models import Site
+from django.core.exceptions import ValidationError
+from django.core.files.uploadedfile import UploadedFile
+from django.core.mail import send_mail, mail_managers
+from django.core.validators import validate_email
+from django import forms
+from django.db.models.fields.files import FieldFile
+from django.template.loader import render_to_string
+from django.template import RequestContext
+from django.utils.translation import ugettext_lazy as _
+
+from . import mailing
+
+
+contact_forms = {}
+update_forms = {}
+admin_list_width = 0
+
+
+class ContactFormMeta(forms.Form.__class__):
+    def __new__(cls, name, bases, attrs):
+        global admin_list_width
+        model = super(ContactFormMeta, cls).__new__(cls, name, bases, attrs)
+        if model.form_tag:
+            if model.form_type == 'create':
+                assert model.form_tag not in contact_forms, 'Duplicate form_tag.'
+                if model.admin_list:
+                    admin_list_width = max(admin_list_width, len(model.admin_list))
+                contact_forms[model.form_tag] = model
+            elif model.form_type == 'update':
+                assert model.form_tag not in update_forms, 'Duplicate form_tag.'
+                update_forms[model.form_tag] = model
+        return model
+
+
+class ContactForm(forms.Form):
+    """Subclass and define some fields."""
+    __metaclass__ = ContactFormMeta
+
+    form_tag = None
+    form_type = 'create'
+    updatable = False
+    old_form_tags = []
+    form_title = _('Contact form')
+    submit_label = _('Submit')
+    admin_list = None
+    result_page = False
+    mailing_field = None
+    mailing = False
+    data_processing = None
+    form_formsets = {}
+
+    disabled = False
+    disabled_template = None
+
+    required_css_class = 'required'
+    contact = NotImplemented
+
+    def __init__(self, data=None, files=None, *args, **kwargs):
+        self.instance = kwargs.pop('instance', None)
+        if self.instance and (data is not None or files is not None):
+            for attachment in self.instance.attachment_set.all():
+                if attachment.tag not in files:
+                    files[attachment.tag] = attachment.file
+        super(ContactForm, self).__init__(data, files, *args, **kwargs)
+        if not self.is_bound and self.instance:
+            self.fields['contact'].initial = self.instance.contact
+            self.fields['contact'].widget = forms.HiddenInput()
+            body = self.instance.body
+            for field, value in body.iteritems():
+                if field in self.fields:
+                    self.fields[field].initial = value
+            for attachment in self.instance.attachment_set.all():
+                self.fields[attachment.tag].initial = attachment
+
+    def get_dictionary(self, contact):
+        site = Site.objects.get_current()
+        return {
+            'form_tag': self.form_tag,
+            'site_name': getattr(self, 'site_name', site.name),
+            'site_domain': getattr(self, 'site_domain', site.domain),
+            'contact': contact,
+        }
+
+    @classmethod
+    def is_disabled(cls):
+        # end_time = localtime_to_utc(datetime(*cls.ends_on)) if cls.ends_on else None
+        # expired = end_time and end_time < timezone.now()
+        return cls.disabled  # or expired
+
+    def formset_initial(self, prefix):
+        if not self.instance:
+            return None
+        return self.instance.body.get(prefix)
+
+    def get_formsets(self, request=None):
+        request_data = {'data': request.POST, 'files': request.FILES} if request else {}
+        kwargs_instance = dict(request_data)
+        kwargs_instance['instance'] = self.instance
+        formsets = {}
+        for prefix, formset_class in self.form_formsets.iteritems():
+            if getattr(formset_class, 'takes_instance', False):
+                kwargs = kwargs_instance
+            else:
+                kwargs = request_data
+            formsets[prefix] = formset_class(
+                prefix=prefix, initial=self.formset_initial(prefix), **kwargs)
+        return formsets
+
+    def save(self, request, formsets=None):
+        from .models import Attachment, Contact
+        body = {}
+        for name, value in self.cleaned_data.items():
+            if not isinstance(value, UploadedFile) and not isinstance(value, FieldFile) and name != 'contact':
+                body[name] = value
+
+        for formset in formsets or []:
+            for f in formset.forms:
+                sub_body = {}
+                for name, value in f.cleaned_data.items():
+                    if not isinstance(value, UploadedFile):
+                        sub_body[name] = value
+                if sub_body:
+                    body.setdefault(f.form_tag, []).append(sub_body)
+
+        if self.instance:
+            contact = self.instance
+            contact.body = body
+            email_changed = contact.contact != self.cleaned_data['contact']
+            contact.contact = self.cleaned_data['contact']
+            assert contact.form_tag == self.form_tag
+            contact.save()
+        else:
+            contact = Contact.objects.create(
+                body=body,
+                ip=request.META['REMOTE_ADDR'],
+                contact=self.cleaned_data['contact'],
+                form_tag=self.form_tag)
+            contact.generate_key()
+            email_changed = True
+        for name, value in self.cleaned_data.items():
+            if isinstance(value, UploadedFile):
+                for attachment in Attachment.objects.filter(contact=contact, tag=name):
+                    os.remove(attachment.file.path)
+                    attachment.delete()
+                attachment = Attachment(contact=contact, tag=name)
+                attachment.file.save(value.name, value)
+                attachment.save()
+
+        site = Site.objects.get_current()
+        dictionary = self.get_dictionary(contact)
+        context = RequestContext(request)
+        mail_managers_subject = render_to_string([
+                'contact/%s/mail_managers_subject.txt' % self.form_tag,
+                'contact/mail_managers_subject.txt', 
+            ], dictionary, context).strip()
+        mail_managers_body = render_to_string([
+                'contact/%s/mail_managers_body.txt' % self.form_tag,
+                'contact/mail_managers_body.txt', 
+            ], dictionary, context)
+        mail_managers(mail_managers_subject, mail_managers_body, fail_silently=True)
+
+        try:
+            validate_email(contact.contact)
+        except ValidationError:
+            pass
+        else:
+            if not self.instance:
+                mail_subject = render_to_string([
+                        'contact/%s/mail_subject.txt' % self.form_tag,
+                        'contact/mail_subject.txt',
+                    ], dictionary, context).strip()
+                if self.result_page:
+                    mail_body = render_to_string(
+                        'contact/%s/results_email.txt' % contact.form_tag,
+                        {
+                            'contact': contact,
+                            'results': self.results(contact),
+                        }, context)
+                else:
+                    mail_body = render_to_string([
+                            'contact/%s/mail_body.txt' % self.form_tag,
+                            'contact/mail_body.txt',
+                        ], dictionary, context)
+                send_mail(mail_subject, mail_body, 'no-reply@%s' % site.domain, [contact.contact], fail_silently=True)
+            if email_changed and (self.mailing or (self.mailing_field and self.cleaned_data[self.mailing_field])):
+                mailing.subscribe(contact.contact)
+
+        return contact
diff --git a/src/contact/locale/pl/LC_MESSAGES/django.mo b/src/contact/locale/pl/LC_MESSAGES/django.mo
new file mode 100644 (file)
index 0000000..ef06814
Binary files /dev/null and b/src/contact/locale/pl/LC_MESSAGES/django.mo differ
diff --git a/src/contact/locale/pl/LC_MESSAGES/django.po b/src/contact/locale/pl/LC_MESSAGES/django.po
new file mode 100644 (file)
index 0000000..cabbe00
--- /dev/null
@@ -0,0 +1,92 @@
+# 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: 2013-11-05 10:16+0100\n"
+"PO-Revision-Date: 2012-10-10 13:12+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"
+
+#: admin.py:77
+msgid "Body"
+msgstr "Treść"
+
+#: admin.py:101
+msgid "all"
+msgstr "wszystko"
+
+#: admin.py:101
+msgid "contacts"
+msgstr "kontakty"
+
+#: forms.py:29
+msgid "Contact form"
+msgstr "Formularz kontaktowy"
+
+#: forms.py:30
+msgid "Submit"
+msgstr "Wyślij"
+
+#: models.py:11
+msgid "submission date"
+msgstr "data wysłania"
+
+#: models.py:12
+msgid "IP address"
+msgstr "adres IP"
+
+#: models.py:13
+msgid "contact"
+msgstr "kontakt"
+
+#: models.py:14
+msgid "form"
+msgstr "formularz"
+
+#: models.py:15
+msgid "body"
+msgstr "treść"
+
+#: models.py:29
+msgid "submitted form"
+msgstr "przysłany formularz"
+
+#: models.py:30
+msgid "submitted forms"
+msgstr "przysłane formularze"
+
+#: templates/admin/contact/contact/change_list.html:12
+msgid "Extract"
+msgstr "Ekstrakt"
+
+#: templates/contact/mail_body.txt:2 templates/contact/mail_subject.txt:1
+#, python-format
+msgid "Thank you for contacting us at %(site_name)s."
+msgstr "Dziękujemy za skontaktowanie się z nami na stronie %(site_name)s."
+
+#: templates/contact/mail_body.txt:3
+msgid "Your submission has been referred to the project coordinator."
+msgstr "Twoje zgłoszenie zostało przekazane osobie koordynującej projekt."
+
+#: templates/contact/mail_body.txt:6
+msgid "Message sent automatically. Please do not reply to it."
+msgstr "Wiadomość wysłana automatycznie, prosimy nie odpowiadać."
+
+#: templates/contact/thanks.html:4 templates/contact/thanks.html.py:8
+msgid "Thank you"
+msgstr "Dziękujemy"
+
+#: templates/contact/thanks.html:11
+msgid "Thank you for submitting the form."
+msgstr "Dziękujemy za wypełnienie formularza."
diff --git a/src/contact/mailing.py b/src/contact/mailing.py
new file mode 100644 (file)
index 0000000..bfd4209
--- /dev/null
@@ -0,0 +1,52 @@
+# -*- coding: utf-8 -*-
+
+from hashlib import md5
+
+import requests
+from django.conf import settings
+from mailchimp3 import MailChimp
+from mailchimp3.mailchimpclient import MailChimpError
+
+INTERESTS = {settings.MAILCHIMP_GROUP_ID: True}
+
+
+def get_client():
+    headers = requests.utils.default_headers()
+    headers['User-Agent'] = '%s (%s)' % settings.MANAGERS[0]
+
+
+def subscriber_hash(email):
+    return md5(email).hexdigest()
+
+
+def remove_from_groups(email, client):
+    group_ids = []
+    categories = client.lists.interest_categories.all(list_id=settings.MAILCHIMP_LIST_ID)['categories']
+    for category in categories:
+        groups = client.lists.interest_categories.interests.all(
+            list_id=settings.MAILCHIMP_LIST_ID, category_id=category['id'])['interests']
+        group_ids += [group['id'] for group in groups]
+    interests = {group_id: False for group_id in group_ids}
+    client.lists.members.update(
+         settings.MAILCHIMP_LIST_ID, subscriber_hash(email),
+         data={'interests': interests})
+
+
+def subscribe(email):
+    client = MailChimp(mc_api=settings.MAILCHIMP_API_KEY, timeout=10.0)
+    try:
+        member = client.lists.members.get(settings.MAILCHIMP_LIST_ID, subscriber_hash(email))
+    except MailChimpError:
+        pass
+    else:
+        if member['status'] != 'subscribed':
+            remove_from_groups(email, client)
+    client.lists.members.create_or_update(
+        settings.MAILCHIMP_LIST_ID, subscriber_hash(email),
+        data={
+            'email_address': email,
+            'status_if_new': 'subscribed',
+            'status': 'subscribed',
+            'interests': INTERESTS,
+        }
+    )
diff --git a/src/contact/management/__init__.py b/src/contact/management/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/src/contact/management/commands/__init__.py b/src/contact/management/commands/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/src/contact/management/commands/export_newsletter.py b/src/contact/management/commands/export_newsletter.py
new file mode 100644 (file)
index 0000000..70ef2b4
--- /dev/null
@@ -0,0 +1,34 @@
+# -*- coding: utf-8 -*-
+# This file is part of EduMed, licensed under GNU Affero GPLv3 or later.
+# Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
+#
+from django.core.management.base import BaseCommand
+
+from contact.models import Contact
+from edumed import contact_forms
+
+FORMS = (
+    contact_forms.CooperateForm,
+    contact_forms.ContestForm,
+    contact_forms.WTEMForm,
+    contact_forms.TEMForm,
+    contact_forms.CybernauciForm,
+    contact_forms.WLEMForm,
+)
+
+
+class Command(BaseCommand):
+    help = 'Export contacts for newsletter.'
+
+    def handle(self, **options):
+        addresses = set(self.get_addresses())
+        for address in addresses:
+            print address
+
+    def get_addresses(self):
+        for form in FORMS:
+            tags = [form.form_tag] + form.old_form_tags
+            contacts = Contact.objects.filter(form_tag__in=tags)
+            for contact in contacts:
+                if contact.body.get(form.mailing_field):
+                    yield contact.contact
diff --git a/src/contact/migrations/0001_initial.py b/src/contact/migrations/0001_initial.py
new file mode 100644 (file)
index 0000000..d16bf4c
--- /dev/null
@@ -0,0 +1,40 @@
+# -*- coding: utf-8 -*-
+import datetime
+from south.db import db
+from south.v2 import SchemaMigration
+from django.db import models
+
+
+class Migration(SchemaMigration):
+
+    def forwards(self, orm):
+        # Adding model 'Contact'
+        db.create_table('contact_contact', (
+            ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
+            ('created_at', self.gf('django.db.models.fields.DateTimeField')(auto_now_add=True, blank=True)),
+            ('ip', self.gf('django.db.models.fields.IPAddressField')(max_length=15)),
+            ('contact', self.gf('django.db.models.fields.CharField')(max_length=128)),
+            ('form_tag', self.gf('django.db.models.fields.CharField')(max_length=32)),
+            ('body', self.gf('jsonfield.fields.JSONField')()),
+        ))
+        db.send_create_signal('contact', ['Contact'])
+
+
+    def backwards(self, orm):
+        # Deleting model 'Contact'
+        db.delete_table('contact_contact')
+
+
+    models = {
+        'contact.contact': {
+            'Meta': {'ordering': "('-created_at',)", 'object_name': 'Contact'},
+            'body': ('jsonfield.fields.JSONField', [], {}),
+            'contact': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
+            'created_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
+            'form_tag': ('django.db.models.fields.CharField', [], {'max_length': '32'}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'ip': ('django.db.models.fields.IPAddressField', [], {'max_length': '15'})
+        }
+    }
+
+    complete_apps = ['contact']
\ No newline at end of file
diff --git a/src/contact/migrations/0002_auto__add_attachment.py b/src/contact/migrations/0002_auto__add_attachment.py
new file mode 100644 (file)
index 0000000..8dc031d
--- /dev/null
@@ -0,0 +1,51 @@
+# -*- coding: utf-8 -*-
+import datetime
+from south.db import db
+from south.v2 import SchemaMigration
+from django.db import models
+
+
+class Migration(SchemaMigration):
+
+    def forwards(self, orm):
+        # Adding model 'Attachment'
+        db.create_table('contact_attachment', (
+            ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
+            ('contact', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['contact.Contact'])),
+            ('tag', self.gf('django.db.models.fields.CharField')(max_length=64)),
+            ('file', self.gf('django.db.models.fields.files.FileField')(max_length=100)),
+        ))
+        db.send_create_signal('contact', ['Attachment'])
+
+        # Adding index on 'Contact', fields ['form_tag']
+        db.create_index('contact_contact', ['form_tag'])
+
+
+    def backwards(self, orm):
+        # Removing index on 'Contact', fields ['form_tag']
+        db.delete_index('contact_contact', ['form_tag'])
+
+        # Deleting model 'Attachment'
+        db.delete_table('contact_attachment')
+
+
+    models = {
+        'contact.attachment': {
+            'Meta': {'object_name': 'Attachment'},
+            'contact': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contact.Contact']"}),
+            'file': ('django.db.models.fields.files.FileField', [], {'max_length': '100'}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'tag': ('django.db.models.fields.CharField', [], {'max_length': '64'})
+        },
+        'contact.contact': {
+            'Meta': {'ordering': "('-created_at',)", 'object_name': 'Contact'},
+            'body': ('jsonfield.fields.JSONField', [], {}),
+            'contact': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
+            'created_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
+            'form_tag': ('django.db.models.fields.CharField', [], {'max_length': '32', 'db_index': 'True'}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'ip': ('django.db.models.fields.IPAddressField', [], {'max_length': '15'})
+        }
+    }
+
+    complete_apps = ['contact']
\ No newline at end of file
diff --git a/src/contact/migrations/0003_auto__add_field_contact_key.py b/src/contact/migrations/0003_auto__add_field_contact_key.py
new file mode 100644 (file)
index 0000000..d9347a4
--- /dev/null
@@ -0,0 +1,42 @@
+# -*- coding: utf-8 -*-
+from south.utils import datetime_utils as datetime
+from south.db import db
+from south.v2 import SchemaMigration
+from django.db import models
+
+
+class Migration(SchemaMigration):
+
+    def forwards(self, orm):
+        # Adding field 'Contact.key'
+        db.add_column(u'contact_contact', 'key',
+                      self.gf('django.db.models.fields.CharField')(default='#', max_length=30),
+                      keep_default=False)
+
+
+    def backwards(self, orm):
+        # Deleting field 'Contact.key'
+        db.delete_column(u'contact_contact', 'key')
+
+
+    models = {
+        u'contact.attachment': {
+            'Meta': {'object_name': 'Attachment'},
+            'contact': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['contact.Contact']"}),
+            'file': ('django.db.models.fields.files.FileField', [], {'max_length': '100'}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'tag': ('django.db.models.fields.CharField', [], {'max_length': '64'})
+        },
+        u'contact.contact': {
+            'Meta': {'ordering': "('-created_at',)", 'object_name': 'Contact'},
+            'body': ('jsonfield.fields.JSONField', [], {}),
+            'contact': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
+            'created_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
+            'form_tag': ('django.db.models.fields.CharField', [], {'max_length': '32', 'db_index': 'True'}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'ip': ('django.db.models.fields.IPAddressField', [], {'max_length': '15'}),
+            'key': ('django.db.models.fields.CharField', [], {'max_length': '30'})
+        }
+    }
+
+    complete_apps = ['contact']
\ No newline at end of file
diff --git a/src/contact/migrations/__init__.py b/src/contact/migrations/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/src/contact/models.py b/src/contact/models.py
new file mode 100644 (file)
index 0000000..fac089a
--- /dev/null
@@ -0,0 +1,83 @@
+# -*- coding: utf-8 -*-
+import yaml
+from hashlib import sha1
+import random
+import string
+from django.db import models
+from django.utils.encoding import smart_unicode, force_str
+from django.db.models import permalink
+from django.utils.translation import ugettext_lazy as _
+from jsonfield import JSONField
+from . import app_settings
+
+
+KEY_SIZE = 30
+
+
+def make_key(length):
+    return ''.join(
+        random.choice(string.ascii_uppercase + string.ascii_lowercase + string.digits)
+        for i in range(length))
+
+
+class Contact(models.Model):
+    created_at = models.DateTimeField(_('submission date'), auto_now_add=True)
+    ip = models.IPAddressField(_('IP address'))
+    contact = models.CharField(_('contact'), max_length=128)
+    form_tag = models.CharField(_('form'), max_length=32, db_index=True)
+    body = JSONField(_('body'))
+    key = models.CharField(max_length=KEY_SIZE)
+
+    def generate_key(self):
+        key = ''
+        while not key or Contact.objects.filter(key=key).exists():
+            key = make_key(KEY_SIZE)
+        self.key = key
+        self.save()
+
+    @staticmethod
+    def pretty_print(value, for_html=False):
+        if type(value) in (tuple, list, dict):
+            value = yaml.safe_dump(value, allow_unicode=True, default_flow_style=False)
+            if for_html:
+                value = smart_unicode(value).replace(u" ", unichr(160))
+        return value
+
+    class Meta:
+        ordering = ('-created_at',)
+        verbose_name = _('submitted form')
+        verbose_name_plural = _('submitted forms')
+
+    def __unicode__(self):
+        return unicode(self.created_at)
+
+    def digest(self):
+        serialized_body = ';'.join(sorted('%s:%s' % item for item in self.body.iteritems()))
+        data = '%s%s%s%s%s' % (self.id, self.contact, serialized_body, self.ip, self.form_tag)
+        data = force_str(data)
+        return sha1(data).hexdigest()
+
+    @permalink
+    def update_url(self):
+        return 'edit_form', [], {'form_tag': self.form_tag, 'contact_id': self.id, 'key': self.key}
+
+
+class Attachment(models.Model):
+    contact = models.ForeignKey(Contact)
+    tag = models.CharField(max_length=64)
+    file = models.FileField(upload_to='contact/attachment')
+
+    @models.permalink
+    def get_absolute_url(self):
+        return 'contact_attachment', [self.contact_id, self.tag]
+
+    @property
+    @models.permalink
+    def url(self):
+        return 'contact_attachment_key', [self.contact_id, self.tag, self.contact.key]
+
+    def __unicode__(self):
+        return self.file.name.rsplit('/', 1)[-1]
+
+
+__import__(app_settings.FORMS_MODULE)
diff --git a/src/contact/templates/admin/contact/contact/change_list.html b/src/contact/templates/admin/contact/contact/change_list.html
new file mode 100644 (file)
index 0000000..3b47c97
--- /dev/null
@@ -0,0 +1,18 @@
+{% extends "admin/change_list.html" %}
+{% load i18n %}
+{% load admin_urls %}
+
+
+{% block object-tools-items %}
+    {{block.super}}
+    {% if request.GET.form_tag %}
+        {% for extract_type in extract_types %}
+            <li>
+                <a href="{% url 'admin:contact_extract' form_tag=request.GET.form_tag extract_type_slug=extract_type.slug %}?created_at__month={{request.GET.created_at__month}}&created_at__year={{request.GET.created_at__year}}">
+                    {% trans 'Extract' %}: {{extract_type.label}}
+                </a>
+            </li>
+        {% endfor %}
+    {% endif %}
+{% endblock %}
+
diff --git a/src/contact/templates/contact/disabled_contact_form.html b/src/contact/templates/contact/disabled_contact_form.html
new file mode 100644 (file)
index 0000000..a3ccfc8
--- /dev/null
@@ -0,0 +1,13 @@
+{% extends "base.html" %}
+
+{% block title %}{{ title }}{% endblock %}
+
+{% block body %}
+
+    <h1>{{ title }}</h1>
+
+    {% block contact_form_description %}
+        <p class="notice">Rejestracja została zamknięta.</p>
+    {% endblock %}
+
+{% endblock %}
diff --git a/src/contact/templates/contact/form.html b/src/contact/templates/contact/form.html
new file mode 100644 (file)
index 0000000..ce837ae
--- /dev/null
@@ -0,0 +1,31 @@
+{% extends form.base_template|default:"base.html" %}
+{% load chunks %}
+{% load honeypot %}
+
+{% block title %}{{ form.form_title }}{% endblock %}
+
+{% block body %}
+
+    <h1>{% block contact_form_title %}{{ form.form_title }}{% endblock %}</h1>
+
+    <div class="form-info">
+    {% block contact_form_description %}
+        {% chunk "contact_form__"|add:form.form_tag %}
+    {% endblock %}
+    </div>
+
+    <form method="POST" action="." enctype="multipart/form-data" class="submit-form">
+    {% csrf_token %}
+    {% render_honeypot_field %}
+    {% block form %}
+        <table>
+            {{ form.as_table }}
+            {% if form.data_processing %}<tr><td></td><td><div class="helptext">{{ form.data_processing }}</div></td></tr>{% endif %}
+            {% block form_extra %}{% endblock %}
+            <tr><td></td><td><button>{% block contact_form_submit %}{{ form.submit_label }}{% endblock %}</button></td></tr>
+        </table>
+    {% endblock %}
+    <div class="form-footer">{% chunk "contact_form_footer__"|add:form.form_tag %}</div>
+    </form>
+
+{% endblock %}
diff --git a/src/contact/templates/contact/mail_body.txt b/src/contact/templates/contact/mail_body.txt
new file mode 100644 (file)
index 0000000..5015757
--- /dev/null
@@ -0,0 +1,6 @@
+{% load i18n %}
+{% blocktrans %}Thank you for contacting us at {{ site_name }}.{% endblocktrans %}
+{% trans "Your submission has been referred to the project coordinator." %}
+
+-- 
+{% trans "Message sent automatically. Please do not reply to it." %}
diff --git a/src/contact/templates/contact/mail_managers_body.txt b/src/contact/templates/contact/mail_managers_body.txt
new file mode 100644 (file)
index 0000000..b7f97cf
--- /dev/null
@@ -0,0 +1,12 @@
+{% load pretty_print from contact_tags %}{% load subdomainurls %}Wypełniono formularz {{ form_tag }} na stronie {{ site_name }}.
+
+{% url 'admin:contact_contact_change' None contact.pk %}
+
+{% for k, v in contact.body.items %}
+{{ k }}:
+{{ v|pretty_print }}
+{% endfor %}
+{% for attachment in contact.attachment_set.all %}
+{{ attachment.tag }}:
+http://{{ site_domain }}{{ attachment.get_absolute_url }}
+{% endfor %}
diff --git a/src/contact/templates/contact/mail_managers_subject.txt b/src/contact/templates/contact/mail_managers_subject.txt
new file mode 100644 (file)
index 0000000..12d2c8e
--- /dev/null
@@ -0,0 +1 @@
+Wypełniono formularz {{ form_tag }} na stronie {{ site_name }}.
\ No newline at end of file
diff --git a/src/contact/templates/contact/mail_subject.txt b/src/contact/templates/contact/mail_subject.txt
new file mode 100644 (file)
index 0000000..b8f586e
--- /dev/null
@@ -0,0 +1 @@
+{% load i18n %}{% blocktrans %}Thank you for contacting us at {{ site_name }}.{% endblocktrans %}
\ No newline at end of file
diff --git a/src/contact/templates/contact/thanks.html b/src/contact/templates/contact/thanks.html
new file mode 100644 (file)
index 0000000..00dc0fe
--- /dev/null
@@ -0,0 +1,14 @@
+{% extends base_template|default:"base.html" %}
+{% load i18n %}
+
+{% block title %}{% trans "Thank you" %}{% endblock %}
+
+{% block body %}
+
+    <h1>{% block contact_form_title %}{% trans "Thank you" %}{% endblock %}</h1>
+
+    {% block contact_form_description %}
+    <p class="notice">{% trans "Thank you for submitting the form." %}</p>
+    {% endblock %}
+
+{% endblock %}
diff --git a/src/contact/templatetags/__init__.py b/src/contact/templatetags/__init__.py
new file mode 100755 (executable)
index 0000000..e69de29
diff --git a/src/contact/templatetags/contact_tags.py b/src/contact/templatetags/contact_tags.py
new file mode 100755 (executable)
index 0000000..d8b18cb
--- /dev/null
@@ -0,0 +1,21 @@
+# -*- coding: utf-8 -*-
+from django.template import Library
+
+from contact.forms import contact_forms
+from contact.models import Contact
+
+register = Library()
+
+
+@register.filter
+def pretty_print(value):
+    return Contact.pretty_print(value)
+
+
+@register.filter
+def is_enabled(form_tag):
+    form_class = contact_forms.get(form_tag)
+    if form_class:
+        return not getattr(form_class, 'disabled', False)
+    else:
+        return False
diff --git a/src/contact/urls.py b/src/contact/urls.py
new file mode 100644 (file)
index 0000000..ed6f49c
--- /dev/null
@@ -0,0 +1,14 @@
+# -*- coding: utf-8 -*-
+from django.conf.urls import patterns, url
+from . import views
+
+urlpatterns = patterns(
+    'contact.views',
+    url(r'^(?P<form_tag>[^/]+)/$', views.form, name='contact_form'),
+    url(r'^(?P<form_tag>[^/]+)/edit/(?P<contact_id>[0-9]+)/(?P<key>[0-9a-zA-Z]+)/$', views.form, name='edit_form'),
+    url(r'^(?P<form_tag>[^/]+)/thanks/$', views.thanks, name='contact_thanks'),
+    url(r'^attachment/(?P<contact_id>\d+)/(?P<tag>[^/]+)/$', views.attachment, name='contact_attachment'),
+    url(r'^attachment/(?P<contact_id>\d+)/(?P<tag>[^/]+)/(?P<key>[0-9a-zA-Z]+)/$', views.attachment_key,
+        name='contact_attachment_key'),
+    url(r'^results/(?P<contact_id>\d+)/(?P<digest>[0-9a-f]+)/', views.results, name='contact_results'),
+)
diff --git a/src/contact/views.py b/src/contact/views.py
new file mode 100644 (file)
index 0000000..580a65d
--- /dev/null
@@ -0,0 +1,103 @@
+# -*- coding: utf-8 -*-
+from urllib import unquote
+
+from django.contrib.auth.decorators import permission_required
+from django.http import Http404
+from django.shortcuts import get_object_or_404, redirect, render
+from django.views.decorators.cache import never_cache
+from fnpdjango.utils.views import serve_file
+from honeypot.decorators import check_honeypot
+
+from .forms import contact_forms, update_forms
+from .models import Attachment, Contact
+
+
+@check_honeypot
+@never_cache
+def form(request, form_tag, force_enabled=False, contact_id=None, key=None):
+    update = bool(contact_id and key)
+    try:
+        if update and form_tag in update_forms:
+            form_class = update_forms[form_tag]
+        else:
+            form_class = contact_forms[form_tag]
+    except KeyError:
+        raise Http404
+    if not (force_enabled and request.user.is_superuser):
+        if form_class.is_disabled():
+            template = form_class.disabled_template
+            if template:
+                return render(request, template, {'title': form_class.form_title})
+            raise Http404
+    if contact_id:
+        contact = get_object_or_404(Contact, id=contact_id, form_tag=form_tag)
+        if not form_class.updatable:
+            raise Http404
+        if key != contact.key:
+            raise Http404
+    else:
+        contact = None
+    if request.method == 'POST':
+        form = form_class(request.POST, request.FILES, instance=contact)
+    else:
+        form = form_class(initial=request.GET, instance=contact)
+    if request.method == 'POST':
+        formsets = form.get_formsets(request)
+        if form.is_valid() and all(formset.is_valid() for formset in formsets.itervalues()):
+            contact = form.save(request, formsets.values())
+            if form.result_page:
+                return redirect('contact_results', contact.id, contact.digest())
+            else:
+                return redirect('contact_thanks', form_tag)
+    else:
+        formsets = form.get_formsets()
+
+    return render(
+        request, ['contact/%s/form.html' % form_tag, 'contact/form.html'],
+        {'form': form, 'formsets': formsets, 'formset_errors': any(formset.errors for formset in formsets.values())}
+    )
+
+
+def thanks(request, form_tag):
+    try:
+        form_class = contact_forms[form_tag]
+    except KeyError:
+        raise Http404
+
+    return render(
+        request, ['contact/%s/thanks.html' % form_tag, 'contact/thanks.html'],
+        {'base_template': getattr(form_class, 'base_template', None)})
+
+
+def results(request, contact_id, digest):
+    contact = get_object_or_404(Contact, id=contact_id)
+    if digest != contact.digest():
+        raise Http404
+    try:
+        form_class = contact_forms[contact.form_tag]
+    except KeyError:
+        raise Http404
+
+    return render(
+        request, 'contact/%s/results.html' % contact.form_tag,
+        {
+            'results': form_class.results(contact),
+            'base_template': getattr(form_class, 'base_template', None),
+        }
+    )
+
+
+@permission_required('contact.change_attachment')
+def attachment(request, contact_id, tag):
+    attachment = get_object_or_404(Attachment, contact_id=contact_id, tag=tag)
+    attachment_url = unquote(attachment.file.url)
+    return serve_file(attachment_url)
+
+
+def attachment_key(request, contact_id, tag, key):
+    contact = Contact.objects.get(id=contact_id)
+    if key != contact.key:
+        raise Http404
+    attachment = get_object_or_404(Attachment, contact_id=contact_id, tag=tag)
+    attachment_url = unquote(attachment.file.url)
+    return serve_file(attachment_url)
diff --git a/src/contact/widgets.py b/src/contact/widgets.py
new file mode 100644 (file)
index 0000000..ddcf3cf
--- /dev/null
@@ -0,0 +1,10 @@
+# -*- coding: utf-8 -*-
+from django import forms
+from django.forms.util import flatatt
+from django.utils.html import format_html
+
+
+class HeaderWidget(forms.widgets.Widget):
+    def render(self, name, value, attrs=None):
+        attrs.update(self.attrs)
+        return format_html('<a{0}></a>', flatatt(attrs))
diff --git a/src/curriculum/__init__.py b/src/curriculum/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/src/curriculum/admin.py b/src/curriculum/admin.py
new file mode 100755 (executable)
index 0000000..0f378bc
--- /dev/null
@@ -0,0 +1,32 @@
+# -*- coding: utf-8 -*-
+from django.contrib import admin
+from .models import Competence, CompetenceLevel, Level, Section, CurriculumCourse, CurriculumLevel, Curriculum
+
+
+class CompetenceLevelInline(admin.TabularInline):
+    model = CompetenceLevel
+
+
+class CompetenceAdmin(admin.ModelAdmin):
+    model = Competence
+    list_display = ['name_pl', 'name_en', 'section', 'slug', 'order']
+    inlines = [CompetenceLevelInline]
+
+
+class LevelAdmin(admin.ModelAdmin):
+    model = Level
+    list_display = ['name_pl', 'name_en', 'group_pl', 'group_en', 'slug', 'order']
+
+
+class SectionAdmin(admin.ModelAdmin):
+    model = Section
+    list_display = ['name_pl', 'name_en', 'slug', 'order']
+
+
+admin.site.register(Level, LevelAdmin)
+admin.site.register(Section, SectionAdmin)
+admin.site.register(Competence, CompetenceAdmin)
+
+admin.site.register(CurriculumCourse)
+admin.site.register(CurriculumLevel)
+admin.site.register(Curriculum)
diff --git a/src/curriculum/fixtures/competences.json b/src/curriculum/fixtures/competences.json
new file mode 100644 (file)
index 0000000..3d6731d
--- /dev/null
@@ -0,0 +1,2951 @@
+[
+    {
+        "pk": 1,
+        "model": "curriculum.section",
+        "fields": {
+            "order": 1,
+            "name": "Korzystanie z informacji",
+            "slug": "korzystanie-z-informacji"
+        }
+    },
+    {
+        "pk": 2,
+        "model": "curriculum.section",
+        "fields": {
+            "order": 2,
+            "name": "Relacje w \u015brodowisku medialnym",
+            "slug": "relacje-w-srodowisku-medialnym"
+        }
+    },
+    {
+        "pk": 3,
+        "model": "curriculum.section",
+        "fields": {
+            "order": 3,
+            "name": "J\u0119zyk medi\u00f3w",
+            "slug": "jezyk-mediow"
+        }
+    },
+    {
+        "pk": 4,
+        "model": "curriculum.section",
+        "fields": {
+            "order": 4,
+            "name": "Kreatywne korzystanie z medi\u00f3w",
+            "slug": "kreatywne-korzystanie-z-mediow"
+        }
+    },
+    {
+        "pk": 5,
+        "model": "curriculum.section",
+        "fields": {
+            "order": 5,
+            "name": "Etyka i warto\u015bci w komunikacji i mediach",
+            "slug": "etyka-i-wartosci-w-komunikacji-i-mediach"
+        }
+    },
+    {
+        "pk": 6,
+        "model": "curriculum.section",
+        "fields": {
+            "order": 6,
+            "name": "Bezpiecze\u0144stwo w komunikacji i mediach",
+            "slug": "bezpieczenstwo-w-komunikacji-i-mediach"
+        }
+    },
+    {
+        "pk": 7,
+        "model": "curriculum.section",
+        "fields": {
+            "order": 7,
+            "name": "Prawo w komunikacji i mediach",
+            "slug": "prawo-w-mediach-i-komunikacji"
+        }
+    },
+    {
+        "pk": 8,
+        "model": "curriculum.section",
+        "fields": {
+            "order": 8,
+            "name": "Ekonomiczne aspekty dzia\u0142ania medi\u00f3w",
+            "slug": "ekonomiczne-aspekty-dzialania-mediow"
+        }
+    },
+    {
+        "pk": 1,
+        "model": "curriculum.competence",
+        "fields": {
+            "section": 1,
+            "order": 1,
+            "name": "\u0179r\u00f3d\u0142a informacji",
+            "slug": "zrodla-informacji"
+        }
+    },
+    {
+        "pk": 2,
+        "model": "curriculum.competence",
+        "fields": {
+            "section": 1,
+            "order": 2,
+            "name": "Wyszukiwanie informacji",
+            "slug": "wyszukiwanie-informacji"
+        }
+    },
+    {
+        "pk": 3,
+        "model": "curriculum.competence",
+        "fields": {
+            "section": 1,
+            "order": 3,
+            "name": "Podej\u015bcie krytyczne do informacji",
+            "slug": "podejscie-krytyczne-do-informacji"
+        }
+    },
+    {
+        "pk": 4,
+        "model": "curriculum.competence",
+        "fields": {
+            "section": 1,
+            "order": 4,
+            "name": "Wykorzystanie informacji",
+            "slug": "wykorzystanie-informacji"
+        }
+    },
+    {
+        "pk": 7,
+        "model": "curriculum.competence",
+        "fields": {
+            "section": 2,
+            "order": 1,
+            "name": "Wizerunek",
+            "slug": "wizerunek"
+        }
+    },
+    {
+        "pk": 5,
+        "model": "curriculum.competence",
+        "fields": {
+            "section": 2,
+            "order": 2,
+            "name": "Komunikacja",
+            "slug": "komunikacja"
+        }
+    },
+    {
+        "pk": 6,
+        "model": "curriculum.competence",
+        "fields": {
+            "section": 2,
+            "order": 3,
+            "name": "Otoczenie",
+            "slug": "otoczenie"
+        }
+    },
+    {
+        "pk": 10,
+        "model": "curriculum.competence",
+        "fields": {
+            "section": 3,
+            "order": 1,
+            "name": "J\u0119zykowa natura medi\u00f3w",
+            "slug": "jezykowa-natura-mediow"
+        }
+    },
+    {
+        "pk": 9,
+        "model": "curriculum.competence",
+        "fields": {
+            "section": 3,
+            "order": 2,
+            "name": "Funkcje komunikat\u00f3w medialnych",
+            "slug": "funkcje-komunikatow-medialnych"
+        }
+    },
+    {
+        "pk": 8,
+        "model": "curriculum.competence",
+        "fields": {
+            "section": 3,
+            "order": 3,
+            "name": "Kultura komunikacji medialnej",
+            "slug": "kultura-komunikacji-medialnej"
+        }
+    },
+    {
+        "pk": 11,
+        "model": "curriculum.competence",
+        "fields": {
+            "section": 4,
+            "order": 1,
+            "name": "Tworzenie",
+            "slug": "tworzenie"
+        }
+    },
+    {
+        "pk": 12,
+        "model": "curriculum.competence",
+        "fields": {
+            "section": 4,
+            "order": 2,
+            "name": "Przetwarzanie",
+            "slug": "przetwarzanie"
+        }
+    },
+    {
+        "pk": 13,
+        "model": "curriculum.competence",
+        "fields": {
+            "section": 4,
+            "order": 3,
+            "name": "Prezentowanie",
+            "slug": "prezentowanie"
+        }
+    },
+    {
+        "pk": 16,
+        "model": "curriculum.competence",
+        "fields": {
+            "section": 5,
+            "order": 1,
+            "name": "Komunikacja i media jako przedmiot refleksji etycznej",
+            "slug": "komunikacja-i-media-jako-przedmiot-refleksji-etycz"
+        }
+    },
+    {
+        "pk": 15,
+        "model": "curriculum.competence",
+        "fields": {
+            "section": 5,
+            "order": 2,
+            "name": "Wyzwania etyczne a tre\u015bci medi\u00f3w i komunikacji",
+            "slug": "wyzwania-etyczne-a-tresci-mediow-i-komunikacji"
+        }
+    },
+    {
+        "pk": 17,
+        "model": "curriculum.competence",
+        "fields": {
+            "section": 5,
+            "order": 3,
+            "name": "Wyzwania etyczne w relacjach przez media",
+            "slug": "wyzwania-etyczne-w-relacjach-przez-media"
+        }
+    },
+    {
+        "pk": 14,
+        "model": "curriculum.competence",
+        "fields": {
+            "section": 5,
+            "order": 4,
+            "name": "Wyzwania etyczne a normy prawa w mediach i komunikacji",
+            "slug": "wyzwania-etyczne-a-normy-prawa"
+        }
+    },
+    {
+        "pk": 21,
+        "model": "curriculum.competence",
+        "fields": {
+            "section": 6,
+            "order": 1,
+            "name": "Ochrona prywatno\u015bci i wizerunku",
+            "slug": "ochrona-prywatnosci-i-wizerunku"
+        }
+    },
+    {
+        "pk": 20,
+        "model": "curriculum.competence",
+        "fields": {
+            "section": 6,
+            "order": 2,
+            "name": "Anonimowo\u015b\u0107",
+            "slug": "anonimowosc"
+        }
+    },
+    {
+        "pk": 18,
+        "model": "curriculum.competence",
+        "fields": {
+            "section": 6,
+            "order": 3,
+            "name": "Bezpiecze\u0144stwo komunikacji, pracy i transakcji",
+            "slug": "bezpieczenstwo-komunikacji-pracy-i-transakcji"
+        }
+    },
+    {
+        "pk": 22,
+        "model": "curriculum.competence",
+        "fields": {
+            "section": 6,
+            "order": 4,
+            "name": "Nadz\u00f3r nad sieci\u0105",
+            "slug": "nadzor-nad-siecia"
+        }
+    },
+    {
+        "pk": 19,
+        "model": "curriculum.competence",
+        "fields": {
+            "section": 6,
+            "order": 5,
+            "name": "Uzale\u017cnienia i higiena korzystania z medi\u00f3w",
+            "slug": "uzaleznienia-i-higiena-korzystania-z-mediow"
+        }
+    },
+    {
+        "pk": 23,
+        "model": "curriculum.competence",
+        "fields": {
+            "section": 7,
+            "order": 1,
+            "name": "Rodzaje, \u017ar\u00f3d\u0142a i praktyka stosowania prawa w kontek\u015bcie medi\u00f3w",
+            "slug": "rodzaje-zrodla-i-praktyka-stosowania-prawa"
+        }
+    },
+    {
+        "pk": 28,
+        "model": "curriculum.competence",
+        "fields": {
+            "section": 7,
+            "order": 2,
+            "name": "Media a prawa cz\u0142owieka, obywatela i dziecka",
+            "slug": "media-a-prawa-czlowieka-obywatela-i-dziecka"
+        }
+    },
+    {
+        "pk": 27,
+        "model": "curriculum.competence",
+        "fields": {
+            "section": 7,
+            "order": 3,
+            "name": "Prawa wy\u0142\u0105czne i monopole intelektualne",
+            "slug": "prawa-wylaczne-i-monopole-intelektualne"
+        }
+    },
+    {
+        "pk": 29,
+        "model": "curriculum.competence",
+        "fields": {
+            "section": 7,
+            "order": 4,
+            "name": "Prawo telekomunikacyjne",
+            "slug": "prawo-telekomunikacyjne"
+        }
+    },
+    {
+        "pk": 25,
+        "model": "curriculum.competence",
+        "fields": {
+            "section": 7,
+            "order": 5,
+            "name": "Prawo medi\u00f3w i media publiczne",
+            "slug": "prawo-mediow-i-media-publiczne"
+        }
+    },
+    {
+        "pk": 24,
+        "model": "curriculum.competence",
+        "fields": {
+            "section": 7,
+            "order": 6,
+            "name": "Prawa os\u00f3b niepe\u0142nosprawnych",
+            "slug": "prawa-osob-niepelnosprawnych"
+        }
+    },
+    {
+        "pk": 26,
+        "model": "curriculum.competence",
+        "fields": {
+            "section": 7,
+            "order": 7,
+            "name": "Ochrona danych osobowych",
+            "slug": "ochrona-danych-osobowych"
+        }
+    },
+    {
+        "pk": 30,
+        "model": "curriculum.competence",
+        "fields": {
+            "section": 8,
+            "order": 1,
+            "name": "Rynek medi\u00f3w",
+            "slug": "rynek-mediow"
+        }
+    },
+    {
+        "pk": 31,
+        "model": "curriculum.competence",
+        "fields": {
+            "section": 8,
+            "order": 2,
+            "name": "Informacja jako dobro ekonomiczne",
+            "slug": "informacja-jako-dobro-ekonomiczne"
+        }
+    },
+    {
+        "pk": 32,
+        "model": "curriculum.competence",
+        "fields": {
+            "section": 8,
+            "order": 3,
+            "name": "Finansowanie medi\u00f3w i wybrane sposoby zarabiania w nowych mediach",
+            "slug": "finansowanie-mediow-i-wybrane-sposoby-zarabiania"
+        }
+    },
+    {
+        "pk": 33,
+        "model": "curriculum.competence",
+        "fields": {
+            "section": 8,
+            "order": 4,
+            "name": "Polityka medialna",
+            "slug": "polityka-medialna"
+        }
+    },
+    {
+        "pk": 1,
+        "model": "curriculum.level",
+        "fields": {
+            "order": 1,
+            "group": "edukacja formalna",
+            "name": "Wych. przedszkolne",
+            "slug": "przedszkole"
+        }
+    },
+    {
+        "pk": 2,
+        "model": "curriculum.level",
+        "fields": {
+            "order": 2,
+            "group": "edukacja formalna",
+            "name": "SP 1-3",
+            "slug": "sp1-3"
+        }
+    },
+    {
+        "pk": 3,
+        "model": "curriculum.level",
+        "fields": {
+            "order": 3,
+            "group": "edukacja formalna",
+            "name": "SP 4-6",
+            "slug": "sp4-6"
+        }
+    },
+    {
+        "pk": 4,
+        "model": "curriculum.level",
+        "fields": {
+            "order": 4,
+            "group": "edukacja formalna",
+            "name": "Gimnazjum",
+            "slug": "gimnazjum"
+        }
+    },
+    {
+        "pk": 5,
+        "model": "curriculum.level",
+        "fields": {
+            "order": 5,
+            "group": "edukacja formalna",
+            "name": "Szk. ponadgimnazjalna",
+            "slug": "liceum"
+        }
+    },
+    {
+        "pk": 6,
+        "model": "curriculum.level",
+        "fields": {
+            "order": 6,
+            "group": "edukacja formalna",
+            "name": "Szk. wy\u017csze",
+            "slug": "studia"
+        }
+    },
+    {
+        "pk": 7,
+        "model": "curriculum.level",
+        "fields": {
+            "order": 101,
+            "group": "edukacja ustawiczna",
+            "name": "Poziom minimum",
+            "slug": "minimum"
+        }
+    },
+    {
+        "pk": 8,
+        "model": "curriculum.level",
+        "fields": {
+            "order": 102,
+            "group": "edukacja ustawiczna",
+            "name": "Poziom optimum",
+            "slug": "optimum"
+        }
+    },
+    {
+        "pk": 9,
+        "model": "curriculum.level",
+        "fields": {
+            "order": 103,
+            "group": "edukacja ustawiczna",
+            "name": "Poziom mistrzowski",
+            "slug": "master"
+        }
+    },
+    {
+        "pk": 1,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- wie, \u017ce informacja wyst\u0119puje w r\u00f3\u017cnych formach; \u00a0np. rozumie, jakie s\u0105 podstawowe r\u00f3\u017cnice pomi\u0119dzy obrazem, tekstem, filmem, stron\u0105 internetow\u0105.\n- wie, \u017ce istniej\u0105 r\u00f3\u017cne \u017ar\u00f3d\u0142a informacji (TV, internet, radio, ksi\u0105\u017cki, gazety, inni ludzie).\n- umie skorzysta\u0107 z wybranych \u017ar\u00f3de\u0142 informacji; np. wyszukuje potrzebne informacje na temat ulubionego zwierz\u0119cia korzystaj\u0105c ze s\u0142ownika obrazkowego, rozmawiaj\u0105c z rodzicem / nauczycielem.",
+            "competence": 1,
+            "level": 1
+        }
+    },
+    {
+        "pk": 2,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- wie, jakie s\u0105 najwa\u017cniejsze \u017ar\u00f3d\u0142a informacji dostosowane do jego wieku i poziomu edukacji i umie z nich skorzysta\u0107;\nnp. korzysta z drukowanych i elektronicznych encyklopedii i s\u0142ownik\u00f3w dla dzieci.\n- umie skorzysta\u0107 z biblioteki szkolnej, kieruj\u0105c si\u0119 wskaz\u00f3wkami nauczyciela;\nnp. wybiera lektury, korzystaj\u0105c z rad nauczyciela.\n- wie, \u017ce informacje pochodz\u0105ce z r\u00f3\u017cnych \u017ar\u00f3de\u0142 mog\u0105 si\u0119 r\u00f3\u017cni\u0107.",
+            "competence": 1,
+            "level": 2
+        }
+    },
+    {
+        "pk": 3,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- wie, jakie s\u0105 podstawowe kryteria oceny \u017ar\u00f3de\u0142 informacji; np. wie, czym jest wiarygodno\u015b\u0107, \u0142atwo\u015b\u0107 i efektywno\u015b\u0107 korzystania, szybko\u015b\u0107 dost\u0119pu w odniesieniu do \u017ar\u00f3de\u0142 informacji.\n- umie dokona\u0107 wyboru \u017ar\u00f3de\u0142 informacji, kieruj\u0105c si\u0119 przede wszystkim kryterium wiarygodno\u015bci;\nnp. umie skorzysta\u0107 z wiarygodnych \u017ar\u00f3de\u0142 takich jak encyklopedie, s\u0142owniki drukowane lub elektroniczne.\n- umie skorzysta\u0107 z zasob\u00f3w biblioteki szkolnej, samodzielnie wybieraj\u0105c lektury oraz dobieraj\u0105c odpowiednie \u017ar\u00f3d\u0142a informacji do konkretnych zada\u0144.\n- wie, \u017ce jako\u015b\u0107 \u017ar\u00f3de\u0142 informacji ma zasadnicze znaczenie dla wynik\u00f3w pracy.",
+            "competence": 1,
+            "level": 3
+        }
+    },
+    {
+        "pk": 4,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- wie, \u017ce \u017ar\u00f3d\u0142a informacji nale\u017cy wybiera\u0107 \u015bwiadomie, maj\u0105c na uwadze potrzeby informacyjne oraz cel wykorzystania informacji.\n- umie biegle wybiera\u0107 \u017ar\u00f3d\u0142a informacji wykorzystywanych w procesie kszta\u0142cenia, kieruj\u0105c si\u0119 poszczeg\u00f3lnymi kryteriami wyboru;\nnp. zale\u017cnie od sytuacji korzysta z Wikipedii lub innych \u017ar\u00f3de\u0142.\n- rozumie konsekwencje korzystania z niew\u0142a\u015bciwych \u017ar\u00f3de\u0142 informacji w odniesieniu do edukacji szkolnej.\n- rozumie, jakie s\u0105 r\u00f3\u017cnice pomi\u0119dzy kana\u0142em a \u017ar\u00f3d\u0142em informacji.",
+            "competence": 1,
+            "level": 4
+        }
+    },
+    {
+        "pk": 5,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- wie, jakie s\u0105 najwa\u017cniejsze \u017ar\u00f3d\u0142a informacji naukowej i umie z nich skorzysta\u0107 w podstawowym zakresie;\nnp. korzysta z katalog\u00f3w elektronicznych bibliotek akademickich.\n- umie dokona\u0107 wyboru \u017ar\u00f3de\u0142 informacji, bior\u0105c pod uwag\u0119 dodatkowe kryteria takie jak relewancja, \u0142atwo\u015b\u0107 i efektywno\u015b\u0107 korzystania.\n- rozumie znaczenie doboru w\u0142a\u015bciwych \u017ar\u00f3de\u0142 informacji dla efekt\u00f3w wykonywanej pracy.\n- rozumie przyczyny ogranicze\u0144 system\u00f3w organizacji informacji;\nnp. rozumie, jakie nast\u0119pstwa ma fakt, \u017ce j\u0119zyki informacyjno-wyszukiwawcze s\u0105 j\u0119zykami sztucznymi.",
+            "competence": 1,
+            "level": 5
+        }
+    },
+    {
+        "pk": 6,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- wie, jaka jest r\u00f3\u017cnica pomi\u0119dzy \u017ar\u00f3d\u0142ami informacji wykorzystywanymi w pracy naukowej i \u017cyciu codziennym.\n- umie dokona\u0107 wyboru optymalnych \u017ar\u00f3de\u0142 informacji naukowej.\n- umie dokona\u0107 wyboru system\u00f3w informacyjnych zgodnie z zapotrzebowaniem wynikaj\u0105cym z jego pracy.\n- rozumie, jakie s\u0105 konsekwencje wykorzystania niew\u0142a\u015bciwych \u017ar\u00f3de\u0142 w pracy naukowej.\n- rozumie konieczno\u015b\u0107 odwo\u0142ywania si\u0119 do wykorzystanych \u017ar\u00f3de\u0142;\nnp. wie, jak i dlaczego nale\u017cy stosowa\u0107 przypisy i zamieszcza\u0107 bibliografi\u0119.",
+            "competence": 1,
+            "level": 6
+        }
+    },
+    {
+        "pk": 7,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- wie, jakie s\u0105 najwa\u017cniejsze \u017ar\u00f3d\u0142a informacji we wsp\u00f3\u0142czesnym \u015bwiecie.\n- wie, \u017ce \u017ar\u00f3d\u0142a informacji nale\u017cy wybiera\u0107 \u015bwiadomie, maj\u0105c na uwadze potrzeby informacyjne oraz cel wykorzystania informacji.\n- umie wykorzysta\u0107 g\u0142\u00f3wne \u017ar\u00f3d\u0142a informacji w procesie zaspokajania swoich potrzeb informacyjnych.\n- umie w spos\u00f3b intuicyjny oceni\u0107 wiarygodno\u015b\u0107 \u017ar\u00f3de\u0142 informacji.\n- umie dokona\u0107 wyboru \u017ar\u00f3de\u0142 informacji, bior\u0105c pod uwag\u0119 takie kryteria jak wiarygodno\u015b\u0107, relewancja, \u0142atwo\u015b\u0107 i efektywno\u015b\u0107 korzystania.\n- rozumie, jakie jest znaczenie informacji w spo\u0142ecze\u0144stwie XXI wieku.\n- rozumie, \u017ce informacje r\u00f3\u017cni\u0105 si\u0119 w zale\u017cno\u015bci od \u017ar\u00f3d\u0142a, z kt\u00f3rego pochodz\u0105, oraz intencji nadawcy.",
+            "competence": 1,
+            "level": 7
+        }
+    },
+    {
+        "pk": 8,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- wie, \u017ce relewantna i wiarygodna informacja powinna zawsze by\u0107 podstaw\u0105 podejmowanych decyzji.\n- wie, jakie s\u0105 najwa\u017cniejsze modele zachowa\u0144 informacyjnych.\n- umie biegle wybiera\u0107 \u017ar\u00f3d\u0142a informacji wykorzystywanych w procesie kszta\u0142cenia, kieruj\u0105c si\u0119 odpowiednimi kryteriami.\n- rozumie, jakie jest znaczenie doboru w\u0142a\u015bciwych \u017ar\u00f3de\u0142 informacji dla efekt\u00f3w wykonywanej pracy.",
+            "competence": 1,
+            "level": 8
+        }
+    },
+    {
+        "pk": 9,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- wie, jaka jest organizacja \u017ar\u00f3de\u0142 informacji oraz przep\u0142ywu informacji w spo\u0142ecze\u0144stwie.\n- umie sprawnie wybiera\u0107 \u017ar\u00f3d\u0142a informacji w zale\u017cno\u015bci od celu dzia\u0142ania i specyfiki realizowanego zadania.\n- rozumie, jakie s\u0105 konsekwencje korzystania z niew\u0142a\u015bciwych \u017ar\u00f3de\u0142 informacji w odniesieniu do efekt\u00f3w wykonywanej pracy i realizacji konkretnego zadania.",
+            "competence": 1,
+            "level": 9
+        }
+    },
+    {
+        "pk": 10,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- umie skorzysta\u0107 z pomocy doros\u0142ego w procesie pozyskiwania informacji; np. prosi rodzica o znalezienie jakiej\u015b informacji.",
+            "competence": 2,
+            "level": 1
+        }
+    },
+    {
+        "pk": 11,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- wie, \u017ce \u201ej\u0119zyk komputera\u201d r\u00f3\u017cni si\u0119 od j\u0119zyka m\u00f3wionego;\nnp. wie, \u017ce komputer zawsze \u201erobi\u201d to, co mu si\u0119 ka\u017ce, dlatego trzeba si\u0119 nauczy\u0107, jak wydawa\u0107 polecenia.\n- umie skorzysta\u0107 z podstawowych technik wyszukiwania w \u017ar\u00f3d\u0142ach tradycyjnych oraz elektronicznych.\n- wie, \u017ce dzia\u0142ania na zbiorach mog\u0105 by\u0107 wykorzystywane przy szukaniu informacji;\nnp. poznaje mo\u017cliwo\u015bci prostych zastosowa\u0144 operator\u00f3w logicznych (kot AND/ORAZ pies itd.)\n- umie zastosowa\u0107 proste has\u0142a osobowe, przedmiotowe, wpisuje proste zapytania informacyjno-wyszukiwawcze w wyszukiwarkach, encyklopediach;\nnp. wyszukuje informacje nt. ulubionego zwierz\u0119cia w s\u0142owniku obrazkowym, encyklopedii elektronicznej dla dzieci i internecie.\n- rozumie, \u017ce umiej\u0119tno\u015b\u0107 wyszukiwania informacji przyda mu si\u0119 w \u017cyciu;\nnp. rozumie, \u017ce na podstawie wyszukanych informacji b\u0119dzie podejmowa\u0142 r\u00f3\u017cne decyzje.",
+            "competence": 2,
+            "level": 2
+        }
+    },
+    {
+        "pk": 12,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- wie, jakie s\u0105 podstawowe r\u00f3\u017cnice w budowie hase\u0142 w j\u0119zyku naturalnym i j\u0119zyku systemu informacyjnego;\nnp. poznaje na przyk\u0142adzie hase\u0142 przedmiotowych r\u00f3\u017cnice w okre\u015blaniu zwierz\u0105t.\n- wie, \u017ce s\u0105 r\u00f3\u017cne modele zachowa\u0144 informacyjnych - umie wyszuka\u0107 informacje w wybranych tradycyjnych i elektronicznych \u017ar\u00f3d\u0142ach.\n- umie budowa\u0107 proste zapytania informacyjno-wyszukiwawcze;\nnp. rozk\u0142ad jazdy pkp warszawa.\n- wie, \u017ce trzeba dok\u0142adnie formu\u0142owa\u0107 zapytania informacyjno-wyszukiwawcze.\n- wie, \u017ce wynik wyszukiwania zale\u017cy od tego, jak b\u0119dzie sformu\u0142owane zapytanie informacyjno-wyszukiwawcze.",
+            "competence": 2,
+            "level": 3
+        }
+    },
+    {
+        "pk": 13,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- wie, jakie s\u0105 podstawowe techniki i strategie wyszukiwania informacji;\nnp. stosuje strategi\u0119 zaw\u0119\u017cania wynik\u00f3w poszukiwa\u0144.\n- umie wyszukiwa\u0107 informacje w \u017ar\u00f3d\u0142ach tradycyjnych i elektronicznych;\nnp. wyszukuje informacje, korzystaj\u0105c ze stron, blog\u00f3w, portali, wortali oraz materia\u0142\u00f3w drukowanych.\n- umie zastosowa\u0107 z\u0142o\u017cone strategie wyszukiwania w oparciu o znane modele zachowa\u0144 informacyjnych w odpowiednich adaptacjach.\n\n- umie wykorzysta\u0107 wybrane techniki wyszukiwania;\nnp. korzysta z operator\u00f3w logicznych.\n- umie budowa\u0107 zapytania informacyjno-wyszukiwawcze w j\u0119zyku systemu informacyjnego.",
+            "competence": 2,
+            "level": 4
+        }
+    },
+    {
+        "pk": 14,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- wie, jakie s\u0105 z\u0142o\u017cone strategie wyszukiwania.\n- umie sprawnie wyszukiwa\u0107 informacje, buduj\u0105c strategie wyszukiwania w oparciu o najwa\u017cniejsze modele zachowa\u0144 informacyjnych.\n- umie przek\u0142ada\u0107 zapytania informacyjno-wyszukiwawcze wyra\u017cone w j\u0119zyku naturalnym na j\u0119zyk systemu informacyjnego.",
+            "competence": 2,
+            "level": 5
+        }
+    },
+    {
+        "pk": 15,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- wie, jak wyszukiwa\u0107 informacj\u0119 naukow\u0105 w r\u00f3\u017cnych \u017ar\u00f3d\u0142ach.\n- umie biegle korzysta\u0107 z najwa\u017cniejszych \u017ar\u00f3de\u0142 informacji naukowej;\nnp. biegle korzysta z katalog\u00f3w bibliotecznych, stosuj\u0105c opcje wyszukiwania zaawansowanego, sprawnie korzysta z dziedzinowych baz danych literatury naukowej.\n- umie zaprojektowa\u0107 efektywn\u0105 strategi\u0119 wyszukiwania informacji.",
+            "competence": 2,
+            "level": 6
+        }
+    },
+    {
+        "pk": 16,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- wie, \u017ce wyszukiwanie informacji wymaga odpowiednich umiej\u0119tno\u015bci.\n- wie, \u017ce trzeba dok\u0142adnie formu\u0142owa\u0107 zapytania informacyjno-wyszukiwawcze.\n- umie skorzysta\u0107 z podstawowych technik wyszukiwania w \u017ar\u00f3d\u0142ach tradycyjnych oraz elektronicznych.\n- umie zastosowa\u0107 proste has\u0142a osobowe, przedmiotowe, wpisuje zapytania informacyjno-wyszukiwawcze w wyszukiwarkach, encyklopediach.\n- rozumie, \u017ce wynik wyszukiwania zale\u017cy od tego, jak b\u0119dzie sformu\u0142owane zapytanie informacyjno-wyszukiwawcze.\n- rozumie konsekwencje, jakie mo\u017ce mie\u0107 opieranie swoich decyzji na niepe\u0142nych lub nieaktualnych informacjach.",
+            "competence": 2,
+            "level": 7
+        }
+    },
+    {
+        "pk": 17,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- wie, jakie s\u0105 podstawowe techniki i strategie wyszukiwania informacji.\n- wie, jakie s\u0105 najwa\u017cniejsze modele zachowa\u0144 informacyjnych.\n- wie, jakie s\u0105 podstawowe r\u00f3\u017cnice w budowie hase\u0142 w j\u0119zyku naturalnym i j\u0119zyku systemu informacyjnego.\n- umie sprawnie wyszukiwa\u0107 informacje, buduj\u0105c strategie wyszukiwania w oparciu o najwa\u017cniejsze modele zachowa\u0144 informacyjnych.\n- umie stosowa\u0107 zaawansowane techniki wyszukiwania informacji.\n- umie dodawa\u0107, ulepsza\u0107 i \u0142\u0105czy\u0107 informacje w r\u00f3\u017cnych formach, zaczerpni\u0119te z r\u00f3\u017cnych \u017ar\u00f3de\u0142.",
+            "competence": 2,
+            "level": 8
+        }
+    },
+    {
+        "pk": 18,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- wie, jakie s\u0105 z\u0142o\u017cone strategie wyszukiwania.\n- umie sprawnie wyszukiwa\u0107 informacje, buduj\u0105c strategie wyszukiwania w oparciu o najwa\u017cniejsze modele zachowa\u0144 informacyjnych.\n- umie zaprojektowa\u0107 efektywn\u0105 strategi\u0119 wyszukiwania informacji.",
+            "competence": 2,
+            "level": 9
+        }
+    },
+    {
+        "pk": 19,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- wie, \u017ce je\u015bli informacja budzi w\u0105tpliwo\u015bci, powinien j\u0105 om\u00f3wi\u0107 z rodzicami lub nauczycielem przedszkolnym.\n- umie zada\u0107 pytanie dotycz\u0105ce wiarygodno\u015bci informacji;\nnp. zadaje pytania \u201emamo, czy to prawda, \u017ce\u201d...",
+            "competence": 3,
+            "level": 1
+        }
+    },
+    {
+        "pk": 20,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- wie, \u017ce informacje mog\u0105 by\u0107 nieprawdziwe, niepe\u0142ne, niedok\u0142adne.\n- wie, \u017ce nale\u017cy zastanawia\u0107 si\u0119 i rozmawia\u0107 na temat sposob\u00f3w korzystania z informacji.\n- wie, \u017ce nadawcy informacji mog\u0105 chcie\u0107 wywrze\u0107 na niego wp\u0142yw i sk\u0142oni\u0107 do okre\u015blonych zachowa\u0144.\n- umie dostrzec r\u00f3\u017cnic\u0119 pomi\u0119dzy informacj\u0105 prawdziw\u0105 i nieprawdziw\u0105, kieruj\u0105c si\u0119 swoj\u0105 intuicj\u0105.",
+            "competence": 3,
+            "level": 2
+        }
+    },
+    {
+        "pk": 21,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- wie, \u017ce przekazywane informacje r\u00f3\u017cni\u0105 si\u0119 w zale\u017cno\u015bci od intencji nadawcy;\nnp. por\u00f3wnuje, jak przekazywana jest ta sama informacja w r\u00f3\u017cnych mediach.\n- wie, \u017ce informacje niskiej jako\u015bci prowadz\u0105 do b\u0142\u0119dnych wniosk\u00f3w.\n- umie kwestionowa\u0107 wiarygodno\u015b\u0107 informacji.\n- umie weryfikowa\u0107 informacje poprzez por\u00f3wnywanie ich w r\u00f3\u017cnych \u017ar\u00f3d\u0142ach.\n- wie, \u017ce jest r\u00f3\u017cnica pomi\u0119dzy informacj\u0105 a plotk\u0105.\n- rozumie, czym jest manipulacja informacj\u0105.",
+            "competence": 3,
+            "level": 3
+        }
+    },
+    {
+        "pk": 22,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- wie, \u017ce zawsze nale\u017cy by\u0107 krytycznym wobec \u017ar\u00f3d\u0142a.\n- wie, z jakich \u017ar\u00f3de\u0142 skorzysta\u0107, by jednoznacznie zweryfikowa\u0107 informacje;\nnp. korzysta z encyklopedii PWN, by potwierdzi\u0107 informacje znalezione na blogu.\n- umie selekcjonowa\u0107 potrzebne informacje, sprawdzaj\u0105c ich dok\u0142adno\u015b\u0107.\n- umie oceni\u0107 wykorzystanie TIK w swojej pracy.\n- umie dostrzec i okre\u015bli\u0107 r\u00f3\u017cnice pomi\u0119dzy informacj\u0105 a innym przekazem, w tym opini\u0105, ocen\u0105, krytyk\u0105;\nnp. por\u00f3wnuje artyku\u0142y z r\u00f3\u017cnych gazet, okre\u015blaj\u0105c ich cechy.\n- umie rozr\u00f3\u017cni\u0107 cechy i funkcje informacji i plotki; np. por\u00f3wnuje teksty z \u201eGazety Wyborczej\u201d, \u201eFaktu\u201d i \u201ePudelka\u201d.",
+            "competence": 3,
+            "level": 4
+        }
+    },
+    {
+        "pk": 23,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- wie, \u017ce umiej\u0119tno\u015b\u0107 krytycznej oceny informacji jest kluczowa w procesie realizacji zada\u0144.\n- wie, \u017ce \u017ar\u00f3d\u0142a informacji i narz\u0119dzia TIK wykorzystywane w pracy maj\u0105 swoje wady, zalety i ograniczenia.\n- umie przedstawi\u0107 argumenty dotycz\u0105ce wad, zalet i ogranicze\u0144 \u017ar\u00f3de\u0142 informacji i narz\u0119dzi TIK.\n- rozumie konsekwencje wynikaj\u0105ce z braku podej\u015bcia krytycznego w zakresie korzystania ze \u017ar\u00f3de\u0142 informacji i narz\u0119dzi TIK.\n- rozumie konsekwencje przyjmowania okre\u015blonego stanowiska w pracy z informacj\u0105; np. np.rozumie, \u017ce wyniki bada\u0144 dotycz\u0105cych preferencji politycznych mog\u0105 by\u0107 r\u00f3\u017cnie interpretowane w zale\u017cno\u015bci od przekona\u0144 i sympatii politycznych autora lub linii programowej stacji oraz zdaje sobie spraw\u0119, \u017ce mo\u017ce to prowadzi\u0107 do b\u0142\u0119dnych wniosk\u00f3w.",
+            "competence": 3,
+            "level": 5
+        }
+    },
+    {
+        "pk": 24,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- umie wykorzysta\u0107 wyniki rozm\u00f3w na temat wad, zalet i ogranicze\u0144 \u017ar\u00f3de\u0142 informacji i narz\u0119dzi TIK do formu\u0142owania ocen dotycz\u0105cych jako\u015bci swojej pracy.\n- rozumie, jaki wp\u0142yw na rozw\u00f3j sektora TIK maj\u0105 czynniki takie jak prawo,etyka, ekonomia i wykorzystuje t\u0119 wiedz\u0119 w procesie realizacji zada\u0144 informacyjnych.",
+            "competence": 3,
+            "level": 6
+        }
+    },
+    {
+        "pk": 25,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- wie, \u017ce nadawcy informacji mog\u0105 chcie\u0107 wywrze\u0107 na niego wp\u0142yw i sk\u0142oni\u0107 do okre\u015blonych zachowa\u0144.\n- wie, \u017ce intencje nadawcy oraz specyfika danego medium ma decyduj\u0105cy wp\u0142yw na tre\u015b\u0107 i form\u0119 informacji.\n- wie, jakie s\u0105 podstawowe kryteria oceny \u017ar\u00f3de\u0142 informacji.\n- umie dostrzec r\u00f3\u017cnic\u0119 pomi\u0119dzy informacj\u0105 prawdziw\u0105 i nieprawdziw\u0105, kieruj\u0105c si\u0119 swoj\u0105 intuicj\u0105.\n- umie kwestionowa\u0107 wiarygodno\u015b\u0107 informacji.\n- umie weryfikowa\u0107 informacje poprzez por\u00f3wnywanie ich w r\u00f3\u017cnych \u017ar\u00f3d\u0142ach.\n- umie dostrzec i okre\u015bli\u0107 r\u00f3\u017cnice pomi\u0119dzy informacj\u0105 a innym przekazem, w tym opini\u0105, ocen\u0105, krytyk\u0105.\n- rozumie, czym jest manipulacja informacj\u0105.",
+            "competence": 3,
+            "level": 7
+        }
+    },
+    {
+        "pk": 26,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- wie, \u017ce umiej\u0119tno\u015b\u0107 krytycznej oceny informacji jest kluczowa w procesie realizacji zada\u0144.\n- rozumie konsekwencje przyjmowania okre\u015blonego stanowiska w pracy z informacj\u0105.",
+            "competence": 3,
+            "level": 8
+        }
+    },
+    {
+        "pk": 27,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- rozumie, jaki wp\u0142yw na rozw\u00f3j sektora TIK maj\u0105 czynniki takie jak prawo,etyka, ekonomia i wykorzystuje t\u0119 wiedz\u0119 w procesie realizacji zada\u0144 informacyjnych.",
+            "competence": 3,
+            "level": 9
+        }
+    },
+    {
+        "pk": 29,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- wie, \u017ce zasoby informacyjne trzeba porz\u0105dkowa\u0107 w celu \u0142atwego ich wykorzystania i odnalezienia.\n- umie wprowadza\u0107, zachowywa\u0107 i odzyskiwa\u0107 wyniki swojej pracy;\nnp. zapisuje wyniki swojej pracy w edytorze tekst\u00f3w.\n- umie zastosowa\u0107 proste schematy organizacji informacji, \u0142\u0105czy\u0107 i organizowa\u0107 materia\u0142;\nnp. szereguje, klasyfikuje, tworzy katalogi i foldery, opisuje je w zrozumia\u0142y dla siebie spos\u00f3b.",
+            "competence": 4,
+            "level": 2
+        }
+    },
+    {
+        "pk": 30,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- wie, \u017ce prezentuj\u0105c wyniki swojej pracy, powinien bra\u0107 pod uwag\u0119 potrzeby odbiorc\u00f3w.\n- umie wykorzystywa\u0107 TIK podczas tworzenia, ulepszania i zapisywania wynik\u00f3w pracy;\nnp. umie skorzysta\u0107 z poczty e-mail, by przes\u0142a\u0107 wyniki pracy kolegom.\n- umie wykorzystywa\u0107 TIK do dzielenia si\u0119 swoimi pomys\u0142ami z innymi, wykorzystuj\u0105c w tym celu r\u00f3\u017cne formy prezentacji informacji;\nnp. tworzy wsp\u00f3lnie z kolegami projekt, wykorzystuj\u0105c tekst, tabele, ilustracje.\n- umie sprawnie organizowa\u0107 w\u0142asne zasoby informacyjne w celu \u0142atwego ich wykorzystania.\n- rozumie, jakie s\u0105 konsekwencje braku opracowania i organizacji informacji.\n- rozumie, jakie s\u0105 potrzeby poszczeg\u00f3lnych grup odbiorc\u00f3w w zakresie prezentowania informacji;\nnp. rozumie, \u017ce komunikat podobnej tre\u015bci nale\u017cy zbudowa\u0107 inaczej, gdy jest adresowany do r\u00f3wie\u015bnik\u00f3w, rodzic\u00f3w, nauczycieli.",
+            "competence": 4,
+            "level": 3
+        }
+    },
+    {
+        "pk": 31,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- wie, jak odpowiednio prezentowa\u0107 wyniki swojej pracy;\nnp. wie, \u017ce prezentacja musi by\u0107 przejrzysta, zawiera\u0107 niezbyt du\u017co tekstu oraz rozmaite ilustracje.\n- umie dodawa\u0107, ulepsza\u0107 i \u0142\u0105czy\u0107 informacje w r\u00f3\u017cnych formach, zaczerpni\u0119te z r\u00f3\u017cnych \u017ar\u00f3de\u0142.\n- umie wykorzystywa\u0107 TIK w procesie prezentowania wynik\u00f3w swojej pracy;\nnp. umie przygotowa\u0107 prezentacje multimedialne i prowadzi\u0107 wyst\u0105pienia publiczne.\n- umie organizowa\u0107 informacje w spos\u00f3b najbardziej odpowiedni do wykorzystania.",
+            "competence": 4,
+            "level": 4
+        }
+    },
+    {
+        "pk": 32,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- umie rozwija\u0107 i ulepsza\u0107 wyniki swojej pracy z wykorzystaniem TIK, by podnie\u015b\u0107 jej jako\u015b\u0107.\n- umie \u0142\u0105czy\u0107 informacje pochodz\u0105ce z r\u00f3\u017cnych \u017ar\u00f3de\u0142, by w odpowiedni spos\u00f3b przedstawi\u0107 je odbiorcom.\n- umie samodzielnie wybra\u0107 narz\u0119dzia TIK odpowiadaj\u0105ce realizacji okre\u015blonych zada\u0144.\n- rozumie, jakie s\u0105 przyczyny ogranicze\u0144 zastosowania TIK w wykonywaniu okre\u015blonych prac;\nnp. rozumie ograniczenia wynikaj\u0105ce z konieczno\u015bci algorytmizacji wszelkich prac, by mog\u0142y by\u0107 wykonywane przez TIK.",
+            "competence": 4,
+            "level": 5
+        }
+    },
+    {
+        "pk": 34,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- wie, \u017ce prezentuj\u0105c wyniki swojej pracy, powinien bra\u0107 pod uwag\u0119 potrzeby odbiorc\u00f3w.\n- umie wprowadza\u0107, zachowywa\u0107 i odzyskiwa\u0107 wyniki swojej pracy.\n- umie wykorzystywa\u0107 TIK podczas tworzenia, ulepszania i zapisywania wynik\u00f3w pracy.\n- umie selekcjonowa\u0107 potrzebne informacje, sprawdzaj\u0105c ich dok\u0142adno\u015b\u0107.",
+            "competence": 4,
+            "level": 7
+        }
+    },
+    {
+        "pk": 35,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- wie, \u017ce \u017ar\u00f3d\u0142a informacji i narz\u0119dzia TIK wykorzystywane w pracy maj\u0105 swoje wady, zalety i ograniczenia.\n- umie wykorzystywa\u0107 TIK w procesie prezentowania wynik\u00f3w swojej pracy.\n- umie oceni\u0107 wykorzystanie TIK w swojej pracy.\n- umie wykorzysta\u0107 wyniki rozm\u00f3w na temat wad, zalet i ogranicze\u0144 \u017ar\u00f3de\u0142 informacji i narz\u0119dzi TIK do formu\u0142owania ocen dotycz\u0105cych jako\u015bci jego pracy.\n- rozumie, jakie s\u0105 przyczyny ogranicze\u0144 zastosowania TIK w wykonywaniu okre\u015blonych prac.",
+            "competence": 4,
+            "level": 8
+        }
+    },
+    {
+        "pk": 36,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- umie \u0142\u0105czy\u0107 informacje pochodz\u0105ce z r\u00f3\u017cnych \u017ar\u00f3de\u0142, by w odpowiedni spos\u00f3b przedstawi\u0107 je odbiorcom.\n- umie wybra\u0107 narz\u0119dzia TIK odpowiadaj\u0105ce realizacji okre\u015blonych zada\u0144.\n- rozumie konsekwencje wynikaj\u0105ce z braku podej\u015bcia krytycznego w zakresie korzystania ze \u017ar\u00f3de\u0142 informacji i narz\u0119dzi TIK.",
+            "competence": 4,
+            "level": 9
+        }
+    },
+    {
+        "pk": 55,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- wie, jakie s\u0105 specyficzne cechy jego samego i najbli\u017cszego otoczenia;\r\nnp. w przekazach medialnych rozpoznaje og\u00f3lne podobie\u0144stwa miejsc i przedmiot\u00f3w, zauwa\u017ca taki sam rower lub plac zabaw.\r\n- umie rozr\u00f3\u017cni\u0107 siebie na tle innych (poczucie indywiduum);\r\nnp. dostrzega na zdj\u0119ciach lub materia\u0142ach filmowych swoje cechy indywidualne w por\u00f3wnaniu z innymi (wzrost, kolor w\u0142os\u00f3w).",
+            "competence": 7,
+            "level": 1
+        }
+    },
+    {
+        "pk": 56,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- wie, \u017ce nie zawsze i wsz\u0119dzie nale\u017cy ujawnia\u0107 informacje o sobie;\r\nnp. rozmawiaj\u0105c z nowo poznan\u0105 osob\u0105 na czacie, nie podaje swojego numeru telefonu ani maila.\r\n- umie dostrzec r\u00f3\u017cnice mi\u0119dzy swoim wizerunkiem, zdolno\u015bciami i umiej\u0119tno\u015bciami a cechami postaci w grze; np. graj\u0105c w gr\u0119 komputerow\u0105, ma \u015bwiadomo\u015b\u0107, \u017ce po wyj\u015bciu z niej nie b\u0119dzie mia\u0142 nadal trzech \u201e\u017cy\u0107\u201d jak jego awatar.",
+            "competence": 7,
+            "level": 2
+        }
+    },
+    {
+        "pk": 57,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- wie, \u017ce wizerunek mo\u017cna budowa\u0107 i prezentowa\u0107 na r\u00f3\u017cne sposoby;\r\nnp. ma \u015bwiadomo\u015b\u0107, \u017ce osoba siedz\u0105ca po drugiej stronie monitora podczas czatu, mo\u017ce by\u0107 zupe\u0142nie kim\u015b innym ni\u017c ta, za kt\u00f3r\u0105 si\u0119 podaje.\r\n- wie, jakie dzia\u0142ania przez media mog\u0105 mie\u0107 negatywne konsekwencje dla niego lub innych;\r\nnp. wie, \u017ce np. \u015bmieszny filmik z jego udzia\u0142em, wrzucony spontanicznie do sieci, mo\u017ce kiedy\u015b zosta\u0107 wykorzystany przeciwko niemu lub sprawi\u0107 komu\u015b przykro\u015b\u0107.\r\n- umie \u015bwiadomie kreowa\u0107 sw\u00f3j wizerunek w podstawowym zakresie;\r\nnp. rejestruj\u0105c si\u0119 na nowym portalu, umie wybra\u0107, kieruj\u0105c si\u0119 wzgl\u0119dami bezpiecze\u0144stwa, kt\u00f3re informacje o sobie podaje, a kt\u00f3rych nie.",
+            "competence": 7,
+            "level": 3
+        }
+    },
+    {
+        "pk": 58,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- umie, w zale\u017cno\u015bci od potrzeb, tworzy\u0107 i modyfikowa\u0107 sw\u00f3j wizerunek;\r\nnp. do\u0142\u0105czaj\u0105c do jakiej\u015b grupy w sieci, podaje tylko wybrane informacje o sobie.\r\n- rozumie szanse i zagro\u017cenia wynikaj\u0105ce z budowania w\u0142asnego wizerunku;\r\nnp. zwraca du\u017c\u0105 uwag\u0119 na to, co i gdzie na jego temat pojawia si\u0119 w internecie. Ma \u015bwiadomo\u015b\u0107, \u017ce nawet po skasowaniu jakiej\u015b tre\u015bci, w sieci i tak pozostaje po niej \u015blad.",
+            "competence": 7,
+            "level": 4
+        }
+    },
+    {
+        "pk": 59,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- wie, jakie s\u0105 elementy sk\u0142adowe wizerunku i umie je interpretowa\u0107;\r\nnp. zdaje sobie spraw\u0119, \u017ce wizerunek medialny os\u00f3b publicznych wykorzystuje j\u0119zyk i mow\u0119 cia\u0142a do realizacji zak\u0142adnych cel\u00f3w (np. pozyskania poparcia wyborc\u00f3w)\r\n- umie \u015bwiadomie tworzy\u0107 sw\u00f3j wizerunek w zale\u017cno\u015bci od kontekstu;\r\nnp. wpisuj\u0105c komentarze na portalach spo\u0142eczno\u015bciowych, zdaje sobie spraw\u0119, \u017ce s\u0105 one elementem jego to\u017csamo\u015bci w oczach innych, w tym r\u00f3wnie\u017c przysz\u0142ych pracodawc\u00f3w.\r\n- rozumie konsekwencje i potrzeb\u0119 \u015bwiadomego budowania w\u0142asnego wizerunku;\r\nnp. nie pozwala przypadkowo fotografowa\u0107 swojej osoby podczas imprez.",
+            "competence": 7,
+            "level": 5
+        }
+    },
+    {
+        "pk": 61,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- umie wskaza\u0107 elementy wizerunku on-line, zar\u00f3wno swojego, jak i innych os\u00f3b.\r\n- umie do\u0142\u0105czy\u0107 do wybranej spo\u0142eczno\u015bci i uczestniczy\u0107 w jej \u017cyciu, odpowiednio kreuj\u0105c sw\u00f3j wizerunek;\r\nnp. aktywnie uczestniczy w r\u00f3\u017cnych grupach hobbystycznych, edukacyjnych, terapeutycznych, \u015bwiatopogl\u0105dowych, politycznych itd.\r\n- rozumie r\u00f3\u017cnice pomi\u0119dzy \u015bwiatem do\u015bwiadczanym bezpo\u015brednio i przez media, zdaje sobie spraw\u0119 z powi\u0105za\u0144 mi\u0119dzy nimi;\r\nnp. tworz\u0105c profil na portalu spo\u0142eczno\u015bciowym dba przy tym o w\u0142asny wizerunek, gdy\u017c ma \u015bwiadomo\u015b\u0107 mo\u017cliwych konsekwencji, m.in. wp\u0142ywu na swoj\u0105 \u015bcie\u017ck\u0119 kariery.",
+            "competence": 7,
+            "level": 7
+        }
+    },
+    {
+        "pk": 62,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- umie budowa\u0107 sieci kontakt\u00f3w \u2013 trwa\u0142e i zadaniowe;\r\nnp. w zale\u017cno\u015bci od kontekstu kreuje sw\u00f3j wizerunek w sieci na potrzeby danych \u015brodowisk, przyjmuj\u0105c w nich r\u00f3\u017cne role spo\u0142eczne.\r\n- umie w spos\u00f3b \u015bwiadomy i odpowiedzialny budowa\u0107 sw\u00f3j wizerunek sieciowy i wykorzysta\u0107 go do realizacji okre\u015blonych cel\u00f3w;\r\nnp. wykorzystuje swojego bloga do budowania pozycji w \u015brodowisku zawodowym.\r\n- rozumie r\u00f3\u017cnice pomi\u0119dzy wizerunkami trwa\u0142ymi a ulotnymi;\r\nnp. inaczej buduje sw\u00f3j wizerunek w procesie tworzenia profilu na portalu spo\u0142eczno\u015bciowym czy forum specjalistycznym, a inaczej na czacie.\r\n- rozumie szanse i korzy\u015bci p\u0142yn\u0105ce z przynale\u017cno\u015bci do danej grupy;\r\n\r\nnp. potrafi je wykorzystywa\u0107 w planowaniu kariery zawodowej, do\u0142\u0105czaj\u0105c do grup specjalist\u00f3w w danej dziedzinie oraz tworz\u0105c profile w spo\u0142eczno\u015bciowych serwisach specjalistycznych.",
+            "competence": 7,
+            "level": 8
+        }
+    },
+    {
+        "pk": 63,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- umie budowa\u0107 spo\u0142eczno\u015bci i wsp\u00f3\u0142tworzy\u0107 \u015brodowisko cyfrowe oraz kreowa\u0107 to\u017csamo\u015bci zbiorowe, takie jak grupy hobbystyczne czy polityczne;\r\nnp. samodzielnie prowadzi forum, administruje stron\u0105 internetow\u0105 lub tworzy potrzebne mu narz\u0119dzia cyfrowe.\r\n- umie kszta\u0142towa\u0107 w\u0142asny wizerunek w sieci stosownie do r\u00f3\u017cnych kontekst\u00f3w;\r\nnp. na tym samym profilu spo\u0142eczno\u015bciowym potrafi wykreowa\u0107 kilka, cz\u0119sto zupe\u0142nie r\u00f3\u017cnych wizerunk\u00f3w w zale\u017cno\u015bci od kontekstu i potrzeb.",
+            "competence": 7,
+            "level": 9
+        }
+    },
+    {
+        "pk": 37,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- wie, jak wyra\u017ca\u0107 swoje elementarne potrzeby i emocje dotycz\u0105ce medi\u00f3w;\r\nnp. w kontakcie z medium (ksi\u0105\u017ck\u0105 czy gr\u0105 w sieci) wskazuje na to, co lubi; wybiera, kt\u00f3r\u0105 ksi\u0105\u017ck\u0119 chce przeczyta\u0107.\r\n- umie korzysta\u0107 ze znanych mu kana\u0142\u00f3w komunikacji;\r\nnp. w podstawowym zakresie rozr\u00f3\u017cnia zasady korzystania z poszczeg\u00f3lnych medi\u00f3w, wie, \u017ce radia (muzyki) si\u0119 s\u0142ucha, a telewizj\u0119 (film) ogl\u0105da.",
+            "competence": 5,
+            "level": 1
+        }
+    },
+    {
+        "pk": 38,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- wie, jak zastosowa\u0107 r\u00f3\u017cne rodzaje komunikat\u00f3w (formalne i nieformalne);\r\nnp. dostrzega, \u017ce innymi kana\u0142ami i w inny spos\u00f3b komunikuje si\u0119 z kolegami z klasy i nauczycielem.\r\n- umie korzysta\u0107 z podstawowych narz\u0119dzi komunikacyjnych;\r\nnp. porozumiewa si\u0119 za pomoc\u0105 telefonu kom\u00f3rkowego i komunikator\u00f3w internetowych.\r\n- wie, jakie s\u0105 podstawowe rodzaje komunikat\u00f3w i zna ich funkcje (obraz, d\u017awi\u0119k, s\u0142owo);\r\nnp. potrafi dopasowa\u0107 element muzyczny do odpowiadaj\u0105cej mu ilustracji.",
+            "competence": 5,
+            "level": 2
+        }
+    },
+    {
+        "pk": 39,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- wie, w jaki spos\u00f3b tworzy\u0107 komunikaty w zale\u017cno\u015bci od kontekstu;\r\nnp. inaczej napisze fragment bloga, a inaczej maila do nauczyciela.\r\n- wie, jak znale\u017a\u0107 w sieci osoby, kt\u00f3re podzielaj\u0105 jego zainteresowania, i umie si\u0119 z nimi komunikowa\u0107;\r\nnp. potrafi za\u0142o\u017cy\u0107 nowy w\u0105tek na forum lub do\u0142\u0105czy\u0107 si\u0119 do istniej\u0105cej ju\u017c grupy dyskusyjnej.\r\n- umie wybra\u0107 narz\u0119dzia / technologie w zale\u017cno\u015bci od potrzeb komunikacyjnych;\r\nnp. \u015bwiadomie w\u0142\u0105cza lub wy\u0142\u0105cza kamer\u0119 internetow\u0105 podczas rozmowy przez komunikator.\r\n- rozumie przebieg procesu komunikacji bezpo\u015bredniej i przez media;\r\nnp. potrafi wyja\u015bni\u0107 r\u00f3\u017cnice i podobie\u0144stwa mi\u0119dzy nadawc\u0105 i odbiorc\u0105 komunikatu, a tak\u017ce bierze odpowiedzialno\u015b\u0107 za komunikowane przez siebie tre\u015bci.",
+            "competence": 5,
+            "level": 3
+        }
+    },
+    {
+        "pk": 40,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- wie, jakie s\u0105 zasady komunikowania si\u0119 z innymi u\u017cytkownikami medi\u00f3w;\r\nnp. zna i potrafi stosowa\u0107 w praktyce zasady netykiety.\r\n- wie, jak u\u017cywa\u0107 r\u00f3\u017cnych rodzaj\u00f3w komunikat\u00f3w do przekazywania okre\u015blonych tre\u015bci w zale\u017cno\u015bci od celu i potrzeb;\r\nnp. ma \u015bwiadomo\u015b\u0107 tego, \u017ce czasami jedno zdj\u0119cie mo\u017ce wyrazi\u0107 wi\u0119cej ni\u017c wiele s\u0142\u00f3w.\r\n- wie, czym s\u0105 spo\u0142eczno\u015bci fanowskie oraz zjawisko fanfiction;\r\nnp. umie tworzy\u0107 sieci kontakt\u00f3w spo\u0142ecznych w internecie, w tym r\u00f3wnie\u017c grupy skupiaj\u0105ce cz\u0142onk\u00f3w subkultur fanowskich.",
+            "competence": 5,
+            "level": 4
+        }
+    },
+    {
+        "pk": 41,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- wie, jakie czynniki mog\u0105 mie\u0107 wp\u0142yw na przebieg komunikacji;\r\nnp. zdaje sobie spraw\u0119, \u017ce to, czy jego wiadomo\u015b\u0107 w rozmowie telefonicznej lub kontakcie mailowym zostanie odebrana zgodnie z jego intencj\u0105, zale\u017cy od sytuacji i mo\u017cliwo\u015bci odbiorcy.\r\n- umie skutecznie i precyzyjnie porozumiewa\u0107 si\u0119 z innymi, wykorzystuj\u0105c do tego r\u00f3\u017cnego rodzaju kana\u0142y komunikacji.",
+            "competence": 5,
+            "level": 5
+        }
+    },
+    {
+        "pk": 43,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- wie, \u017ce anonimowo\u015b\u0107 w sieci jest cz\u0119sto pozorna;\r\nzdaje sobie spraw\u0119, \u017ce ka\u017cdy jego ruch w internecie pozostawia \u015blad mo\u017cliwy potem do odtworzenia.\r\n- wie, \u017ce swoim zachowaniem nie wolno rani\u0107 innych i w procesie komunikacji nie dopuszcza si\u0119 zachowa\u0144 nieakceptowanych spo\u0142ecznie;\r\nnp. prowokowanie k\u0142\u00f3tni, u\u017cywanie obelg, trollowanie itp.\r\n- umie zachowywa\u0107 si\u0119 w spos\u00f3b asertywny i skutecznie komunikowa\u0107 si\u0119 w \u015brodowisku medialnym;\r\nnp. umie w spos\u00f3b jasny, konkretny, otwarty i szczery wyra\u017ca\u0107 swoje opinie, ch\u0119ci, potrzeby i uczucia, a tak\u017ce odrzuca\u0107 propozycje mog\u0105ce stanowi\u0107 zagro\u017cenie.\r\n- umie wyr\u00f3\u017cnia\u0107 komunikaty k\u0142amliwe, propagandowe, maj\u0105ce na celu manipulacj\u0119;\r\nnp. ogl\u0105daj\u0105c reklam\u0119 telewizyjn\u0105 dostrzega w niej elementy r\u00f3\u017cnych socjotechnik.\r\n- rozumie r\u00f3\u017cnice pomi\u0119dzy komunikacj\u0105 formaln\u0105 a nieformaln\u0105;\r\nnp. tworz\u0105c komunikat, uwzgl\u0119dnia specyfik\u0119 jego odbiorcy oraz kontekstu wypowiedzi (np. inaczej napisze maila do prze\u0142o\u017conego, a inaczej do kolegi z pracy).\r\n- wie, jak znale\u017a\u0107 w sieci osoby, kt\u00f3re podzielaj\u0105 jego zainteresowania, i umie si\u0119 z nimi komunikowa\u0107;\r\nnp. potrafi za\u0142o\u017cy\u0107 nowy w\u0105tek na forum lub do\u0142\u0105czy\u0107 si\u0119 do istniej\u0105cej ju\u017c grupy dyskusyjnej.",
+            "competence": 5,
+            "level": 7
+        }
+    },
+    {
+        "pk": 44,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- wie, jakie s\u0105 zasady komunikowania si\u0119 z innymi u\u017cytkownikami medi\u00f3w;\r\nnp. zna i potrafi stosowa\u0107 w praktyce zasady netykiety.\r\n- wie, jakie czynniki mog\u0105 mie\u0107 wp\u0142yw na przebieg komunikacji;\r\nnp. zdaje sobie spraw\u0119, \u017ce to, czy jego wiadomo\u015b\u0107 w rozmowie telefonicznej lub kontakcie mailowym zostanie odebrana zgodnie z jego intencj\u0105, zale\u017cy od sytuacji i mo\u017cliwo\u015bci odbiorcy.\r\n- umie nawi\u0105zywa\u0107 kontakty z osobami mieszkaj\u0105cymi w r\u00f3\u017cnych cz\u0119\u015bciach \u015bwiata, wie, jak r\u00f3\u017cnice kulturowe mog\u0105 wp\u0142ywa\u0107 na proces komunikacji;\r\nnp. potrafi aktywnie uczestniczy\u0107 w spo\u0142eczno\u015bciach ponadlokalnych, mi\u0119dzynarodowych.",
+            "competence": 5,
+            "level": 8
+        }
+    },
+    {
+        "pk": 45,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- umie wychwytywa\u0107 dzia\u0142ania niezgodne z prawem lub spo\u0142ecznie nieakceptowane pope\u0142niane przez lub wobec innych cz\u0142onk\u00f3w spo\u0142eczno\u015bci oraz reaguje na nie;\r\nnp. b\u0119d\u0105c administratorem forum moderuje i weryfikuje proces przep\u0142ywu informacji.\r\n- umie przeciwdzia\u0142a\u0107 barierom informacyjnym, wykluczeniu cyfrowemu, asymetrii informacji oraz prowadzi\u0107 dzia\u0142alno\u015b\u0107 informacyjn\u0105;\r\nnp. samodzielnie tworzy materia\u0142y edukacyjne oraz odpowiednie narz\u0119dzia medialne dla os\u00f3b maj\u0105cych trudno\u015bci z poruszaniem si\u0119 w \u015brodowisku medialnym.",
+            "competence": 5,
+            "level": 9
+        }
+    },
+    {
+        "pk": 46,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- umie dostrzec w przekazie medialnym elementy znanego mu otoczenia;\r\nnp. wyr\u00f3\u017cnia z t\u0142a medialnego znane mu miejsca.\r\n- umie intuicyjnie pos\u0142ugiwa\u0107 si\u0119 na poziomie elementarnym dost\u0119pnymi w jego otoczeniu mediami;\r\nnp. samodzielnie w\u0142\u0105czy telewizor na kana\u0142 z kresk\u00f3wkami lub uruchomi w telefonie aplikacj\u0119 z ulubion\u0105 gr\u0105.",
+            "competence": 6,
+            "level": 1
+        }
+    },
+    {
+        "pk": 47,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- wie, \u017ce \u015bwiat przedstawiany w mediach nie jest tym samym, co \u015bwiat do\u015bwiadczany bezpo\u015brednio;\r\nnp. zdaje sobie spraw\u0119, \u017ce nie wszystko to, co jest mo\u017cliwe w grach, jest mo\u017cliwe r\u00f3wnie\u017c w rzeczywisto\u015bci.\r\n- wie, jakie s\u0105 zasady bezpiecze\u0144stwa i higieny korzystania z medi\u00f3w;\r\nnp. ma \u015bwiadomo\u015b\u0107, \u017ce nie nale\u017cy zbyt d\u0142ugo siedzie\u0107 przed telewizorem lub monitorem komputera.\r\n- wie, \u017ce dzi\u0119ki mediom mo\u017cemy poznawa\u0107 \u015bwiat\r\nnp. zdaje sobie spraw\u0119, \u017ce na wybranym kanale telewizyjnym lub w internecie mo\u017ce \u00a0ogl\u0105da\u0107 rzeczy odleg\u0142e i nieznane mu z najbli\u017cszego otoczenia, np. filmy przyrodnicze.\r\n- umie korzysta\u0107 z r\u00f3\u017cnych \u017ar\u00f3de\u0142 i kana\u0142\u00f3w informacji;\r\nnp. potrafi wyszukiwa\u0107 informacje w internecie.",
+            "competence": 6,
+            "level": 2
+        }
+    },
+    {
+        "pk": 48,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- wie, jakie s\u0105 mo\u017cliwo\u015bci i zagro\u017cenia w korzystaniu z r\u00f3\u017cnych medi\u00f3w;\r\nnp. ma \u015bwiadomo\u015b\u0107, \u017ce nale\u017cy by\u0107 ostro\u017cnym w kontaktach z nieznajomymi poznanymi np. poprzez komunikator internetowy.\r\n- umie aktywnie korzysta\u0107 z nowych medi\u00f3w;\r\nnp. potrafi zapisa\u0107 si\u0119 do grupy dyskusyjnej i bra\u0107 w niej aktywny udzia\u0142 lub przy\u0142\u0105czy\u0107 si\u0119 do czatu.\r\n- umie w spos\u00f3b \u015bwiadomy korzysta\u0107 z r\u00f3\u017cnych kana\u0142\u00f3w informacji;\r\nnp. znajduje kilka r\u00f3\u017cnych \u017ar\u00f3de\u0142 odnosz\u0105cych si\u0119 do tej samej informacji i dokonuje ich weryfikacji.\r\n- rozumie podstawowe zasady bezpiecze\u0144stwa w przestrzeni cyfrowej;\r\nnp. nie pobiera z internetu tre\u015bci nieznanych lub pochodz\u0105cych z niepewnych \u017ar\u00f3de\u0142.",
+            "competence": 6,
+            "level": 3
+        }
+    },
+    {
+        "pk": 49,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- wie, jakie s\u0105 og\u00f3lne zasady dzia\u0142ania i umie wykorzystywa\u0107 r\u00f3\u017cne narz\u0119dzia medialne w zale\u017cno\u015bci od specyfiki otoczenia;\r\nnp. w miar\u0119 potrzeby komunikuje si\u0119 za pomoc\u0105 telefonu kom\u00f3rkowego,\r\nkomunikatora internetowego lub pisz\u0105c na forum.\r\n- wie, jak grupa i otoczenie wp\u0142ywaj\u0105 na jego \u017cycie;\r\nnp. umie dostrzec wp\u0142yw komentarzy pod swoim wpisem na portalu spo\u0142eczno\u015bciowym na w\u0142asne wybory, decyzje i upodobania.\r\n- umie aktywnie uczestniczy\u0107 w wybranych spo\u0142eczno\u015bciach on-line;\r\nnp. wymienia si\u0119 informacjami, wyra\u017ca opinie i prowadzi dyskusje w r\u00f3\u017cnych sieciach spo\u0142ecznych w internecie.",
+            "competence": 6,
+            "level": 4
+        }
+    },
+    {
+        "pk": 50,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- wie, \u017ce r\u00f3\u017cne grupy istniej\u0105ce w otoczeniu medialnym maj\u0105 sw\u00f3j specyficzny charakter, zasady funkcjonowania oraz dynamik\u0119;\r\nnp. wskazuje r\u00f3\u017cnice pomi\u0119dzy spo\u0142eczno\u015bciami on-line os\u00f3b, kt\u00f3re si\u0119 nigdy nie spotka\u0142y, a tymi, kt\u00f3re znaj\u0105 si\u0119 np. ze szko\u0142y.\r\n- umie wykorzystywa\u0107 spo\u0142eczno\u015bciowy potencja\u0142 sieci dla realizacji w\u0142asnych cel\u00f3w;\r\nnp. potrafi w zale\u017cno\u015bci od potrzeby znale\u017a\u0107 po\u017c\u0105dany produkt lub us\u0142ug\u0119 i pozna\u0107 opinie innych u\u017cytkownik\u00f3w na jej temat.\r\n- rozumie procesy powstawania grup i budowania sieci spo\u0142ecznych;\r\nnp. dostrzega r\u00f3\u017cnice w sposobie uczestnictwa w spontanicznie zebranej grupie os\u00f3b w internecie, a r\u00f3wnolegle dzia\u0142aj\u0105cej grupie graczy spotykaj\u0105cych si\u0119 regularnie on-line.",
+            "competence": 6,
+            "level": 5
+        }
+    },
+    {
+        "pk": 52,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- umie pos\u0142ugiwa\u0107 si\u0119 nowymi technologiami w zakresie umo\u017cliwiaj\u0105cym uczestnictwo w spo\u0142e\r\n- umie aktywnie uczestniczy\u0107 w wybranych spo\u0142eczno\u015bciach on-line;\r\nnp. wymienia si\u0119 informacjami, wyra\u017ca opinie i prowadzi dyskusje w r\u00f3\u017cnych sieciach spo\u0142ecznych w internecie.\r\n- zna zasady bezpiecze\u0144stwa i higieny korzystania z medi\u00f3w.\r\n- umie kszta\u0142towa\u0107 swoje relacje przez media tak, by nie zaburza\u0142y one relacji bezpo\u015brednich;\r\nnp. bezpo\u015brednie kontakty z najbli\u017cszymi osobami uzupe\u0142nia o mo\u017cliwo\u015bci komunikacji przez media, a nie zast\u0119puje ich nimi.",
+            "competence": 6,
+            "level": 7
+        }
+    },
+    {
+        "pk": 53,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- wie, \u017ce internet to wi\u0119cej ni\u017c tylko medium;\r\nma \u015bwiadomo\u015b\u0107, \u017ce jest to nowy rodzaj rzeczywisto\u015bci, w kt\u00f3rym toczy si\u0119 r\u00f3wnoleg\u0142e, cz\u0119sto tak samo prawdziwe \u017cycie, za\u015b komunikacja przez media jest tylko innym, r\u00f3wnorz\u0119dnym i r\u00f3wnoprawnym sposobem komunikacji z lud\u017ami.\r\n- rozumie zagro\u017cenia mog\u0105ce p\u0142yn\u0105\u0107 z uzale\u017cnienia od internetu.\r\n- wie, \u017ce r\u00f3\u017cne grupy istniej\u0105ce w otoczeniu medialnym maj\u0105 sw\u00f3j specyficzny charakter, zasady funkcjonowania oraz dynamik\u0119;\r\nnp. wskazuje r\u00f3\u017cnice pomi\u0119dzy spo\u0142eczno\u015bciami on-line os\u00f3b, kt\u00f3re si\u0119 nigdy nie spotka\u0142y, a tymi, kt\u00f3re znaj\u0105 si\u0119 np. z pracy.\r\n- umie wykorzystywa\u0107 spo\u0142eczno\u015bciowy potencja\u0142 sieci dla realizacji w\u0142asnych cel\u00f3w;\r\nnp. potrafi w zale\u017cno\u015bci od potrzeby znale\u017a\u0107 po\u017c\u0105dany produkt lub us\u0142ug\u0119 i pozna\u0107 opinie innych u\u017cytkownik\u00f3w na jej temat.",
+            "competence": 6,
+            "level": 8
+        }
+    },
+    {
+        "pk": 54,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- umie zarz\u0105dza\u0107 infrastruktur\u0105 informatyczn\u0105. Posiada odpowiednie umiej\u0119tno\u015bci techniczne pozwalaj\u0105ce na dob\u00f3r specyficznych narz\u0119dzi i technologii do realizacji okre\u015blonych zada\u0144;\r\nnp. potrafi od podstaw stworzy\u0107 i skutecznie pozycjonowa\u0107 stron\u0119 internetow\u0105 lub portal.\r\n- rozumie procesy powstawania grup i budowania sieci spo\u0142ecznych, umie nimi zarz\u0105dza\u0107.",
+            "competence": 6,
+            "level": 9
+        }
+    },
+    {
+        "pk": 82,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- wie, \u017ce postacie obserwowane w mediach, ukazywane na ekranie telewizyjnym mog\u0105 by\u0107 fikcyjne;\r\nnp. wie, \u017ce postacie z bajek telewizyjnych tj. Gumisie, Kaczor Donald nie istniej\u0105 w rzeczywisto\u015bci, a s\u0105 jedynie wymys\u0142em cz\u0142owieka.\r\n- rozumie r\u00f3\u017cnic\u0119 pomi\u0119dzy bezpo\u015bredni\u0105 rozmow\u0105 a komunikacj\u0105 przez media;\r\nnp. wie, \u017ce podczas rozmowy telefonicznej s\u0142yszymy jedynie g\u0142os rozm\u00f3wcy, ale mo\u017ce on pozostawa\u0107 daleko od nas.\r\n- wie, \u017ce s\u0105 r\u00f3\u017cne sposoby zapisywania i przekazywania s\u0142\u00f3w, obraz\u00f3w i d\u017awi\u0119k\u00f3w, \u017ce mo\u017cna przekazywa\u0107 t\u0119 sam\u0105 tre\u015b\u0107 za pomoc\u0105 r\u00f3\u017cnych urz\u0105dze\u0144;\r\nnp. wie, \u017ce mo\u017cna nagra\u0107 i odtwarza\u0107 odg\u0142osy przyrody i w\u0142asnej mowy, rysowa\u0107, a potem zeskanowa\u0107 rysunek i ogl\u0105da\u0107 go na ekranie komputera, telewizora lub telefonu.\r\n- znai rozr\u00f3\u017cnia r\u00f3\u017cnorakie urz\u0105dzenia s\u0142u\u017c\u0105ce do przekazywania informacji;\r\nnp. umie wskazywa\u0107, podawa\u0107 nazwy oraz opisywa\u0107 w\u0142asnymi s\u0142owami, do czego s\u0142u\u017c\u0105 radio, telewizja, komputer przy\u0142\u0105czony do internetu, telefon kom\u00f3rkowy.",
+            "competence": 10,
+            "level": 1
+        }
+    },
+    {
+        "pk": 83,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- wie, \u017ce same przekazy audiowizualne, nawet prezentuj\u0105ce realnie istniej\u0105ce postacie, r\u00f3\u017cni\u0105 si\u0119 od spotkania w rzeczywistym \u015bwiecie;\r\nnp. postacie obserwowane w telewizji, na ekranie kinowym lub komputera mog\u0105 wygl\u0105da\u0107 odmiennie, kiedy spotkamy je osobi\u015bcie.\r\n- umie rozr\u00f3\u017cnia\u0107 pomi\u0119dzy potocznym j\u0119zykiem, kt\u00f3rym m\u00f3wimy do rodzic\u00f3w i r\u00f3wie\u015bnik\u00f3w, a s\u0142owami p\u0142yn\u0105cymi z telewizji;\r\nnp. wie, czym r\u00f3\u017cni si\u0119 j\u0119zyk ogl\u0105danej bajki czy transmisji sportowej od codziennej rozmowy.\r\n- zna r\u00f3\u017cne formy przekaz\u00f3w audialnych i audiowizualnych, potrafi wskazywa\u0107 na r\u00f3\u017cnice mi\u0119dzy nimi oraz sposobem ich odbioru;\r\nnp. potrafi wskaza\u0107, czym r\u00f3\u017cni si\u0119 bajka na DVD, emitowana w telewizji, nagrana w formie s\u0142uchowiska na audiobooku, drukowana w formie ksi\u0105\u017cki lub wydana jako e-book.\r\n- zna r\u00f3\u017cnic\u0119 pomi\u0119dzy przekazem tekstowym, d\u017awi\u0119kowym i wideo, potrafi wskaza\u0107 na korzy\u015bci i ograniczenia w odbiorze tych przekaz\u00f3w;\r\nnp. wie, \u017ce lektura s\u0142owa drukowanego wymaga wi\u0119kszego zaanga\u017cowania uwagi ni\u017c telewizja, \u017ce druk bardziej oddzia\u0142uje na nasze my\u015bli, a telewizja na emocje; \u017ce radio pozwala wykonywa\u0107 inne czynno\u015bci i najmniej anga\u017cuje nasz\u0105 uwag\u0119 po\u015br\u00f3d wy\u017cej wymienionych.",
+            "competence": 10,
+            "level": 2
+        }
+    },
+    {
+        "pk": 84,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- zna poj\u0119cie technologii analogowej i cyfrowej;\r\nnp. wie, \u017ce media cyfrowe opieraj\u0105 si\u0119 na kodowaniu przekaz\u00f3w w formie zapisu binarnego (zerojedynkowego).\r\n- umie w\u0142asnymi s\u0142owami wskaza\u0107 najprostsze r\u00f3\u017cnice mi\u0119dzy zapisami analogowymi i cyfrowymi oraz wskaza\u0107 przyk\u0142ady urz\u0105dze\u0144 do zapisu i odtwarzania w obu technologiach;\r\nnp. wie, czym r\u00f3\u017cni si\u0119 fotografia cyfrowa od wykonanej na kliszy, jaki jest proces jej powstawania, czym si\u0119 r\u00f3\u017cni\u0105 te procesy.\r\n- zna podstawowe poj\u0119cia zwi\u0105zane z j\u0119zykiem filmu oraz fotografii zar\u00f3wno w odniesieniu do medi\u00f3w analogowych, jak i cyfrowych;\r\nnp. wie, czym jest kadr, uj\u0119cie, monta\u017c, zna proces powstawania fotografii i filmu w technologii analogowej i cyfrowej.\r\n- rozumie poj\u0119cie multimedi\u00f3w jako technologii integruj\u0105cych r\u00f3\u017cne techniki przekazu;\r\nnp. wie, \u017ce \u0142\u0105cz\u0105 one d\u017awi\u0119ki, teksty drukowane, fotografie i filmy, \u017ce dzi\u0119ki technologii cyfrowej mamy wi\u0119ksz\u0105 mo\u017cliwo\u015b\u0107 nie tylko modyfikowania, ale i \u0142\u0105czenia zapisywanych dot\u0105d w odmienny spos\u00f3b przekaz\u00f3w.",
+            "competence": 10,
+            "level": 3
+        }
+    },
+    {
+        "pk": 85,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- rozumie poj\u0119cie hipertekstu oraz umie wyja\u015bni\u0107 r\u00f3\u017cnic\u0119 mi\u0119dzy hipertekstem a tekstem linearnym;\r\nnp. wie, \u017ce s\u0105 to powi\u0105zane ze sob\u0105 odsy\u0142aczami teksty elektroniczne, co u\u0142atwia tworzenie skojarze\u0144 i poznawanie wiedzy, wie, \u017ce spos\u00f3b lektury hipertekst\u00f3w jest r\u00f3\u017cny od lektury drukowanych ksi\u0105\u017cek.\r\n- umie rozr\u00f3\u017cnia\u0107 podstawowe gatunki filmowe i telewizyjne;\r\nnp. potrafi opisa\u0107 w\u0142asnymi s\u0142owami, czym charakteryzuj\u0105 si\u0119 thriller, komedia romantyczna, telenowela dokumentalna, talk show.\r\n- rozumie zjawisko konwergencji gatunk\u00f3w medialnych;\r\nnp. zdaje sobie spraw\u0119, jak tradycyjne audycje i programy telewizyjne mo\u017cna odbiera\u0107 poprzez internet w formie podcast\u00f3w i wideocast\u00f3w, transmisji strumieniowych, jakie zmiany to powoduje dla tre\u015bci przekaz\u00f3w.\r\n- dostrzega, w jaki spos\u00f3b ten sam tekst kultury medialnej mo\u017ce by\u0107 przedstawiany za pomoc\u0105 r\u00f3\u017cnych no\u015bnik\u00f3w przekazu i reklamy;\r\nnp. strony internetowe, film kinowy i DVD, gad\u017cety zwi\u0105zane z seri\u0105 wydawnicz\u0105 o Harrym Potterze.",
+            "competence": 10,
+            "level": 4
+        }
+    },
+    {
+        "pk": 86,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- zna cechy r\u00f3\u017cnicuj\u0105ce przekazu tekstowego dostosowanego do r\u00f3\u017cnych medi\u00f3w i potrafi dostosowywa\u0107 form\u0119 przekazu do medium;\r\nnp. wie, czym r\u00f3\u017cni si\u0119 dany tekst zapisany w formie linearnej, strony internetowej, e-maila, czatu, SMS-a, postu w serwisie spo\u0142eczno\u015bciowym, wsp\u00f3lnie pisanego dokumentu w sieci \u00a0(booksprint).\r\n- rozumie poj\u0119cie interfejsu w relacjach u\u017cytkownik-medium;\r\nnp. potrafi scharakteryzowa\u0107 r\u00f3\u017cnice w sposobie korzystania z tabletu i z gazety, z interfejsu graficznego (GUI) i z interfejsu tekstowego aplikacji komputerowych.\r\n- rozumie poj\u0119cie ekranu, umie opisa\u0107 jego rol\u0119 i przemiany w kulturze audiowizualnej;\r\nnp. umie rozr\u00f3\u017cni\u0107 pomi\u0119dzy odbiorem filmu w kinie, na ekranie telewizora, komputera, tabletu.",
+            "competence": 10,
+            "level": 5
+        }
+    },
+    {
+        "pk": 87,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- rozumie poj\u0119cie medialnej reprezentacji rzeczywisto\u015bci i umie wskaza\u0107 na jej rol\u0119 i ograniczenia w poznaniu;\r\nnp. potrafi scharakteryzowa\u0107 spos\u00f3b, w jaki tw\u00f3rcy medi\u00f3w konstruuj\u0105 przekazy, opisa\u0107, czym gatunkowo przekazy audiowizualne r\u00f3\u017cni\u0105 si\u0119 od rzeczywisto\u015bci poznawanej bezpo\u015brednio, dlaczego m\u00f3wimy, \u017ce s\u0105 \u201eobrazami\u201d rzeczywisto\u015bci, potrafi wyja\u015bni\u0107 zjawisko teleobecno\u015bci podmiotu poznania w kategoriach filozoficznych.\r\n- rozumie poj\u0119cie tekstu w szerokim kulturowym znaczeniu, poj\u0119cia kodowania i dekodowania, znaku, semiotyki;\r\nnp. wie, w jaki spos\u00f3b mo\u017cemy postrzega\u0107 film, rze\u017ab\u0119, architektur\u0119 jako teksty kultury z\u0142o\u017cone z okre\u015blonych znak\u00f3w i kod\u00f3w j\u0119zykowych.\r\n- rozumie poj\u0119cie new media literacies;\r\nnp. potrafi opisa\u0107 w kategoriach gatunku medialnego nie tylko przekazy audiowizualne, ale tak\u017ce sieci spo\u0142eczno\u015bciowe, gry wideo, potrafi analizowa\u0107 i scharakteryzowa\u0107 obraz \u015bwiata, kt\u00f3ry tworz\u0105 te przekazy.",
+            "competence": 10,
+            "level": 6
+        }
+    },
+    {
+        "pk": 88,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- rozumie r\u00f3\u017cnice mi\u0119dzy gatunkami medialnymi;\r\nnp. potrafi odr\u00f3\u017cni\u0107 program informacyjny, debat\u0119 w studio telewizyjnym, serial, thriller, talent show i scharakteryzowa\u0107 ich g\u0142\u00f3wne cechy.\r\n- potrafi formu\u0142owa\u0107 komunikaty informacyjne w r\u00f3\u017cnych formach, tak\u017ce za po\u015brednictwem wybranych \u015brodk\u00f3w komunikacji internetowej, takich jak np. poczta elektroniczna, czat, komunikator g\u0142osowy, Skype.",
+            "competence": 10,
+            "level": 7
+        }
+    },
+    {
+        "pk": 89,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- rozumie specyfik\u0119 poszczeg\u00f3lnych gatunk\u00f3w medialnych i innych zagadnie\u0144;\r\nnp. zwi\u0105zanych z kadrowaniem w filmie, znajomo\u015bci\u0105 form i zasad komunikowania si\u0119 w internecie, w spo\u0142eczno\u015bciach sieciowych.",
+            "competence": 10,
+            "level": 8
+        }
+    },
+    {
+        "pk": 90,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- umie tworzy\u0107 przekazy medialne (audiowizualne, multimedialne), pos\u0142uguj\u0105c si\u0119 r\u00f3\u017cnymi gatunkami dziennikarskimi i medialnymi w swobodny spos\u00f3b;\r\nnp. potrafi za\u0142o\u017cy\u0107 stron\u0119 internetow\u0105 lub bloga, przygotowa\u0107 film amatorski, zredagowa\u0107 gazet\u0119 \u015brodowiskow\u0105, biuletyn elektroniczny, pos\u0142uguj\u0105c si\u0119 swobodnie aplikacjami umo\u017cliwiaj\u0105cymi wykonanie tych zada\u0144.",
+            "competence": 10,
+            "level": 9
+        }
+    },
+    {
+        "pk": 73,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- wie, \u017ce pewne przekazy medialne mog\u0105 zach\u0119ca\u0107 nas do czego\u015b;\r\nnp. do zakupu okre\u015blonego produktu, zabawki, czy te\u017c wykonania jakiej\u015b czynno\u015bci, obejrzenia bajki w telewizji.\r\n- wie, kt\u00f3re przekazy s\u0142u\u017c\u0105 zabawie, a kt\u00f3re dotycz\u0105 powa\u017cnych spraw, informuj\u0105 o pewnych wydarzeniach;\r\nnp. umie rozr\u00f3\u017cni\u0107 pomi\u0119dzy bajk\u0105 a programem dla dzieci, w kt\u00f3rym podawane s\u0105 wiadomo\u015bci dotycz\u0105ce naszego \u017cycia.",
+            "competence": 9,
+            "level": 1
+        }
+    },
+    {
+        "pk": 74,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- znapoj\u0119cie reklamy i umie zidentyfikowa\u0107 przekazy reklamowe, kt\u00f3re go otaczaj\u0105;\r\nnp. potrafi rozpoznawa\u0107 i por\u00f3wnywa\u0107 reklamy na ulicy, w prasie, telewizji, internecie.\r\n\r\n- umie rozr\u00f3\u017cni\u0107 pomi\u0119dzy przekazami medialnymi, kt\u00f3re wywo\u0142uj\u0105 r\u00f3\u017cne emocje;\r\nnp. strach, smutek, rado\u015b\u0107.",
+            "competence": 9,
+            "level": 2
+        }
+    },
+    {
+        "pk": 75,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- wie, jakie podstawowe elementy powinna zawiera\u0107 ka\u017cda informacja, tak\u017ce medialna;\r\nnp. umie analizowa\u0107 dany przekaz wiadomo\u015bci telewizyjnych pod k\u0105tem kategorii dlaczego, kto, co, kiedy, gdzie.\r\n- rozumie r\u00f3\u017cnic\u0119 pomi\u0119dzy informacj\u0105 a opini\u0105 i umie formu\u0142owa\u0107 komunikaty zr\u00f3\u017cnicowane pod wzgl\u0119dem funkcji w mediach, tak\u017ce spo\u0142eczno\u015bciowych;\r\nnp. umie poda\u0107 informacj\u0119 o danym przedsi\u0119wzi\u0119ciu spo\u0142ecznym czy kulturalnym oraz wyrazi\u0107 swoj\u0105 opini\u0119; widzi r\u00f3\u017cnic\u0119 pomi\u0119dzy tymi dwoma rodzajami wypowiedzi medialnych.",
+            "competence": 9,
+            "level": 3
+        }
+    },
+    {
+        "pk": 76,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- umie dyskutowa\u0107, formu\u0142uj\u0105c w\u0142asne opinie w mediach spo\u0142eczno\u015bciowych przy poszanowaniu godno\u015bci dyskutant\u00f3w i koncentrowaniu si\u0119 na merytorycznej stronie przekazu;\r\nnp. zna podstawy etykiety j\u0119zykowej w komunikacji internetowej.\r\n- umie przekonywa\u0107 do swoich racji innych, uzasadniaj\u0105c i obrazuj\u0105c swoje przekonania tak\u017ce przy u\u017cyciu \u015brodk\u00f3w audiowizualnych;\r\nnp. potrafi zaprezentowa\u0107 swoje stanowisko, przedstawi\u0107 je w punktach, zilustrowa\u0107 przyk\u0142adami, pos\u0142u\u017cy\u0107 si\u0119 obrazami, statystykami przestawionymi w formie wizualnej.",
+            "competence": 9,
+            "level": 4
+        }
+    },
+    {
+        "pk": 77,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- umie tworzy\u0107 przekazy informacyjne\r\ni reklamowe;\r\nnp. inicjatyw spo\u0142ecznych, kulturalnych, w kt\u00f3rych bierze udzia\u0142.\r\n- wie, \u017ce pewne przekazy informacyjne mog\u0105 zawiera\u0107 elementy rozrywki, potrafi wskaza\u0107 przyk\u0142ady takiego po\u0142\u0105czenia w r\u00f3\u017cnych gatunkach medialnych;\r\nnp. umie wskaza\u0107, co w danym przekazie audiowizualnym jest elementem telewizyjnego show, a co ma warto\u015b\u0107 poznawcz\u0105.",
+            "competence": 9,
+            "level": 5
+        }
+    },
+    {
+        "pk": 78,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- zna zagadnienia wsp\u00f3\u0142czesnej teorii wywierania wp\u0142ywu na spo\u0142ecze\u0144stwo, obejmuj\u0105cej zar\u00f3wno reklam\u0119, jak i elementy marketingu;\r\nnp. umie wskaza\u0107 przyk\u0142ady technik stosowanych przez polityk\u00f3w, sprzedawc\u00f3w w przekazach audiowizualnych dobieranych w celu przekonania nas do swojej racji lub produktu.\r\n- rozumie poj\u0119cia infotainment i edutaintment, potrafi \u0142\u0105czy\u0107 elementy edukacji opartej na przekazach werbalnych z reprezentacjami wizualnymi, d\u017awi\u0119kowymi;\r\nnp. umie tworzy\u0107 notatki, prezentacje, kt\u00f3re zawieraj\u0105 nie tylko informacje, ale r\u00f3wnie\u017c przekazy wizualne wyra\u017caj\u0105ce okre\u015blone emocje, potrafi pos\u0142ugiwa\u0107 si\u0119 j\u0119zykiem anegdoty, humoru w prezentowaniu informacji.",
+            "competence": 9,
+            "level": 6
+        }
+    },
+    {
+        "pk": 79,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- dostrzega r\u00f3\u017cnic\u0119 pomi\u0119dzy przekazami informacyjnymi, opiniami a perswazj\u0105;\r\nnp. w reklamie, w wypowiedziach polityk\u00f3w.\r\n- rozr\u00f3\u017cnia przekaz informacyjny od rozrywkowego;\r\nnp. umie okre\u015bli\u0107, co ma warto\u015b\u0107 poznawcz\u0105 w danym przekazie, a co jest elementem, kt\u00f3ry ma budzi\u0107 emocje odbiorcy.",
+            "competence": 9,
+            "level": 7
+        }
+    },
+    {
+        "pk": 80,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- potrafi formu\u0142owa\u0107 poprawne, jasne i logiczne komunikaty informacyjne w mowie i pi\u015bmie, tak\u017ce za po\u015brednictwem\r\n- potrafi wykorzysta\u0107 r\u00f3\u017cne media do formu\u0142owania komunikat\u00f3w perswazyjnych;\r\nnp. forum internetowe.\r\n- sprawnie pos\u0142uguje si\u0119 r\u00f3\u017cnymi \u015brodkami retorycznymi w formu\u0142owanych przez siebie komunikatach. Umie odwo\u0142ywa\u0107 si\u0119 do emocji w swoim przekazie stosownie do potrzeb, wywo\u0142ywa\u0107 wzruszenie;\r\nnp. potrafi przygotowa\u0107 i wyg\u0142osi\u0107 przem\u00f3wienie.",
+            "competence": 9,
+            "level": 8
+        }
+    },
+    {
+        "pk": 81,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- potrafi formu\u0142owa\u0107 skuteczne komunikaty informacyjne w mowie i pi\u015bmie, dostosowane do specyfiki r\u00f3\u017cnych medi\u00f3w komunikacyjnych;\r\nnp. mo\u017ce swobodnie operowa\u0107 j\u0119zykiem publicystycznym, informacyjnym, urz\u0119dowym, naukowym.",
+            "competence": 9,
+            "level": 9
+        }
+    },
+    {
+        "pk": 64,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- umie wyra\u017ca\u0107 swoj\u0105 opini\u0119 o danym przekazie i uzasadni\u0107 j\u0105 swoimi s\u0142owami;\r\nnp. m\u00f3wi: \u201epodoba mi si\u0119 ta bajka, bo te postacie s\u0105 bardzo zabawne\u201d.\r\n- wie, \u017ce zar\u00f3wno s\u0142owa, jak i obrazy maj\u0105 swoje specyficzne znaczenie;\r\nnp. wie, \u017ce mo\u017cna poinformowa\u0107 kogo\u015b zar\u00f3wno za pomoc\u0105 s\u0142owa, jak i rysunku.",
+            "competence": 8,
+            "level": 1
+        }
+    },
+    {
+        "pk": 65,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- umieoceni\u0107 dany przekaz medialny w kategoriach estetycznych, uzasadniaj\u0105c swoj\u0105 opini\u0119;\r\nnp. umie powiedzie\u0107, \u017ce w tym filmie s\u0105 interesuj\u0105ce efekty specjalne, ale niezbyt interesuj\u0105ca fabu\u0142a, a bohater grany przez aktora jest osob\u0105 godn\u0105 na\u015bladowania, poniewa\u017c...\r\n- umie pos\u0142ugiwa\u0107 si\u0119 emotikonami w komunikacji SMS-owej i internetowej;\r\nnp. zna znaczenie symbolu :) czy :(\r\n- zna i rozumie r\u00f3\u017cnice pomi\u0119dzy komunikowaniem za pomoc\u0105 s\u0142\u00f3w i gest\u00f3w;\r\nnp. wie, co oznacza gest OK (uniesionego kciuka) lub V, kt\u00f3re gesty s\u0105 uznawane za obra\u017aliwe w danym kr\u0119gu kulturowym.",
+            "competence": 8,
+            "level": 2
+        }
+    },
+    {
+        "pk": 66,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- rozumie zjawisko wulgaryzacji kultury medialnej, umie ocenia\u0107 i wybiera\u0107 przekazy, kt\u00f3re temu przeciwdzia\u0142aj\u0105;\r\nnp. potrafi skrytykowa\u0107 film lub gr\u0119 komputerow\u0105 wskazuj\u0105c jej niski poziom, s\u0142u\u017c\u0105cy jedynie prostej rozrywce, brak przes\u0142ania, ub\u00f3stwo \u015brodk\u00f3w obrazowania czy warstwy d\u017awi\u0119kowej, agresywny j\u0119zyk przekazu.\r\n- umie przet\u0142umaczy\u0107 emocje wyra\u017cane emotikonami na zdania opisuj\u0105ce i uzasadniaj\u0105ce te emocje w komunikacji internetowej. Np. u\u017cywa stwierdze\u0144 takich jak: \u201eJestem smutny i rozczarowany, poniewa\u017c...\u201d zamiast skr\u00f3tu :(",
+            "competence": 8,
+            "level": 3
+        }
+    },
+    {
+        "pk": 67,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- zna podstawowe poj\u0119cia z zakresu estetyki, krytyki kulturalnej;\r\nnp. potrafi tworzy\u0107 recenzje przekaz\u00f3w medialnych, swobodnie operuj\u0105c przyk\u0142adami i por\u00f3wnaniami dzie\u0142 audiowizualnych.\r\n- wie, jakie znaczenie w komunikacji maj\u0105 poszczeg\u00f3lne gesty, mimika, postawy cia\u0142a czy odleg\u0142o\u015b\u0107 pomi\u0119dzy osobami i umie wskazywa\u0107 przyk\u0142ady w przekazach audiowizualnych;\r\nnp. potrafi okre\u015bli\u0107 na podstawie zachowa\u0144 polityk\u00f3w w studio telewizyjnym ich stosunek do omawianych kwestii.",
+            "competence": 8,
+            "level": 4
+        }
+    },
+    {
+        "pk": 68,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- rozumie i potrafi opisa\u0107 zasady zwi\u0105zane z savoir vivre w zakresie komunikowania si\u0119 z innymi osobami za po\u015brednictwem medi\u00f3w;\r\nnp. wie, o jakiej porze mo\u017cna zadzwoni\u0107 do danej osoby ze wzgl\u0119du na pe\u0142nion\u0105 funkcj\u0119, w jaki spos\u00f3b powinno si\u0119 odnosi\u0107 do go\u015bci w studio telewizyjnym itp.\r\n- umie stosowa\u0107 odpowiedni\u0105 dykcj\u0119, intonacj\u0119 g\u0142osu i mow\u0119 cia\u0142a podczas komunikacji bezpo\u015bredniej oraz pos\u0142ugiwa\u0107 si\u0119 symbolami w komunikacji wizualnej;\r\nnp. umie dobra\u0107 ilustracje do prezentacji wyra\u017caj\u0105cej r\u00f3\u017cne emocje, przekonania.",
+            "competence": 8,
+            "level": 5
+        }
+    },
+    {
+        "pk": 69,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- umiewykorzysta\u0107 podstawowe poj\u0119cia z zakresu retoryki, umie przygotowa\u0107 i wyg\u0142osi\u0107 publiczne przem\u00f3wienie na zaj\u0119ciach akademickich;\r\nnp. potrafi wyst\u0105pi\u0107 publicznie w studio radiowym i telewizyjnym.\r\n- rozumie zagadnienia z zakresu komunikowania i kultury medialnej;\r\nnp. potrafi poda\u0107 podstawowe modele komunikowania, opisa\u0107 charakter przemian kulturowych (np. j\u0119zykowych) wywo\u0142anych przez zmiany technologiczne.",
+            "competence": 8,
+            "level": 6
+        }
+    },
+    {
+        "pk": 70,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- rozumie potrzeb\u0119 i specyfik\u0119 dostosowania j\u0119zyka do komunikacji z r\u00f3\u017cnymi grupami odbiorc\u00f3w za po\u015brednictwem medi\u00f3w;\r\nnp. wie, jakie s\u0105 psychologiczne i spo\u0142eczne uwarunkowania j\u0119zyka kierowanego do dzieci, podw\u0142adnych, prze\u0142o\u017conych, urz\u0119dnik\u00f3w, dziennikarzy.\r\n- zna znaczenie mowy cia\u0142a, rozpoznaje podstawowe gesty, pozycje cia\u0142a, mimik\u0119, rozumie znaczenie odleg\u0142o\u015bci od innych os\u00f3b w komunikacji, dostosowywania intonacji g\u0142osu;\r\nnp. potrafi wskazywa\u0107 je w \u017cyciu publicznym.",
+            "competence": 8,
+            "level": 7
+        }
+    },
+    {
+        "pk": 71,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- umie tworzy\u0107 przekazy medialne w pracy i \u017cyciu osobistym.\r\n- dba o logiczny, jasny i czytelny przekaz swoich komunikat\u00f3w.\r\n- potrafi wypowiada\u0107 si\u0119 podczas audycji radiowej i telewizyjnej, dyskusji internetowej z poszanowaniem zasad dyskusji i godno\u015bci jej uczestnik\u00f3w.",
+            "competence": 8,
+            "level": 8
+        }
+    },
+    {
+        "pk": 72,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- swobodnie dostosowuje sw\u00f3j przekaz do konkretnej osoby i sytuacji komunikacyjnej.\r\n- biegle zna j\u0119zyk cia\u0142a, umie si\u0119 nim pos\u0142ugiwa\u0107 w komunikacji publicznej, w kontaktach z mediami instytucjonalnymi. Potrafi dostosowa\u0107 sw\u00f3j przekaz do sytuacji medialnej, gatunku, formatu.\r\n- swobodnie wyst\u0119puje przed kamer\u0105, ma i stosuje wiedz\u0119 z zakresu wywierania wp\u0142ywu na inne osoby za pomoc\u0105 mowy cia\u0142a i intonacji g\u0142osu.\r\n- potrafiprzekazywa\u0107 swoj\u0105 wiedz\u0119 i umiej\u0119tno\u015bci w zakresie komunikacji innym;\r\nnp. mo\u017ce prowadzi\u0107 szkolenia i warsztaty z zakresu edukacji medialnej, etykiety komunikacyjnej.",
+            "competence": 8,
+            "level": 9
+        }
+    },
+    {
+        "pk": 91,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- wie, za pomoc\u0105 jakich narz\u0119dzi medialnych mo\u017cna przygotowa\u0107 zdj\u0119cie, nagranie d\u017awi\u0119kowe, kr\u00f3tki film wideo, rysunek.\r\n- zna podstawowe poj\u0119cia zwi\u0105zane z korzystaniem z medi\u00f3w;\r\nnp. klikanie, ikona.\r\n- pr\u00f3buje samodzielnie korzysta\u0107 z medialnych narz\u0119dzi;\r\nnp. umie korzysta\u0107 z ekranu dotykowego lub pos\u0142ugiwa\u0107 si\u0119 myszk\u0105.\r\n- umie utrwala\u0107 subiektywny obraz \u015bwiata za pomoc\u0105 narz\u0119dzi medialnych;\r\n\r\nnp. fotografuje swoje zabawki.",
+            "competence": 11,
+            "level": 1
+        }
+    },
+    {
+        "pk": 92,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- umie przygotowa\u0107 z zastosowaniem prostego sprz\u0119tu: zdj\u0119cie, nagranie w\u0142asnego g\u0142osu lub d\u017awi\u0119k\u00f3w otoczenia, nagranie kr\u00f3tkiego filmu wideo, narysowa\u0107 prosty obraz przy u\u017cyciu odpowiedniego oprogramowania, napisa\u0107 kr\u00f3tki tekst w edytorze tekstu.\r\n- umie, wsp\u00f3lnie z innymi uczniami, przygotowa\u0107 prost\u0105 opowie\u015b\u0107 z wykorzystaniem komunikat\u00f3w medialnych jednego typu;\r\nnp. serii zdj\u0119\u0107, wykonanych przez r\u00f3\u017cnych uczni\u00f3w lub serii rysunk\u00f3w lub serii uj\u0119\u0107 wideo.",
+            "competence": 11,
+            "level": 2
+        }
+    },
+    {
+        "pk": 93,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- umie przygotowa\u0107 prost\u0105 fotografi\u0119 otoczenia lub obiekt\u00f3w, potrafi samodzielnie nagrywa\u0107 d\u017awi\u0119ki, umie przygotowa\u0107 kr\u00f3tki film wideo, przygotowa\u0107 prosty rysunek w odpowiednim programie, przygotowa\u0107 prost\u0105 form\u0119 graficzn\u0105 przy u\u017cyciu oprogramowania, przygotowa\u0107 kr\u00f3tki tekst w edytorze tekstu.\r\n- umie przygotowa\u0107 (przy wsparciu nauczyciela, animatora) w trakcie pracy grupowej prost\u0105 opowie\u015b\u0107 medialn\u0105 z wykorzystaniem medi\u00f3w jednego typu (elementy sk\u0142adowe przygotowuj\u0105 poszczeg\u00f3lni cz\u0142onkowie grupy), z dodaniem kr\u00f3tkich element\u00f3w tekstowych opisuj\u0105cych scen\u0119, zwiastuj\u0105cych kolejne wydarzenia.\r\n- pr\u00f3buje tworzy\u0107 w grupie proste narracje medialne z wykorzystaniem r\u00f3\u017cnorodnych komunikat\u00f3w sk\u0142adowych (<em>digital storytelling</em>).",
+            "competence": 11,
+            "level": 3
+        }
+    },
+    {
+        "pk": 94,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- umie samodzielnie przygotowa\u0107 zestaw fotografii, scen filmowych, rysunk\u00f3w, nagra\u0144, element\u00f3w graficznych na wybrany temat.- umie swobodnie \u0142\u0105czy\u0107 ze sob\u0105 r\u00f3\u017cnorodne zgromadzone tre\u015bci i tworzy\u0107 rozbudowane narracje cyfrowe na wybrany temat.\r\n- umie przygotowa\u0107 w grupie narracj\u0119 z\u0142o\u017con\u0105 z r\u00f3\u017cnorodnych medi\u00f3w na wybrany temat, planuj\u0105c wcze\u015bniej zespo\u0142owo dzia\u0142ania grupy on-line w edytorze rozszerzonych medi\u00f3w lub wymieniaj\u0105c si\u0119 informacjami na temat przygotowa\u0144 i planowania projektu na blogu lub w grupie w serwisie spo\u0142eczno\u015bciowym.\r\n- umie wsp\u00f3\u0142tworzy\u0107 w grupie proste teksty i prezentacje multimedialne przy u\u017cyciu narz\u0119dzi umo\u017cliwiaj\u0105cych sieciow\u0105 wsp\u00f3\u0142prac\u0119.",
+            "competence": 11,
+            "level": 4
+        }
+    },
+    {
+        "pk": 95,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- umie samodzielnie przygotowa\u0107 obszerny zestaw r\u00f3\u017cnorodnych tre\u015bci medialnych na wybrany temat.\r\n- umie swobodnie \u0142\u0105czy\u0107 ze sob\u0105 r\u00f3\u017cnorodne zgromadzone tre\u015bci i tworzy\u0107 na ich bazie rozbudowane narracje cyfrowe;\r\n\r\nnp. kolekcje i archiwa cyfrowe, blogi, wiki, opowiadanie hipertekstowe, serwis internetowy, gazeta on-line lub inne formy oparte na hipertekstowej architekturze.\r\n- umie zrealizowa\u0107 w grupie projekt medialny z podzia\u0142em zada\u0144 dotycz\u0105cych przygotowywania sk\u0142adowych cz\u0119\u015bci medialnych oraz montowania w ca\u0142o\u015b\u0107 zgromadzonych element\u00f3w lub ich kolekcji;\r\n\r\nnp. umie organizowa\u0107 prac\u0119 zwi\u0105zan\u0105 z przygotowaniem dzia\u0142a\u0144 grupy, w\u0142\u0105cza\u0107 si\u0119 za pomoc\u0105 narz\u0119dzi medialnych do grupowej pracy, nadzorowa\u0107 przebieg prac grupy, realizacj\u0119 kolejnych krok\u00f3w i tworzenie efekt\u00f3w projektu przy u\u017cyciu sieciowych technologii wsp\u00f3\u0142pracy, takich jak portal edukacyjny, wiki, blog, edytory tekstu lub prezentacje multimedialne wsp\u00f3\u0142tworzone on-line, serwisy spo\u0142eczno\u015bciowe.\r\n- umie wsp\u00f3\u0142tworzy\u0107 w grupie teksty i prezentacje multimedialne przy u\u017cyciu sieciowych narz\u0119dzi wsp\u00f3\u0142pracy.\r\n- umie dokumentowa\u0107 i komentowa\u0107 otoczenie i zachodz\u0105ce w nim procesy;\r\n\r\nnp. tworzy reporta\u017c tekstowy, zdj\u0119ciowy, wideo, reporta\u017c radiowy i inne formy radiowe publikowane w formie podcastu, wywiady, digitalizuje artefakty.",
+            "competence": 11,
+            "level": 5
+        }
+    },
+    {
+        "pk": 97,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- umie samodzielnie przygotowa\u0107 zestaw fotografii, scen filmowych, rysunk\u00f3w, nagra\u0144, element\u00f3w graficznych na wybrany temat.\r\n- umie swobodnie \u0142\u0105czy\u0107 ze sob\u0105 r\u00f3\u017cnorodne zgromadzone tre\u015bci i tworzy\u0107 proste narracje cyfrowe na wybrany temat.\r\n- umie przygotowa\u0107 w grupie narracj\u0119 z\u0142o\u017con\u0105 z r\u00f3\u017cnorodnych medi\u00f3w na wybrany temat, planuj\u0105c wcze\u015bniej zespo\u0142owo dzia\u0142ania grupy on-line w edytorze rozszerzonych medi\u00f3w lub wymieniaj\u0105c si\u0119 informacjami na temat przygotowa\u0144 i planowania projektu na blogu lub w grupie w serwisie spo\u0142eczno\u015bciowym.\r\n- umie wsp\u00f3\u0142tworzy\u0107 w grupie proste teksty i prezentacje multimedialne przy u\u017cyciu narz\u0119dzi umo\u017cliwiaj\u0105cych sieciow\u0105 wsp\u00f3\u0142prac\u0119.",
+            "competence": 11,
+            "level": 7
+        }
+    },
+    {
+        "pk": 98,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- umie samodzielnie przygotowa\u0107 obszerny zestaw r\u00f3\u017cnorodnych tre\u015bci medialnych na wybrany temat.\r\n- umie swobodnie \u0142\u0105czy\u0107 ze sob\u0105 r\u00f3\u017cnorodne zgromadzone tre\u015bci i tworzy\u0107 na ich bazie rozbudowane narracje cyfrowe (np. kolekcje i archiwa cyfrowe, blogi, wiki, opowiadanie hipertekstowe, serwis internetowy, gazeta on-line lub inne formy oparte na hipertekstowej architekturze).\r\n- umie zrealizowa\u0107 w grupie projekt medialny z podzia\u0142em zada\u0144 dotycz\u0105cych przygotowywania sk\u0142adowych cz\u0119\u015bci medialnych oraz montowania w ca\u0142o\u015b\u0107 zgromadzonych element\u00f3w lub ich kolekcji;\r\n\r\nnp. umie organizowa\u0107 prac\u0119 zwi\u0105zan\u0105 z przygotowaniem dzia\u0142a\u0144 grupy, w\u0142\u0105cza\u0107 si\u0119 za pomoc\u0105 narz\u0119dzi medialnych do grupowej pracy, nadzorowa\u0107 przebieg prac grupy, realizacj\u0119 kolejnych krok\u00f3w i tworzenie efekt\u00f3w projektu przy u\u017cyciu sieciowych technologii wsp\u00f3\u0142pracy, takich jak portal edukacyjny, wiki, blog, edytory tekstu lub prezentacje multimedialne wsp\u00f3\u0142tworzone on-line, serwisy spo\u0142eczno\u015bciowe.\r\n- umie wsp\u00f3\u0142tworzy\u0107 w grupie teksty i prezentacje multimedialne przy u\u017cyciu sieciowych narz\u0119dzi wsp\u00f3\u0142pracy.\r\n- umie dokumentowa\u0107 i komentowa\u0107 otoczenie i zachodz\u0105ce w nim procesy;\r\n\r\nnp. tworzy reporta\u017c tekstowy, zdj\u0119ciowy, wideo, reporta\u017c radiowy i inne formy radiowe publikowane w formie podcastu, wywiady, digitalizuje artefakty.",
+            "competence": 11,
+            "level": 8
+        }
+    },
+    {
+        "pk": 99,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- umie koordynowa\u0107 dzia\u0142anie zespo\u0142u przygotowuj\u0105cego tre\u015bci do realizowanego projektu medialnego.\r\n- umie uczy\u0107 innych, jak gromadzi\u0107 tre\u015bci i tworzy\u0107 na ich podstawie rozbudowane narracje cyfrowe.\r\n- umie nadzorowa\u0107 realizacj\u0119 projektu medialnego, dzieli\u0107 zadania dotycz\u0105ce przygotowywania sk\u0142adowych cz\u0119\u015bci medialnych oraz montowania w ca\u0142o\u015b\u0107 zgromadzonych element\u00f3w lub ich kolekcji, potrafi organizowa\u0107 prac\u0119 kilku zespo\u0142\u00f3w realizuj\u0105cych wsp\u00f3lny projekt medialny.\r\n- umie uczy\u0107 innych, jak przygotowywa\u0107 prezentacje medialne, umie tworzy\u0107 prezentacje medialne na profesjonalnym poziomie.\r\n- umie przeprowadzi\u0107 szkolenie w zakresie dokumentowania i komentowania otoczenia i zachodz\u0105cych w nim proces\u00f3w;\r\n\r\nnp. tworzenia reporta\u017cy tekstowych, zdj\u0119ciowych, wideo, reporta\u017cy radiowych i innych form radiowych publikowanych w formie podcastu, wywiad\u00f3w, digitalizowania artefakt\u00f3w.",
+            "competence": 11,
+            "level": 9
+        }
+    },
+    {
+        "pk": 100,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- wie, \u017ce proste tre\u015bci medialne mo\u017cna przetwarza\u0107.\r\n- pr\u00f3buje przy u\u017cyciu prostego oprogramowania modyfikowa\u0107 zdj\u0119cie lub grafik\u0119;\r\n\r\nnp. bawi si\u0119 programami do modyfikacji zdj\u0119\u0107 lub narz\u0119dziem do rysowania.",
+            "competence": 12,
+            "level": 1
+        }
+    },
+    {
+        "pk": 101,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- umie przetwarza\u0107 w podstawowym zakresie dost\u0119pne tre\u015bci medialne \u00a0 (zdj\u0119cia, grafik\u0119, filmy wideo, d\u017awi\u0119k) przy u\u017cyciu prostego oprogramowania do obr\u00f3bki tre\u015bci.\r\n- wie, \u017ce tre\u015bci analogowe mo\u017cna przekszta\u0142ci\u0107 na form\u0119 cyfrow\u0105, odtwarzan\u0105 za pomoc\u0105 cyfrowych urz\u0105dze\u0144.",
+            "competence": 12,
+            "level": 2
+        }
+    },
+    {
+        "pk": 102,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- umie przetwarza\u0107 dost\u0119pne i samodzielnie przygotowane tre\u015bci medialne (zdj\u0119cia, grafik\u0119, filmy wideo, d\u017awi\u0119k).\r\n- umie w grupie tworzy\u0107 cyfrowe narracje na bazie zmodyfikowanych wcze\u015bniej znalezionych lub przygotowanych przez zesp\u00f3\u0142 tre\u015bci medialnych.\r\n- potrafi skanowa\u0107 dokumenty, zdj\u0119cia i przeprowadza\u0107 ich podstawow\u0105 edycj\u0119 za pomoc\u0105 program\u00f3w do skanowania.",
+            "competence": 12,
+            "level": 3
+        }
+    },
+    {
+        "pk": 103,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- umie przetwarza\u0107 znalezione i przygotowane wcze\u015bniej rozbudowane kolekcje tre\u015bci medialnych z\u0142o\u017cone ze zdj\u0119\u0107, grafiki, film\u00f3w wideo, d\u017awi\u0119ku.\r\n- umie w grupie tworzy\u0107 rozbudowane cyfrowe narracje, filmy, hipermedialne projekty oparte na zmodyfikowanych przez cz\u0142onk\u00f3w grupy tre\u015bciach lub znalezionych, przetworzonych materia\u0142ach.\r\n- umie samodzielnie digitalizowa\u0107 tre\u015bci analogowe;\r\n\r\nnp. umie skanowa\u0107 ksi\u0105\u017cki, gazety, dokumenty, zdj\u0119cia.",
+            "competence": 12,
+            "level": 4
+        }
+    },
+    {
+        "pk": 104,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- umie na zaawansowanym poziomie modyfikowa\u0107 przygotowane i znalezione rozbudowane zasoby tre\u015bci multimedialnych i hipermedialnych.\r\n- umie w grupie tworzy\u0107 zaawansowane cyfrowe narracje, filmy, hipermedialne projekty oparte na zmodyfikowanych przez uczestnik\u00f3w grupy tre\u015bciach lub znalezionych, z\u0142o\u017conych komunikatach medialnych.\r\n- umie, dzia\u0142aj\u0105c w grupie, digitalizowa\u0107 analogowe tre\u015bci;\r\n\r\nnp. wsp\u00f3lnie z innymi realizuje projekt digitalizacyjny.",
+            "competence": 12,
+            "level": 5
+        }
+    },
+    {
+        "pk": 106,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- umie przetwarza\u0107 znalezione i przygotowane wcze\u015bniej rozbudowane kolekcje tre\u015bci medialnych z\u0142o\u017cone ze zdj\u0119\u0107, grafiki, film\u00f3w wideo, d\u017awi\u0119ku.\r\n- umie w grupie tworzy\u0107 proste cyfrowe narracje, filmy, hipermedialne projekty oparte na zmodyfikowanych przez uczestnik\u00f3w grupy tre\u015bciach lub znalezionych, przetworzonych materia\u0142ach.\r\n- umie samodzielnie digitalizowa\u0107 tre\u015bci analogowe: skanowa\u0107 ksi\u0105\u017cki, gazety, dokumenty, zdj\u0119cia.",
+            "competence": 12,
+            "level": 7
+        }
+    },
+    {
+        "pk": 107,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- umie na zaawansowanym poziomie modyfikowa\u0107 przygotowane i znalezione rozbudowane zasoby tre\u015bci multimedialnych i hipermedialnych.\r\n- umie w grupie tworzy\u0107 zaawansowane cyfrowe narracje, filmy, hipermedialne projekty oparte na zmodyfikowanych przez cz\u0142onk\u00f3w grupy tre\u015bciach lub znalezionych, z\u0142o\u017conych komunikatach medialnych.\r\n- umie, dzia\u0142aj\u0105c w grupie, digitalizowa\u0107 analogowe tre\u015bci.",
+            "competence": 12,
+            "level": 8
+        }
+    },
+    {
+        "pk": 108,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- umie rozwi\u0105zywa\u0107 problemy pojawiaj\u0105ce si\u0119 w trakcie zaawansowanego modyfikowania tre\u015bci multimedialnych i hipermedialnych.\r\n- umie przeprowadzi\u0107 warsztatowe szkolenie w zakresie modyfikacji tre\u015bci dla u\u017cytkownik\u00f3w od poziomu pocz\u0105tkuj\u0105cego do zaawansowanego.\r\n- umie koordynowa\u0107 dzia\u0142anie zespo\u0142u lub zespo\u0142\u00f3w tworz\u0105cych zaawansowane cyfrowe narracje, filmy, hipermedialne projekty oparte na zmodyfikowanych tre\u015bciach.\r\n- umie koordynowa\u0107 zaawansowane dzia\u0142ania w zakresie digitalizacji.",
+            "competence": 12,
+            "level": 9
+        }
+    },
+    {
+        "pk": 109,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- przy wsparciu osoby doros\u0142ej pokazuje grupie efekty pr\u00f3b samodzielnego tworzenia i przetwarzania komunikat\u00f3w.",
+            "competence": 13,
+            "level": 1
+        }
+    },
+    {
+        "pk": 110,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- umie zaprezentowa\u0107, z wykorzystaniem sprz\u0119tu multimedialnego (np. komputer z rzutnikiem multimedialnym), przygotowane indywidualnie lub w grupie tre\u015bci medialne.",
+            "competence": 13,
+            "level": 2
+        }
+    },
+    {
+        "pk": 111,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- umie obs\u0142ugiwa\u0107 rzutnik multimedialny lub inne narz\u0119dzie o podobnym zastosowaniu;\r\n\r\nnp. umie za jego pomoc\u0105 wy\u015bwietli\u0107 pojedyncze komunikaty \u2013 zdj\u0119cia, teksty, slajdy prezentacji multimedialnej, filmy, strony internetowe.\r\n- wie o istnieniu serwis\u00f3w internetowych, blog\u00f3w, narz\u0119dzi do kolektywnego tworzenia tre\u015bci on-line.",
+            "competence": 13,
+            "level": 3
+        }
+    },
+    {
+        "pk": 112,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- umie obs\u0142ugiwa\u0107 narz\u0119dzia do synchronicznego prezentowania tre\u015bci (prezentacje on-line w czasie rzeczywistym).\r\n- umie obs\u0142ugiwa\u0107 narz\u0119dzia do asynchronicznego prezentowania tre\u015bci (prezentacje multimedialne on-line i off-line).\r\n- umie obs\u0142ugiwa\u0107 narz\u0119dzia do prowadzenia zbiorowej komunikacji on-line z wykorzystaniem d\u017awi\u0119ku i wideo.\r\n- umie prezentowa\u0107 tre\u015bci na blogu, publikowa\u0107 za pomoc\u0105 narz\u0119dzi do kolektywnego tworzenia tre\u015bci, umie w grupie przygotowa\u0107 prezentacj\u0119 tre\u015bci za pomoc\u0105 systemu typu wiki oraz zak\u0142ada\u0107 i moderowa\u0107 dyskusje sieciowe za pomoc\u0105 listy dyskusyjnej, forum oraz serwis\u00f3w spo\u0142eczno\u015bciowych.\r\n- wie, jakie s\u0105 podstawy pracy dziennikarskiej w internecie i potrafi po wcze\u015bniejszym przygotowaniu publikowa\u0107 tre\u015bci na temat \u017cycia w spo\u0142eczno\u015bci lokalnej;\r\n\r\nnp. wie, czym jest \u201edziennikarstwo obywatelskie\u201d i pr\u00f3buje dzia\u0142a\u0107 jako dziennikarz obywatelski.\r\n- umie tworzy\u0107 proste archiwa cyfrowe z\u0142o\u017cone ze zdigitalizowanych materia\u0142\u00f3w.",
+            "competence": 13,
+            "level": 4
+        }
+    },
+    {
+        "pk": 113,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- umie obs\u0142ugiwa\u0107 systemy zarz\u0105dzania tre\u015bci\u0105, zarz\u0105dza\u0107 list\u0105 autor\u00f3w i publikowanymi tre\u015bciami, dodawa\u0107, edytowa\u0107 i usuwa\u0107 tre\u015bci przy u\u017cyciu narz\u0119dzi typu blog, sieciowy pakiet biurowy.\r\n- umie rozpowszechnia\u0107 informacje na temat w\u0142asnej lub grupowej tw\u00f3rczo\u015bci;\r\n\r\nnp. umie wykorzystywa\u0107 serwisy spo\u0142eczno\u015bciowe do tworzenia przestrzeni publikacji na okre\u015blony temat.\r\n- wie, jak funkcjonuje redakcja internetowa, potrafi wykorzysta\u0107 podstawy umiej\u0119tno\u015bci dziennikarskich do publikowania (wcze\u015bniej przygotowanych samodzielnie i/lub w grupie) bie\u017c\u0105cych informacji na temat \u017cycia spo\u0142eczno\u015bci lokalnej.\r\n- umie tworzy\u0107 rozbudowane archiwa cyfrowe z\u0142o\u017cone ze zdigitalizowanych materia\u0142\u00f3w.",
+            "competence": 13,
+            "level": 5
+        }
+    },
+    {
+        "pk": 115,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- umie obs\u0142ugiwa\u0107 narz\u0119dzia do synchronicznego prezentowania tre\u015bci (prezentacje on-line w czasie rzeczywistym).\r\n- umie obs\u0142ugiwa\u0107 narz\u0119dzia do asynchronicznego prezentowania tre\u015bci (prezentacje multimedialne on-line i off-line).\r\n- umie obs\u0142ugiwa\u0107 narz\u0119dzia do prowadzenia zbiorowej komunikacji on-line z wykorzystaniem d\u017awi\u0119ku i wideo.\r\n- umie prezentowa\u0107 tre\u015bci na blogu, publikowa\u0107 za pomoc\u0105 narz\u0119dzi do kolektywnego tworzenia tre\u015bci;\r\n\r\nnp. umie w grupie przygotowa\u0107 prezentacj\u0119 tre\u015bci za pomoc\u0105 systemu typu wiki oraz zak\u0142ada\u0107 i moderowa\u0107 dyskusje sieciowe za pomoc\u0105 listy dyskusyjnej, forum oraz serwis\u00f3w spo\u0142eczno\u015bciowych.\r\n- wie, jakie s\u0105 podstawy pracy dziennikarskiej w internecie i potrafi po wcze\u015bniejszym przygotowaniu publikowa\u0107 tre\u015bci na temat \u017cycia w spo\u0142eczno\u015bci lokalnej;\r\n\r\nnp. wie, czym jest \u201edziennikarstwo obywatelskie\u201d i pr\u00f3buje dzia\u0142a\u0107 jako dziennikarz obywatelski.\r\n- umie tworzy\u0107 proste archiwa cyfrowe z\u0142o\u017cone ze zdigitalizowanych materia\u0142\u00f3w.",
+            "competence": 13,
+            "level": 7
+        }
+    },
+    {
+        "pk": 116,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- umie obs\u0142ugiwa\u0107 systemy zarz\u0105dzania tre\u015bci\u0105, zarz\u0105dza\u0107 list\u0105 autor\u00f3w i publikowanymi tre\u015bciami, dodawa\u0107, edytowa\u0107 i usuwa\u0107 tre\u015bci przy u\u017cyciu narz\u0119dzi typu blog, sieciowy pakiet biurowy.\r\n- umie wykorzystywa\u0107 serwisy spo\u0142eczno\u015bciowe do tworzenia przestrzeni publikacji na okre\u015blony temat, umie rozpowszechnia\u0107 informacje na temat w\u0142asnej lub grupowej tw\u00f3rczo\u015bci.\r\n- wie, jak funkcjonuje redakcja internetowa, potrafi wykorzysta\u0107 podstawy umiej\u0119tno\u015bci dziennikarskich do publikowania (wcze\u015bniej przygotowanych samodzielnie i/lub w grupie) bie\u017c\u0105cych informacji na temat \u017cycia spo\u0142eczno\u015bci lokalnej.\r\n- umie tworzy\u0107 rozbudowane archiwa cyfrowe z\u0142o\u017cone ze zdigitalizowanych materia\u0142\u00f3w.",
+            "competence": 13,
+            "level": 8
+        }
+    },
+    {
+        "pk": 117,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- umie rozwi\u0105zywa\u0107 problemy zwi\u0105zane z obs\u0142ug\u0105 system\u00f3w zarz\u0105dzania tre\u015bci\u0105.\r\n- umie animowa\u0107 sieciowe spo\u0142eczno\u015bci i szkoli\u0107 na temat zarz\u0105dzania sieciowymi spo\u0142eczno\u015bciami inne osoby.\r\n- umie zorganizowa\u0107 internetow\u0105 redakcj\u0119, koordynowa\u0107 jej funkcjonowanie i aktywizowa\u0107 za jej pomoc\u0105 spo\u0142eczno\u015b\u0107 lokaln\u0105.\r\n- wie, jak stworzy\u0107 zaawansowane archiwa cyfrowe, umie przeprowadzi\u0107 szkolenie w zakresie tworzenia cyfrowych archiw\u00f3w od poziomu pocz\u0105tkuj\u0105cego do zaawansowanego.",
+            "competence": 13,
+            "level": 9
+        }
+    },
+    {
+        "pk": 136,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- umie na podstawowym poziomie rozr\u00f3\u017cni\u0107 dobro i z\u0142o w mediach i komunikacji;\r\nnp. potrafi wskaza\u0107 z\u0142e post\u0119powanie bohatera ogl\u0105danego filmu.",
+            "competence": 16,
+            "level": 1
+        }
+    },
+    {
+        "pk": 137,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- wie, \u017ce problem dobra i z\u0142a, k\u0142amstwa i prawdy dotyczy tak\u017ce medi\u00f3w i komunikacji;\r\nnp. wie, \u017ce w telewizji mo\u017cna us\u0142ysze\u0107 k\u0142amstwo albo \u017ce granie w okre\u015blone gry mo\u017ce by\u0107 z\u0142e.\r\n- wie, \u017ce zosta\u0142y ustalone okre\u015blone regu\u0142y komunikacji i korzystania z medi\u00f3w oraz \u017ce nale\u017cy si\u0119 do nich stosowa\u0107.\r\n- umie wskaza\u0107 zagro\u017cenia etyczne zwi\u0105zane z korzystaniem z medi\u00f3w;\r\nnp. umie opowiedzie\u0107 o problemie k\u0142amstwa w reklamie telewizyjnej.",
+            "competence": 16,
+            "level": 2
+        }
+    },
+    {
+        "pk": 138,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- rozumie, dlaczego normy moralne i warto\u015bci odnosz\u0105 si\u0119 tak\u017ce do medi\u00f3w i komunikacji przez media;\r\nnp. rozumie, dlaczego obra\u017canie kogo\u015b w internecie ma takie samo znaczenie jak obra\u017canie kogo\u015b twarz\u0105 w twarz.",
+            "competence": 16,
+            "level": 3
+        }
+    },
+    {
+        "pk": 139,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- umie stawia\u0107 pytania dotycz\u0105ce etycznych konsekwencji komunikacji i korzystania z medi\u00f3w w perspektywie w\u0142asnych zachowa\u0144 i do\u015bwiadcze\u0144;\r\nnp. potrafi zastanowi\u0107 si\u0119 nad konsekwencjami i moraln\u0105 ocen\u0105 propozycji radykalnych sposob\u00f3w odchudzania, kt\u00f3re publikuje na swoim blogu.\r\n- rozumie, \u017ce wyzwania etyczne w mediach i komunikacji istniej\u0105 tak\u017ce poza perspektyw\u0105 jego w\u0142asnych do\u015bwiadcze\u0144 i umie zadawa\u0107 pytania na ich temat;\r\nnp. potrafi opisa\u0107, na czym polega moralny problem kontroli aktywno\u015bci internetowych pracownika przez pracodawc\u0119 oraz zada\u0107 pytania dotycz\u0105ce natury tego problemu: granic prywatno\u015bci pracownika, wymog\u00f3w uczciwej i skutecznej pracy itp.",
+            "competence": 16,
+            "level": 4
+        }
+    },
+    {
+        "pk": 140,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- umie zdefiniowa\u0107 i zanalizowa\u0107 wyzwania etyczne w perspektywie medi\u00f3w i komunikacji niezale\u017cnie od w\u0142asnych do\u015bwiadcze\u0144 oraz potrafi znale\u017a\u0107 pomoc w ich krytycznej analizie i rozwi\u0105zywaniu;\r\nnp. potrafi krytycznie zanalizowa\u0107 etyczny problem zdrady on-line dzi\u0119ki znalezionym w internecie wypowiedziom psycholog\u00f3w, badaniom itp.\r\n- umie podj\u0105\u0107 refleksj\u0119 etyczn\u0105 nad komunikacj\u0105 i mediami z r\u00f3\u017cnych perspektyw, np. dzia\u0142alno\u015bci biznesowej, reklamy, polityki, edukacji, nauki, z punktu widzenia r\u00f3\u017cnych system\u00f3w moralnych.\r\n- rozumie problem j\u0119zyka w dyskusjach nad etyk\u0105 medi\u00f3w i komunikacji;\r\nnp. rozumie problem zdefiniowania poj\u0119cia piractwa komputerowego.\r\n- rozumie potrzeb\u0119 kszta\u0142towania swoich postaw w komunikacji i korzystaniu z medi\u00f3w w kierunku wykszta\u0142cenia w\u0142asnych zasad post\u0119powania opartych o sumienie.",
+            "competence": 16,
+            "level": 5
+        }
+    },
+    {
+        "pk": 141,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- umie wypracowa\u0107 subiektywne zasady etyczne dotycz\u0105ce komunikacji i korzystania z medi\u00f3w oraz stosowa\u0107 je na co dzie\u0144.",
+            "competence": 16,
+            "level": 6
+        }
+    },
+    {
+        "pk": 142,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- umie stawia\u0107 pytania dotycz\u0105ce etycznych konsekwencji komunikacji i korzystania z medi\u00f3w w perspektywie w\u0142asnych zachowa\u0144 i do\u015bwiadcze\u0144;\r\nnp. rozwa\u017ca: czy \u017ale zrobi\u0142em \u015bci\u0105gaj\u0105c ten plik?",
+            "competence": 16,
+            "level": 7
+        }
+    },
+    {
+        "pk": 143,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- umie zanalizowa\u0107 problemy etyczne w perspektywie medi\u00f3w i komunikacji niezale\u017cnie od w\u0142asnych do\u015bwiadcze\u0144 (na poziomie og\u00f3lnym, abstrakcyjnym) oraz potrafi znale\u017a\u0107 pomoc w ich krytycznej analizie i rozwi\u0105zywaniu;\r\nnp. zastanawia si\u0119: w jakich warunkach nielegalne \u015bci\u0105ganie plik\u00f3w z internetu mo\u017ce nie by\u0107 nieetyczne?\r\n\r\n- rozumie problem j\u0119zyka w dyskusjach nad etyk\u0105 medi\u00f3w.",
+            "competence": 16,
+            "level": 8
+        }
+    },
+    {
+        "pk": 144,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- umie zainicjowa\u0107 proces etycznej analizy medi\u00f3w i komunikacji w\u015br\u00f3d uczni\u00f3w, uczestnik\u00f3w warsztat\u00f3w itp.;\r\nnp. pyta: Czy kiedykolwiek ogl\u0105daj\u0105c \u201eWiadomo\u015bci, mieli\u015bcie poczucie, \u017ce jaki\u015b materia\u0142 nie powinien si\u0119 tam znale\u017a\u0107, poniewa\u017c by\u0142o to niestosowne albo krzywdz\u0105ce dla kogo\u015b?\r\n- umie wypracowa\u0107 subiektywne zasady etyczne dotycz\u0105ce komunikacji i korzystania z medi\u00f3w oraz stosowa\u0107 je na co dzie\u0144.",
+            "competence": 16,
+            "level": 9
+        }
+    },
+    {
+        "pk": 128,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- rozumie, \u017ce nale\u017cy stosowa\u0107 si\u0119 do ogranicze\u0144 w dost\u0119pie do tre\u015bci medi\u00f3w wprowadzonych dla jego dobra.\r\nnp. zakaz ogl\u0105dania niekt\u00f3rych program\u00f3w w telewizji",
+            "competence": 15,
+            "level": 2
+        }
+    },
+    {
+        "pk": 129,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- wie, \u017ce ma prawo dost\u0119pu do informacji i komunikacji.\r\n- rozumie, dlaczego korzystaj\u0105c z materia\u0142\u00f3w dost\u0119pnych w internecie, nale\u017cy szanowa\u0107 prac\u0119 innych;\r\nnp. rozumie, dlaczego wklejaj\u0105c do prezentacji multimedialnej obrazek \u015bci\u0105gni\u0119ty z internetu, nale\u017cy poda\u0107 jego \u017ar\u00f3d\u0142o.\r\n- umie wskaza\u0107 podstawowe warto\u015bci w przekazie medialnym;\r\nnp. wskaza\u0107, do jakich warto\u015bci odwo\u0142uje si\u0119 post\u0119powanie bohatera ogl\u0105danego filmu.\r\n- rozumie, \u017ce warto\u015bci promowane w tre\u015bci medi\u00f3w i komunikacji s\u0105 zale\u017cne od wielu czynnik\u00f3w;\r\nnp. rozumie, \u017ce reklama nie jest bezinteresownym informowaniem o produkcie, poniewa\u017c jej g\u0142\u00f3wn\u0105 funkcj\u0105 jest zach\u0119canie do kupna produktu, rozbudzanie potrzeb itp.\r\n- rozumie poj\u0119cie wolno\u015bci s\u0142owa w perspektywie medi\u00f3w i komunikacji.\r\n- rozumie potrzeb\u0119 krytycznej tolerancji i otwarto\u015bci (tak\u017ce na inne kultury) przy kontakcie z tre\u015bciami medi\u00f3w.",
+            "competence": 15,
+            "level": 3
+        }
+    },
+    {
+        "pk": 130,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- wie, jakie czynniki wp\u0142ywaj\u0105 na obecno\u015b\u0107 i kszta\u0142t okre\u015blonych warto\u015bci w mediach i komunikacji;\r\nnp. wie, \u017ce frakcja polityczna kontroluj\u0105ca media publiczne mo\u017ce mie\u0107 wp\u0142yw na warto\u015bci, jakie dominowa\u0107 b\u0119d\u0105 w przekazach tych medi\u00f3w.\r\n- umie krytycznie analizowa\u0107 warto\u015bci w tre\u015bci medi\u00f3w i komunikacji z uwzgl\u0119dnieniem tej wiedzy;\r\nnp. wiedz\u0105c o zasadach dzia\u0142ania tabloid\u00f3w, o modelu biznesowym tego gatunku medialnego, potrafi krytycznie opisa\u0107 warto\u015bci promowane na \u0142amach \u201eFaktu\u201d.\r\n- rozumie prawo do sprzeciwu lub czynnego oporu wobec tre\u015bci medialnych czy komunikacji;\r\nnp. rozumie, dlaczego mo\u017ce protestowa\u0107 przeciwko instalacji baner\u00f3w reklamowych w budynku szko\u0142y. Rozumie, \u017ce instalacja dodatku AdBlock w przegl\u0105darce wynika z jego prawa do kontrolowania tre\u015bci, kt\u00f3re odbiera.\r\n- wie o prawie dost\u0119pu do informacji, do d\u0105\u017cenia do jej uzyskania oraz ograniczeniach z tym zwi\u0105zanych;\r\nnp. zna warto\u015b\u0107 czyjej\u015b prywatno\u015bci i wie, \u017ce ogranicza ona jego prawo do dost\u0119pu do informacji. Zna poj\u0119cie informacji publicznej i wie o prawie dost\u0119pu do niej.\r\n- rozumie problem komunikowania tre\u015bci takich jak przemoc, nago\u015b\u0107, prywatno\u015b\u0107. Rozumie, \u017ce problem ten dotyczy\u0107 mo\u017ce tak\u017ce tre\u015bci o charakterze historycznym;\r\nnp. rozumie, \u017ce nale\u017cy zastanowi\u0107 si\u0119 nad form\u0105 i stylem fotografii dokumentuj\u0105cej wizyt\u0119 klasow\u0105 w Muzeum Auschwitz.\r\n- rozumie poj\u0119cie etyki dziennikarskiej i umie wskaza\u0107, jak odnosi si\u0119 ono do r\u00f3\u017cnych dostawc\u00f3w tre\u015bci.\r\n- umie przedstawi\u0107 pozytywn\u0105 interpretacj\u0119 poj\u0119cia hakowania jako dzia\u0142ania zmierzaj\u0105cego do dostosowania systemu (medium) do w\u0142asnych cel\u00f3w.",
+            "competence": 15,
+            "level": 4
+        }
+    },
+    {
+        "pk": 131,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- umie praktycznie rozpozna\u0107 wyzwania wobec etyki dziennikarskiej, obejmuj\u0105cej r\u00f3wnie\u017c innych nadawc\u00f3w tre\u015bci, z perspektywy r\u00f3\u017cnych system\u00f3w moralnych;\r\nnp. potrafi skonfrontowa\u0107 zasady etyki dziennikarskiej dotycz\u0105ce prezentowania scen przemocy z obejrzan\u0105 relacj\u0105 korespondenta wojennego.\r\n\r\n- umie odnie\u015b\u0107 problem wolno\u015bci s\u0142owa i pluralizmu medi\u00f3w do konkretnych zjawisk medialnych;\r\nnp. potrafi zanalizowa\u0107 funkcjonowanie Wikileaks w perspektywie wolno\u015bci s\u0142owa i polityki bezpiecze\u0144stwa pa\u0144stw.\r\n- umie odnie\u015b\u0107 problem dobra wsp\u00f3lnego do systemu medi\u00f3w i komunikacji z wykorzystaniem poj\u0119cia kultury (ekonomii) daru oraz poj\u0119\u0107 zwi\u0105zanych z ide\u0105 otwarto\u015bci tre\u015bci w internecie (Otwarta Nauka, Otwarte Zasoby Edukacyjne, wolne licencje itp.);\r\nnp. potrafi zanalizowa\u0107 model Wikipedii pod k\u0105tem dobra wsp\u00f3lnego, akcentuj\u0105c znaczenie licencji Creative Commons wykorzystywanej przez autor\u00f3w hase\u0142.\r\n\r\n- umie krytycznie zanalizowa\u0107 problem dobra wsp\u00f3lnego i otwarto\u015bci w perspektywie tre\u015bci medialnych;\r\nnp. potrafi wskaza\u0107 argumenty za udost\u0119pnianiem on-line wynik\u00f3w bada\u0144 naukowych. Potrafi krytycznie zanalizowa\u0107 problem abonamentu i funkcjonowania medi\u00f3w publicznych w perspektywie warto\u015bci dobra wsp\u00f3lnego.",
+            "competence": 15,
+            "level": 5
+        }
+    },
+    {
+        "pk": 133,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- wie o prawie dost\u0119pu do informacji oraz ograniczeniach z tym zwi\u0105zanych.\r\n- umie wskaza\u0107 podstawowe warto\u015bci w wybranym przekazie medialnym.\r\n- rozumie, \u017ce warto\u015bci obecne w tre\u015bci medi\u00f3w i komunikacji zale\u017c\u0105 od wielu czynnik\u00f3w.\r\n- wie, \u017ce korzystaj\u0105c z materia\u0142\u00f3w dost\u0119pnych w internecie nale\u017cy szanowa\u0107 prac\u0119 innych.\r\n- rozumie poj\u0119cie etyki dziennikarskiej.",
+            "competence": 15,
+            "level": 7
+        }
+    },
+    {
+        "pk": 134,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- wie, jakie czynniki wp\u0142ywaj\u0105 na obecno\u015b\u0107 i kszta\u0142t okre\u015blonych warto\u015bci w mediach i komunikacji.\r\n- umie krytycznie analizowa\u0107 warto\u015bci w tre\u015bci medi\u00f3w i komunikacji z uwzgl\u0119dnieniem tej wiedzy.\r\n- rozumie prawo do sprzeciwu lub czynnego oporu wobec tre\u015bci medialnych czy komunikacji.\r\n- rozumie problem komunikowania tre\u015bci takich jak przemoc, nago\u015b\u0107, prywatno\u015b\u0107 (tak\u017ce w odniesieniu do tre\u015bci o charakterze historycznym).\r\n- rozumie warto\u015b\u0107 r\u00f3wnego dost\u0119pu do informacji.\r\n- umie praktycznie rozpozna\u0107 wyzwania wobec etyki dziennikarskiej i odnie\u015b\u0107 je do innych dostawc\u00f3w tre\u015bci.",
+            "competence": 15,
+            "level": 8
+        }
+    },
+    {
+        "pk": 135,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- umie odnie\u015b\u0107 problem wolno\u015bci s\u0142owa i pluralizmu medi\u00f3w do konkretnych zjawisk medialnych.\r\n- umie odnie\u015b\u0107 problem dobra wsp\u00f3lnego do systemu medi\u00f3w i komunikacji z wykorzystaniem poj\u0119cia kultury (ekonomii) daru oraz poj\u0119\u0107 zwi\u0105zanych z ide\u0105 otwarto\u015bci tre\u015bci w internecie (Otwarta Nauka, Otwarte Zasoby Edukacyjne, wolne licencje itp.)\r\n- umie przedstawi\u0107 pozytywn\u0105 interpretacj\u0119 poj\u0119cia hakowania jako dzia\u0142ania zmierzaj\u0105cego do dostosowania systemu (medium) do w\u0142asnych cel\u00f3w.",
+            "competence": 15,
+            "level": 9
+        }
+    },
+    {
+        "pk": 146,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- wie, \u017ce ma prawo do zachowania anonimowo\u015bci i prywatno\u015bci;\r\nnp. wie, \u017ce nie musi si\u0119 zgadza\u0107 na to zrobienie sobie zdj\u0119cia przez kogo\u015b obcego. Wie, \u017ce nie musi podawa\u0107 swojego adresu domowego osobie spotkanej w internecie (i \u017ce to nie \u015bwiadczy o jej / jego z\u0142ym zachowaniu).\r\n- rozumie, \u017ce komunikacja w mediach to wci\u0105\u017c komunikacja mi\u0119dzy lud\u017ami;\r\nnp. rozumie, \u017ce po drugiej stronie ekranu siedzi inny cz\u0142owiek, kt\u00f3remu nale\u017cy si\u0119 szacunek.\r\n- rozumie, \u017ce komunikacja przez media nie mo\u017ce by\u0107 wystarczaj\u0105c\u0105 alternatyw\u0105 komunikacji interpersonalnej;\r\nnp. rozumie wady przyja\u017ani tylko przez internet.",
+            "competence": 17,
+            "level": 2
+        }
+    },
+    {
+        "pk": 147,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- wie, \u017ce prywatno\u015b\u0107 w\u0142asna i innych jest warto\u015bci\u0105;\r\nnp. wie, dlaczego nie nale\u017cy podawa\u0107 numeru telefonu znajomej osoby innym bez jej wyra\u017anej zgody.\r\n- umie stosowa\u0107 w komunikacji w internecie zasady netykiety.\r\n- rozumie postaw\u0119 krytycznej otwarto\u015bci i tolerancji w relacjach w mediach;\r\nnp. rozumie, \u017ce dyskutuj\u0105c on-line, nie zawsze ma si\u0119 racj\u0119 i czasem warto zaakceptowa\u0107 argument drugiej strony.",
+            "competence": 17,
+            "level": 3
+        }
+    },
+    {
+        "pk": 148,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- rozumie problem moralnej oceny zachowa\u0144 komunikacyjnych w mediach;\r\nnp. rozumie, \u017ce o\u015bmieszanie kogo\u015b w internecie ma tak\u0105 sam\u0105 warto\u015b\u0107 moraln\u0105 jak o\u015bmieszanie kogo\u015b w komunikacji bezpo\u015bredniej.\r\n- rozumie poj\u0119cie mowy nienawi\u015bci w internecie i potrafi je odnie\u015b\u0107 do wypowiedzi obserwowanych on-line oraz do idei wolno\u015bci s\u0142owa.\r\n- rozumie warto\u015b\u0107 wsp\u00f3\u0142pracy mi\u0119dzy u\u017cytkownikami internetu (w perspektywie zjawisk takich jak ruch open source, Wikipedia, crowdsourcing, peer-production itp.)",
+            "competence": 17,
+            "level": 4
+        }
+    },
+    {
+        "pk": 149,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- umie okre\u015bli\u0107 zasady ograniczania prawa do prywatno\u015bci w mediach;\r\nnp. umie poda\u0107 katalog warto\u015bci, wobec kt\u00f3rych prawo do prywatno\u015bci mo\u017ce by\u0107 zanegowane (np. wsp\u00f3lne bezpiecze\u0144stwo). Umie wskaza\u0107 i oceni\u0107 negatywne zjawiska ograniczania prawa do prywatno\u015bci (np. kontrola internaut\u00f3w w Chinach, problem ACTA).\r\n- potrafi krytycznie podej\u015b\u0107 do skodyfikowanych zasad netykiety.\r\n- potrafi wypracowa\u0107 w\u0142asne zasady kszta\u0142towania relacji w komunikacji przez media w oparciu o w\u0142asne do\u015bwiadczenia.",
+            "competence": 17,
+            "level": 5
+        }
+    },
+    {
+        "pk": 151,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- wie, \u017ce ma prawo do zachowania anonimowo\u015bci i prywatno\u015bci.\r\n- rozumie, \u017ce komunikacja w mediach to wci\u0105\u017c komunikacja mi\u0119dzy lud\u017ami.\r\n- wie, \u017ce nale\u017cy szanowa\u0107 prywatno\u015b\u0107 swoj\u0105 i innych.\r\n- umie stosowa\u0107 w komunikacji w internecie zasady netykiety.\r\n- rozumie postaw\u0119 krytycznej otwarto\u015bci i tolerancji w relacjach w mediach.",
+            "competence": 17,
+            "level": 7
+        }
+    },
+    {
+        "pk": 152,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- rozumie problem etycznej oceny zachowa\u0144 w komunikacji przez media.\r\n- rozumie poj\u0119cie mowy nienawi\u015bci w internecie i potrafi je odnie\u015b\u0107 do wypowiedzi obserwowanych on-line oraz do idei wolno\u015bci s\u0142owa.\r\n- rozumie warto\u015b\u0107 wsp\u00f3\u0142pracy mi\u0119dzy u\u017cytkownikami internetu (w perspektywie zjawisk takich jak ruch open source, Wikipedia, crowdsourcing, peer-production itp.)",
+            "competence": 17,
+            "level": 8
+        }
+    },
+    {
+        "pk": 153,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- potrafi krytycznie podej\u015b\u0107 do skodyfikowanych zasad netykiety.\r\n- potrafi wypracowa\u0107 w\u0142asne zasady kszta\u0142towania relacji w komunikacji przez media w oparciu o w\u0142asne do\u015bwiadczenia.",
+            "competence": 17,
+            "level": 9
+        }
+    },
+    {
+        "pk": 119,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- wie, \u017ce przepisy prawa stosuj\u0105 si\u0119 tak\u017ce do medi\u00f3w i komunikacji.\r\n- rozumie obowi\u0105zek przestrzegania prawa tak\u017ce w perspektywie medi\u00f3w i komunikacji;\r\nnp. potrafi wyja\u015bni\u0107, dlaczego kradzie\u017c w internecie ma taki sam status jak kradzie\u017c towaru ze sklepu.",
+            "competence": 14,
+            "level": 2
+        }
+    },
+    {
+        "pk": 121,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- wie, \u017ce system prawny nie zawsze odpowiednio szybko reaguje na nowe zjawiska w mediach;\r\nnp. zna poj\u0119cie stalkingu i wie, \u017ce jeszcze niedawno nie by\u0142o takiego przest\u0119pstwa w kodeksie karnym.\r\n- rozumie, \u017ce nie wszystkie zasady komunikacji i funkcjonowania w mediach musz\u0105 by\u0107 regulowane przez przepisy prawa;\r\nnp. umie wyja\u015bni\u0107 zasady i znaczenie kultury dyskusji na forach internetowych oraz pokaza\u0107, kt\u00f3re z tych zasad nie wynikaj\u0105 wprost z przepis\u00f3w prawa, a mimo to obowi\u0105zuj\u0105.",
+            "competence": 14,
+            "level": 4
+        }
+    },
+    {
+        "pk": 122,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- rozumie problem relacji mi\u0119dzy prawem stanowionym a moralno\u015bci\u0105 szczeg\u00f3lnie w odniesieniu do prawa autorskiego, prawa w\u0142asno\u015bci i prawa do prywatno\u015bci w mediach oraz rozumie problem j\u0119zyka w dyskusjach na ten temat;\r\nnp. rozumie z\u0142o\u017cono\u015b\u0107 moralnej oceny piractwa komputerowego, potrafi rozwa\u017ca\u0107, czy nielegalne korzystanie z program\u00f3w komputerowych do cel\u00f3w edukacyjnych jest etyczne, czy nie. Potrafi krytycznie zanalizowa\u0107 poj\u0119cie piractwa komputerowego.\r\n- rozumie, \u017ce normy funkcjonowania medi\u00f3w mog\u0105 by\u0107 r\u00f3\u017cne w r\u00f3\u017cnych systemach prawnych i normatywnych.\r\n- potrafi odnie\u015b\u0107 si\u0119 do tego problemu w pr\u00f3bie etycznej oceny zjawiska medialnego;\r\nnp. rozumie, \u017ce funkcjonowanie portalu Redwatch w kulturze prawnej USA jest dozwolone jako wyraz wolno\u015bci s\u0142owa, a w Polsce traktowane jako przest\u0119pstwo. Rozumie, jakie problemy rodzi zr\u00f3\u017cnicowanie system\u00f3w prawnych i normatywnych w pr\u00f3bie moralnej oceny tego zjawiska.",
+            "competence": 14,
+            "level": 5
+        }
+    },
+    {
+        "pk": 124,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- rozumie obowi\u0105zek przestrzegania prawa tak\u017ce w perspektywie medi\u00f3w i komunikacji.",
+            "competence": 14,
+            "level": 7
+        }
+    },
+    {
+        "pk": 125,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- wie, \u017ce system prawny nie zawsze odpowiednio szybko reaguje na nowe zjawiska w mediach.\r\n- rozumie, \u017ce nie wszystkie zasady komunikacji i funkcjonowania w mediach musz\u0105 by\u0107 regulowane przez przepisy prawa.\r\n- rozumie, \u017ce normy funkcjonowania medi\u00f3w mog\u0105 by\u0107 r\u00f3\u017cne w r\u00f3\u017cnych systemach prawnych i normatywnych.",
+            "competence": 14,
+            "level": 8
+        }
+    },
+    {
+        "pk": 126,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- rozumie problem relacji mi\u0119dzy prawem stanowionym a etyk\u0105, szczeg\u00f3lnie w odniesieniu do prawa autorskiego, prawa w\u0142asno\u015bci i prawa do prywatno\u015bci w mediach oraz rozumie problem j\u0119zyka w dyskusjach na ten temat.\r\n- potrafi odnie\u015b\u0107 problem r\u00f3\u017cnorodnych system\u00f3w prawnych i normatywnych do etycznej oceny zjawiska medialnego;\r\nnp. rozwa\u017ca: Czy skoro w USA nie jest zakazane propagowanie nazizmu (ze wzgl\u0119du na zasady wolno\u015bci s\u0142owa), oznacza to, \u017ce takie dzia\u0142anie w Polsce r\u00f3wnie\u017c powinno by\u0107 dozwolone?",
+            "competence": 14,
+            "level": 9
+        }
+    },
+    {
+        "pk": 181,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- umie zakomunikowa\u0107, \u017ce si\u0119 wstydzi i nie chce uczestniczy\u0107 w danej sytuacji komunikacyjnej;\r\nnp. nie chce by\u0107 nagrywane lub fotografowane, nie chce rozmawia\u0107 przez telefon.",
+            "competence": 21,
+            "level": 1
+        }
+    },
+    {
+        "pk": 182,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- wie, \u017ce pewnych informacji nie wolno udost\u0119pnia\u0107 obcym; w razie w\u0105tpliwo\u015bci pyta rodzic\u00f3w lub opiekun\u00f3w.\r\n- umie odr\u00f3\u017cni\u0107 uwiecznienie od upublicznienia.\r\n- umie sprzeciwi\u0107 si\u0119 innemu dziecku lub doros\u0142emu w kwestii publikacji swojego utworu lub zwi\u0105zanej z wizerunkiem;\r\nnp. pokazywanie filmu z jego udzia\u0142em.",
+            "competence": 21,
+            "level": 2
+        }
+    },
+    {
+        "pk": 183,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- umie wskaza\u0107 r\u00f3\u017cnice pomi\u0119dzy komunikacj\u0105 prywatn\u0105 i publiczn\u0105.",
+            "competence": 21,
+            "level": 3
+        }
+    },
+    {
+        "pk": 184,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- umie zdecydowa\u0107, czy w danej sytuacji komunikacja powinna by\u0107 prywatna czy publiczna.",
+            "competence": 21,
+            "level": 4
+        }
+    },
+    {
+        "pk": 185,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- umie poprawnie zidentyfikowa\u0107, czy dane narz\u0119dzia (np. czat na portalach spo\u0142eczno\u015bciowych) faktycznie oferuj\u0105 komunikacj\u0119 prywatn\u0105, czy tylko jej z\u0142udzenie.\r\n- umie pos\u0142u\u017cy\u0107 si\u0119 narz\u0119dziami zwi\u0119kszaj\u0105cymi prywatno\u015b\u0107,\r\nnp. rozszerzenia przegl\u0105darek, ustawienia prywatno\u015bci.\r\n- wie, do czego s\u0142u\u017c\u0105 regulaminy na stronach, z kt\u00f3rych korzysta.",
+            "competence": 21,
+            "level": 5
+        }
+    },
+    {
+        "pk": 186,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- umie p\u0142ynnie pos\u0142ugiwa\u0107 si\u0119 metodami i narz\u0119dziami ochrony prywatno\u015bci.\r\n- czyta ze zrozumieniem regulaminy stron, z kt\u00f3rych korzysta, i umie \u015bwiadomie podj\u0105\u0107 decyzje dotycz\u0105ce przyj\u0119cia lub odrzucenia ich postanowie\u0144.",
+            "competence": 21,
+            "level": 6
+        }
+    },
+    {
+        "pk": 187,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- wie, \u017ce prywatno\u015b\u0107 jest dobrem i \u017ce mamy do niej prawo.\r\n- wie, \u017ce ochrona wizerunku wymaga ochrony prywatno\u015bci.\r\n- wie, \u017ce dane prywatne mog\u0105 by\u0107 traktowane jak towar.\r\n- wie, \u017ce pewne komunikaty mog\u0105 by\u0107 przekazywane wy\u0142\u0105cznie prywatnie, a inne udost\u0119pniane publicznie.\r\n- rozumie, \u017ce bior\u0105c udzia\u0142 w komunikacji, potencjalnie odpowiada za wizerunek nie tylko sw\u00f3j, ale np. swojego pracodawcy, je\u015bli u\u017cywa np. firmowego adresu e-mail.",
+            "competence": 21,
+            "level": 7
+        }
+    },
+    {
+        "pk": 188,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- umie u\u017cywa\u0107 podstawowych narz\u0119dzi chroni\u0105cych prywatno\u015b\u0107, np. rozszerzenia do przegl\u0105darek, blokada ciasteczek.\r\n- umie precyzyjnie wskaza\u0107, kt\u00f3re, komunikaty mog\u0105 by\u0107 przekazywane wy\u0142\u0105cznie prywatnie, a kt\u00f3re udost\u0119pniane publicznie.\r\n- wie, \u017ce nawet dane anonimizowane zebrane w odpowiedniej ilo\u015bci mog\u0105 pozwoli\u0107 na naruszenie prywatno\u015bci.\r\n- wie, \u017ce jego decyzje dotycz\u0105ce prywatno\u015bci mog\u0105 r\u00f3\u017cni\u0107 si\u0119 od decyzji innych i umie to uszanowa\u0107.\r\n- umie dostosowa\u0107 sw\u00f3j wizerunek do sytuacji i roli.",
+            "competence": 21,
+            "level": 8
+        }
+    },
+    {
+        "pk": 189,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- \u015bwiadomie kreuje sw\u00f3j wizerunek on-line w r\u00f3\u017cnych kontekstach.\r\n- p\u0142ynnie pos\u0142uguje si\u0119 technikami i narz\u0119dziami ochrony prywatno\u015bci.\r\n- umie \u015bwiadomie podejmowa\u0107 decyzje dotycz\u0105ce udost\u0119pnienia b\u0105d\u017a nie danych swoich i swoich znajomych, uwzgl\u0119dniaj\u0105c ich preferencje w zakresie ochrony prywatno\u015bci i wizerunku.",
+            "competence": 21,
+            "level": 9
+        }
+    },
+    {
+        "pk": 173,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- wie, co to znaczy \u201eanonimowo\u015b\u0107\u201d.",
+            "competence": 20,
+            "level": 2
+        }
+    },
+    {
+        "pk": 174,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- wie, \u017ce z sieci mo\u017cemy korzysta\u0107 anonimowo.\r\n- umie poda\u0107 przyk\u0142ad sytuacji, w kt\u00f3rej anonimowo\u015b\u0107 jest wskazana.",
+            "competence": 20,
+            "level": 3
+        }
+    },
+    {
+        "pk": 175,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- wie, \u017ce s\u0105 specjalne narz\u0119dzia do zwi\u0119kszania anonimowo\u015bci w sieci i umie o nie spyta\u0107.\r\n- wie, \u017ce anonimowo\u015b\u0107 w sieci mo\u017ce by\u0107 pozorna i \u017ce cz\u0119sto mo\u017cliwe jest ustalenie autora danej informacji nawet je\u017celi u\u017cywa\u0142 pseudonimu.\r\n- wie, \u017ce je\u017celi ujawni w tre\u015bci komunikacji dane identyfikuj\u0105ce, sam fakt komunikowania si\u0119 anonimowo (np. przy u\u017cyciu odpowiednich narz\u0119dzi) nie wystarczy do zachowania anonimowo\u015bci.",
+            "competence": 20,
+            "level": 4
+        }
+    },
+    {
+        "pk": 176,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- umie pos\u0142u\u017cy\u0107 si\u0119 narz\u0119dziami zwi\u0119kszaj\u0105cymi anonimowo\u015b\u0107; np. TOR, anonimowe proxy, dystrybucja Linuksa TAILS.",
+            "competence": 20,
+            "level": 5
+        }
+    },
+    {
+        "pk": 177,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- \u015bwiadomie i trafnie podejmuje decyzje dotycz\u0105ce anonimowo\u015bci w r\u00f3\u017cnych sytuacjach komunikacyjnych;\r\nnp. \u015bwiadomie w pewnych sytuacjach wy\u0142\u0105cza us\u0142ugi lokalizacyjne dost\u0119pne w przegl\u0105darce.",
+            "competence": 20,
+            "level": 6
+        }
+    },
+    {
+        "pk": 178,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- wie, \u017ce z sieci mo\u017cemy korzysta\u0107 anonimowo\r\n- wie, \u017ce korzystanie anonimowe nie wyklucza mo\u017cliwo\u015bci ustalenia autora.\r\n- wie, \u017ce istniej\u0105 metody \u015bledzenia os\u00f3b w sieci bez ich wiedzy, np. ciasteczka.",
+            "competence": 20,
+            "level": 7
+        }
+    },
+    {
+        "pk": 179,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- wie, \u017ce istniej\u0105 narz\u0119dzia zwi\u0119kszaj\u0105ce anonimowo\u015b\u0107 (jak rozszerzenia do przegl\u0105darek, systemy TOR, I2P, proxy).\r\n- umie znale\u017a\u0107 i dostosowa\u0107 do swoich potrzeb ustawienia przegl\u0105darek zwi\u0119kszaj\u0105ce anonimowo\u015b\u0107.",
+            "competence": 20,
+            "level": 8
+        }
+    },
+    {
+        "pk": 180,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- biegle korzysta z narz\u0119dzi i technik zapewniaj\u0105cych anonimowo\u015b\u0107 w sieci.\r\n- umie kompleksowo zadba\u0107 o zachowanie anonimowo\u015bci, korzystaj\u0105c z kombinacji narz\u0119dzi, np. tryb prywatny, TOR, blokada ciasteczek.",
+            "competence": 20,
+            "level": 9
+        }
+    },
+    {
+        "pk": 154,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- umie zakomunikowa\u0107, \u017ce dana tre\u015b\u0107 budzi strach lub poczucie zagro\u017cenia, ale niekoniecznie umie temu zaradzi\u0107, np. celowo prze\u0142\u0105czy\u0107 kana\u0142.",
+            "competence": 18,
+            "level": 1
+        }
+    },
+    {
+        "pk": 155,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- rozumie, co to \u201esekret\u201d, \u201etajemnica\u201d i umie jej dochowa\u0107, r\u00f3wnie\u017c w sytuacji komunikacyjnej.\r\n- umie selekcjonowa\u0107 tre\u015bci, kt\u00f3re odbiera\r\nnp. poprzez wy\u0142\u0105czenie telewizora, zmian\u0119 filmu, zmian\u0119 strony.",
+            "competence": 18,
+            "level": 2
+        }
+    },
+    {
+        "pk": 156,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- wie, \u017ce pewne informacje i rodzaje komunikacji powinny by\u0107 \u201etajemnic\u0105\u201d (np. has\u0142o do poczty).\r\n- wie, \u017ce istniej\u0105 sposoby zapewnienia tej \u201etajemnicy\u201d i umie o nie spyta\u0107.\r\n- wie, \u017ce zakupy mo\u017cna zrobi\u0107 w fizycznym sklepie, jak i w sklepie internetowym czy portalu aukcyjnym; potrafi poda\u0107 przyk\u0142ady.\r\n- wie, co to spam i umie rozpozna\u0107 bardziej oczywiste jego przyk\u0142ady.",
+            "competence": 18,
+            "level": 3
+        }
+    },
+    {
+        "pk": 157,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- wie, \u017ce dane prywatne mog\u0105 by\u0107 traktowane jak towar.\r\n- umie skorzysta\u0107 z podstawowych narz\u0119dzi zapewniaj\u0105cych bezpiecze\u0144stwo komunikacji;\r\nnp. korzysta z https na stronach bank\u00f3w czy portalach spo\u0142eczno\u015bciowych.\r\n- wie, \u017ce nale\u017cy wylogowa\u0107 si\u0119 z portali po zako\u0144czeniu pracy.\r\n- wie, \u017ce s\u0105 r\u00f3\u017cne formy p\u0142atno\u015bci w internecie o r\u00f3\u017cnym poziomie bezpiecze\u0144stwa.\r\n- zna podstawowe zasady bezpiecze\u0144stwa przy zakupach on-line.",
+            "competence": 18,
+            "level": 4
+        }
+    },
+    {
+        "pk": 158,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- z du\u017c\u0105 doz\u0105 pewno\u015bci rozpoznaje spam i pr\u00f3by phishingu;\r\nnp. zwraca uwag\u0119 na to, \u017ce nie zgadza si\u0119 adres strony bankowej.\r\n- zwraca uwag\u0119 na certyfikaty;\r\nnp. nie akceptuje automatycznie ka\u017cdego napotkanego b\u0142\u0119dnego certyfikatu zg\u0142oszonego przez przegl\u0105dark\u0119.\r\n- wie, \u017ce istniej\u0105 narz\u0119dzia dodatkowo zwi\u0119kszaj\u0105ce bezpiecze\u0144stwo komunikacji i umie do nich dotrze\u0107;\r\nnp. szyfrowanie end-to-end, poczty, PGP/GPG, OTR.",
+            "competence": 18,
+            "level": 5
+        }
+    },
+    {
+        "pk": 159,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- p\u0142ynnie pos\u0142uguje si\u0119 narz\u0119dziami zwi\u0119kszaj\u0105cymi bezpiecze\u0144stwo komunikacji.\r\n- zna narz\u0119dzia szyfrowania end-to-end i umie ich u\u017cy\u0107 np. PGP/GPG, OTR.",
+            "competence": 18,
+            "level": 6
+        }
+    },
+    {
+        "pk": 160,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- umie skorzysta\u0107 z podstawowych narz\u0119dzi zapewniaj\u0105cych bezpiecze\u0144stwo transmisji (https).\r\n- wie, \u017ce nale\u017cy wylogowa\u0107 si\u0119 po zako\u0144czeniu pracy na publicznym terminalu lub w sytuacji, w kt\u00f3rej inni b\u0119d\u0105 korzysta\u0107 z tego samego komputera.\r\n- zwraca uwag\u0119 na ostrze\u017cenia o wygas\u0142ych/nieprawid\u0142owych certyfikatach, w razie w\u0105tpliwo\u015bci pyta (nie akceptuje automatycznie).\r\n- docenia wag\u0119 traktowania pewnych informacji jako tajnych, zdaje sobie spraw\u0119, \u017ce dzielenie si\u0119 has\u0142ami (nawet je\u015bli np. zwi\u0119ksza wygod\u0119) jest niedopuszczalne.\r\n- potrafi zachowa\u0107 \u201ehigien\u0119 informatyczn\u0105\u201d, np. zwraca uwag\u0119 na komunikaty pojawiaj\u0105ce si\u0119 na ekranie i nie akceptuje rzeczy, kt\u00f3rych nie rozumie \u2013 w takich sytuacjach pyta; zdaje sobie spraw\u0119 z zagro\u017ce\u0144 takich jak wirusy; potrafi korzysta\u0107 z tzw. \u201etrybu prywatnego\u201d przegl\u0105darek.",
+            "competence": 18,
+            "level": 7
+        }
+    },
+    {
+        "pk": 161,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- umie samodzielnie podj\u0105\u0107 decyzj\u0119 dotycz\u0105c\u0105 bezpiecze\u0144stwa komunikacji w danym przypadku, np. decyduje o zaakceptowaniu b\u0105d\u017a nie wygas\u0142ego/nieprawid\u0142owego certyfikatu.\r\n- zdaje sobie spraw\u0119 z zagro\u017ce\u0144 zwi\u0105zanych ze scentralizowanymi sieciami i us\u0142ugami; umie poda\u0107 przyk\u0142ady sieci scentralizowanych (np. Facebook, Google) oraz zagro\u017ce\u0144 z nimi zwi\u0105zanych (np. utrata kontroli nad komunikacj\u0105, pods\u0142uch).",
+            "competence": 18,
+            "level": 8
+        }
+    },
+    {
+        "pk": 162,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- p\u0142ynnie pos\u0142uguje si\u0119 systemami szyfrowania end-to-end (PGP/GPG, OTR).\r\n- \u015bledzi najwa\u017cniejsze doniesienia dotycz\u0105ce narusze\u0144 bezpiecze\u0144stwa i umie wdro\u017cy\u0107 rozwi\u0105zania problem\u00f3w oraz sugerowane praktyki.\r\n- podejmuje \u015bwiadome, oparte na rzetelnych przes\u0142ankach decyzje dotycz\u0105ce narz\u0119dzi, kt\u00f3rych u\u017cywa, bior\u0105c pod uwag\u0119 r\u00f3wnie\u017c przes\u0142anki pozatechniczne;\r\nnp. bierze pod uwag\u0119 to, czy wszystkie kana\u0142y komunikacji, z kt\u00f3rych korzysta, mog\u0105 by\u0107 \u0142atwo kontrolowane przez jedn\u0105 organizacj\u0119.\r\n- rozumie zalety decentralizacji i umie je uwzgl\u0119dni\u0107 w podejmowanych decyzjach.\r\n- potrafi przeprowadzi\u0107 prosty, nieformalny audyt bezpiecze\u0144stwa, wskazuj\u0105c na braki w danej sytuacji;\r\nnp. doradza szyfrowanie.",
+            "competence": 18,
+            "level": 9
+        }
+    },
+    {
+        "pk": 192,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- wie, co to znaczy \u201ecenzura\u201d.\r\n- wie, co to znaczy \u201epods\u0142uchiwa\u0107\u201d, r\u00f3wnie\u017c w kontek\u015bcie technologii i sieci;\r\nnp. wie, \u017ce kiedy pisze do kogo\u015b w internecie, czyta to te\u017c jeszcze kto\u015b inny.",
+            "competence": 22,
+            "level": 3
+        }
+    },
+    {
+        "pk": 193,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- wie, \u017ce sie\u0107 mo\u017ce by\u0107 nadzorowana.\r\n- wie, \u017ce nadz\u00f3r ten mo\u017ce mie\u0107 wiele form, w tym cenzury czy pods\u0142uchu.\r\n- wie, \u017ce nadz\u00f3r mo\u017ce nie by\u0107 zauwa\u017calny dla nadzorowanych;\r\nnp. zdaje sobie spraw\u0119, \u017ce skutkiem nadzoru mo\u017ce by\u0107 trudna do identyfikacji zmiana wynik\u00f3w wyszukiwania.",
+            "competence": 22,
+            "level": 4
+        }
+    },
+    {
+        "pk": 194,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- wie, \u017ce mog\u0105 by\u0107 r\u00f3\u017cne cele wprowadzania nadzoru i umie je wymieni\u0107;\r\nnp. ochrona dzieci w internecie; uzyskiwanie dodatkowych przychod\u00f3w przez dan\u0105 korporacj\u0119 ze sprzeda\u017cy prywatnych danych u\u017cytkownik\u00f3w.\r\n- wie, \u017ce nadz\u00f3r mo\u017ce by\u0107 legalny lub bezprawny; \u017ce mo\u017ce by\u0107 prowadzony przez organy pa\u0144stwowe (np. policj\u0119) i osoby prywatne czy korporacje;\r\n- wie, \u017ce istniej\u0105 metody obej\u015bcia / utrudnienia nadzoru, nie tylko techniczne;\r\nnp. potrafi wymieni\u0107 takie metody jak \u015bwiadome umieszczanie informacji fa\u0142szywych lub stosowanie szyfrowania nie tylko do tre\u015bci wra\u017cliwych, ale r\u00f3wnie\u017c banalnych, celem utrudnienia identyfikacji, kiedy zachodzi wa\u017cna / wra\u017cliwa komunikacja.",
+            "competence": 22,
+            "level": 5
+        }
+    },
+    {
+        "pk": 195,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- umie korzysta\u0107 z narz\u0119dzi obej\u015bcia / utrudnienia nadzoru.\r\n- \u015bwiadomie podejmuje decyzje o doborze narz\u0119dzi do konkretnych cel\u00f3w, bior\u0105c pod uwag\u0119 mo\u017cliwo\u015b\u0107 nadzoru os\u00f3b trzecich nad tymi narz\u0119dziami, oraz specyfik\u0119 tre\u015bci.",
+            "competence": 22,
+            "level": 6
+        }
+    },
+    {
+        "pk": 196,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- wie, \u017ce komunikacja w sieci mo\u017ce by\u0107 nadzorowana w spos\u00f3b niezauwa\u017calny dla korzystaj\u0105cego.\r\n- wie, \u017ce istniej\u0105 narz\u0119dzia obchodz\u0105ce nadz\u00f3r, umie znale\u017a\u0107 informacje na ich temat.\r\n- wie, \u017ce nadz\u00f3r mo\u017ce by\u0107 legalny lub bezprawny; prywatny i pa\u0144stwowy.\r\n- wie, \u017ce nadz\u00f3r mo\u017ce prowadzi\u0107 do cenzury.",
+            "competence": 22,
+            "level": 7
+        }
+    },
+    {
+        "pk": 197,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- umie skorzysta\u0107 samodzielnie z podstawowych narz\u0119dzi walki z potencjalnym nadzorem w sieci.\r\n- wie, \u017ce nadz\u00f3r nad komunikacj\u0105 w sieci jest wielopoziomowy.\r\n- umie rozpozna\u0107, kt\u00f3re kana\u0142y komunikacji s\u0105 bardziej podatne na nadz\u00f3r od innych.\r\n- umie poda\u0107 przyk\u0142ady sytuacji, w kt\u00f3rych nadz\u00f3r jest uzasadniony, i takich, w kt\u00f3rych nie jest.",
+            "competence": 22,
+            "level": 8
+        }
+    },
+    {
+        "pk": 198,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- umie aktywnie przeciwdzia\u0142a\u0107 nadzorowi w sieci, \u015bwiadomie stosuj\u0105c wiele technik w tym celu.\r\n- umie z du\u017c\u0105 doz\u0105 pewno\u015bci okre\u015bli\u0107, kt\u00f3re kana\u0142y komunikacji s\u0105 najprawdopodobniej nadzorowane i w jakich celach.",
+            "competence": 22,
+            "level": 9
+        }
+    },
+    {
+        "pk": 165,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- umie dostrzec sytuacje, w kt\u00f3rych przekroczone zostaj\u0105 granice higieny korzystania z medi\u00f3w;\r\nnp. mama za du\u017co gra w gry, kolega za du\u017co rozmawia przez telefon.\r\n- wie, \u017ce relacje przez media maj\u0105 wp\u0142yw na relacje bezpo\u015brednie, a czynno\u015bci dokonywane przez media mog\u0105 mie\u0107 bardzo realne konsekwencje (np. p\u0142atno\u015bci).",
+            "competence": 19,
+            "level": 3
+        }
+    },
+    {
+        "pk": 166,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- wie, \u017ce pewne wzorce zachowa\u0144 mog\u0105 prowadzi\u0107 do uzale\u017cnienia.\r\n- umie zidentyfikowa\u0107 niebezpieczne wzorce i ich unika\u0107.\r\n- wie, czym jest stalking (n\u0119kanie).",
+            "competence": 19,
+            "level": 4
+        }
+    },
+    {
+        "pk": 167,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- umie \u015bwiadomie kszta\u0142towa\u0107 swoje nawyki zwi\u0105zane z korzystaniem z technologii.\r\n- umie zaobserwowa\u0107 oznaki uzale\u017cnienia u siebie i u innych.\r\n- umie przewidzie\u0107 konsekwencje dzia\u0142a\u0144 w sieci, kt\u00f3re mog\u0105 spowodowa\u0107 gro\u017ane sytuacje tak\u017ce poza ni\u0105;\r\nnp. nie podaje publicznie informacji o planowanej d\u0142u\u017cszej nieobecno\u015bci w domu na portalu spo\u0142eczno\u015bciowym, na kt\u00f3rym podany jest r\u00f3wnie\u017c adres zamieszkania.\r\n- umie rozpozna\u0107 stalking (n\u0119kanie) i wie, jak si\u0119 przed nim broni\u0107.\r\n- umie zarz\u0105dza\u0107 wizerunkiem on-line; \u015bwiadomie podejmuje decyzj\u0119, na ile wizerunek on-line odzwierciedla jego prawdziw\u0105 to\u017csamo\u015b\u0107;\r\nnp. nie publikuje danych umo\u017cliwiaj\u0105cych odkrycie jego to\u017csamo\u015bci.",
+            "competence": 19,
+            "level": 5
+        }
+    },
+    {
+        "pk": 168,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- umie zareagowa\u0107 na negatywne wzorce zachowa\u0144 u innych, np. szukaj\u0105c pomocy specjalisty.\r\n- dostrzega powi\u0105zania pomi\u0119dzy swoimi dzia\u0142aniami w mediach a innymi sferami \u017cycia, umie tymi powi\u0105zaniami zarz\u0105dza\u0107.",
+            "competence": 19,
+            "level": 6
+        }
+    },
+    {
+        "pk": 169,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- wie, \u017ce pewne wzorce zachowa\u0144 mog\u0105 prowadzi\u0107 do uzale\u017cnienia.\r\n- wie, \u017ce relacje przez media maj\u0105 wp\u0142yw na relacje bezpo\u015brednie a czynno\u015bci dokonywane przez media maj\u0105 bardzo realne konsekwencje (np. p\u0142atno\u015bci).\r\n- umie przewidzie\u0107 konsekwencje dzia\u0142a\u0144 w sieci, kt\u00f3re mog\u0105 spowodowa\u0107 gro\u017ane sytuacje tak\u017ce poza ni\u0105.\r\n- wie,",
+            "competence": 19,
+            "level": 7
+        }
+    },
+    {
+        "pk": 170,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- umie zidentyfikowa\u0107 niebezpieczne wzorce zachowa\u0144 i unika\u0107 sytuacji, kt\u00f3re do nich prowadz\u0105.\r\n- umie \u015bwiadomie kszta\u0142towa\u0107 swoje nawyki zwi\u0105zane z korzystaniem z technologii.\r\n- umie zaobserwowa\u0107 oznaki uzale\u017cnienia u siebie i u innych.\r\n- zna podstawowe narz\u0119dzia i metody obrony przed zagro\u017ceniami zwi\u0105zanymi z komunikacj\u0105 przez media.",
+            "competence": 19,
+            "level": 8
+        }
+    },
+    {
+        "pk": 171,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- umie zareagowa\u0107 na negatywne wzorce zachowa\u0144, np. szukaj\u0105c pomocy specjalisty.\r\n- umie zidentyfikowa\u0107 pr\u00f3by aktywnych atak\u00f3w w \u015brodowisku medialnym (phishing targetowany) i si\u0119 przed nimi obroni\u0107.",
+            "competence": 19,
+            "level": 9
+        }
+    },
+    {
+        "pk": 199,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- wie, co znaczy da\u0107 komu\u015b s\u0142owo, um\u00f3wi\u0107 si\u0119 na co\u015b\r\nnp. gdy obieca mamie, \u017ce posprz\u0105ta zabawki w pokoju.",
+            "competence": 23,
+            "level": 1
+        }
+    },
+    {
+        "pk": 200,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- wie, czym s\u0105 zwyczajowe normy komunikacyjne i umie je zastosowa\u0107 w typowych sytuacjach;\r\nnp. wie, kiedy m\u00f3wi si\u0119 dzie\u0144 dobry, dobry wiecz\u00f3r, dzi\u0119kuj\u0119, przepraszam\r\n- wie, \u017ce prawo obowi\u0105zuje tak\u017ce w komunikacji z innymi, a naruszenie go jest karane.",
+            "competence": 23,
+            "level": 2
+        }
+    },
+    {
+        "pk": 201,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- rozumie poj\u0119cia wolno\u015bci s\u0142owa, prawa do prywatno\u015bci , ochrony dobrego imienia.\r\n- umie wskaza\u0107 przyk\u0142ady swoich praw i obowi\u0105zk\u00f3w w sferze komunikacji.\r\nnp. prawo do tajemnicy korespondencji\r\n- rozumie poj\u0119cie umowy.\r\n- wie, \u017ce korzystanie z us\u0142ug komunikacyjnych wi\u0105\u017ce si\u0119 z zawarciem umowy.",
+            "competence": 23,
+            "level": 3
+        }
+    },
+    {
+        "pk": 202,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- wie, \u017ce przed naruszeniem praw komunikacyjnych mo\u017cna si\u0119 broni\u0107 w s\u0105dzie.\r\n- wie, \u017ce istniej\u0105 regulacje prawne dotycz\u0105ce komunikacji przez media (prawo telekomunikacyjne, prawo autorskie, prawo prasowe, ochrona danych osobowych itd.)\r\n- wie, \u017ce zbiorem norm zwyczajowych w komunikacji on-line jest netykieta.",
+            "competence": 23,
+            "level": 4
+        }
+    },
+    {
+        "pk": 203,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- umie \u015bwiadomie zawrze\u0107 umow\u0119 na us\u0142ugi komunikacyjne, umie wskaza\u0107 wynikaj\u0105ce z niej swoje prawa i obowi\u0105zki.\r\n- umie egzekwowa\u0107 swoje prawa.\r\n- umie zwr\u00f3ci\u0107 si\u0119 o pomoc do organ\u00f3w regulacyjnych i rzecznik\u00f3w r\u00f3\u017cnych grup;\r\nnp. w przypadku naruszenia ochrony danych osobowych lub naruszenia praw autorskich.\r\n\r\n- umie zapisy traktatowe, konstytucyjne i ustawowe prze\u0142o\u017cy\u0107 na w\u0142asne otoczenie i dzia\u0142ania.",
+            "competence": 23,
+            "level": 5
+        }
+    },
+    {
+        "pk": 204,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- umie zinterpretowa\u0107 normy prawne i zastosowa\u0107 je w ci\u0105gle zmieniaj\u0105cym si\u0119 \u015brodowisku technologicznym.",
+            "competence": 23,
+            "level": 6
+        }
+    },
+    {
+        "pk": 205,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- wie, czym s\u0105 zwyczajowe normy komunikacyjne.\r\n- wie, \u017ce prawo obowi\u0105zuje tak\u017ce w komunikacji z innymi, a naruszenie go jest karane.\r\n- wie, \u017ce narusze\u0144 praw komunikacyjnych mo\u017ce dochodzi\u0107 w s\u0105dzie.\r\n- rozumie poj\u0119cia wolno\u015bci s\u0142owa, prawa do prywatno\u015bci (tajemnica korespondencji), ochrony dobrego imienia.\r\n- umie wskaza\u0107 przyk\u0142ady swoich praw i obowi\u0105zk\u00f3w w sferze komunikacji.\r\n- rozumie poj\u0119cie umowy.\r\n- wie, \u017ce korzystanie z us\u0142ug komunikacyjnych wi\u0105\u017ce si\u0119 z zawarciem umowy.\r\n- wie, \u017ce zbiorem norm zwyczajowych w komunikacji on-line jest netykieta.",
+            "competence": 23,
+            "level": 7
+        }
+    },
+    {
+        "pk": 206,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- umie zapisy traktatowe, konstytucyjne i ustawowe prze\u0142o\u017cy\u0107 na w\u0142asne otoczenie i dzia\u0142ania.\r\n- wie, \u017ce istniej\u0105 regulacje prawne dotycz\u0105ce komunikacji przez media (prawo telekomunikacyjne, prawo autorskie, prawo prasowe, ochrona danych osobowych itd.)",
+            "competence": 23,
+            "level": 8
+        }
+    },
+    {
+        "pk": 207,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- umie egzekwowa\u0107 swoje prawa.\r\n- umie zwr\u00f3ci\u0107 si\u0119 o pomoc do organ\u00f3w regulacyjnych i rzecznik\u00f3w r\u00f3\u017cnych grup.\r\n- umie zinterpretowa\u0107 normy prawne i zastosowa\u0107 je w ci\u0105gle zmieniaj\u0105cym si\u0119 \u015brodowisku technologicznym.",
+            "competence": 23,
+            "level": 9
+        }
+    },
+    {
+        "pk": 244,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- wie, \u017ce media \u0142\u0105cz\u0105 z lud\u017ami;\r\nnp. mo\u017ce zadzwoni\u0107 do babci.\r\n- wie, \u017ce nie nale\u017cy ura\u017ca\u0107 innych, zar\u00f3wno w kontakcie bezpo\u015brednim, jak i przez media.\r\n- umie powiadomi\u0107 rodzic\u00f3w lub opiekun\u00f3w, gdy korzystaj\u0105c z medi\u00f3w spotyka si\u0119 z nieprzyjemn\u0105 sytuacj\u0105.",
+            "competence": 28,
+            "level": 1
+        }
+    },
+    {
+        "pk": 245,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- wie, \u017ce ma prawo do anonimowo\u015bci, ale nie do bezkarno\u015bci;\r\nnp. mo\u017ce podpisa\u0107 rysunek pseudonimem i nie musi ujawnia\u0107 prawdziwego imienia.\r\n- umie sprzeciwi\u0107 si\u0119 naruszaniu norm komunikacyjnych.\r\n- wie, \u017ce ka\u017cdy ma prawo dost\u0119pu do wiedzy.",
+            "competence": 28,
+            "level": 2
+        }
+    },
+    {
+        "pk": 246,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- zna swoje prawa komunikacyjne jako dziecka, ucznia i obywatela\r\n(prawo do uczestnictwa w kulturze, wolno\u015b\u0107 s\u0142owa itd.) i wie, dlaczego s\u0105 wa\u017cne;\r\nnp. wie, \u017ce ma prawo czyta\u0107 ksi\u0105\u017cki, ma prawo komunikowa\u0107 si\u0119 z innymi.\r\n- umie dostrzec naruszenia praw, wolno\u015bci, r\u00f3wno\u015bci i prywatno\u015bci w mediach.\r\n- rozumie, \u017ce prawo ma chroni\u0107 u\u017cytkownik\u00f3w medi\u00f3w.",
+            "competence": 28,
+            "level": 3
+        }
+    },
+    {
+        "pk": 247,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- wie, jakie konkretnie prawa dziecka, cz\u0142owieka i obywatela dotycz\u0105 medi\u00f3w.\r\nnp. tejemnica korespondencji.\r\n- wie, \u017ce prawa komunikacyjne wymagaj\u0105 ochrony.\r\n- umie opisa\u0107 naruszenia praw i swob\u00f3d oraz reaguje na nie.",
+            "competence": 28,
+            "level": 4
+        }
+    },
+    {
+        "pk": 248,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- wie, jakie s\u0105 zadania regulator\u00f3w medi\u00f3w,\r\nrzecznik\u00f3w praw oraz s\u0105d\u00f3w krajowych i europejskich;\r\nnp. odr\u00f3\u017cnia rol\u0119, zadania i obszar dzia\u0142ania Europejskiego Trybuna\u0142u Sprawiedliwo\u015bci od Europejskiego Trybuna\u0142u Praw Cz\u0142owieka.\r\n- umie zwr\u00f3ci\u0107 si\u0119 o wsparcie urz\u0119du, rzecznika lub s\u0105du dla ochrony praw swoich i innych.\r\n- rozumie potrzeb\u0119 aktywnej obrony praw i swob\u00f3d komunikacyjnych.",
+            "competence": 28,
+            "level": 5
+        }
+    },
+    {
+        "pk": 249,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- umie u\u017cy\u0107 medi\u00f3w do publicznej obrony praw swoich i innych.",
+            "competence": 28,
+            "level": 6
+        }
+    },
+    {
+        "pk": 250,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- wie, \u017ce ma prawo do anonimowo\u015bci, ale nie do bezkarno\u015bci.\r\n- umie godnie si\u0119 zachowa\u0107 w sytuacjach komunikacyjnych.\r\n- rozumie, \u017ce ka\u017cdy ma prawo do nauki i dost\u0119pu do wiedzy.\r\n- zna swoje prawa komunikacyjne wynikaj\u0105ce z praw cz\u0142owieka i obywatela.",
+            "competence": 28,
+            "level": 7
+        }
+    },
+    {
+        "pk": 251,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- umie dostrzec naruszenia praw, wolno\u015bci, r\u00f3wno\u015bci i prywatno\u015bci w mediach i reaguje na nie.\r\n- rozumie rol\u0119 prawa do edukacji i do udzia\u0142u w kulturze.\r\n- wie, jakie konkretnie prawa cz\u0142owieka i obywatela dotycz\u0105 medi\u00f3w.",
+            "competence": 28,
+            "level": 8
+        }
+    },
+    {
+        "pk": 252,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- wie, jakie s\u0105 zadania regulator\u00f3w medi\u00f3w, rzecznik\u00f3w i s\u0105d\u00f3w krajowych i europejskich.\r\n- umie zwr\u00f3ci\u0107 si\u0119 o wsparcie urz\u0119du, rzecznika lub s\u0105du dla ochrony praw swoich i innych os\u00f3b.\r\n- umie u\u017cy\u0107 medi\u00f3w do publicznej obrony praw swoich i innych.\r\n- rozumie potrzeb\u0119 aktywnej obrony praw i swob\u00f3d.",
+            "competence": 28,
+            "level": 9
+        }
+    },
+    {
+        "pk": 235,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- wie, \u017ce ka\u017cde dzie\u0142o ma autora;\r\nnp. umie wskaza\u0107, \u017ce to rysunek Kasi, a ten wierszyk wymy\u015bli\u0142 Tomek.\r\n- wie, \u017ce nie powinno si\u0119 przypisywa\u0107 sobie cudzych dzie\u0142.",
+            "competence": 27,
+            "level": 1
+        }
+    },
+    {
+        "pk": 236,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- wie, \u017ce jest autorem i u\u017cytkownikiem informacji, np. kiedy rysuje czy ogl\u0105da bajki.\r\n- wie, \u017ce o publikacji decyduje autor, np. sam mo\u017ce zadecydowa\u0107 kiedy rysunek jest gotowy i kiedy pokaza\u0107 go kolegom.\r\n- wie, co to jest plagiat; np. umie wskaza\u0107, \u017ce ten wierszyk napisa\u0142 Tuwim, a nie kolega.\r\n- wie, czym jest cytat.\r\n- umie wskaza\u0107 cytat we w\u0142asnej i cudzej wypowiedzi.",
+            "competence": 27,
+            "level": 2
+        }
+    },
+    {
+        "pk": 237,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- wie, \u017ce s\u0105 r\u00f3\u017cne prawa wy\u0142\u0105czne: autorskie, patentowe, do znak\u00f3w towarowych.\r\n- wie, co to jest\r\ndozwolony u\u017cytek osobisty i publiczny: np. biblioteka, prawo do czytania, prawo do kopiowania informacji.\r\n- umie poprawnie cytowa\u0107 i oznacza\u0107 autorstwo\r\n- umie opisa\u0107 przyk\u0142ad dzie\u0142a zale\u017cnego:\r\nnp. t\u0142umaczenia.",
+            "competence": 27,
+            "level": 3
+        }
+    },
+    {
+        "pk": 238,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- potrafi rozr\u00f3\u017cni\u0107 r\u00f3\u017cne rodzaje praw wy\u0142\u0105cznych i umie wskaza\u0107, jakiego rodzaju prawo dotyczy danej sytuacji.\r\n- rozumie, \u017ce prawa wy\u0142\u0105czne ograniczaj\u0105 wolno\u015b\u0107 u\u017cytkownik\u00f3w.\r\n- wie, czym jest licencja.\r\n- rozumie i umie stosowa\u0107 prawa osobiste autora: prawo do oznaczenia autorstwa i zachowania integralno\u015bci dzie\u0142a.\r\n- wie, \u017ce prawa wy\u0142\u0105czne s\u0105 ograniczone w czasie.\r\n- wie, czym s\u0105 i czemu s\u0142u\u017c\u0105 wolne licencje.\r\n- wie, co to jest domena publiczna.\r\n- rozumie granice cytatu i dozwolonego u\u017cytku.",
+            "competence": 27,
+            "level": 4
+        }
+    },
+    {
+        "pk": 239,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- rozumie cele istnienia prawa autorskiego.\r\n- wie, \u017ce monopol tw\u00f3rczy jest kompromisem pomi\u0119dzy prawami u\u017cytkownika a prawami autora.\r\n- umie opisa\u0107, jak powstaj\u0105 r\u00f3\u017cne prawa wy\u0142\u0105czne i jak d\u0142ugo trwa ich ochrona;\r\nnp. wie, \u017ce dzie\u0142o uzyskuje ochron\u0119 w chwili ustalenia, a patent i znak towarowy trzeba rejestrowa\u0107.\r\n- wie, jakie s\u0105 cele organizacji zbiorowego zarz\u0105du prawami.\r\n- umie opisa\u0107 obszary stosowania monopolu autorskiego i patentowego;\r\nnp. wie, \u017ce prawo autorskie nie dotyczy dokument\u00f3w urz\u0119dowych, a ochrona patentowa odkry\u0107 naukowych, matematyki i program\u00f3w komputerowych.\r\n- umie opisa\u0107 konflikt mi\u0119dzy ochron\u0105 praw wy\u0142\u0105cznych a wolno\u015bci\u0105 dost\u0119pu do tre\u015bci.\r\n- umie stosowa\u0107 i rozumie cele wolnych licencji.\r\n- wie, czym jest copyleft.",
+            "competence": 27,
+            "level": 5
+        }
+    },
+    {
+        "pk": 240,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- umie ustali\u0107 status prawny dzie\u0142a lub rozwi\u0105zania technicznego.\r\n- rozumie konflikt mi\u0119dzy monopolem rozpowszechniania a modelem komunikowania si\u0119 w sieci.\r\n- rozumie przes\u0142anki i skutki wyboru licencji dla swoich dzie\u0142.\r\n- rozumie istot\u0119 sporu o patenty na programy, o obowi\u0105zki po\u015brednik\u00f3w oraz o prawa i wolno\u015bci prywatnego uczestnika obiegu kultury.\r\n- rozumie zasady ochrony patentowej i znak\u00f3w towarowych.\r\n- wie, czym jest ochrona baz danych.",
+            "competence": 27,
+            "level": 6
+        }
+    },
+    {
+        "pk": 241,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- wie, \u017ce o publikacji decyduje autor.\r\n- wie, co to jest plagiat.\r\n- wie, \u017ce s\u0105 r\u00f3\u017cne prawa wy\u0142\u0105czne: autorskie, patentowe, do znak\u00f3w towarowych.\r\n- umie poprawnie cytowa\u0107 i oznacza\u0107 autorstwo.",
+            "competence": 27,
+            "level": 7
+        }
+    },
+    {
+        "pk": 242,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- wie, czym jest licencja.\r\n- rozumie i umie stosowa\u0107 prawa osobiste autora: prawo do oznaczenia autorstwa i zachowania integralno\u015bci dzie\u0142a.\r\n- wie, co to jest domena publiczna.\r\n- wie, co to jest dozwolony u\u017cytek osobisty i publiczny.\r\n- wie, \u017ce prawa wy\u0142\u0105czne s\u0105 ograniczone w czasie.\r\n- wie, co to s\u0105 dzie\u0142a zale\u017cne.\r\n- umie wskaza\u0107, jaki rodzaj prawa wy\u0142\u0105cznego dotyczy danej sytuacji.\r\n- umie opisa\u0107, jak powstaj\u0105 r\u00f3\u017cne prawa wy\u0142\u0105czne i jak d\u0142ugo trwa ich ochrona.\r\n- wie, czym s\u0105 i czemu s\u0142u\u017c\u0105 wolne licencje oraz zna ich rodzaje.\r\n- umie post\u0105pi\u0107 w typowych sytuacjach zwi\u0105zanych z publikacj\u0105 w\u0142asnej i cudzej tw\u00f3rczo\u015bci.\r\n- rozumie granice cytatu i dozwolonego u\u017cytku.\r\n- rozumie, \u017ce prawa wy\u0142\u0105czne ograniczaj\u0105 wolno\u015b\u0107 u\u017cytkownik\u00f3w.",
+            "competence": 27,
+            "level": 8
+        }
+    },
+    {
+        "pk": 243,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- rozumie cele istnienia prawa autorskiego.\r\n- wie, \u017ce monopol tw\u00f3rczy jest kompromisem pomi\u0119dzy prawami u\u017cytkownika a prawami autora.\r\n- wie, jakie s\u0105 cele organizacji zbiorowego zarz\u0105du prawami.\r\n- umie opisa\u0107 konflikt mi\u0119dzy ochron\u0105 praw wy\u0142\u0105cznych a wolno\u015bci\u0105 dost\u0119pu do tre\u015bci.\r\n- umie stosowa\u0107 i rozumie cele wolnych licencji.\r\n- wie, czym jest copyleft.\r\n- umie prawid\u0142owo ustali\u0107 status prawny dzie\u0142a lub rozwi\u0105zania technicznego.\r\n- rozumie konflikt mi\u0119dzy monopolem rozpowszechniania a modelem komunikowania si\u0119 w sieci.\r\n- rozumie przes\u0142anki i skutki wyboru licencji dla swoich dzie\u0142.\r\n- rozumie istot\u0119 sporu o patenty na programy, o obowi\u0105zki po\u015brednik\u00f3w oraz o prawa i wolno\u015bci prywatnego uczestnika obiegu kultury.\r\n- rozumie zasady ochrony patentowej i znak\u00f3w towarowych.\r\n- wie, czym jest ochrona baz danych.",
+            "competence": 27,
+            "level": 9
+        }
+    },
+    {
+        "pk": 254,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- umie zg\u0142osi\u0107 doros\u0142emu problem techniczny i poprosi\u0107 o wsparcie.",
+            "competence": 29,
+            "level": 2
+        }
+    },
+    {
+        "pk": 255,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- umie opisa\u0107 r\u00f3\u017cnice mi\u0119dzy rodzajami us\u0142ug telekomunikacyjnych.\r\n- umie poda\u0107 przyk\u0142ady p\u0142atnych us\u0142ug.\r\n- wie, \u017ce operatorzy maj\u0105 obowi\u0105zki i potrafi wskaza\u0107 ich przyk\u0142ady.\r\n- wie, \u017ce nie mo\u017ce samodzielnie zawiera\u0107 um\u00f3w;\r\nnp. zak\u0142ada\u0107 kont w serwisach internetowych.\r\n- umie poprosi\u0107 opiekun\u00f3w o pomoc przy zak\u0142adaniu konta w serwisach internetowych.",
+            "competence": 29,
+            "level": 3
+        }
+    },
+    {
+        "pk": 256,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- umie opisa\u0107 rol\u0119 i zadania us\u0142ugodawcy sieciowego.\r\n- umie poda\u0107 przyk\u0142ady wzajemnych zobowi\u0105za\u0144 wynikaj\u0105cych z um\u00f3w zawartych z dostawcami us\u0142ug; np. na jaki okres zawarta jest umowa, jak j\u0105 mo\u017cna rozwi\u0105za\u0107, jakie s\u0105 standardy us\u0142ugi.",
+            "competence": 29,
+            "level": 4
+        }
+    },
+    {
+        "pk": 257,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- wie, co to jest us\u0142uga powszechna.\r\n- umie broni\u0107 swych praw, gdy operator odetnie go od us\u0142ugi lub danych;\r\nnp. skierowa\u0107 pismo do urz\u0119du.\r\n- umie oceni\u0107 i sprawdzi\u0107 jako\u015b\u0107 us\u0142ugi.\r\n- wie, \u017ce us\u0142ugi podlegaj\u0105 regulacji, umie wskaza\u0107 powo\u0142ane do tego urz\u0119dy;\r\nnp. rozr\u00f3\u017cnia zadania UKE, UOKiK, KRRiT i GIODO.",
+            "competence": 29,
+            "level": 5
+        }
+    },
+    {
+        "pk": 258,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- umie \u017c\u0105da\u0107 dostarczenia us\u0142ug powszechnych.\r\n- rozumie obowi\u0105zki po\u015brednika wynikaj\u0105ce z\r\npowiadomienia o naruszeniu regulaminu lub prawa.",
+            "competence": 29,
+            "level": 6
+        }
+    },
+    {
+        "pk": 259,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- wie, \u017ce operatorzy maj\u0105 obowi\u0105zki i potrafi wskaza\u0107 ich przyk\u0142ady.\r\n- umie poda\u0107 przyk\u0142ady wzajemnych zobowi\u0105za\u0144 wynikaj\u0105cych z um\u00f3w zawartych z dostawcami us\u0142ug.\r\n- wie, co to jest us\u0142uga powszechna.",
+            "competence": 29,
+            "level": 7
+        }
+    },
+    {
+        "pk": 260,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- wie, \u017ce us\u0142ugi podlegaj\u0105 regulacji, umie wskaza\u0107 powo\u0142ane do tego urz\u0119dy\r\n- umie broni\u0107 swych praw, gdy operator odetnie go od us\u0142ugi lub danych.\r\n- umie oceni\u0107 i sprawdzi\u0107 jako\u015b\u0107 us\u0142ugi.",
+            "competence": 29,
+            "level": 8
+        }
+    },
+    {
+        "pk": 261,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- umie \u017c\u0105da\u0107 dostarczenia us\u0142ug powszechnych.\r\n- rozumie obowi\u0105zki po\u015brednika wynikaj\u0105ce z powiadomienia o naruszeniu.",
+            "competence": 29,
+            "level": 9
+        }
+    },
+    {
+        "pk": 217,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- wie, \u017ce gazeta, audycja i portal maj\u0105 redakcj\u0119.\r\n- wie, \u017ce s\u0105 ksi\u0105\u017cki, gazety, audycje i aplikacje przeznaczone dla dzieci.",
+            "competence": 25,
+            "level": 1
+        }
+    },
+    {
+        "pk": 218,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- wie, \u017ce w mediach za tre\u015b\u0107 odpowiada redaktor.\r\n- umie rozpozna\u0107 oznaczenie programu dla dzieci i m\u0142odzie\u017cy.",
+            "competence": 25,
+            "level": 2
+        }
+    },
+    {
+        "pk": 219,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- wie, \u017ce gazety i portale s\u0105 prywatne, a radio i telewizja mog\u0105 by\u0107 prywatne lub publiczne.\r\n- wie o prawie do autoryzacji i sprostowania.\r\n- wie, \u017ce materia\u0142y reklamowe i sponsorowane musz\u0105 by\u0107 odpowiednio oznaczone.\r\n- umie rozpozna\u0107 reklam\u0119.",
+            "competence": 25,
+            "level": 3
+        }
+    },
+    {
+        "pk": 220,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- wie, \u017ce radio i telewizja s\u0105 regulowane\r\nprzez KRRiT.\r\n- umie opisa\u0107 zadania medi\u00f3w publicznych, ich misj\u0119 oraz spos\u00f3b finansowania;\r\nnp. abonament, reklamy, datki.\r\n- umie opisa\u0107 modele zarabiania pieni\u0119dzy przez media prywatne\r\nnp. reklamy, abonament, dost\u0119p na \u017c\u0105danie, datki.\r\n- umie rozpozna\u0107 lokowanie produktu.",
+            "competence": 25,
+            "level": 4
+        }
+    },
+    {
+        "pk": 221,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- wie, czym jest licencja programowa i przydzia\u0142 pasma.\r\n- umie rozpozna\u0107 ukryt\u0105 reklam\u0119 i przes\u0142anie marketingowe.\r\n- umie skorzysta\u0107 z prawa do sprostowania.\r\n- umie rozr\u00f3\u017cni\u0107 tre\u015bci informacyjne,\r\npublicystyczne i rozrywkowe.",
+            "competence": 25,
+            "level": 5
+        }
+    },
+    {
+        "pk": 222,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- umie przygotowa\u0107 komunikat medialny i wie, kt\u00f3re medium mo\u017ce lub musi go zamie\u015bci\u0107.\r\n- umie rozpozna\u0107 naruszenie obowi\u0105zk\u00f3w wydawcy lub nadawcy.\r\n- umie sprawdzi\u0107 dane rejestracyjne medium.",
+            "competence": 25,
+            "level": 6
+        }
+    },
+    {
+        "pk": 223,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- wie, \u017ce w mediach za tre\u015b\u0107 odpowiada redaktor.\r\n- umie rozpozna\u0107 oznaczenie programu dla dzieci i m\u0142odzie\u017cy.\r\n- wie, \u017ce gazety i portale s\u0105 prywatne, a radio i telewizja mog\u0105 by\u0107 prywatne lub publiczne.",
+            "competence": 25,
+            "level": 7
+        }
+    },
+    {
+        "pk": 224,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- wie, \u017ce radio i telewizja s\u0105 regulowane przez KRRiT.\r\n- wie o prawie do autoryzacji i sprostowania.\r\n- wie, \u017ce materia\u0142y reklamowe i sponsorowane musz\u0105 by\u0107 odpowiednio oznaczone.\r\n- umie rozpozna\u0107 reklam\u0119 i lokowanie produktu.\r\n- umie opisa\u0107 zadania medi\u00f3w publicznych, ich misj\u0119 oraz spos\u00f3b finansowania.\r\n- umie opisa\u0107 modele zarabiania przez media prywatne.",
+            "competence": 25,
+            "level": 8
+        }
+    },
+    {
+        "pk": 225,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- wie, czym jest licencja programowa i przydzia\u0142 pasma.\r\n- umie skorzysta\u0107 z prawa do sprostowania.\r\n- umie przygotowa\u0107 komunikat medialny i wie, kt\u00f3re medium mo\u017ce lub musi go zamie\u015bci\u0107.\r\n- umie rozpozna\u0107 naruszenie obowi\u0105zk\u00f3w wydawcy lub nadawcy.\r\n- umie sprawdzi\u0107 dane rejestracyjne medium.",
+            "competence": 25,
+            "level": 9
+        }
+    },
+    {
+        "pk": 208,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- wie, \u017ce ka\u017cdy ma prawo do korzystania z medi\u00f3w, bez wzgl\u0119du na stopie\u0144 sprawno\u015bci.\r\n- wie, \u017ce osoby niepe\u0142nosprawne maj\u0105 trudno\u015bci w korzystaniu z medi\u00f3w;\r\nnp. zdaje sobie spraw\u0119, \u017ce babcia musi nastawia\u0107 g\u0142o\u015bno telewizor, tata zak\u0142ada okulary do czytania gazety, a niewidomi nie mog\u0105 czyta\u0107 drukowanych ksi\u0105\u017cek.",
+            "competence": 24,
+            "level": 1
+        }
+    },
+    {
+        "pk": 209,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- wie, \u017ce niepe\u0142nosprawny ma r\u00f3wne prawo do wypowiedzi w mediach.\r\n- umie poda\u0107 przyk\u0142ady barier w dost\u0119pie do edukacji, informacji i kultury.\r\n- umie poda\u0107 przyk\u0142ad u\u0142atwie\u0144 dla niepe\u0142nosprawnych;\r\nnp. wie, \u017ce mo\u017cna powi\u0119kszy\u0107 litery, aby ka\u017cdy m\u00f3g\u0142 je przeczyta\u0107, do film\u00f3w mo\u017cna doda\u0107 napisy.",
+            "competence": 24,
+            "level": 2
+        }
+    },
+    {
+        "pk": 210,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- umie rozpozna\u0107 typowe bariery dost\u0119pno\u015bci w danym przekazie medialnym.\r\n- umie rozpozna\u0107 \u0142amanie praw s\u0142abszych w tre\u015bci przekazu.\r\n- umie dostrzec i opisa\u0107 bezpo\u015brednie bariery dost\u0119pno\u015bci; np. brak napis\u00f3w pod filmem.",
+            "competence": 24,
+            "level": 3
+        }
+    },
+    {
+        "pk": 211,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- wie, co to jest konwencja o prawach os\u00f3b niepe\u0142nosprawnych.\r\n- umie dostrzec i opisa\u0107 po\u015brednie bariery dost\u0119pno\u015bci; np. zbyt ma\u0142e czcionki, nieprawid\u0142owy kontrast, chaotyczny uk\u0142ad informacji.\r\n- umie reagowa\u0107 na \u0142amanie praw.",
+            "competence": 24,
+            "level": 4
+        }
+    },
+    {
+        "pk": 212,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- wie o ustawowych udogodnieniach dla niepe\u0142nosprawnych, kt\u00f3re musz\u0105 stosowa\u0107 wydawcy i nadawcy;\r\nnp. audiodeskrypcja, j\u0119zyk migowy, napisy pod filmem.\r\n- wie o istnieniu standard\u00f3w dost\u0119pno\u015bci i obowi\u0105zku ich stosowania;\r\nnp. znane mu s\u0105 <em>Wytyczne dotycz\u0105ce dost\u0119pno\u015bci tre\u015bci internetowych</em> (WCAG).\r\n- wie, \u017ce informacja przedstawiona w spos\u00f3b uniwersalny dociera do wi\u0119kszej liczby odbiorc\u00f3w, a niestosowanie standard\u00f3w dost\u0119pno\u015bci \u00a0powoduje wykluczenie cz\u0119\u015bci obywateli, np. os\u00f3b starszych.",
+            "competence": 24,
+            "level": 5
+        }
+    },
+    {
+        "pk": 213,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- umie sprawdzi\u0107 spe\u0142nienie wymog\u00f3w dost\u0119pno\u015bci;\r\nnp. korzysta z narz\u0119dzi do samodzielnego badania dost\u0119pno\u015bci.\r\n- umie skutecznie reagowa\u0107 na naruszenia wymog\u00f3w dost\u0119pno\u015bci.",
+            "competence": 24,
+            "level": 6
+        }
+    },
+    {
+        "pk": 214,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- wie, \u017ce niepe\u0142nosprawny ma r\u00f3wne prawo do wypowiedzi w mediach.\r\n- umie poda\u0107 przyk\u0142ady barier w dost\u0119pie do edukacji, informacji i kultury.",
+            "competence": 24,
+            "level": 7
+        }
+    },
+    {
+        "pk": 215,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- wie o istnieniu standard\u00f3w dost\u0119pno\u015bci.\r\n- wie, co to jest konwencja o prawach os\u00f3b niepe\u0142nosprawnych.\r\n- umie rozpozna\u0107 \u0142amanie praw s\u0142abszych w tre\u015bci przekazu.\r\n- umie dostrzec i opisa\u0107 bezpo\u015brednie i po\u015brednie bariery dost\u0119pno\u015bci.\r\n- umie reagowa\u0107 na \u0142amanie praw.",
+            "competence": 24,
+            "level": 8
+        }
+    },
+    {
+        "pk": 216,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- wie o ustawowych udogodnieniach dla niepe\u0142nosprawnych, kt\u00f3re musz\u0105 stosowa\u0107 wydawcy i nadawcy.\r\n- umie sprawdzi\u0107 spe\u0142nienie wymog\u00f3w dost\u0119pno\u015bci.\r\n- umie skutecznie reagowa\u0107 na naruszenia.",
+            "competence": 24,
+            "level": 9
+        }
+    },
+    {
+        "pk": 226,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- wie, \u017ce nie nale\u017cy m\u00f3wi\u0107 i pisa\u0107 o sobie i o rodzinie bez potrzeby;\r\nnp. nie m\u00f3wi obcym osobom, gdzie mieszka lub jaki samoch\u00f3d maj\u0105 rodzice.",
+            "competence": 26,
+            "level": 1
+        }
+    },
+    {
+        "pk": 227,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- rozumie ide\u0119 ochrony prywatno\u015bci, ochrony danych osobowych i swoje prawa do takiej ochrony.",
+            "competence": 26,
+            "level": 2
+        }
+    },
+    {
+        "pk": 228,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- wie, \u017ce komunikacja elektroniczna wi\u0105\u017ce si\u0119 z gromadzeniem i przechowywaniem informacji o u\u017cytkownikach.\r\n- umie rozpozna\u0107 sytuacje wymuszania danych osobowych.\r\n- umie odm\u00f3wi\u0107 podania danych osobowych.\r\n- umie zak\u0142ada\u0107 konta, korzystaj\u0105c z pseudonim\u00f3w.",
+            "competence": 26,
+            "level": 3
+        }
+    },
+    {
+        "pk": 229,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- umie poda\u0107 przyk\u0142ady gromadzenia i przechowywania informacji o u\u017cytkownikach;\r\nnp. billingi, dane geolokalizacyjne, emaile, wiadomo\u015bci, wpisy na forach i w mediach spo\u0142eczno\u015bciowych.\r\n- umie w praktyce chroni\u0107 prywatno\u015b\u0107 swoj\u0105 i innych.\r\n- wie o istnieniu obowi\u0105zk\u00f3w informacyjnych administrator\u00f3w danych np. wie, \u017ce mo\u017ce uzyska\u0107 informacj\u0119 na temat swoich danych przechowywanych przez w\u0142a\u015bciciela serwisu internetowego.\r\n- wie, czego dotyczy ustawa o ochronie danych osobowych.\r\n- umie opisa\u0107 obowi\u0105zki dostawc\u00f3w us\u0142ug w zakresie ochrony danych osobowych.\r\n- umie opisa\u0107 problemy zwi\u0105zane z ochron\u0105 danych;\r\nnp. bazy danych, wycieki, \u0142\u0105czenie danych z r\u00f3\u017cnych zasob\u00f3w, dane wra\u017cliwe.",
+            "competence": 26,
+            "level": 4
+        }
+    },
+    {
+        "pk": 230,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- wie, czym jest polityka prywatno\u015bci.\r\n- umie opisa\u0107 tre\u015b\u0107 ustawy o ochronie danych osobowych.\r\n- rozumie poj\u0119cia przetwarzania danych osobowych i administratora danych.\r\n- wie, co to s\u0105 dane wra\u017cliwe.\r\n- wie, co to jest GIODO i jakie s\u0105 jego zadania.",
+            "competence": 26,
+            "level": 5
+        }
+    },
+    {
+        "pk": 231,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- rozumie polityk\u0119 prywatno\u015bci firm, z kt\u00f3rych us\u0142ug korzysta.\r\n- umie stosowa\u0107 zasady ochrony we w\u0142asnych publikacjach i us\u0142ugach.\r\n- umie zwr\u00f3ci\u0107 si\u0119 do GIODO z pro\u015bb\u0105 o interwencj\u0119 lub interpretacj\u0119.\r\n- umie sprawdzi\u0107 w\u0142asne dane w zbiorach, w kt\u00f3rych s\u0105 zawarte.\r\n- umie zarejestrowa\u0107 zbi\u00f3r i sprawdzi\u0107, czy dany zbi\u00f3r jest zarejestrowany.",
+            "competence": 26,
+            "level": 6
+        }
+    },
+    {
+        "pk": 232,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- umie dba\u0107 o prywatno\u015b\u0107.\r\n- rozumie ide\u0119 ochrony danych osobowych i swoje prawa do takiej ochrony.\r\n- wie, \u017ce komunikacja elektroniczna wi\u0105\u017ce si\u0119 z gromadzeniem i przechowywaniem informacji o u\u017cytkownikach.\r\n- umie rozpozna\u0107 sytuacje wymuszania danych osobowych.\r\n- umie odm\u00f3wi\u0107 podania danych osobowych.",
+            "competence": 26,
+            "level": 7
+        }
+    },
+    {
+        "pk": 233,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- wie, co to jest polityka prywatno\u015bci.\r\n- wie, co to s\u0105 dane wra\u017cliwe.\r\n- wie, co to jest GIODO.\r\n- wie o istnieniu obowi\u0105zk\u00f3w informacyjnych administrator\u00f3w danych.\r\n- wie, co to jest powierzenie przetwarzania danych.\r\n- wie, czego dotyczy ustawa o ochronie danych osobowych.\r\n- umie opisa\u0107 obowi\u0105zki dostawc\u00f3w us\u0142ug w zakresie ochrony danych osobowych.\r\n- umie opisa\u0107 problemy zwi\u0105zane z ochron\u0105 danych.\r\n- umie w praktyce chroni\u0107 prywatno\u015b\u0107 swoj\u0105 i innych.",
+            "competence": 26,
+            "level": 8
+        }
+    },
+    {
+        "pk": 234,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- wie, jakie dane i jak d\u0142ugo gromadzi i przechowuje operator us\u0142ugi.\r\n- umie opisa\u0107 tre\u015b\u0107 ustawy o ochronie danych osobowych.\r\n- umie stosowa\u0107 zasady ochrony we w\u0142asnych publikacjach i us\u0142ugach.\r\n- umie zwr\u00f3ci\u0107 si\u0119 do GIODO z pro\u015bb\u0105 o interwencj\u0119 lub interpretacj\u0119.\r\n- umie sprawdzi\u0107 w\u0142asne dane w zbiorach, w kt\u00f3rych s\u0105 zawarte.\r\n- umie zarejestrowa\u0107 zbi\u00f3r i sprawdzi\u0107, czy dany zbi\u00f3r jest zarejestrowany.\r\n- rozumie polityk\u0119 prywatno\u015bci firm, z kt\u00f3rymi zawiera umowy.",
+            "competence": 26,
+            "level": 9
+        }
+    },
+    {
+        "pk": 262,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- wie, \u017ce s\u0105 r\u00f3\u017cne rodzaje medi\u00f3w i umie to pokaza\u0107 na przyk\u0142adach;\r\nnp. umie wymieni\u0107: pismo dla dzieci do czytania, audycja telewizyjna do ogl\u0105dania, audiobook do s\u0142uchania, gra w internecie do grania itp.\r\n- wie, \u017ce media maj\u0105 odbiorc\u00f3w / u\u017cytkownik\u00f3w.",
+            "competence": 30,
+            "level": 1
+        }
+    },
+    {
+        "pk": 263,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- wie, \u017ce media tworz\u0105 wraz z ich u\u017cytkownikami tzw. rynek medi\u00f3w.\r\n- umie nazwa\u0107 tradycyjne rodzaje medi\u00f3w: prasa, radio, telewizja.\r\n- wie i rozumie, \u017ce internet to medium innego rodzaju.",
+            "competence": 30,
+            "level": 2
+        }
+    },
+    {
+        "pk": 264,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- wie, \u017ce s\u0105 r\u00f3\u017cne typologie medi\u00f3w: np. media tradycyjne i tzw. nowe media, mass-media i media spo\u0142eczno\u015bciowe; prasa drukowana i media elektroniczne; media publiczne i media prywatne.\r\n- umie wskaza\u0107 podstawowe r\u00f3\u017cnice mi\u0119dzy tymi typami medi\u00f3w.\r\n- wie, \u017ce w obszarze medi\u00f3w dzia\u0142aj\u0105 przedsi\u0119biorstwa: kto\u015b tam pracuje i w ten spos\u00f3b zarabia na \u017cycie, kto\u015b tym zarz\u0105dza.\r\n- rozumie \u00a0zale\u017cno\u015b\u0107 mi\u0119dzy mediami i ich u\u017cytkownikami (relacja wymiany, uczestnictwa i wsp\u00f3\u0142tworzenia).",
+            "competence": 30,
+            "level": 3
+        }
+    },
+    {
+        "pk": 265,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- wie, \u017ce rynek medi\u00f3w tworz\u0105 nie tylko media i ich u\u017cytkownicy, ale te\u017c instytucje publiczne powo\u0142ane do nadzoru i kontroli rynku.\r\n- wie, \u017ce przedsi\u0119biorstwa medialne maj\u0105: w\u0142a\u015bciciela, organ zarz\u0105dczy i okre\u015blon\u0105 form\u0119 prawn\u0105; maj\u0105 te\u017c okre\u015blon\u0105 lini\u0119 redakcyjn\u0105.",
+            "competence": 30,
+            "level": 4
+        }
+    },
+    {
+        "pk": 266,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- umie rozr\u00f3\u017cni\u0107 media publiczne od medi\u00f3w prywatnych i wie, jakie s\u0105 podstawowe konsekwencje tego podzia\u0142u; np. obowi\u0105zek uzyskania koncesji lub jego brak, r\u00f3\u017cnice w formie finansowania.\r\n- wie, \u017ce na rynku medi\u00f3w wyst\u0119puje zjawisko konkurencji i koncentracji.\r\n- umie wskaza\u0107 r\u00f3\u017cnice mi\u0119dzy mediami tradycyjnymi a nowymi mediami w zakresie regulacji\r\n- rozumie, \u017ce bariery wej\u015bcia na rynek s\u0105 tak\u017ce tworzone przez regulatora, np. wie, \u017ce opr\u00f3cz wymog\u00f3w kapita\u0142owych potrzebne jest zdobycie koncesji lub rejestracja.",
+            "competence": 30,
+            "level": 5
+        }
+    },
+    {
+        "pk": 267,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- wie, czym jest pluralizm medi\u00f3w i rozumie, dlaczego nale\u017cy chroni\u0107 konkurencj\u0119 na rynku medi\u00f3w.\r\n- wie o istnieniu nieformalnej ekonomii medi\u00f3w, b\u0119d\u0105cej w du\u017cej cz\u0119\u015bci lub w ca\u0142o\u015bci poza zasi\u0119giem polityki pa\u0144stwa, jego regulacji i opodatkowania.\r\n- umie poda\u0107 przyk\u0142ady nieformalnej ekonomii medi\u00f3w; np. sie\u0107 wymiany plik\u00f3w.\r\n- wie, czym jest konsolidacja i koncentracja w\u0142asno\u015bci medi\u00f3w; rozumie ich podstawowe przyczyny i umie dostrzec efekty \u00a0(cho\u0107 nie musi zna\u0107 ich nazewnictwa; np. efekt skali, zakresu, czy synergii.\r\n- umie rozr\u00f3\u017cni\u0107: koncentracj\u0119 pionow\u0105, (wydawca gazety kupuje / tworzy radio) \u00a0od koncentracji poziomej (radio kupuje inne radio); np. wie, \u017ce Eurozet, kt\u00f3ry w 2008 r. naby\u0142 Radio J\u00f3zef to przyk\u0142ad koncentracji poziomej, a sp\u00f3\u0142ka Agora, do kt\u00f3rej nale\u017c\u0105 gazety, radio, portale internetowe i platformy blogerskie \u2013 koncentracji pionowej.\r\n- rozumie funkcjonowanie \u0142a\u0144cucha warto\u015bci w mediach i wie, \u017ce \u017caden z element\u00f3w nie pe\u0142ni w nim nadrz\u0119dnej roli (r\u00f3\u017cne etapy procesu s\u0105 wobec siebie komplementarne i \u201ewzajemnie si\u0119 karmi\u0105\u201d).",
+            "competence": 30,
+            "level": 6
+        }
+    },
+    {
+        "pk": 268,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- wie, \u017ce istniej\u0105 r\u00f3\u017cne rodzaje medi\u00f3w (radio, TV, internet, prasa).\r\n- wie, czym jest abonament radiowo-telewizyjny.\r\n- umie odr\u00f3\u017cni\u0107 media publiczne od prywatnych.\r\n- wie, \u017ce rynek medi\u00f3w jest regulowany.",
+            "competence": 30,
+            "level": 7
+        }
+    },
+    {
+        "pk": 269,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- wie, \u017ce prywatna stacja radiowa lub telewizyjna musi ubiega\u0107 si\u0119 o koncesj\u0119 na nadawanie, a publiczne stacje nie maj\u0105 tego obowi\u0105zku.\r\n- wie, \u017ce na rynku wyst\u0119puje zjawisko konkurencji i koncentracji i umie wskaza\u0107 ich przyk\u0142ady.\r\n- wie, \u017ce rynek medialny sk\u0142ada si\u0119 z medi\u00f3w, ich u\u017cytkownik\u00f3w oraz z otoczenia regulacyjnego.\r\n- umie wskaza\u0107 regulator\u00f3w medi\u00f3w (obecnie: KRRiT, UKE) oraz cia\u0142a samoreguluj\u0105ce (samorz\u0105dy bran\u017cowe, komisje etyki).",
+            "competence": 30,
+            "level": 8
+        }
+    },
+    {
+        "pk": 270,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- rozumie konsekwencje konsolidacji i koncentracji medi\u00f3w.\r\n- rozumie r\u00f3\u017cnice mi\u0119dzy koncentracj\u0105 poziom\u0105 i pionow\u0105.\r\n- umie wskaza\u0107 bariery wej\u015bcia na rynek medi\u00f3w.",
+            "competence": 30,
+            "level": 9
+        }
+    },
+    {
+        "pk": 271,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- intuicyjnie wie, czym jest informacja;\r\nnp. wie, na jakim kanale znajdzie ulubion\u0105 bajk\u0119, albo \u017ce ta bajka jest nadawana o takiej, a nie o innej porze dnia.\r\n- umie dzieli\u0107 si\u0119 informacjami z innymi.",
+            "competence": 31,
+            "level": 1
+        }
+    },
+    {
+        "pk": 272,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- wie, \u017ce informacj\u0119 mo\u017cna przekaza\u0107 bezpo\u015brednio lub po\u015brednio. Tym drugim zajmuj\u0105 si\u0119 media (prasa, media elektroniczne).\r\n- wie, \u017ce w j\u0119zyku medi\u00f3w informacje to: wydarzenia / newsy / wiadomo\u015bci.\r\n- rozumie poj\u0119cie reklamy. Wie, \u017ce s\u0105 komunikaty perswazyjne i informacyjne.",
+            "competence": 31,
+            "level": 2
+        }
+    },
+    {
+        "pk": 273,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- rozumie, \u017ce informacja ma sw\u00f3j kontekst, kt\u00f3ry decyduje, czy mamy do czynienia z przekazem perswazyjnym, czy czysto informacyjnym.\r\n- umie rozr\u00f3\u017cni\u0107 reklam\u0119 od przekazu informacyjnego.\r\n- wie, \u017ce r\u00f3wnie\u017c reklama zawiera element informacyjny, ale jest on podporz\u0105dkowany celowi perswazyjnemu.",
+            "competence": 31,
+            "level": 3
+        }
+    },
+    {
+        "pk": 274,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- wie, \u017ce informacja to dobro.\r\n- wie, \u017ce nie ka\u017cdy ma do niej dost\u0119p.\r\n- zna poj\u0119cie asymetrii informacji.\r\n- wie, \u017ce w cyfrowym \u015bwiecie informacja nie tylko nie traci na znaczeniu, ale zyskuje, tyle, \u017ce zmienia si\u0119 jej ekonomika (maleje / zanika asymetria informacyjna).\r\n- wie, \u017ce tworzenie informacji, jak r\u00f3wnie\u017c jej przekazywanie, niesie za sob\u0105 koszty. Te koszty nie s\u0105 dostrzegane przez bezpo\u015brednich odbiorc\u00f3w (czytelnik\u00f3w, s\u0142uchaczy, widz\u00f3w), bo ponosz\u0105 je np. producenci.\r\n- wie, \u017ce koszt wytworzenia danego dobra nie jest r\u00f3wnoznaczny z jego warto\u015bci\u0105 ani cen\u0105.\r\n- wie o istnieniu ekonomii daru i umie rozpozna\u0107 jej elementy w relacjach dotycz\u0105cych medi\u00f3w.\r\n- wie, \u017ce jedn\u0105 z zasad biznesu w sieci jest ekonomia uwagi i umie pokaza\u0107 ten mechanizm; np. na przyk\u0142adzie historii wyszukiwania w Google.\r\n- wie, \u017ce istnieje prawo w\u0142asno\u015bci intelektualnej (w tym w szczeg\u00f3lno\u015bci prawo autorskie) i wie, \u017ce przestrzeganie jego zasad ma wp\u0142yw na ekonomiczn\u0105 warto\u015b\u0107 oraz dost\u0119pno\u015b\u0107 danego dobra.\r\n- rozumie, \u017ce cena jest warto\u015bci\u0105 umown\u0105 \u2013 sprzedawca proponuje cen\u0119, a nabywca j\u0105 akceptuje lub odrzuca.",
+            "competence": 31,
+            "level": 4
+        }
+    },
+    {
+        "pk": 275,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- wie, \u017ce mi\u0119dzy mediami tradycyjnymi a odbiorcami odbywa si\u0119 wymiana na poziomie ekonomicznym (w sieci \u2013 na poziomie ekonomii uwagi), cho\u0107 odbiorca nie p\u0142aci bezpo\u015brednio za informacj\u0119, co wynika ze sposobu finansowania tych medi\u00f3w.\r\n- wie, \u017ce obowi\u0105zuj\u0105ce przepisy dot. w\u0142asno\u015bci intelektualnej mog\u0105 wp\u0142ywa\u0107 na postrzeganie informacji i cen\u0119 danego dobra np. wie, \u017ce idea nie ma w\u0142a\u015bciciela, ale zapisana na kartce papieru przez autora automatycznie podlega ochronie prawnej.\r\n- rozumie ekonomiczne i prawne konsekwencje obowi\u0105zuj\u0105cych przepis\u00f3w dotycz\u0105cych w\u0142asno\u015bci intelektualnej;\r\nnp. rozumie ograniczenie mo\u017cliwo\u015bci korzystania z prywatnej kopii filmu na DVD \u2013 mo\u017cna go ogl\u0105da\u0107 samemu w domu, ale wy\u015bwietlanie w szkole kopii bez licencji na publiczne odtwarzanie grozi konsekwencjami prawnymi i ekonomicznymi.\r\n- wie, czym jest informacja publiczna.",
+            "competence": 31,
+            "level": 5
+        }
+    },
+    {
+        "pk": 276,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- umie przeanalizowa\u0107 wp\u0142yw ustawodawstwa na polityk\u0119 informacyjn\u0105 i medialn\u0105.",
+            "competence": 31,
+            "level": 6
+        }
+    },
+    {
+        "pk": 277,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- rozumie kontekst informacji (umie przetwarza\u0107 informacje otrzymane za po\u015brednictwem\r\n- umie odr\u00f3\u017cni\u0107 przekaz informacyjny od reklamowego.\r\n- wie, \u017ce informacja to dobro i \u017ce cz\u0119\u015bciej si\u0119 p\u0142aci za dost\u0119p ni\u017c za sam\u0105 informacj\u0119; np. op\u0142ata za korzystanie z program\u00f3w TV w sieci kablowej.",
+            "competence": 31,
+            "level": 7
+        }
+    },
+    {
+        "pk": 278,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- wie, co oznacza poj\u0119cie \u201easymetria informacji\u201d i wie, \u017ce jej znaczenie maleje w \u015brodowisku cyfrowym.\r\n- wie, \u017ce koszt wytworzenia danego dobra nie jest r\u00f3wnoznaczny z jego cen\u0105 ani warto\u015bci\u0105; np. wie \u017ce minimalny koszt wyprodukowania telefonu kom\u00f3rkowego jest inny ni\u017c jego cena rynkowa, kt\u00f3ra ulega zmianom, m.in. w promocjach cenowych.\r\n- wie, \u017ce istnieje w\u0142asno\u015b\u0107 intelektualna (w tym prawo autorskie) i rozumie jej prawne oraz ekonomiczne konsekwencje.\r\n- umie poda\u0107 przyk\u0142ady ekonomii uwagi i ekonomii daru.",
+            "competence": 31,
+            "level": 8
+        }
+    },
+    {
+        "pk": 279,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- rozumie, na czym w \u015brodowisku cyfrowym polega zmiana ekonomicznego uj\u0119cia \u201einformacji jako dobra\u201d.\r\n- rozumie, na czym polega ekonomia uwagi i ekonomia daru.\r\n- rozumie ekonomiczne konsekwencje przepis\u00f3w dot. w\u0142asno\u015bci intelektualnej.\r\n- wie, czym jest informacja publiczna i jak uzyska\u0107 do niej dost\u0119p.",
+            "competence": 31,
+            "level": 9
+        }
+    },
+    {
+        "pk": 280,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- wie, \u017ce w mediach s\u0105 reklamy; np. umie wskaza\u0107 reklamy w ulubionym pi\u015bmie albo mi\u0119dzy \u00a0bajkami w telewizji.\r\n- wie, \u017ce za dost\u0119p do medi\u00f3w si\u0119 p\u0142aci np. kupowanie gazety w kiosku.\r\n- wie, \u017ce dobra mo\u017cna nabywa\u0107 w sklepie, ale te\u017c przez internet.",
+            "competence": 32,
+            "level": 1
+        }
+    },
+    {
+        "pk": 281,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- wie, \u017ce s\u0105 takie gry sieciowe, w kt\u00f3rych podstawowa us\u0142uga jest bezp\u0142atna, ale trzeba p\u0142aci\u0107 za dodatkowe funkcjonalno\u015bci.\r\n- wie, \u017ce jako nieletni nie mo\u017ce dokonywa\u0107 samodzielnie transakcji w internecie.\r\n- umie wskaza\u0107 r\u00f3\u017cne sposoby nabywania d\u00f3br; np. sklep w galerii handlowej, sklep internetowy, aukcja.\r\n- rozumie, \u017ce za dost\u0119p do medi\u00f3w si\u0119 p\u0142aci.",
+            "competence": 32,
+            "level": 2
+        }
+    },
+    {
+        "pk": 282,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- wie, \u017ce s\u0105 np. takie hostingi plik\u00f3w,czy takie gry sieciowe, w kt\u00f3rych podstawowa us\u0142uga jest bezp\u0142atna, ale trzeba p\u0142aci\u0107 za dodatkowe funkcjonalno\u015bci; wie, \u017ce w \u015bwietle prawa nie \u00a0mo\u017ce dokonywa\u0107 takich p\u0142atno\u015bci.\r\n- wie, \u017ce czasem informacja o podwy\u017cszonej p\u0142atno\u015bci za skorzystanie z jakiej\u015b us\u0142ugi nie jest do\u015b\u0107 wyeksponowana i trzeba umie\u0107 j\u0105 rozkodowa\u0107: np. koszt SMS-\u00f3w w g\u0142osowaniach telewizyjnych czy regu\u0142a dla telefonicznych numer\u00f3w specjalnych, gdzie cena zakodowana jest w pierwszych cyfrach danego numeru.\r\n- wie o istnieniu ukrytych p\u0142atno\u015bci w internecie; np. w serwisie Pobieraczek.\r\n- wie, \u017ce w mediach p\u0142aci si\u0119 za dost\u0119p, a nie za tre\u015b\u0107, st\u0105d potrzeba finansowania medi\u00f3w z innych \u017ar\u00f3de\u0142; np. w TVP reklamy nie przerywaj\u0105 audycji, ale jest abonament.\r\n\r\n- wie zatem, \u017ce reklama s\u0142u\u017cy r\u00f3wnie\u017c finansowaniu medi\u00f3w.\r\n- rozumie, dlaczego nie mo\u017ce samodzielnie dokonywa\u0107 transakcji w internecie.",
+            "competence": 32,
+            "level": 3
+        }
+    },
+    {
+        "pk": 283,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- wie, \u017ce media dziel\u0105 si\u0119 na prywatne i publiczne ze wzgl\u0119du na spos\u00f3b ich finansowania.\r\n- wie, czym jest i do czego s\u0142u\u017cy abonament radiowo-telewizyjny.\r\n- wie, \u017ce niekt\u00f3re blogi s\u0105 sponsorowane przez firmy i umie odr\u00f3\u017cni\u0107 zach\u0119t\u0119 do zakupu danego dobra od informacji o tym dobru.",
+            "competence": 32,
+            "level": 4
+        }
+    },
+    {
+        "pk": 284,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- wie, \u017ce serwisy, w kt\u00f3rych sprzedaje si\u0119 tre\u015bci, to wyj\u0105tek, a nie zasada finansowania medi\u00f3w; np. wie, \u017ce w internecie mo\u017cna kupi\u0107 uprzywilejowany dost\u0119p i czas \u00a0- \u00a0abonament dot. notowa\u0144 na gie\u0142dzie.\r\n- wie, na czym polegaj\u0105 podstawowe zasady handlu w sieci i p\u0142atno\u015bci on-line; np. wie, jak dzia\u0142aj\u0105 aukcje on-line.\r\n- biegle umie pos\u0142ugiwa\u0107 si\u0119 terminami dot. nast\u0119puj\u0105cych zagadnie\u0144 finansowania medi\u00f3w i rozumie ich znaczenie oraz powi\u0105zania: przychody z reklam, dotacje, abonament.\r\n- rozumie powi\u0105zanie malej\u0105cej asymetrii informacyjnej w \u015brodowisku cyfrowym z cen\u0105 na niekt\u00f3re produkty nabywane w sieci np. rozumie wp\u0142yw wyszukiwarek internetowych, por\u00f3wnywarek cenowych i internetowych platform handlowych na obni\u017ck\u0119 mar\u017c produkt\u00f3w nabywanych w sieci.",
+            "competence": 32,
+            "level": 5
+        }
+    },
+    {
+        "pk": 286,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- wie, na czym polegaj\u0105 podstawowe zasady handlu w sieci i p\u0142atno\u015bci on-line; np. wie, jak dzia\u0142aj\u0105 aukcje internetowe.\r\n- wie, \u017ce s\u0105 takie us\u0142ugi w internecie, gdzie podstawowa us\u0142uga jest bezp\u0142atna, ale trzeba p\u0142aci\u0107 za dodatkowe funkcjonalno\u015bci.\r\n- wie, \u017ce czasem us\u0142uga o podwy\u017cszonej p\u0142atno\u015bci nie jest do\u015b\u0107 wyeksponowana i trzeba umie\u0107 j\u0105 rozkodowa\u0107; np. koszt SMS-\u00f3w w g\u0142osowaniach telewizyjnych lub regu\u0142a telefonicznych numer\u00f3w specjalnych, w kt\u00f3rych cena jest zakodowana w pierwszych cyfrach danego numeru.\r\n- wie, \u017ce w mediach p\u0142aci si\u0119 za dost\u0119p, a nie za tre\u015b\u0107, st\u0105d potrzeba finansowania medi\u00f3w z innych \u017ar\u00f3de\u0142, takich jak reklama czy abonament rtv.\r\n- wie, \u017ce media dziel\u0105 si\u0119 na publiczne i prywatne ze wzgl\u0119du na spos\u00f3b finansowania.",
+            "competence": 32,
+            "level": 7
+        }
+    },
+    {
+        "pk": 287,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- wie, czym jest i do czego s\u0142u\u017cy abonament rtv.\r\n- wie, \u017ce niekt\u00f3re blogi s\u0105 sponsorowane przez firmy i umie odr\u00f3\u017cni\u0107 zach\u0119t\u0119 do zakupu danego dobra od informacji o nim.\r\n- wie o ukrytych p\u0142atno\u015bciach w internecie.\r\n- umie dokonywa\u0107 bezpiecznych i skutecznych transakcji internetowych oraz rozumie zasady handlu w sieci i p\u0142atno\u015bci on-line.",
+            "competence": 32,
+            "level": 8
+        }
+    },
+    {
+        "pk": 288,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- umie wskaza\u0107 \u017ar\u00f3d\u0142a presji politycznej i ekonomicznej wywieranej na media ze wzgl\u0119du na model finansowania.\r\n- rozumie, \u017ce serwisy, w kt\u00f3rych sprzedaje si\u0119 tre\u015bci, to wyj\u0105tek, a nie zasada finansowania medi\u00f3w; np. internecie mo\u017cna sprzedawa\u0107 uprzywilejowany dost\u0119p i czas",
+            "competence": 32,
+            "level": 9
+        }
+    },
+    {
+        "pk": 291,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- wie, \u017ce polityka medialna to og\u00f3\u0142 dzia\u0142a\u0144 zwi\u0105zanych z funkcjonowaniem medi\u00f3w (ich regulacj\u0105, nadzorem i kontrol\u0105) i umie wskaza\u0107 elementy tej polityki; np. umie wskaza\u0107 przyk\u0142ady regulacji rynku.",
+            "competence": 33,
+            "level": 3
+        }
+    },
+    {
+        "pk": 292,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- umie poda\u0107 przyk\u0142ady / elementy polityki medialnej.\r\n- umie wyja\u015bni\u0107 r\u00f3\u017cnice mi\u0119dzy mediami publicznymi a prywatnymi w zakresie kontroli i regulacji (struktura w\u0142a\u015bcicielska).",
+            "competence": 33,
+            "level": 4
+        }
+    },
+    {
+        "pk": 293,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- umie wyja\u015bni\u0107 poj\u0119cie polityki medialnej oraz wymieni\u0107 jej wybrane cele i narz\u0119dzia; np. \u00a0 prawo medialne i telekomunikacyjne, regulacja i otoczenie instytucjonalne.",
+            "competence": 33,
+            "level": 5
+        }
+    },
+    {
+        "pk": 294,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- wie o istnieniu mi\u0119dzynarodowego wymiaru polityki medialnej; zna rol\u0119 organizacji mi\u0119dzynarodowych: UE, ITU, WTO, OECD.\r\n- umie wskaza\u0107 \u017ar\u00f3d\u0142a presji politycznej i ekonomicznej wywieranej na media ze wzgl\u0119du na model finansowania.\r\n- rozumie wp\u0142yw polityki medialnej na zjawiska natury ekonomicznej zachodz\u0105ce w mediach; np. tworzenie barier wej\u015bcia na rynek, koncentracja, finansowanie medi\u00f3w.",
+            "competence": 33,
+            "level": 6
+        }
+    },
+    {
+        "pk": 295,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- wie, \u017ce rynek medi\u00f3w podlega nadzorowi i kontroli.",
+            "competence": 33,
+            "level": 7
+        }
+    },
+    {
+        "pk": 296,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- wie o istnieniu nieformalnych system\u00f3w medialnych, b\u0119d\u0105cych w du\u017cej cz\u0119\u015bci lub w ca\u0142o\u015bci s\u0105 poza zasi\u0119giem polityki pa\u0144stwa.\r\n- wie o istnieniu mi\u0119dzynarodowego wymiaru polityki medialnej i umie poda\u0107 przyk\u0142ady organizacji mi\u0119dzynarodowych maj\u0105cych wp\u0142yw na ten wymiar.\r\n- umie rozpozna\u0107 elementy polityki medialnej.",
+            "competence": 33,
+            "level": 8
+        }
+    },
+    {
+        "pk": 297,
+        "model": "curriculum.competencelevel",
+        "fields": {
+            "description": "- rozumie podstawowe funkcje, cele i narz\u0119dzia polityki medialnej.\r\n- umie poda\u0107 przyk\u0142ady wp\u0142ywu polityki medialnej na funkcjonowanie medi\u00f3w (spos\u00f3b ich finansowania, tworzenie nowych medi\u00f3w).",
+            "competence": 33,
+            "level": 9
+        }
+    }
+]
diff --git a/src/curriculum/fixtures/curriculum.json b/src/curriculum/fixtures/curriculum.json
new file mode 100644 (file)
index 0000000..dc62f07
--- /dev/null
@@ -0,0 +1,567 @@
+[
+    {
+        "pk": 1,
+        "model": "curriculum.curriculumlevel",
+        "fields": {
+            "title": "III"
+        }
+    },
+    {
+        "pk": 2,
+        "model": "curriculum.curriculumlevel",
+        "fields": {
+            "title": "IV"
+        }
+    },
+    {
+        "pk": 1,
+        "model": "curriculum.curriculumcourse",
+        "fields": {
+            "accusative": "j\u0119zyk polski",
+            "slug": "polski",
+            "title": "J\u0119zyk polski"
+        }
+    },
+    {
+        "pk": 2,
+        "model": "curriculum.curriculumcourse",
+        "fields": {
+            "accusative": "plastyk\u0119",
+            "slug": "plastyka",
+            "title": "Plastyka"
+        }
+    },
+    {
+        "pk": 3,
+        "model": "curriculum.curriculumcourse",
+        "fields": {
+            "accusative": "wiedz\u0119 o spo\u0142ecze\u0144stwie",
+            "slug": "wos",
+            "title": "Wiedza o spo\u0142ecze\u0144stwie"
+        }
+    },
+    {
+        "pk": 4,
+        "model": "curriculum.curriculumcourse",
+        "fields": {
+            "accusative": "informatyk\u0119",
+            "slug": "informatyka",
+            "title": "Informatyka"
+        }
+    },
+    {
+        "pk": 5,
+        "model": "curriculum.curriculumcourse",
+        "fields": {
+            "accusative": "etyk\u0119",
+            "slug": "etyka",
+            "title": "Etyka"
+        }
+    },
+    {
+        "pk": 1,
+        "model": "curriculum.curriculum",
+        "fields": {
+            "course": 1,
+            "level": 1,
+            "identifier": "2012/III/POLSKI/c1",
+            "type": "c",
+            "title": "I. Odbi\u00f3r wypowiedzi i wykorzystanie zawartych w nich informacji."
+        }
+    },
+    {
+        "pk": 2,
+        "model": "curriculum.curriculum",
+        "fields": {
+            "course": 1,
+            "level": 1,
+            "identifier": "2012/III/POLSKI/c2",
+            "type": "c",
+            "title": "II. Analiza i interpretacja tekst\u00f3w kultury."
+        }
+    },
+    {
+        "pk": 3,
+        "model": "curriculum.curriculum",
+        "fields": {
+            "course": 1,
+            "level": 1,
+            "identifier": "2012/III/POLSKI/c3",
+            "type": "c",
+            "title": "III. Tworzenie wypowiedzi."
+        }
+    },
+    {
+        "pk": 4,
+        "model": "curriculum.curriculum",
+        "fields": {
+            "course": 2,
+            "level": 1,
+            "identifier": "2012/III/PLASTYKA/c1",
+            "type": "c",
+            "title": "I. Odbi\u00f3r wypowiedzi i wykorzystanie zawartych w nich informacji \u2013 percepcja sztuki."
+        }
+    },
+    {
+        "pk": 5,
+        "model": "curriculum.curriculum",
+        "fields": {
+            "course": 2,
+            "level": 1,
+            "identifier": "2012/III/PLASTYKA/c2",
+            "type": "c",
+            "title": "II. Tworzenie wypowiedzi \u2013 ekspresja przez sztuk\u0119."
+        }
+    },
+    {
+        "pk": 6,
+        "model": "curriculum.curriculum",
+        "fields": {
+            "course": 2,
+            "level": 1,
+            "identifier": "2012/III/PLASTYKA/c3",
+            "type": "c",
+            "title": "III. Analiza i interpretacja tekst\u00f3w kultury \u2013 recepcja sztuki."
+        }
+    },
+    {
+        "pk": 7,
+        "model": "curriculum.curriculum",
+        "fields": {
+            "course": 3,
+            "level": 1,
+            "identifier": "2012/III/WOS/c1",
+            "type": "c",
+            "title": "I. Wykorzystanie i tworzenie informacji."
+        }
+    },
+    {
+        "pk": 8,
+        "model": "curriculum.curriculum",
+        "fields": {
+            "course": 3,
+            "level": 1,
+            "identifier": "2012/III/WOS/c2",
+            "type": "c",
+            "title": "II. Rozpoznawanie i rozwi\u0105zywanie problem\u00f3w."
+        }
+    },
+    {
+        "pk": 9,
+        "model": "curriculum.curriculum",
+        "fields": {
+            "course": 3,
+            "level": 1,
+            "identifier": "2012/III/WOS/c3",
+            "type": "c",
+            "title": "III. Wsp\u00f3\u0142dzia\u0142anie w sprawach publicznych."
+        }
+    },
+    {
+        "pk": 10,
+        "model": "curriculum.curriculum",
+        "fields": {
+            "course": 3,
+            "level": 1,
+            "identifier": "2012/III/WOS/c4",
+            "type": "c",
+            "title": "IV. Znajomo\u015b\u0107 zasad i procedur demokracji."
+        }
+    },
+    {
+        "pk": 11,
+        "model": "curriculum.curriculum",
+        "fields": {
+            "course": 3,
+            "level": 1,
+            "identifier": "2012/III/WOS/c5",
+            "type": "c",
+            "title": "V. Znajomo\u015b\u0107 podstaw ustroju Rzeczypospolitej Polskiej."
+        }
+    },
+    {
+        "pk": 12,
+        "model": "curriculum.curriculum",
+        "fields": {
+            "course": 3,
+            "level": 1,
+            "identifier": "2012/III/WOS/t1",
+            "type": "t",
+            "title": "Podstawowe umiej\u0119tno\u015bci \u017cycia w grupie."
+        }
+    },
+    {
+        "pk": 13,
+        "model": "curriculum.curriculum",
+        "fields": {
+            "course": 3,
+            "level": 1,
+            "identifier": "2012/III/WOS/t2",
+            "type": "t",
+            "title": "\u017bycie spo\u0142eczne"
+        }
+    },
+    {
+        "pk": 14,
+        "model": "curriculum.curriculum",
+        "fields": {
+            "course": 3,
+            "level": 1,
+            "identifier": "2012/III/WOS/t3",
+            "type": "t",
+            "title": "Wsp\u00f3\u0142czesne spo\u0142ecze\u0144stwo polskie."
+        }
+    },
+    {
+        "pk": 15,
+        "model": "curriculum.curriculum",
+        "fields": {
+            "course": 3,
+            "level": 1,
+            "identifier": "2012/III/WOS/t4",
+            "type": "t",
+            "title": "By\u0107 obywatelem."
+        }
+    },
+    {
+        "pk": 16,
+        "model": "curriculum.curriculum",
+        "fields": {
+            "course": 3,
+            "level": 1,
+            "identifier": "2012/III/WOS/t5",
+            "type": "t",
+            "title": "Udzia\u0142 obywateli w \u017cyciu publicznym"
+        }
+    },
+    {
+        "pk": 17,
+        "model": "curriculum.curriculum",
+        "fields": {
+            "course": 3,
+            "level": 1,
+            "identifier": "2012/III/WOS/t6",
+            "type": "t",
+            "title": "\u015arodki masowego przekazu."
+        }
+    },
+    {
+        "pk": 18,
+        "model": "curriculum.curriculum",
+        "fields": {
+            "course": 3,
+            "level": 1,
+            "identifier": "2012/III/WOS/t9",
+            "type": "t",
+            "title": "Patriotyzm dzisiaj."
+        }
+    },
+    {
+        "pk": 19,
+        "model": "curriculum.curriculum",
+        "fields": {
+            "course": 3,
+            "level": 1,
+            "identifier": "2012/III/WOS/t10",
+            "type": "t",
+            "title": "Pa\u0144stwo i w\u0142adza demokratyczna."
+        }
+    },
+    {
+        "pk": 20,
+        "model": "curriculum.curriculum",
+        "fields": {
+            "course": 3,
+            "level": 1,
+            "identifier": "2012/III/WOS/t11",
+            "type": "t",
+            "title": "Rzeczpospolita Polska jako demokracja konstytucyjna."
+        }
+    },
+    {
+        "pk": 21,
+        "model": "curriculum.curriculum",
+        "fields": {
+            "course": 3,
+            "level": 1,
+            "identifier": "2012/III/WOS/t24",
+            "type": "t",
+            "title": "Praca i przedsi\u0119biorczo\u015b\u0107."
+        }
+    },
+    {
+        "pk": 22,
+        "model": "curriculum.curriculum",
+        "fields": {
+            "course": 3,
+            "level": 1,
+            "identifier": "2012/III/WOS/t25",
+            "type": "t",
+            "title": "Gospodarka rynkowa."
+        }
+    },
+    {
+        "pk": 23,
+        "model": "curriculum.curriculum",
+        "fields": {
+            "course": 3,
+            "level": 1,
+            "identifier": "2012/III/WOS/t26",
+            "type": "t",
+            "title": "Gospodarstwo domowe."
+        }
+    },
+    {
+        "pk": 24,
+        "model": "curriculum.curriculum",
+        "fields": {
+            "course": 4,
+            "level": 1,
+            "identifier": "2012/III/INFORMATYKA/c1",
+            "type": "c",
+            "title": "I. Bezpieczne pos\u0142ugiwanie si\u0119 komputerem i jego oprogramowaniem, wykorzystanie sieci komputerowej; komunikowanie si\u0119 za pomoc\u0105 komputera i technologii informacyjno-komunikacyjnych."
+        }
+    },
+    {
+        "pk": 25,
+        "model": "curriculum.curriculum",
+        "fields": {
+            "course": 4,
+            "level": 1,
+            "identifier": "2012/III/INFORMATYKA/c2",
+            "type": "c",
+            "title": "II. Wyszukiwanie, gromadzenie i przetwarzanie informacji z r\u00f3\u017cnych \u017ar\u00f3de\u0142; opracowywanie za pomoc\u0105 komputera: rysunk\u00f3w, tekst\u00f3w, danych liczbowych, motyw\u00f3w, animacji, prezentacji multimedialnych."
+        }
+    },
+    {
+        "pk": 26,
+        "model": "curriculum.curriculum",
+        "fields": {
+            "course": 4,
+            "level": 1,
+            "identifier": "2012/III/INFORMATYKA/c5",
+            "type": "c",
+            "title": "V. Ocena zagro\u017ce\u0144 i ogranicze\u0144, docenianie spo\u0142ecznych aspekt\u00f3w rozwoju i zastosowa\u0144 informatyki."
+        }
+    },
+    {
+        "pk": 27,
+        "model": "curriculum.curriculum",
+        "fields": {
+            "course": 5,
+            "level": 1,
+            "identifier": "2012/III/ETYKA/c1",
+            "type": "c",
+            "title": "I. Kszta\u0142towanie refleksyjnej postawy wobec cz\u0142owieka, jego natury, powinno\u015bci moralnych oraz wobec r\u00f3\u017cnych sytuacji \u017cyciowych."
+        }
+    },
+    {
+        "pk": 28,
+        "model": "curriculum.curriculum",
+        "fields": {
+            "course": 5,
+            "level": 1,
+            "identifier": "2012/III/ETYKA/c4",
+            "type": "c",
+            "title": "IV. Podj\u0119cie odpowiedzialno\u015bci za siebie i innych oraz za dokonywane wybory moralne; rozstrzyganie w\u0105tpliwo\u015bci i problem\u00f3w moralnych zgodnie z przyj\u0119t\u0105 hierarchi\u0105 warto\u015bci i dobrem wsp\u00f3lnym."
+        }
+    },
+    {
+        "pk": 29,
+        "model": "curriculum.curriculum",
+        "fields": {
+            "course": 5,
+            "level": 1,
+            "identifier": "2012/III/ETYKA/t1",
+            "type": "t",
+            "title": "Cz\u0142owiek jako osoba; natura i godno\u015b\u0107 cz\u0142owieka."
+        }
+    },
+    {
+        "pk": 30,
+        "model": "curriculum.curriculum",
+        "fields": {
+            "course": 5,
+            "level": 1,
+            "identifier": "2012/III/ETYKA/t5",
+            "type": "t",
+            "title": "Cz\u0142owiek wobec warto\u015bci; cz\u0142owiek wobec cierpienia i \u015bmierci."
+        }
+    },
+    {
+        "pk": 31,
+        "model": "curriculum.curriculum",
+        "fields": {
+            "course": 5,
+            "level": 1,
+            "identifier": "2012/III/ETYKA/t9",
+            "type": "t",
+            "title": "Normy i warto\u015bci demokratyczne le\u017c\u0105ce u podstaw aktywno\u015bci spo\u0142ecznej na poziomie ma\u0142ej grupy, szko\u0142y, spo\u0142eczno\u015bci lokalnej."
+        }
+    },
+    {
+        "pk": 32,
+        "model": "curriculum.curriculum",
+        "fields": {
+            "course": 5,
+            "level": 1,
+            "identifier": "2012/III/ETYKA/t11",
+            "type": "t",
+            "title": "Praca i jej warto\u015b\u0107 dla cz\u0142owieka, znaczenie etyki zawodowej."
+        }
+    },
+    {
+        "pk": 33,
+        "model": "curriculum.curriculum",
+        "fields": {
+            "course": 3,
+            "level": 2,
+            "identifier": "2012/IV/WOS/c4",
+            "type": "c",
+            "title": "IV. Znajomo\u015b\u0107 zasad i procedur demokracji."
+        }
+    },
+    {
+        "pk": 34,
+        "model": "curriculum.curriculum",
+        "fields": {
+            "course": 3,
+            "level": 2,
+            "identifier": "2012/IV/WOS/c6",
+            "type": "c",
+            "title": "VI. Znajomo\u015b\u0107 praw cz\u0142owieka i sposob\u00f3w ich ochrony."
+        }
+    },
+    {
+        "pk": 35,
+        "model": "curriculum.curriculum",
+        "fields": {
+            "course": 3,
+            "level": 2,
+            "identifier": "2012/IV/WOS/t1",
+            "type": "t",
+            "title": "M\u0142ody obywatel w urz\u0119dzie."
+        }
+    },
+    {
+        "pk": 36,
+        "model": "curriculum.curriculum",
+        "fields": {
+            "course": 3,
+            "level": 2,
+            "identifier": "2012/IV/WOS/t2",
+            "type": "t",
+            "title": "Prawo i s\u0105dy."
+        }
+    },
+    {
+        "pk": 37,
+        "model": "curriculum.curriculum",
+        "fields": {
+            "course": 3,
+            "level": 2,
+            "identifier": "2012/IV/WOS/t5",
+            "type": "t",
+            "title": "Prawa cz\u0142owieka."
+        }
+    },
+    {
+        "pk": 38,
+        "model": "curriculum.curriculum",
+        "fields": {
+            "course": 3,
+            "level": 2,
+            "identifier": "2012/IV/WOS/t6",
+            "type": "t",
+            "title": "Ochrona praw i wolno\u015bci."
+        }
+    },
+    {
+        "pk": 39,
+        "model": "curriculum.curriculum",
+        "fields": {
+            "course": 3,
+            "level": 2,
+            "identifier": "2012/IV/WOS/t10/roz",
+            "type": "t",
+            "title": "Edukacja w XXI w. (zakres rozszerzony)"
+        }
+    },
+    {
+        "pk": 40,
+        "model": "curriculum.curriculum",
+        "fields": {
+            "course": 3,
+            "level": 2,
+            "identifier": "2012/IV/WOS/t14/roz",
+            "type": "t",
+            "title": "\u015arodki masowego przekazu. (zakres rozszerzony)"
+        }
+    },
+    {
+        "pk": 41,
+        "model": "curriculum.curriculum",
+        "fields": {
+            "course": 3,
+            "level": 2,
+            "identifier": "2012/IV/WOS/t15/roz",
+            "type": "t",
+            "title": "Demokracja \u2013 zasady i procedury. (zakres rozszerzony)"
+        }
+    },
+    {
+        "pk": 42,
+        "model": "curriculum.curriculum",
+        "fields": {
+            "course": 3,
+            "level": 2,
+            "identifier": "2012/IV/WOS/t27/roz",
+            "type": "t",
+            "title": "Organy kontroli pa\u0144stwowej, ochrony prawa i zaufania publicznego. (zakres rozszerzony)"
+        }
+    },
+    {
+        "pk": 43,
+        "model": "curriculum.curriculum",
+        "fields": {
+            "course": 3,
+            "level": 2,
+            "identifier": "2012/IV/WOS/t32/roz",
+            "type": "t",
+            "title": "Prawo cywilne i rodzinne. (zakres rozszerzony)"
+        }
+    },
+    {
+        "pk": 44,
+        "model": "curriculum.curriculum",
+        "fields": {
+            "course": 3,
+            "level": 2,
+            "identifier": "2012/IV/WOS/t36/roz",
+            "type": "t",
+            "title": "Obywatel wobec prawa. (zakres rozszerzony)"
+        }
+    },
+    {
+        "pk": 45,
+        "model": "curriculum.curriculum",
+        "fields": {
+            "course": 4,
+            "level": 2,
+            "identifier": "2012/IV/INFORMATYKA/c1",
+            "type": "c",
+            "title": "I. Bezpieczne pos\u0142ugiwanie si\u0119 komputerem i jego oprogramowaniem, wykorzystanie sieci komputerowej; komunikowanie si\u0119 za pomoc\u0105 komputera i technologii informacyjno-komunikacyjnych."
+        }
+    },
+    {
+        "pk": 46,
+        "model": "curriculum.curriculum",
+        "fields": {
+            "course": 4,
+            "level": 2,
+            "identifier": "2012/IV/INFORMATYKA/c5",
+            "type": "c",
+            "title": "V. Ocena zagro\u017ce\u0144 i ogranicze\u0144, docenianie spo\u0142ecznych aspekt\u00f3w rozwoju i zastosowa\u0144 informatyki."
+        }
+    }
+]
diff --git a/src/curriculum/locale/pl/LC_MESSAGES/django.mo b/src/curriculum/locale/pl/LC_MESSAGES/django.mo
new file mode 100644 (file)
index 0000000..16f5b95
Binary files /dev/null and b/src/curriculum/locale/pl/LC_MESSAGES/django.mo differ
diff --git a/src/curriculum/locale/pl/LC_MESSAGES/django.po b/src/curriculum/locale/pl/LC_MESSAGES/django.po
new file mode 100644 (file)
index 0000000..04048df
--- /dev/null
@@ -0,0 +1,131 @@
+# 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: 2013-10-18 14:01+0200\n"
+"PO-Revision-Date: 2013-02-08 13:16+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"
+
+#: models.py:9 models.py:33 models.py:68
+msgid "slug"
+msgstr ""
+
+#: models.py:10 models.py:34 models.py:69
+msgid "order"
+msgstr "kolejność"
+
+#: models.py:14
+msgid "section"
+msgstr "dział"
+
+#: models.py:15
+msgid "sections"
+msgstr "działy"
+
+#: models.py:27 models.py:63 models.py:80
+msgid "name"
+msgstr "nazwa"
+
+#: models.py:38
+msgid "competence"
+msgstr "kompetencja"
+
+#: models.py:39
+msgid "competences"
+msgstr "kompetencje"
+
+#: models.py:73
+msgid "educational level"
+msgstr "poziom edukacyjny"
+
+#: models.py:74
+msgid "educational levels"
+msgstr "poziomy edukacyjne"
+
+#: models.py:81
+msgid "group"
+msgstr "grupa"
+
+#: models.py:91
+msgid "competence on level"
+msgstr "kompetencja na poziomie"
+
+#: models.py:92
+msgid "competences on levels"
+msgstr "kompetencje na poziomach"
+
+#: models.py:101
+msgid "description"
+msgstr "opis"
+
+#: models.py:109
+msgid "curriculum level"
+msgstr "poziom w podstawie programowej"
+
+#: models.py:110
+msgid "curriculum levels"
+msgstr "poziomy w podstawie programowej"
+
+#: models.py:122
+msgid "curriculum course"
+msgstr "przedmiot w podstawie programowej"
+
+#: models.py:123
+msgid "curriculum courses"
+msgstr "przedmioty w podstawie programowej"
+
+#: models.py:141
+msgid "curriculum item"
+msgstr "pozycja w podstawie programowej"
+
+#: models.py:142
+msgid "curriculum items"
+msgstr "podstawa programowa"
+
+#: views.py:51
+msgid "You must select at least one competency from the list."
+msgstr "Proszę wybrać kompetencje z listy."
+
+#: views.py:53
+msgid "You must select at least one education level."
+msgstr "Proszę wybrać poziom edukacyjny."
+
+#: templates/curriculum/competence_list.html:8
+msgid "Media, information and digital literacy competencies catalogue"
+msgstr "Katalog kompetencji medialnych, informacyjnych i cyfrowych"
+
+#: templates/curriculum/competence_list.html:15
+msgid "Browse competencies"
+msgstr "Przeglądaj kompetencje"
+
+#: templates/curriculum/competence_list.html:15
+msgid "expand"
+msgstr "rozwiń"
+
+#: templates/curriculum/competence_list.html:18
+msgid "Education level"
+msgstr "Poziom edukacyjny"
+
+#: templates/curriculum/competence_list.html:31
+msgid "Competency categories"
+msgstr "Kategorie kompetencji"
+
+#: templates/curriculum/competence_list.html:49
+msgid "Show"
+msgstr "Pokaż"
+
+#: templates/curriculum/competence_list.html:55
+msgid "Selected competencies"
+msgstr "Wybrane kompetencje"
diff --git a/src/curriculum/migrations/0001_initial.py b/src/curriculum/migrations/0001_initial.py
new file mode 100644 (file)
index 0000000..6ac7f4f
--- /dev/null
@@ -0,0 +1,95 @@
+# -*- coding: utf-8 -*-
+import datetime
+from south.db import db
+from south.v2 import SchemaMigration
+from django.db import models
+
+
+class Migration(SchemaMigration):
+
+    def forwards(self, orm):
+        # Adding model 'Section'
+        db.create_table('curriculum_section', (
+            ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
+            ('name', self.gf('django.db.models.fields.CharField')(max_length=255)),
+            ('slug', self.gf('django.db.models.fields.SlugField')(max_length=50)),
+            ('order', self.gf('django.db.models.fields.IntegerField')()),
+        ))
+        db.send_create_signal('curriculum', ['Section'])
+
+        # Adding model 'Competence'
+        db.create_table('curriculum_competence', (
+            ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
+            ('section', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['curriculum.Section'])),
+            ('name', self.gf('django.db.models.fields.CharField')(max_length=255)),
+            ('slug', self.gf('django.db.models.fields.SlugField')(max_length=50)),
+            ('order', self.gf('django.db.models.fields.IntegerField')()),
+        ))
+        db.send_create_signal('curriculum', ['Competence'])
+
+        # Adding model 'Level'
+        db.create_table('curriculum_level', (
+            ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
+            ('name', self.gf('django.db.models.fields.CharField')(max_length=255)),
+            ('slug', self.gf('django.db.models.fields.SlugField')(max_length=50)),
+            ('order', self.gf('django.db.models.fields.IntegerField')()),
+        ))
+        db.send_create_signal('curriculum', ['Level'])
+
+        # Adding model 'CompetenceLevel'
+        db.create_table('curriculum_competencelevel', (
+            ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
+            ('competence', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['curriculum.Competence'])),
+            ('level', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['curriculum.Level'])),
+            ('description', self.gf('django.db.models.fields.TextField')()),
+        ))
+        db.send_create_signal('curriculum', ['CompetenceLevel'])
+
+
+    def backwards(self, orm):
+        # Deleting model 'Section'
+        db.delete_table('curriculum_section')
+
+        # Deleting model 'Competence'
+        db.delete_table('curriculum_competence')
+
+        # Deleting model 'Level'
+        db.delete_table('curriculum_level')
+
+        # Deleting model 'CompetenceLevel'
+        db.delete_table('curriculum_competencelevel')
+
+
+    models = {
+        'curriculum.competence': {
+            'Meta': {'ordering': "['order']", 'object_name': 'Competence'},
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+            'order': ('django.db.models.fields.IntegerField', [], {}),
+            'section': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['curriculum.Section']"}),
+            'slug': ('django.db.models.fields.SlugField', [], {'max_length': '50'})
+        },
+        'curriculum.competencelevel': {
+            'Meta': {'ordering': "['competence', 'level']", 'object_name': 'CompetenceLevel'},
+            'competence': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['curriculum.Competence']"}),
+            'description': ('django.db.models.fields.TextField', [], {}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'level': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['curriculum.Level']"})
+        },
+        'curriculum.level': {
+            'Meta': {'ordering': "['order']", 'object_name': 'Level'},
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+            'order': ('django.db.models.fields.IntegerField', [], {}),
+            'slug': ('django.db.models.fields.SlugField', [], {'max_length': '50'})
+        },
+        'curriculum.section': {
+            'Meta': {'ordering': "['order']", 'object_name': 'Section'},
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+            'order': ('django.db.models.fields.IntegerField', [], {}),
+            'slug': ('django.db.models.fields.SlugField', [], {'max_length': '50'})
+        }
+    }
+
+    complete_apps = ['curriculum']
\ No newline at end of file
diff --git a/src/curriculum/migrations/0002_auto__add_field_level_group.py b/src/curriculum/migrations/0002_auto__add_field_level_group.py
new file mode 100644 (file)
index 0000000..0f7cf5d
--- /dev/null
@@ -0,0 +1,55 @@
+# -*- coding: utf-8 -*-
+import datetime
+from south.db import db
+from south.v2 import SchemaMigration
+from django.db import models
+
+
+class Migration(SchemaMigration):
+
+    def forwards(self, orm):
+        # Adding field 'Level.group'
+        db.add_column('curriculum_level', 'group',
+                      self.gf('django.db.models.fields.CharField')(default='', max_length=255),
+                      keep_default=False)
+
+
+    def backwards(self, orm):
+        # Deleting field 'Level.group'
+        db.delete_column('curriculum_level', 'group')
+
+
+    models = {
+        'curriculum.competence': {
+            'Meta': {'ordering': "['order']", 'object_name': 'Competence'},
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+            'order': ('django.db.models.fields.IntegerField', [], {}),
+            'section': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['curriculum.Section']"}),
+            'slug': ('django.db.models.fields.SlugField', [], {'max_length': '50'})
+        },
+        'curriculum.competencelevel': {
+            'Meta': {'ordering': "['competence', 'level']", 'object_name': 'CompetenceLevel'},
+            'competence': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['curriculum.Competence']"}),
+            'description': ('django.db.models.fields.TextField', [], {}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'level': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['curriculum.Level']"})
+        },
+        'curriculum.level': {
+            'Meta': {'ordering': "['order']", 'object_name': 'Level'},
+            'group': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+            'order': ('django.db.models.fields.IntegerField', [], {}),
+            'slug': ('django.db.models.fields.SlugField', [], {'max_length': '50'})
+        },
+        'curriculum.section': {
+            'Meta': {'ordering': "['order']", 'object_name': 'Section'},
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+            'order': ('django.db.models.fields.IntegerField', [], {}),
+            'slug': ('django.db.models.fields.SlugField', [], {'max_length': '50'})
+        }
+    }
+
+    complete_apps = ['curriculum']
\ No newline at end of file
diff --git a/src/curriculum/migrations/0003_auto__chg_field_level_slug.py b/src/curriculum/migrations/0003_auto__chg_field_level_slug.py
new file mode 100644 (file)
index 0000000..f22e753
--- /dev/null
@@ -0,0 +1,59 @@
+# -*- coding: utf-8 -*-
+import datetime
+from south.db import db
+from south.v2 import SchemaMigration
+from django.db import models
+
+
+class Migration(SchemaMigration):
+
+    def forwards(self, orm):
+
+        # Changing field 'Level.slug'
+        db.alter_column('curriculum_level', 'slug', self.gf('django.db.models.fields.CharField')(max_length=255))
+        # Removing index on 'Level', fields ['slug']
+        db.delete_index('curriculum_level', ['slug'])
+
+
+    def backwards(self, orm):
+        # Adding index on 'Level', fields ['slug']
+        db.create_index('curriculum_level', ['slug'])
+
+
+        # Changing field 'Level.slug'
+        db.alter_column('curriculum_level', 'slug', self.gf('django.db.models.fields.SlugField')(max_length=50))
+
+    models = {
+        'curriculum.competence': {
+            'Meta': {'ordering': "['order']", 'object_name': 'Competence'},
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+            'order': ('django.db.models.fields.IntegerField', [], {}),
+            'section': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['curriculum.Section']"}),
+            'slug': ('django.db.models.fields.SlugField', [], {'max_length': '50'})
+        },
+        'curriculum.competencelevel': {
+            'Meta': {'ordering': "['competence', 'level']", 'object_name': 'CompetenceLevel'},
+            'competence': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['curriculum.Competence']"}),
+            'description': ('django.db.models.fields.TextField', [], {}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'level': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['curriculum.Level']"})
+        },
+        'curriculum.level': {
+            'Meta': {'ordering': "['order']", 'object_name': 'Level'},
+            'group': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+            'order': ('django.db.models.fields.IntegerField', [], {}),
+            'slug': ('django.db.models.fields.CharField', [], {'max_length': '255'})
+        },
+        'curriculum.section': {
+            'Meta': {'ordering': "['order']", 'object_name': 'Section'},
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+            'order': ('django.db.models.fields.IntegerField', [], {}),
+            'slug': ('django.db.models.fields.SlugField', [], {'max_length': '50'})
+        }
+    }
+
+    complete_apps = ['curriculum']
\ No newline at end of file
diff --git a/src/curriculum/migrations/0004_auto__add_curriculum__add_curriculumlevel__add_curriculumcourse.py b/src/curriculum/migrations/0004_auto__add_curriculum__add_curriculumlevel__add_curriculumcourse.py
new file mode 100644 (file)
index 0000000..3a45ff5
--- /dev/null
@@ -0,0 +1,102 @@
+# -*- coding: utf-8 -*-
+import datetime
+from south.db import db
+from south.v2 import SchemaMigration
+from django.db import models
+
+
+class Migration(SchemaMigration):
+
+    def forwards(self, orm):
+        # Adding model 'Curriculum'
+        db.create_table('curriculum_curriculum', (
+            ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
+            ('identifier', self.gf('django.db.models.fields.CharField')(max_length=255, db_index=True)),
+            ('title', self.gf('django.db.models.fields.CharField')(max_length=255)),
+            ('course', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['curriculum.CurriculumCourse'])),
+            ('level', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['curriculum.CurriculumLevel'])),
+            ('type', self.gf('django.db.models.fields.CharField')(max_length=16)),
+        ))
+        db.send_create_signal('curriculum', ['Curriculum'])
+
+        # Adding model 'CurriculumLevel'
+        db.create_table('curriculum_curriculumlevel', (
+            ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
+            ('title', self.gf('django.db.models.fields.CharField')(max_length=16, db_index=True)),
+        ))
+        db.send_create_signal('curriculum', ['CurriculumLevel'])
+
+        # Adding model 'CurriculumCourse'
+        db.create_table('curriculum_curriculumcourse', (
+            ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
+            ('title', self.gf('django.db.models.fields.CharField')(max_length=255)),
+            ('slug', self.gf('django.db.models.fields.CharField')(max_length=255, db_index=True)),
+        ))
+        db.send_create_signal('curriculum', ['CurriculumCourse'])
+
+
+    def backwards(self, orm):
+        # Deleting model 'Curriculum'
+        db.delete_table('curriculum_curriculum')
+
+        # Deleting model 'CurriculumLevel'
+        db.delete_table('curriculum_curriculumlevel')
+
+        # Deleting model 'CurriculumCourse'
+        db.delete_table('curriculum_curriculumcourse')
+
+
+    models = {
+        'curriculum.competence': {
+            'Meta': {'ordering': "['order']", 'object_name': 'Competence'},
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+            'order': ('django.db.models.fields.IntegerField', [], {}),
+            'section': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['curriculum.Section']"}),
+            'slug': ('django.db.models.fields.SlugField', [], {'max_length': '50'})
+        },
+        'curriculum.competencelevel': {
+            'Meta': {'ordering': "['competence', 'level']", 'object_name': 'CompetenceLevel'},
+            'competence': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['curriculum.Competence']"}),
+            'description': ('django.db.models.fields.TextField', [], {}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'level': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['curriculum.Level']"})
+        },
+        'curriculum.curriculum': {
+            'Meta': {'object_name': 'Curriculum'},
+            'course': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['curriculum.CurriculumCourse']"}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'identifier': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}),
+            'level': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['curriculum.CurriculumLevel']"}),
+            'title': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+            'type': ('django.db.models.fields.CharField', [], {'max_length': '16'})
+        },
+        'curriculum.curriculumcourse': {
+            'Meta': {'object_name': 'CurriculumCourse'},
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'slug': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}),
+            'title': ('django.db.models.fields.CharField', [], {'max_length': '255'})
+        },
+        'curriculum.curriculumlevel': {
+            'Meta': {'object_name': 'CurriculumLevel'},
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'title': ('django.db.models.fields.CharField', [], {'max_length': '16', 'db_index': 'True'})
+        },
+        'curriculum.level': {
+            'Meta': {'ordering': "['order']", 'object_name': 'Level'},
+            'group': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+            'order': ('django.db.models.fields.IntegerField', [], {}),
+            'slug': ('django.db.models.fields.CharField', [], {'max_length': '255'})
+        },
+        'curriculum.section': {
+            'Meta': {'ordering': "['order']", 'object_name': 'Section'},
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+            'order': ('django.db.models.fields.IntegerField', [], {}),
+            'slug': ('django.db.models.fields.SlugField', [], {'max_length': '50'})
+        }
+    }
+
+    complete_apps = ['curriculum']
\ No newline at end of file
diff --git a/src/curriculum/migrations/0005_auto__add_field_curriculumcourse_accusative.py b/src/curriculum/migrations/0005_auto__add_field_curriculumcourse_accusative.py
new file mode 100644 (file)
index 0000000..0708f44
--- /dev/null
@@ -0,0 +1,79 @@
+# -*- coding: utf-8 -*-
+import datetime
+from south.db import db
+from south.v2 import SchemaMigration
+from django.db import models
+
+
+class Migration(SchemaMigration):
+
+    def forwards(self, orm):
+        # Adding field 'CurriculumCourse.accusative'
+        db.add_column('curriculum_curriculumcourse', 'accusative',
+                      self.gf('django.db.models.fields.CharField')(default='', max_length=255),
+                      keep_default=False)
+
+        if not db.dry_run:
+            orm.CurriculumCourse.objects.all().update(accusative=models.F('title'))
+
+
+    def backwards(self, orm):
+        # Deleting field 'CurriculumCourse.accusative'
+        db.delete_column('curriculum_curriculumcourse', 'accusative')
+
+
+    models = {
+        'curriculum.competence': {
+            'Meta': {'ordering': "['order']", 'object_name': 'Competence'},
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+            'order': ('django.db.models.fields.IntegerField', [], {}),
+            'section': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['curriculum.Section']"}),
+            'slug': ('django.db.models.fields.SlugField', [], {'max_length': '50'})
+        },
+        'curriculum.competencelevel': {
+            'Meta': {'ordering': "['competence', 'level']", 'object_name': 'CompetenceLevel'},
+            'competence': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['curriculum.Competence']"}),
+            'description': ('django.db.models.fields.TextField', [], {}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'level': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['curriculum.Level']"})
+        },
+        'curriculum.curriculum': {
+            'Meta': {'object_name': 'Curriculum'},
+            'course': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['curriculum.CurriculumCourse']"}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'identifier': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}),
+            'level': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['curriculum.CurriculumLevel']"}),
+            'title': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+            'type': ('django.db.models.fields.CharField', [], {'max_length': '16'})
+        },
+        'curriculum.curriculumcourse': {
+            'Meta': {'object_name': 'CurriculumCourse'},
+            'accusative': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'slug': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}),
+            'title': ('django.db.models.fields.CharField', [], {'max_length': '255'})
+        },
+        'curriculum.curriculumlevel': {
+            'Meta': {'object_name': 'CurriculumLevel'},
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'title': ('django.db.models.fields.CharField', [], {'max_length': '16', 'db_index': 'True'})
+        },
+        'curriculum.level': {
+            'Meta': {'ordering': "['order']", 'object_name': 'Level'},
+            'group': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+            'order': ('django.db.models.fields.IntegerField', [], {}),
+            'slug': ('django.db.models.fields.CharField', [], {'max_length': '255'})
+        },
+        'curriculum.section': {
+            'Meta': {'ordering': "['order']", 'object_name': 'Section'},
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+            'order': ('django.db.models.fields.IntegerField', [], {}),
+            'slug': ('django.db.models.fields.SlugField', [], {'max_length': '50'})
+        }
+    }
+
+    complete_apps = ['curriculum']
diff --git a/src/curriculum/migrations/0006_auto__add_field_competencelevel_description_pl__add_field_competencele.py b/src/curriculum/migrations/0006_auto__add_field_competencelevel_description_pl__add_field_competencele.py
new file mode 100644 (file)
index 0000000..d62e37a
--- /dev/null
@@ -0,0 +1,158 @@
+# -*- coding: utf-8 -*-
+import datetime
+from south.db import db
+from south.v2 import SchemaMigration
+from django.db import models
+
+
+class Migration(SchemaMigration):
+
+    def forwards(self, orm):
+        # Adding field 'CompetenceLevel.description_pl'
+        db.add_column(u'curriculum_competencelevel', 'description_pl',
+                      self.gf('django.db.models.fields.TextField')(null=True),
+                      keep_default=False)
+
+        # Adding field 'CompetenceLevel.description_en'
+        db.add_column(u'curriculum_competencelevel', 'description_en',
+                      self.gf('django.db.models.fields.TextField')(null=True),
+                      keep_default=False)
+
+        # Adding field 'Section.name_pl'
+        db.add_column(u'curriculum_section', 'name_pl',
+                      self.gf('django.db.models.fields.CharField')(max_length=255, null=True),
+                      keep_default=False)
+
+        # Adding field 'Section.name_en'
+        db.add_column(u'curriculum_section', 'name_en',
+                      self.gf('django.db.models.fields.CharField')(max_length=255, null=True),
+                      keep_default=False)
+
+        # Adding field 'Competence.name_pl'
+        db.add_column(u'curriculum_competence', 'name_pl',
+                      self.gf('django.db.models.fields.CharField')(max_length=255, null=True),
+                      keep_default=False)
+
+        # Adding field 'Competence.name_en'
+        db.add_column(u'curriculum_competence', 'name_en',
+                      self.gf('django.db.models.fields.CharField')(max_length=255, null=True),
+                      keep_default=False)
+
+        # Adding field 'Level.name_pl'
+        db.add_column(u'curriculum_level', 'name_pl',
+                      self.gf('django.db.models.fields.CharField')(max_length=255, null=True),
+                      keep_default=False)
+
+        # Adding field 'Level.name_en'
+        db.add_column(u'curriculum_level', 'name_en',
+                      self.gf('django.db.models.fields.CharField')(max_length=255, null=True),
+                      keep_default=False)
+
+        # Adding field 'Level.group_pl'
+        db.add_column(u'curriculum_level', 'group_pl',
+                      self.gf('django.db.models.fields.CharField')(max_length=255, null=True),
+                      keep_default=False)
+
+        # Adding field 'Level.group_en'
+        db.add_column(u'curriculum_level', 'group_en',
+                      self.gf('django.db.models.fields.CharField')(max_length=255, null=True),
+                      keep_default=False)
+
+
+    def backwards(self, orm):
+        # Deleting field 'CompetenceLevel.description_pl'
+        db.delete_column(u'curriculum_competencelevel', 'description_pl')
+
+        # Deleting field 'CompetenceLevel.description_en'
+        db.delete_column(u'curriculum_competencelevel', 'description_en')
+
+        # Deleting field 'Section.name_pl'
+        db.delete_column(u'curriculum_section', 'name_pl')
+
+        # Deleting field 'Section.name_en'
+        db.delete_column(u'curriculum_section', 'name_en')
+
+        # Deleting field 'Competence.name_pl'
+        db.delete_column(u'curriculum_competence', 'name_pl')
+
+        # Deleting field 'Competence.name_en'
+        db.delete_column(u'curriculum_competence', 'name_en')
+
+        # Deleting field 'Level.name_pl'
+        db.delete_column(u'curriculum_level', 'name_pl')
+
+        # Deleting field 'Level.name_en'
+        db.delete_column(u'curriculum_level', 'name_en')
+
+        # Deleting field 'Level.group_pl'
+        db.delete_column(u'curriculum_level', 'group_pl')
+
+        # Deleting field 'Level.group_en'
+        db.delete_column(u'curriculum_level', 'group_en')
+
+
+    models = {
+        u'curriculum.competence': {
+            'Meta': {'ordering': "['section', 'order']", 'object_name': 'Competence'},
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+            'name_en': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True'}),
+            'name_pl': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True'}),
+            'order': ('django.db.models.fields.IntegerField', [], {}),
+            'section': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['curriculum.Section']"}),
+            'slug': ('django.db.models.fields.SlugField', [], {'max_length': '50'})
+        },
+        u'curriculum.competencelevel': {
+            'Meta': {'ordering': "['competence', 'level']", 'object_name': 'CompetenceLevel'},
+            'competence': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['curriculum.Competence']"}),
+            'description': ('django.db.models.fields.TextField', [], {}),
+            'description_en': ('django.db.models.fields.TextField', [], {'null': 'True'}),
+            'description_pl': ('django.db.models.fields.TextField', [], {'null': 'True'}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'level': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['curriculum.Level']"})
+        },
+        u'curriculum.curriculum': {
+            'Meta': {'object_name': 'Curriculum'},
+            'course': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['curriculum.CurriculumCourse']"}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'identifier': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}),
+            'level': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['curriculum.CurriculumLevel']"}),
+            'title': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+            'type': ('django.db.models.fields.CharField', [], {'max_length': '16'})
+        },
+        u'curriculum.curriculumcourse': {
+            'Meta': {'ordering': "['slug']", 'object_name': 'CurriculumCourse'},
+            'accusative': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'slug': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}),
+            'title': ('django.db.models.fields.CharField', [], {'max_length': '255'})
+        },
+        u'curriculum.curriculumlevel': {
+            'Meta': {'object_name': 'CurriculumLevel'},
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'title': ('django.db.models.fields.CharField', [], {'max_length': '16', 'db_index': 'True'})
+        },
+        u'curriculum.level': {
+            'Meta': {'ordering': "['order']", 'object_name': 'Level'},
+            'group': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+            'group_en': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True'}),
+            'group_pl': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True'}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+            'name_en': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True'}),
+            'name_pl': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True'}),
+            'order': ('django.db.models.fields.IntegerField', [], {}),
+            'slug': ('django.db.models.fields.CharField', [], {'max_length': '255'})
+        },
+        u'curriculum.section': {
+            'Meta': {'ordering': "['order']", 'object_name': 'Section'},
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+            'name_en': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True'}),
+            'name_pl': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True'}),
+            'order': ('django.db.models.fields.IntegerField', [], {}),
+            'slug': ('django.db.models.fields.SlugField', [], {'max_length': '50'})
+        }
+    }
+
+    complete_apps = ['curriculum']
\ No newline at end of file
diff --git a/src/curriculum/migrations/0007_translatable_fields_data_migration.py b/src/curriculum/migrations/0007_translatable_fields_data_migration.py
new file mode 100644 (file)
index 0000000..f881621
--- /dev/null
@@ -0,0 +1,92 @@
+# -*- coding: utf-8 -*-
+import datetime
+from south.db import db
+from south.v2 import DataMigration
+from django.db import models
+
+class Migration(DataMigration):
+
+    def forwards(self, orm):
+        for section in orm.Section.objects.all():
+            section.name_pl = section.name_en = section.name
+            section.save()
+        for competence in orm.Competence.objects.all():
+            competence.name_pl = competence.name_en = competence.name
+            competence.save()
+        for level in orm.Level.objects.all():
+            level.name_pl = level.name_en = level.name
+            level.group_pl = level.group_en = level.group
+            level.save()
+        for competence_level in orm.CompetenceLevel.objects.all():
+            competence_level.description_pl = competence_level.description_en = competence_level.description
+            competence_level.save()
+
+    def backwards(self, orm):
+        raise RuntimeError("Cannot reverse this migration.")
+
+    models = {
+        u'curriculum.competence': {
+            'Meta': {'ordering': "['section', 'order']", 'object_name': 'Competence'},
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+            'name_en': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True'}),
+            'name_pl': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True'}),
+            'order': ('django.db.models.fields.IntegerField', [], {}),
+            'section': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['curriculum.Section']"}),
+            'slug': ('django.db.models.fields.SlugField', [], {'max_length': '50'})
+        },
+        u'curriculum.competencelevel': {
+            'Meta': {'ordering': "['competence', 'level']", 'object_name': 'CompetenceLevel'},
+            'competence': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['curriculum.Competence']"}),
+            'description': ('django.db.models.fields.TextField', [], {}),
+            'description_en': ('django.db.models.fields.TextField', [], {'null': 'True'}),
+            'description_pl': ('django.db.models.fields.TextField', [], {'null': 'True'}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'level': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['curriculum.Level']"})
+        },
+        u'curriculum.curriculum': {
+            'Meta': {'object_name': 'Curriculum'},
+            'course': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['curriculum.CurriculumCourse']"}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'identifier': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}),
+            'level': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['curriculum.CurriculumLevel']"}),
+            'title': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+            'type': ('django.db.models.fields.CharField', [], {'max_length': '16'})
+        },
+        u'curriculum.curriculumcourse': {
+            'Meta': {'ordering': "['slug']", 'object_name': 'CurriculumCourse'},
+            'accusative': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'slug': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}),
+            'title': ('django.db.models.fields.CharField', [], {'max_length': '255'})
+        },
+        u'curriculum.curriculumlevel': {
+            'Meta': {'object_name': 'CurriculumLevel'},
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'title': ('django.db.models.fields.CharField', [], {'max_length': '16', 'db_index': 'True'})
+        },
+        u'curriculum.level': {
+            'Meta': {'ordering': "['order']", 'object_name': 'Level'},
+            'group': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+            'group_en': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True'}),
+            'group_pl': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True'}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+            'name_en': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True'}),
+            'name_pl': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True'}),
+            'order': ('django.db.models.fields.IntegerField', [], {}),
+            'slug': ('django.db.models.fields.CharField', [], {'max_length': '255'})
+        },
+        u'curriculum.section': {
+            'Meta': {'ordering': "['order']", 'object_name': 'Section'},
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+            'name_en': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True'}),
+            'name_pl': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True'}),
+            'order': ('django.db.models.fields.IntegerField', [], {}),
+            'slug': ('django.db.models.fields.SlugField', [], {'max_length': '50'})
+        }
+    }
+
+    complete_apps = ['curriculum']
+    symmetrical = True
diff --git a/src/curriculum/migrations/0008_auto__del_field_competencelevel_description__del_field_section_name__d.py b/src/curriculum/migrations/0008_auto__del_field_competencelevel_description__del_field_section_name__d.py
new file mode 100644 (file)
index 0000000..4c0a89a
--- /dev/null
@@ -0,0 +1,103 @@
+# -*- coding: utf-8 -*-
+import datetime
+from south.db import db
+from south.v2 import SchemaMigration
+from django.db import models
+
+
+class Migration(SchemaMigration):
+
+    def forwards(self, orm):
+        # Deleting field 'CompetenceLevel.description'
+        db.delete_column(u'curriculum_competencelevel', 'description')
+
+        # Deleting field 'Section.name'
+        db.delete_column(u'curriculum_section', 'name')
+
+        # Deleting field 'Competence.name'
+        db.delete_column(u'curriculum_competence', 'name')
+
+        # Deleting field 'Level.group'
+        db.delete_column(u'curriculum_level', 'group')
+
+        # Deleting field 'Level.name'
+        db.delete_column(u'curriculum_level', 'name')
+
+
+    def backwards(self, orm):
+
+        # User chose to not deal with backwards NULL issues for 'CompetenceLevel.description'
+        raise RuntimeError("Cannot reverse this migration. 'CompetenceLevel.description' and its values cannot be restored.")
+
+        # User chose to not deal with backwards NULL issues for 'Section.name'
+        raise RuntimeError("Cannot reverse this migration. 'Section.name' and its values cannot be restored.")
+
+        # User chose to not deal with backwards NULL issues for 'Competence.name'
+        raise RuntimeError("Cannot reverse this migration. 'Competence.name' and its values cannot be restored.")
+
+        # User chose to not deal with backwards NULL issues for 'Level.group'
+        raise RuntimeError("Cannot reverse this migration. 'Level.group' and its values cannot be restored.")
+
+        # User chose to not deal with backwards NULL issues for 'Level.name'
+        raise RuntimeError("Cannot reverse this migration. 'Level.name' and its values cannot be restored.")
+
+    models = {
+        u'curriculum.competence': {
+            'Meta': {'ordering': "['section', 'order']", 'object_name': 'Competence'},
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'name_en': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True'}),
+            'name_pl': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True'}),
+            'order': ('django.db.models.fields.IntegerField', [], {}),
+            'section': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['curriculum.Section']"}),
+            'slug': ('django.db.models.fields.SlugField', [], {'max_length': '50'})
+        },
+        u'curriculum.competencelevel': {
+            'Meta': {'ordering': "['competence', 'level']", 'object_name': 'CompetenceLevel'},
+            'competence': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['curriculum.Competence']"}),
+            'description_en': ('django.db.models.fields.TextField', [], {'null': 'True'}),
+            'description_pl': ('django.db.models.fields.TextField', [], {'null': 'True'}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'level': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['curriculum.Level']"})
+        },
+        u'curriculum.curriculum': {
+            'Meta': {'object_name': 'Curriculum'},
+            'course': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['curriculum.CurriculumCourse']"}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'identifier': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}),
+            'level': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['curriculum.CurriculumLevel']"}),
+            'title': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+            'type': ('django.db.models.fields.CharField', [], {'max_length': '16'})
+        },
+        u'curriculum.curriculumcourse': {
+            'Meta': {'ordering': "['slug']", 'object_name': 'CurriculumCourse'},
+            'accusative': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'slug': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}),
+            'title': ('django.db.models.fields.CharField', [], {'max_length': '255'})
+        },
+        u'curriculum.curriculumlevel': {
+            'Meta': {'object_name': 'CurriculumLevel'},
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'title': ('django.db.models.fields.CharField', [], {'max_length': '16', 'db_index': 'True'})
+        },
+        u'curriculum.level': {
+            'Meta': {'ordering': "['order']", 'object_name': 'Level'},
+            'group_en': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True'}),
+            'group_pl': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True'}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'name_en': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True'}),
+            'name_pl': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True'}),
+            'order': ('django.db.models.fields.IntegerField', [], {}),
+            'slug': ('django.db.models.fields.CharField', [], {'max_length': '255'})
+        },
+        u'curriculum.section': {
+            'Meta': {'ordering': "['order']", 'object_name': 'Section'},
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'name_en': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True'}),
+            'name_pl': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True'}),
+            'order': ('django.db.models.fields.IntegerField', [], {}),
+            'slug': ('django.db.models.fields.SlugField', [], {'max_length': '50'})
+        }
+    }
+
+    complete_apps = ['curriculum']
\ No newline at end of file
diff --git a/src/curriculum/migrations/0009_auto__chg_field_competencelevel_description_en__chg_field_competencele.py b/src/curriculum/migrations/0009_auto__chg_field_competencelevel_description_en__chg_field_competencele.py
new file mode 100644 (file)
index 0000000..4fbdde5
--- /dev/null
@@ -0,0 +1,133 @@
+# -*- coding: utf-8 -*-
+import datetime
+from south.db import db
+from south.v2 import SchemaMigration
+from django.db import models
+
+
+class Migration(SchemaMigration):
+
+    def forwards(self, orm):
+
+        # Changing field 'CompetenceLevel.description_en'
+        db.alter_column(u'curriculum_competencelevel', 'description_en', self.gf('django.db.models.fields.TextField')())
+
+        # Changing field 'CompetenceLevel.description_pl'
+        db.alter_column(u'curriculum_competencelevel', 'description_pl', self.gf('django.db.models.fields.TextField')())
+
+        # Changing field 'Section.name_en'
+        db.alter_column(u'curriculum_section', 'name_en', self.gf('django.db.models.fields.CharField')(max_length=255))
+
+        # Changing field 'Section.name_pl'
+        db.alter_column(u'curriculum_section', 'name_pl', self.gf('django.db.models.fields.CharField')(max_length=255))
+
+        # Changing field 'Competence.name_pl'
+        db.alter_column(u'curriculum_competence', 'name_pl', self.gf('django.db.models.fields.CharField')(max_length=255))
+
+        # Changing field 'Competence.name_en'
+        db.alter_column(u'curriculum_competence', 'name_en', self.gf('django.db.models.fields.CharField')(max_length=255))
+
+        # Changing field 'Level.name_pl'
+        db.alter_column(u'curriculum_level', 'name_pl', self.gf('django.db.models.fields.CharField')(max_length=255))
+
+        # Changing field 'Level.group_pl'
+        db.alter_column(u'curriculum_level', 'group_pl', self.gf('django.db.models.fields.CharField')(max_length=255))
+
+        # Changing field 'Level.group_en'
+        db.alter_column(u'curriculum_level', 'group_en', self.gf('django.db.models.fields.CharField')(max_length=255))
+
+        # Changing field 'Level.name_en'
+        db.alter_column(u'curriculum_level', 'name_en', self.gf('django.db.models.fields.CharField')(max_length=255))
+
+    def backwards(self, orm):
+
+        # Changing field 'CompetenceLevel.description_en'
+        db.alter_column(u'curriculum_competencelevel', 'description_en', self.gf('django.db.models.fields.TextField')(null=True))
+
+        # Changing field 'CompetenceLevel.description_pl'
+        db.alter_column(u'curriculum_competencelevel', 'description_pl', self.gf('django.db.models.fields.TextField')(null=True))
+
+        # Changing field 'Section.name_en'
+        db.alter_column(u'curriculum_section', 'name_en', self.gf('django.db.models.fields.CharField')(max_length=255, null=True))
+
+        # Changing field 'Section.name_pl'
+        db.alter_column(u'curriculum_section', 'name_pl', self.gf('django.db.models.fields.CharField')(max_length=255, null=True))
+
+        # Changing field 'Competence.name_pl'
+        db.alter_column(u'curriculum_competence', 'name_pl', self.gf('django.db.models.fields.CharField')(max_length=255, null=True))
+
+        # Changing field 'Competence.name_en'
+        db.alter_column(u'curriculum_competence', 'name_en', self.gf('django.db.models.fields.CharField')(max_length=255, null=True))
+
+        # Changing field 'Level.name_pl'
+        db.alter_column(u'curriculum_level', 'name_pl', self.gf('django.db.models.fields.CharField')(max_length=255, null=True))
+
+        # Changing field 'Level.group_pl'
+        db.alter_column(u'curriculum_level', 'group_pl', self.gf('django.db.models.fields.CharField')(max_length=255, null=True))
+
+        # Changing field 'Level.group_en'
+        db.alter_column(u'curriculum_level', 'group_en', self.gf('django.db.models.fields.CharField')(max_length=255, null=True))
+
+        # Changing field 'Level.name_en'
+        db.alter_column(u'curriculum_level', 'name_en', self.gf('django.db.models.fields.CharField')(max_length=255, null=True))
+
+    models = {
+        u'curriculum.competence': {
+            'Meta': {'ordering': "['section', 'order']", 'object_name': 'Competence'},
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'name_en': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
+            'name_pl': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
+            'order': ('django.db.models.fields.IntegerField', [], {}),
+            'section': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['curriculum.Section']"}),
+            'slug': ('django.db.models.fields.SlugField', [], {'max_length': '50'})
+        },
+        u'curriculum.competencelevel': {
+            'Meta': {'ordering': "['competence', 'level']", 'object_name': 'CompetenceLevel'},
+            'competence': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['curriculum.Competence']"}),
+            'description_en': ('django.db.models.fields.TextField', [], {'default': "''"}),
+            'description_pl': ('django.db.models.fields.TextField', [], {'default': "''"}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'level': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['curriculum.Level']"})
+        },
+        u'curriculum.curriculum': {
+            'Meta': {'object_name': 'Curriculum'},
+            'course': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['curriculum.CurriculumCourse']"}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'identifier': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}),
+            'level': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['curriculum.CurriculumLevel']"}),
+            'title': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+            'type': ('django.db.models.fields.CharField', [], {'max_length': '16'})
+        },
+        u'curriculum.curriculumcourse': {
+            'Meta': {'ordering': "['slug']", 'object_name': 'CurriculumCourse'},
+            'accusative': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'slug': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}),
+            'title': ('django.db.models.fields.CharField', [], {'max_length': '255'})
+        },
+        u'curriculum.curriculumlevel': {
+            'Meta': {'object_name': 'CurriculumLevel'},
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'title': ('django.db.models.fields.CharField', [], {'max_length': '16', 'db_index': 'True'})
+        },
+        u'curriculum.level': {
+            'Meta': {'ordering': "['order']", 'object_name': 'Level'},
+            'group_en': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
+            'group_pl': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'name_en': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
+            'name_pl': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
+            'order': ('django.db.models.fields.IntegerField', [], {}),
+            'slug': ('django.db.models.fields.CharField', [], {'max_length': '255'})
+        },
+        u'curriculum.section': {
+            'Meta': {'ordering': "['order']", 'object_name': 'Section'},
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'name_en': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
+            'name_pl': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
+            'order': ('django.db.models.fields.IntegerField', [], {}),
+            'slug': ('django.db.models.fields.SlugField', [], {'max_length': '50'})
+        }
+    }
+
+    complete_apps = ['curriculum']
\ No newline at end of file
diff --git a/src/curriculum/migrations/0010_auto__add_field_level_meta_name.py b/src/curriculum/migrations/0010_auto__add_field_level_meta_name.py
new file mode 100644 (file)
index 0000000..24fc996
--- /dev/null
@@ -0,0 +1,82 @@
+# -*- coding: utf-8 -*-
+import datetime
+from south.db import db
+from south.v2 import SchemaMigration
+from django.db import models
+
+
+class Migration(SchemaMigration):
+
+    def forwards(self, orm):
+        # Adding field 'Level.meta_name'
+        db.add_column(u'curriculum_level', 'meta_name',
+                      self.gf('django.db.models.fields.CharField')(default=' ', max_length=255),
+                      keep_default=False)
+
+
+    def backwards(self, orm):
+        # Deleting field 'Level.meta_name'
+        db.delete_column(u'curriculum_level', 'meta_name')
+
+
+    models = {
+        u'curriculum.competence': {
+            'Meta': {'ordering': "['section', 'order']", 'object_name': 'Competence'},
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'name_en': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
+            'name_pl': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
+            'order': ('django.db.models.fields.IntegerField', [], {}),
+            'section': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['curriculum.Section']"}),
+            'slug': ('django.db.models.fields.SlugField', [], {'max_length': '50'})
+        },
+        u'curriculum.competencelevel': {
+            'Meta': {'ordering': "['competence', 'level']", 'object_name': 'CompetenceLevel'},
+            'competence': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['curriculum.Competence']"}),
+            'description_en': ('django.db.models.fields.TextField', [], {'default': "''"}),
+            'description_pl': ('django.db.models.fields.TextField', [], {'default': "''"}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'level': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['curriculum.Level']"})
+        },
+        u'curriculum.curriculum': {
+            'Meta': {'object_name': 'Curriculum'},
+            'course': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['curriculum.CurriculumCourse']"}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'identifier': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}),
+            'level': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['curriculum.CurriculumLevel']"}),
+            'title': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+            'type': ('django.db.models.fields.CharField', [], {'max_length': '16'})
+        },
+        u'curriculum.curriculumcourse': {
+            'Meta': {'ordering': "['slug']", 'object_name': 'CurriculumCourse'},
+            'accusative': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'slug': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}),
+            'title': ('django.db.models.fields.CharField', [], {'max_length': '255'})
+        },
+        u'curriculum.curriculumlevel': {
+            'Meta': {'object_name': 'CurriculumLevel'},
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'title': ('django.db.models.fields.CharField', [], {'max_length': '16', 'db_index': 'True'})
+        },
+        u'curriculum.level': {
+            'Meta': {'ordering': "['order']", 'object_name': 'Level'},
+            'group_en': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
+            'group_pl': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'meta_name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+            'name_en': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
+            'name_pl': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
+            'order': ('django.db.models.fields.IntegerField', [], {}),
+            'slug': ('django.db.models.fields.CharField', [], {'max_length': '255'})
+        },
+        u'curriculum.section': {
+            'Meta': {'ordering': "['order']", 'object_name': 'Section'},
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'name_en': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
+            'name_pl': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
+            'order': ('django.db.models.fields.IntegerField', [], {}),
+            'slug': ('django.db.models.fields.SlugField', [], {'max_length': '50'})
+        }
+    }
+
+    complete_apps = ['curriculum']
\ No newline at end of file
diff --git a/src/curriculum/migrations/0011_meta_name.py b/src/curriculum/migrations/0011_meta_name.py
new file mode 100644 (file)
index 0000000..0539ae7
--- /dev/null
@@ -0,0 +1,77 @@
+# -*- coding: utf-8 -*-
+import datetime
+from south.db import db
+from south.v2 import DataMigration
+from django.db import models
+
+class Migration(DataMigration):
+
+    def forwards(self, orm):
+        "Write your forwards methods here."
+        orm.Level.objects.all().update(meta_name=models.F('slug'))
+
+    def backwards(self, orm):
+        "Write your backwards methods here."
+
+    models = {
+        u'curriculum.competence': {
+            'Meta': {'ordering': "['section', 'order']", 'object_name': 'Competence'},
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'name_en': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
+            'name_pl': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
+            'order': ('django.db.models.fields.IntegerField', [], {}),
+            'section': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['curriculum.Section']"}),
+            'slug': ('django.db.models.fields.SlugField', [], {'max_length': '50'})
+        },
+        u'curriculum.competencelevel': {
+            'Meta': {'ordering': "['competence', 'level']", 'object_name': 'CompetenceLevel'},
+            'competence': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['curriculum.Competence']"}),
+            'description_en': ('django.db.models.fields.TextField', [], {'default': "''"}),
+            'description_pl': ('django.db.models.fields.TextField', [], {'default': "''"}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'level': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['curriculum.Level']"})
+        },
+        u'curriculum.curriculum': {
+            'Meta': {'object_name': 'Curriculum'},
+            'course': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['curriculum.CurriculumCourse']"}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'identifier': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}),
+            'level': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['curriculum.CurriculumLevel']"}),
+            'title': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+            'type': ('django.db.models.fields.CharField', [], {'max_length': '16'})
+        },
+        u'curriculum.curriculumcourse': {
+            'Meta': {'ordering': "['slug']", 'object_name': 'CurriculumCourse'},
+            'accusative': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'slug': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}),
+            'title': ('django.db.models.fields.CharField', [], {'max_length': '255'})
+        },
+        u'curriculum.curriculumlevel': {
+            'Meta': {'object_name': 'CurriculumLevel'},
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'title': ('django.db.models.fields.CharField', [], {'max_length': '16', 'db_index': 'True'})
+        },
+        u'curriculum.level': {
+            'Meta': {'ordering': "['order']", 'object_name': 'Level'},
+            'group_en': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
+            'group_pl': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'meta_name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+            'name_en': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
+            'name_pl': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
+            'order': ('django.db.models.fields.IntegerField', [], {}),
+            'slug': ('django.db.models.fields.CharField', [], {'max_length': '255'})
+        },
+        u'curriculum.section': {
+            'Meta': {'ordering': "['order']", 'object_name': 'Section'},
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'name_en': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
+            'name_pl': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
+            'order': ('django.db.models.fields.IntegerField', [], {}),
+            'slug': ('django.db.models.fields.SlugField', [], {'max_length': '50'})
+        }
+    }
+
+    complete_apps = ['curriculum']
+    symmetrical = True
diff --git a/src/curriculum/migrations/0012_auto__add_unique_level_meta_name__add_unique_level_slug.py b/src/curriculum/migrations/0012_auto__add_unique_level_meta_name__add_unique_level_slug.py
new file mode 100644 (file)
index 0000000..f9fa032
--- /dev/null
@@ -0,0 +1,86 @@
+# -*- coding: utf-8 -*-
+import datetime
+from south.db import db
+from south.v2 import SchemaMigration
+from django.db import models
+
+
+class Migration(SchemaMigration):
+
+    def forwards(self, orm):
+        # Adding unique constraint on 'Level', fields ['meta_name']
+        db.create_unique(u'curriculum_level', ['meta_name'])
+
+        # Adding unique constraint on 'Level', fields ['slug']
+        db.create_unique(u'curriculum_level', ['slug'])
+
+
+    def backwards(self, orm):
+        # Removing unique constraint on 'Level', fields ['slug']
+        db.delete_unique(u'curriculum_level', ['slug'])
+
+        # Removing unique constraint on 'Level', fields ['meta_name']
+        db.delete_unique(u'curriculum_level', ['meta_name'])
+
+
+    models = {
+        u'curriculum.competence': {
+            'Meta': {'ordering': "['section', 'order']", 'object_name': 'Competence'},
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'name_en': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
+            'name_pl': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
+            'order': ('django.db.models.fields.IntegerField', [], {}),
+            'section': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['curriculum.Section']"}),
+            'slug': ('django.db.models.fields.SlugField', [], {'max_length': '50'})
+        },
+        u'curriculum.competencelevel': {
+            'Meta': {'ordering': "['competence', 'level']", 'object_name': 'CompetenceLevel'},
+            'competence': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['curriculum.Competence']"}),
+            'description_en': ('django.db.models.fields.TextField', [], {'default': "''"}),
+            'description_pl': ('django.db.models.fields.TextField', [], {'default': "''"}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'level': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['curriculum.Level']"})
+        },
+        u'curriculum.curriculum': {
+            'Meta': {'object_name': 'Curriculum'},
+            'course': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['curriculum.CurriculumCourse']"}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'identifier': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}),
+            'level': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['curriculum.CurriculumLevel']"}),
+            'title': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+            'type': ('django.db.models.fields.CharField', [], {'max_length': '16'})
+        },
+        u'curriculum.curriculumcourse': {
+            'Meta': {'ordering': "['slug']", 'object_name': 'CurriculumCourse'},
+            'accusative': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'slug': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}),
+            'title': ('django.db.models.fields.CharField', [], {'max_length': '255'})
+        },
+        u'curriculum.curriculumlevel': {
+            'Meta': {'object_name': 'CurriculumLevel'},
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'title': ('django.db.models.fields.CharField', [], {'max_length': '16', 'db_index': 'True'})
+        },
+        u'curriculum.level': {
+            'Meta': {'ordering': "['order']", 'object_name': 'Level'},
+            'group_en': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
+            'group_pl': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'meta_name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'}),
+            'name_en': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
+            'name_pl': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
+            'order': ('django.db.models.fields.IntegerField', [], {}),
+            'slug': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'})
+        },
+        u'curriculum.section': {
+            'Meta': {'ordering': "['order']", 'object_name': 'Section'},
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'name_en': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
+            'name_pl': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
+            'order': ('django.db.models.fields.IntegerField', [], {}),
+            'slug': ('django.db.models.fields.SlugField', [], {'max_length': '50'})
+        }
+    }
+
+    complete_apps = ['curriculum']
\ No newline at end of file
diff --git a/src/curriculum/migrations/0013_auto__add_field_level_package__add_field_level_student_package.py b/src/curriculum/migrations/0013_auto__add_field_level_package__add_field_level_student_package.py
new file mode 100644 (file)
index 0000000..4e0ee70
--- /dev/null
@@ -0,0 +1,92 @@
+# -*- coding: utf-8 -*-
+import datetime
+from south.db import db
+from south.v2 import SchemaMigration
+from django.db import models
+
+
+class Migration(SchemaMigration):
+
+    def forwards(self, orm):
+        # Adding field 'Level.package'
+        db.add_column(u'curriculum_level', 'package',
+                      self.gf('django.db.models.fields.files.FileField')(max_length=255, null=True, blank=True),
+                      keep_default=False)
+
+        # Adding field 'Level.student_package'
+        db.add_column(u'curriculum_level', 'student_package',
+                      self.gf('django.db.models.fields.files.FileField')(max_length=255, null=True, blank=True),
+                      keep_default=False)
+
+
+    def backwards(self, orm):
+        # Deleting field 'Level.package'
+        db.delete_column(u'curriculum_level', 'package')
+
+        # Deleting field 'Level.student_package'
+        db.delete_column(u'curriculum_level', 'student_package')
+
+
+    models = {
+        u'curriculum.competence': {
+            'Meta': {'ordering': "['section', 'order']", 'object_name': 'Competence'},
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'name_en': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
+            'name_pl': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
+            'order': ('django.db.models.fields.IntegerField', [], {}),
+            'section': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['curriculum.Section']"}),
+            'slug': ('django.db.models.fields.SlugField', [], {'max_length': '50'})
+        },
+        u'curriculum.competencelevel': {
+            'Meta': {'ordering': "['competence', 'level']", 'object_name': 'CompetenceLevel'},
+            'competence': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['curriculum.Competence']"}),
+            'description_en': ('django.db.models.fields.TextField', [], {'default': "''"}),
+            'description_pl': ('django.db.models.fields.TextField', [], {'default': "''"}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'level': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['curriculum.Level']"})
+        },
+        u'curriculum.curriculum': {
+            'Meta': {'object_name': 'Curriculum'},
+            'course': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['curriculum.CurriculumCourse']"}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'identifier': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}),
+            'level': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['curriculum.CurriculumLevel']"}),
+            'title': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+            'type': ('django.db.models.fields.CharField', [], {'max_length': '16'})
+        },
+        u'curriculum.curriculumcourse': {
+            'Meta': {'ordering': "['slug']", 'object_name': 'CurriculumCourse'},
+            'accusative': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'slug': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}),
+            'title': ('django.db.models.fields.CharField', [], {'max_length': '255'})
+        },
+        u'curriculum.curriculumlevel': {
+            'Meta': {'object_name': 'CurriculumLevel'},
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'title': ('django.db.models.fields.CharField', [], {'max_length': '16', 'db_index': 'True'})
+        },
+        u'curriculum.level': {
+            'Meta': {'ordering': "['order']", 'object_name': 'Level'},
+            'group_en': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
+            'group_pl': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'meta_name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'}),
+            'name_en': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
+            'name_pl': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
+            'order': ('django.db.models.fields.IntegerField', [], {}),
+            'package': ('django.db.models.fields.files.FileField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
+            'slug': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'}),
+            'student_package': ('django.db.models.fields.files.FileField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'})
+        },
+        u'curriculum.section': {
+            'Meta': {'ordering': "['order']", 'object_name': 'Section'},
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'name_en': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
+            'name_pl': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
+            'order': ('django.db.models.fields.IntegerField', [], {}),
+            'slug': ('django.db.models.fields.SlugField', [], {'max_length': '50'})
+        }
+    }
+
+    complete_apps = ['curriculum']
\ No newline at end of file
diff --git a/src/curriculum/migrations/0014_auto__add_unique_curriculum_identifier.py b/src/curriculum/migrations/0014_auto__add_unique_curriculum_identifier.py
new file mode 100644 (file)
index 0000000..4c85c7e
--- /dev/null
@@ -0,0 +1,82 @@
+# -*- coding: utf-8 -*-
+from south.utils import datetime_utils as datetime
+from south.db import db
+from south.v2 import SchemaMigration
+from django.db import models
+
+
+class Migration(SchemaMigration):
+
+    def forwards(self, orm):
+        # Adding unique constraint on 'Curriculum', fields ['identifier']
+        db.create_unique(u'curriculum_curriculum', ['identifier'])
+
+
+    def backwards(self, orm):
+        # Removing unique constraint on 'Curriculum', fields ['identifier']
+        db.delete_unique(u'curriculum_curriculum', ['identifier'])
+
+
+    models = {
+        u'curriculum.competence': {
+            'Meta': {'ordering': "['section', 'order']", 'object_name': 'Competence'},
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'name_en': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
+            'name_pl': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
+            'order': ('django.db.models.fields.IntegerField', [], {}),
+            'section': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['curriculum.Section']"}),
+            'slug': ('django.db.models.fields.SlugField', [], {'max_length': '50'})
+        },
+        u'curriculum.competencelevel': {
+            'Meta': {'ordering': "['competence', 'level']", 'object_name': 'CompetenceLevel'},
+            'competence': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['curriculum.Competence']"}),
+            'description_en': ('django.db.models.fields.TextField', [], {'default': "''"}),
+            'description_pl': ('django.db.models.fields.TextField', [], {'default': "''"}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'level': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['curriculum.Level']"})
+        },
+        u'curriculum.curriculum': {
+            'Meta': {'ordering': "['identifier']", 'object_name': 'Curriculum'},
+            'course': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['curriculum.CurriculumCourse']"}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'identifier': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255', 'db_index': 'True'}),
+            'level': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['curriculum.CurriculumLevel']"}),
+            'title': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+            'type': ('django.db.models.fields.CharField', [], {'max_length': '16'})
+        },
+        u'curriculum.curriculumcourse': {
+            'Meta': {'ordering': "['slug']", 'object_name': 'CurriculumCourse'},
+            'accusative': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'slug': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}),
+            'title': ('django.db.models.fields.CharField', [], {'max_length': '255'})
+        },
+        u'curriculum.curriculumlevel': {
+            'Meta': {'object_name': 'CurriculumLevel'},
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'title': ('django.db.models.fields.CharField', [], {'max_length': '16', 'db_index': 'True'})
+        },
+        u'curriculum.level': {
+            'Meta': {'ordering': "['order']", 'object_name': 'Level'},
+            'group_en': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
+            'group_pl': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'meta_name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'}),
+            'name_en': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
+            'name_pl': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
+            'order': ('django.db.models.fields.IntegerField', [], {}),
+            'package': ('django.db.models.fields.files.FileField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
+            'slug': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'}),
+            'student_package': ('django.db.models.fields.files.FileField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'})
+        },
+        u'curriculum.section': {
+            'Meta': {'ordering': "['order']", 'object_name': 'Section'},
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'name_en': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
+            'name_pl': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
+            'order': ('django.db.models.fields.IntegerField', [], {}),
+            'slug': ('django.db.models.fields.SlugField', [], {'max_length': '50'})
+        }
+    }
+
+    complete_apps = ['curriculum']
\ No newline at end of file
diff --git a/src/curriculum/migrations/0015_auto__chg_field_curriculum_title.py b/src/curriculum/migrations/0015_auto__chg_field_curriculum_title.py
new file mode 100644 (file)
index 0000000..3100293
--- /dev/null
@@ -0,0 +1,82 @@
+# -*- coding: utf-8 -*-
+from south.utils import datetime_utils as datetime
+from south.db import db
+from south.v2 import SchemaMigration
+from django.db import models
+
+
+class Migration(SchemaMigration):
+
+    def forwards(self, orm):
+
+        # Changing field 'Curriculum.title'
+        db.alter_column(u'curriculum_curriculum', 'title', self.gf('django.db.models.fields.CharField')(max_length=1024))
+
+    def backwards(self, orm):
+
+        # Changing field 'Curriculum.title'
+        db.alter_column(u'curriculum_curriculum', 'title', self.gf('django.db.models.fields.CharField')(max_length=255))
+
+    models = {
+        u'curriculum.competence': {
+            'Meta': {'ordering': "['section', 'order']", 'object_name': 'Competence'},
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'name_en': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
+            'name_pl': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
+            'order': ('django.db.models.fields.IntegerField', [], {}),
+            'section': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['curriculum.Section']"}),
+            'slug': ('django.db.models.fields.SlugField', [], {'max_length': '50'})
+        },
+        u'curriculum.competencelevel': {
+            'Meta': {'ordering': "['competence', 'level']", 'object_name': 'CompetenceLevel'},
+            'competence': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['curriculum.Competence']"}),
+            'description_en': ('django.db.models.fields.TextField', [], {'default': "''"}),
+            'description_pl': ('django.db.models.fields.TextField', [], {'default': "''"}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'level': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['curriculum.Level']"})
+        },
+        u'curriculum.curriculum': {
+            'Meta': {'ordering': "['identifier']", 'object_name': 'Curriculum'},
+            'course': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['curriculum.CurriculumCourse']"}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'identifier': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255', 'db_index': 'True'}),
+            'level': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['curriculum.CurriculumLevel']"}),
+            'title': ('django.db.models.fields.CharField', [], {'max_length': '1024'}),
+            'type': ('django.db.models.fields.CharField', [], {'max_length': '16'})
+        },
+        u'curriculum.curriculumcourse': {
+            'Meta': {'ordering': "['slug']", 'object_name': 'CurriculumCourse'},
+            'accusative': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'slug': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}),
+            'title': ('django.db.models.fields.CharField', [], {'max_length': '255'})
+        },
+        u'curriculum.curriculumlevel': {
+            'Meta': {'object_name': 'CurriculumLevel'},
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'title': ('django.db.models.fields.CharField', [], {'max_length': '16', 'db_index': 'True'})
+        },
+        u'curriculum.level': {
+            'Meta': {'ordering': "['order']", 'object_name': 'Level'},
+            'group_en': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
+            'group_pl': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'meta_name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'}),
+            'name_en': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
+            'name_pl': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
+            'order': ('django.db.models.fields.IntegerField', [], {}),
+            'package': ('django.db.models.fields.files.FileField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
+            'slug': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'}),
+            'student_package': ('django.db.models.fields.files.FileField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'})
+        },
+        u'curriculum.section': {
+            'Meta': {'ordering': "['order']", 'object_name': 'Section'},
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'name_en': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
+            'name_pl': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
+            'order': ('django.db.models.fields.IntegerField', [], {}),
+            'slug': ('django.db.models.fields.SlugField', [], {'max_length': '50'})
+        }
+    }
+
+    complete_apps = ['curriculum']
\ No newline at end of file
diff --git a/src/curriculum/migrations/0016_auto__add_field_curriculumlevel_verbose.py b/src/curriculum/migrations/0016_auto__add_field_curriculumlevel_verbose.py
new file mode 100644 (file)
index 0000000..d60b155
--- /dev/null
@@ -0,0 +1,85 @@
+# -*- coding: utf-8 -*-
+from south.utils import datetime_utils as datetime
+from south.db import db
+from south.v2 import SchemaMigration
+from django.db import models
+
+
+class Migration(SchemaMigration):
+
+    def forwards(self, orm):
+        # Adding field 'CurriculumLevel.verbose'
+        db.add_column(u'curriculum_curriculumlevel', 'verbose',
+                      self.gf('django.db.models.fields.CharField')(default='', max_length=32),
+                      keep_default=False)
+
+
+    def backwards(self, orm):
+        # Deleting field 'CurriculumLevel.verbose'
+        db.delete_column(u'curriculum_curriculumlevel', 'verbose')
+
+
+    models = {
+        u'curriculum.competence': {
+            'Meta': {'ordering': "['section', 'order']", 'object_name': 'Competence'},
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'name_en': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
+            'name_pl': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
+            'order': ('django.db.models.fields.IntegerField', [], {}),
+            'section': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['curriculum.Section']"}),
+            'slug': ('django.db.models.fields.SlugField', [], {'max_length': '50'})
+        },
+        u'curriculum.competencelevel': {
+            'Meta': {'ordering': "['competence', 'level']", 'object_name': 'CompetenceLevel'},
+            'competence': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['curriculum.Competence']"}),
+            'description_en': ('django.db.models.fields.TextField', [], {'default': "''"}),
+            'description_pl': ('django.db.models.fields.TextField', [], {'default': "''"}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'level': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['curriculum.Level']"})
+        },
+        u'curriculum.curriculum': {
+            'Meta': {'ordering': "['identifier']", 'object_name': 'Curriculum'},
+            'course': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['curriculum.CurriculumCourse']"}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'identifier': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255', 'db_index': 'True'}),
+            'level': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['curriculum.CurriculumLevel']"}),
+            'title': ('django.db.models.fields.CharField', [], {'max_length': '1024'}),
+            'type': ('django.db.models.fields.CharField', [], {'max_length': '16'})
+        },
+        u'curriculum.curriculumcourse': {
+            'Meta': {'ordering': "['slug']", 'object_name': 'CurriculumCourse'},
+            'accusative': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'slug': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}),
+            'title': ('django.db.models.fields.CharField', [], {'max_length': '255'})
+        },
+        u'curriculum.curriculumlevel': {
+            'Meta': {'object_name': 'CurriculumLevel'},
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'title': ('django.db.models.fields.CharField', [], {'max_length': '16', 'db_index': 'True'}),
+            'verbose': ('django.db.models.fields.CharField', [], {'max_length': '32'})
+        },
+        u'curriculum.level': {
+            'Meta': {'ordering': "['order']", 'object_name': 'Level'},
+            'group_en': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
+            'group_pl': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'meta_name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'}),
+            'name_en': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
+            'name_pl': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
+            'order': ('django.db.models.fields.IntegerField', [], {}),
+            'package': ('django.db.models.fields.files.FileField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
+            'slug': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'}),
+            'student_package': ('django.db.models.fields.files.FileField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'})
+        },
+        u'curriculum.section': {
+            'Meta': {'ordering': "['order']", 'object_name': 'Section'},
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'name_en': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
+            'name_pl': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
+            'order': ('django.db.models.fields.IntegerField', [], {}),
+            'slug': ('django.db.models.fields.SlugField', [], {'max_length': '50'})
+        }
+    }
+
+    complete_apps = ['curriculum']
\ No newline at end of file
diff --git a/src/curriculum/migrations/0017_verbose_level.py b/src/curriculum/migrations/0017_verbose_level.py
new file mode 100644 (file)
index 0000000..c6a10a0
--- /dev/null
@@ -0,0 +1,95 @@
+# -*- coding: utf-8 -*-
+from south.utils import datetime_utils as datetime
+from south.db import db
+from south.v2 import DataMigration
+from django.db import models
+
+
+KLASA = ['I-III', 'IV-VI', 'VII-VIII', 'IV-VIII']
+POZIOM = ['O', 'I', 'II', 'III', 'IV']
+OTHER = {
+    'LO': 'liceum i technikum',
+}
+
+
+class Migration(DataMigration):
+
+    def forwards(self, orm):
+        for level in orm.CurriculumLevel.objects.all():
+            if level.title in KLASA:
+                level.verbose = '%s klasa' % level.title
+            elif level.title in POZIOM:
+                level.verbose = '%s poziom edukacyjny' % level.title
+            elif level.title in OTHER:
+                level.verbose = OTHER[level.title]
+            else:
+                raise ValueError('Unknown level')
+            level.save()
+
+    def backwards(self, orm):
+        pass
+
+    models = {
+        u'curriculum.competence': {
+            'Meta': {'ordering': "['section', 'order']", 'object_name': 'Competence'},
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'name_en': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
+            'name_pl': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
+            'order': ('django.db.models.fields.IntegerField', [], {}),
+            'section': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['curriculum.Section']"}),
+            'slug': ('django.db.models.fields.SlugField', [], {'max_length': '50'})
+        },
+        u'curriculum.competencelevel': {
+            'Meta': {'ordering': "['competence', 'level']", 'object_name': 'CompetenceLevel'},
+            'competence': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['curriculum.Competence']"}),
+            'description_en': ('django.db.models.fields.TextField', [], {'default': "''"}),
+            'description_pl': ('django.db.models.fields.TextField', [], {'default': "''"}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'level': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['curriculum.Level']"})
+        },
+        u'curriculum.curriculum': {
+            'Meta': {'ordering': "['identifier']", 'object_name': 'Curriculum'},
+            'course': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['curriculum.CurriculumCourse']"}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'identifier': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255', 'db_index': 'True'}),
+            'level': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['curriculum.CurriculumLevel']"}),
+            'title': ('django.db.models.fields.CharField', [], {'max_length': '1024'}),
+            'type': ('django.db.models.fields.CharField', [], {'max_length': '16'})
+        },
+        u'curriculum.curriculumcourse': {
+            'Meta': {'ordering': "['slug']", 'object_name': 'CurriculumCourse'},
+            'accusative': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'slug': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}),
+            'title': ('django.db.models.fields.CharField', [], {'max_length': '255'})
+        },
+        u'curriculum.curriculumlevel': {
+            'Meta': {'object_name': 'CurriculumLevel'},
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'title': ('django.db.models.fields.CharField', [], {'max_length': '16', 'db_index': 'True'}),
+            'verbose': ('django.db.models.fields.CharField', [], {'max_length': '32'})
+        },
+        u'curriculum.level': {
+            'Meta': {'ordering': "['order']", 'object_name': 'Level'},
+            'group_en': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
+            'group_pl': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'meta_name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'}),
+            'name_en': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
+            'name_pl': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
+            'order': ('django.db.models.fields.IntegerField', [], {}),
+            'package': ('django.db.models.fields.files.FileField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
+            'slug': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'}),
+            'student_package': ('django.db.models.fields.files.FileField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'})
+        },
+        u'curriculum.section': {
+            'Meta': {'ordering': "['order']", 'object_name': 'Section'},
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'name_en': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
+            'name_pl': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
+            'order': ('django.db.models.fields.IntegerField', [], {}),
+            'slug': ('django.db.models.fields.SlugField', [], {'max_length': '50'})
+        }
+    }
+
+    complete_apps = ['curriculum']
\ No newline at end of file
diff --git a/src/curriculum/migrations/__init__.py b/src/curriculum/migrations/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/src/curriculum/models.py b/src/curriculum/models.py
new file mode 100644 (file)
index 0000000..0c3acb2
--- /dev/null
@@ -0,0 +1,242 @@
+# -*- coding: utf-8
+import re
+from django.core.urlresolvers import reverse
+from django.db import models
+from django.utils.translation import ugettext_lazy as _, get_language
+from fnpdjango.storage import BofhFileSystemStorage
+from fnpdjango.utils.models.translation import add_translatable
+from fnpdjango.utils.text.slughifi import slughifi as slugify
+
+bofh_storage = BofhFileSystemStorage()
+
+
+class Section(models.Model):
+    slug = models.SlugField(_('slug'))
+    order = models.IntegerField(_('order'))
+
+    class Meta:
+        ordering = ['order']
+        verbose_name = _('section')
+        verbose_name_plural = _('sections')
+
+    def __unicode__(self):
+        return self.name
+
+    def get_absolute_url(self):
+        return "%s?s=%d" % (reverse("curriculum"), self.pk)
+
+    def url_for_level(self, level):
+        return "%s?s=%d&level=%s&d=1" % (reverse("curriculum"), self.pk, level.slug)
+
+add_translatable(Section, {
+    'name': models.CharField(_('name'), max_length=255, default='')
+})
+
+
+class Competence(models.Model):
+    section = models.ForeignKey(Section)
+    slug = models.SlugField(_('slug'))
+    order = models.IntegerField(_('order'))
+
+    class Meta:
+        ordering = ['section', 'order']
+        verbose_name = _('competence')
+        verbose_name_plural = _('competences')
+
+    def __unicode__(self):
+        return self.name
+
+    def get_absolute_url(self):
+        return "%s?c=%d" % (reverse("curriculum"), self.pk)
+
+    def for_level(self, level):
+        return self.competencelevel_set.get(level=level)
+
+    def url_for_level(self, level):
+        return self.for_level(level).get_absolute_url()
+
+    @classmethod
+    def from_text(cls, text):
+        """Tries to return a Competence or a Section."""
+        parts = re.split(ur'[-\u2013]', text, 1)
+        lookup_field_name = 'name_%s__iexact' % get_language()
+        if len(parts) == 1:
+            return Section.objects.get(**{lookup_field_name: text.strip()})
+        else:
+            return cls.objects.get(**{lookup_field_name: parts[1].strip()})
+
+add_translatable(Competence, {
+    'name': models.CharField(_('name'), max_length=255, default='')
+})
+
+
+class Level(models.Model):
+    slug = models.CharField(_('slug'), max_length=255, unique=True)
+    meta_name = models.CharField(_('meta name'), max_length=255, unique=True)
+    order = models.IntegerField(_('order'))
+    package = models.FileField(
+        upload_to=lambda i, f: "curriculum/pack/edukacjamedialna_%s.zip" % i.slug,
+        null=True, blank=True, max_length=255, storage=bofh_storage)
+    student_package = models.FileField(
+        upload_to=lambda i, f: "curriculum/pack/edukacjamedialna_%s_uczen.zip" % i.slug,
+        null=True, blank=True, max_length=255, storage=bofh_storage)
+
+    class Meta:
+        ordering = ['order']
+        verbose_name = _('educational level')
+        verbose_name_plural = _('educational levels')
+
+    def __unicode__(self):
+        return self.name
+
+    def length_course(self):
+        return self.lesson_set.filter(type='course').count()
+
+    def length_synthetic(self):
+        return self.lesson_set.filter(type='synthetic').count()
+
+    def build_package(self, student):
+        from StringIO import StringIO
+        import zipfile
+        from django.core.files.base import ContentFile
+        from catalogue.templatetags.catalogue_tags import level_box
+        from catalogue.models import Lesson
+
+        buff = StringIO()
+        zipf = zipfile.ZipFile(buff, 'w', zipfile.ZIP_STORED)
+
+        lessons = level_box(self)['lessons']
+        for i, lesson in enumerate(lessons['synthetic']):
+            prefix = 'Skrocony kurs/%d %s/' % (i, lesson.slug)
+            lesson.add_to_zip(zipf, student, prefix)
+        for c, (section, clessons) in enumerate(lessons['course'].items()):
+            assert section, clessons
+            for i, lesson in enumerate(clessons):
+                prefix = 'Pelny kurs/%d %s/%d %s/' % (c, section.slug, i, lesson.slug)
+                lesson.add_to_zip(zipf, student, prefix)
+        for i, lesson in enumerate(lessons['project']):
+            prefix = 'Projekty/%d %s/' % (i, lesson.slug)
+            lesson.add_to_zip(zipf, student, prefix)
+        # Add all appendix lessons, from all levels.
+        for lesson in Lesson.objects.filter(type='appendix'):
+            # ugly fix
+            if self.slug in ('przedszkole', 'sp1-3', 'sp4-6'):
+                if lesson.slug == 'slowniczek':
+                    continue
+            else:
+                if lesson.slug == 'slowniczek-sp':
+                    continue
+            prefix = '%s/' % lesson.slug
+            lesson.add_to_zip(zipf, student, prefix)
+        zipf.close()
+
+        fieldname = "student_package" if student else "package"
+        getattr(self, fieldname).save(None, ContentFile(buff.getvalue()))
+
+    def build_packages(self):
+        self.build_package(False)
+        self.build_package(True)
+
+
+add_translatable(Level, {
+    'name': models.CharField(_('name'), max_length=255, default=''),
+    'group': models.CharField(_('group'), max_length=255, default='')
+})
+
+
+class CompetenceLevel(models.Model):
+    competence = models.ForeignKey(Competence)
+    level = models.ForeignKey(Level)
+
+    class Meta:
+        ordering = ['competence', 'level']
+        verbose_name = _('competence on level')
+        verbose_name_plural = _('competences on levels')
+
+    def __unicode__(self):
+        return u"%s/%s" % (self.competence, self.level)
+
+    def get_absolute_url(self):
+        return "%s?c=%d&level=%s&d=1" % (reverse("curriculum"), self.competence.pk, self.level.slug)
+
+add_translatable(CompetenceLevel, {
+    'description': models.TextField(_('description'), default='')
+})
+
+
+class CurriculumLevel(models.Model):
+    title = models.CharField(max_length=16, db_index=True)
+    verbose = models.CharField(max_length=32)
+
+    class Meta:
+        verbose_name = _("curriculum level")
+        verbose_name_plural = _("curriculum levels")
+
+    def __unicode__(self):
+        return self.title
+
+
+class CurriculumCourse(models.Model):
+    title = models.CharField(max_length=255)
+    accusative = models.CharField(max_length=255)
+    slug = models.CharField(max_length=255, db_index=True)
+
+    class Meta:
+        verbose_name = _("curriculum course")
+        verbose_name_plural = _("curriculum courses")
+        ordering = ['slug']
+
+    def __unicode__(self):
+        return self.title
+
+
+class Curriculum(models.Model):
+    """Official curriculum."""
+    TYPES = {'c': u'Cele kształcenia', 't': u'Treści nauczania', 'o': u'Osiągnięcia'}
+
+    identifier = models.CharField(max_length=255, db_index=True, unique=True)
+    title = models.CharField(max_length=1024)
+    course = models.ForeignKey(CurriculumCourse)
+    level = models.ForeignKey(CurriculumLevel)
+    type = models.CharField(max_length=16, choices=TYPES.items())
+
+    class Meta:
+        ordering = ['identifier']
+        verbose_name = _("curriculum item")
+        verbose_name_plural = _("curriculum items")
+
+    def __unicode__(self):
+        return self.identifier
+
+    @classmethod
+    def from_text(cls, identifier, title):
+        m = re.match(r"^\d+/(?P<level>[^/]+)/(?P<course>[^/]+)/"
+                     r"(?P<type>(?:%s))[^/]+(?P<roz>/roz)?" % "|".join(cls.TYPES), identifier)
+        assert m is not None, "Curriculum identifier doesn't match template."
+        level, created = CurriculumLevel.objects.get_or_create(
+                                       title=m.group('level'))
+        if created:
+            print 'created level:', m.group('level')
+        def_title = m.group('course').capitalize()
+        course, created = CurriculumCourse.objects.get_or_create(
+                                        slug=slugify(m.group('course')),
+                                        defaults={
+                                            'title': def_title,
+                                            'accusative': def_title,
+                                        })
+        if created:
+            print 'created course:', slugify(m.group('course')), def_title
+        type_ = m.group('type')
+        if m.group('roz'):
+            title += " (zakres rozszerzony)"
+
+        try:
+            curr = cls.objects.get(identifier=identifier)
+        except cls.DoesNotExist:
+            curr = cls(identifier=identifier)
+        curr.title = title
+        curr.course = course
+        curr.level = level
+        curr.type = type_
+        curr.save()
+        return curr
diff --git a/src/curriculum/static/curriculum/curriculum.css b/src/curriculum/static/curriculum/curriculum.css
new file mode 100644 (file)
index 0000000..9ae2e35
--- /dev/null
@@ -0,0 +1,40 @@
+.curriculum-form {
+  border: 1px solid #ddd;
+  padding: 1em;
+  border-radius: 0.688em;
+  background: #ADAEAF;
+  color: white; }
+  .curriculum-form a {
+    cursor: pointer; }
+  .curriculum-form a:hover {
+    text-decoration: underline; }
+  .curriculum-form .error {
+    padding-left: 1em;
+    border-radius: .5em;
+    background: #ed7831;
+    color: white;
+    font-weight: bold; }
+  .curriculum-form h2 {
+    margin: 0; }
+    .curriculum-form h2 a {
+      display: block;
+      color: white; }
+      .curriculum-form h2 a span {
+        display: none; }
+  .curriculum-form strong {
+    display: inline-block;
+    vertical-align: top;
+    width: 12em; }
+  .curriculum-form .curriculum-levels {
+    display: inline-block;
+    list-style: none;
+    padding: 0;
+    margin: 0;
+    width: 40em;
+    vertical-align: top; }
+    .curriculum-form .curriculum-levels li {
+      display: inline-block;
+      width: 13em; }
+  .curriculum-form .curriculum-section-toggler {
+    display: none;
+    color: white; }
diff --git a/src/curriculum/static/curriculum/curriculum.js b/src/curriculum/static/curriculum/curriculum.js
new file mode 100755 (executable)
index 0000000..0bdafc2
--- /dev/null
@@ -0,0 +1,43 @@
+$(function() {
+    if (typeof(curriculum_hide_form) != "undefined") {
+        $('.curriculum-form form').hide();
+        $('.curriculum-form h2 a span').show();
+    }
+    $('.curriculum-form h2 a').click(function() {
+        $('.curriculum-form form').toggle('fast');
+        $('span', this).toggle();
+    });
+
+    /* show togglers */
+    $('.curriculum-section-toggler').show();
+
+    $('.curriculum-section').each(function() {
+        var category = this;
+
+        /* set up togglers */
+        $('.curriculum-section-toggler', this).click(function() {
+            $('ul', category).toggle('fast');
+        });
+
+        /* set up section checkboxes */
+        $('.s', category).change(function() {
+            if ($(this).attr('checked')) {
+                $('ul input', category).attr('checked', 'checked');
+            }
+            else {
+                $('ul input', category).removeAttr('checked');
+            }
+        });
+
+        /* unset section checkbox on unselect single competence */
+        $('ul input', category).change(function() {
+            if (!$(this).attr('checked')) {
+                $('.s', category).removeAttr('checked', 'checked');
+            }
+        });
+
+        /* hide unused section details on start */
+        if ($('.s', category).attr('checked') || !$('ul input[checked]', category).length)
+            $('ul', category).hide();
+    });
+});
diff --git a/src/curriculum/static/curriculum/curriculum.scss b/src/curriculum/static/curriculum/curriculum.scss
new file mode 100755 (executable)
index 0000000..355a6c5
--- /dev/null
@@ -0,0 +1,67 @@
+$px: 0.0625em;
+$oranji: #ed7831;
+$ciemny: #363a3e;
+$zielony: #16a487;
+
+.curriculum-form {
+    border: 1px solid #ddd;
+    padding: 1em;
+    border-radius: 11*$px;
+    background: #ADAEAF;
+    color: white;
+
+    a {
+        cursor: pointer;
+    }
+    a:hover {
+        text-decoration: underline;
+    }
+
+    .error {
+        padding-left: 1em;
+        border-radius: .5em;
+        background: $oranji;
+        color: white;
+        font-weight: bold;
+        
+    }
+
+    h2 {
+        margin: 0;
+        a {
+            display: block;
+            color: white;
+            span {display: none;}
+        }
+    }
+
+    strong {
+        display: inline-block;
+        vertical-align: top;
+        width: 12em;
+    }
+
+    .curriculum-levels {
+        display: inline-block;
+        list-style: none;
+        padding: 0;
+        margin: 0;
+        width: 40em;
+        vertical-align: top;
+
+        li {
+            display: inline-block;
+            width: 13em;
+        }
+    }
+
+    .curriculum-section-toggler {
+        display: none;
+        color: white;
+    }
+
+    .categories {
+        
+    }
+
+}
diff --git a/src/curriculum/templates/curriculum/competence_detail.html b/src/curriculum/templates/curriculum/competence_detail.html
new file mode 100755 (executable)
index 0000000..7bb76e1
--- /dev/null
@@ -0,0 +1,13 @@
+{% extends base_template %}
+
+{% block title %}{{ object }}{% endblock %}
+
+{% block body %}
+<h1>{{ object }}</h1>
+
+{% for cl in object.competencelevel_set.all %}
+    <h2>{{ cl }}</h2>
+    {{ cl.description|linebreaksbr }}
+{% endfor %}
+
+{% endblock %}
diff --git a/src/curriculum/templates/curriculum/competence_list.html b/src/curriculum/templates/curriculum/competence_list.html
new file mode 100755 (executable)
index 0000000..cea4d4e
--- /dev/null
@@ -0,0 +1,73 @@
+{% extends base_template %}
+{% load chunks %}
+{% load i18n %}
+
+{% block title %}{% trans 'Media, information and digital literacy competencies catalogue' %}{% endblock %}
+
+{% block body %}
+<h1>{% trans 'Media, information and digital literacy competencies catalogue' %}</h1>
+
+{% if request.LANGUAGE_CODE == 'pl' %}
+    {% chunk 'katalog_kompetencji' %}
+{% endif %}
+
+<div class="curriculum-form">
+<h2><a>{% trans 'Browse competencies' %} <span>({% trans 'expand' %})</span></a></h2>
+<form>
+
+<h3>{% trans 'Education level' %}:</h3>
+{% if errors.level %}<p class="error">{{ errors.level }}</p>{% endif %}
+{% for lev_group, levels in levels.items %}
+    <strong>{{ lev_group }}</strong>
+    <ul class="curriculum-levels">
+    {% for lev in levels %}
+    <li><label><input type="radio" name="level" value="{{ lev.slug }}"
+        {% if lev == level %}checked="checked"{% endif %} />
+        {{ lev }}</label></li>
+    {% endfor %}
+    </ul>
+{% endfor %}
+
+<h3>{% trans 'Competency categories' %}:</h3>
+{% if errors.competences %}<p class="error">{{ errors.competences }}</p>{% endif %}
+<ul class="curriculum-sections">
+{% for section in sections %}
+    <li class="curriculum-section">
+    <label><input type="checkbox" class="s" name="s" value="{{ section.pk }}"
+        {% if section.pk in sect_ids %}checked="checked"{% endif %} /> {{ section }}</label>
+        <a class="curriculum-section-toggler">({% trans 'expand' %})</a>
+    <ul class="competences">
+    {% for competence in section.competence_set.all %}
+        <li class="competence"><label><input class="c" type="checkbox" name="c" value="{{ competence.pk }}"
+            {% if competence.pk in comp_ids %}checked="checked"{% endif %} />
+            {{ competence }}</label></li>
+    {% endfor %}
+    </ul>
+    </li>
+{% endfor %}
+</ul>
+<button>{% trans 'Show' %}</button>
+</form>
+</div>
+
+{% if chosen_competences %}
+
+<h2>{% trans 'Selected competencies' %} – {{ level }}</h2>
+
+{% for section, competences in chosen_competences.items %}
+    <h3>{{ section }}</h3>
+    {% for competence in competences %}
+        <h4>{{ competence }}</h4>
+        {{ competence.for_level_.description|linebreaksbr }}
+    {% endfor %}
+{% endfor %}
+
+{% endif %}
+
+
+{% if request.GET.d %}
+<script type="text/javascript">
+    var curriculum_hide_form = true;
+</script>
+{% endif %}
+{% endblock %}
diff --git a/src/curriculum/templates/curriculum/snippets/competence.html b/src/curriculum/templates/curriculum/snippets/competence.html
new file mode 100755 (executable)
index 0000000..7f62ac8
--- /dev/null
@@ -0,0 +1,12 @@
+{% load url_for_level from curriculum_tags %}
+{% if comps %}
+    {% for competence in comps %}
+        <li><a href="{{ competence|url_for_level:level }}">
+            {{ competence }}</a></li>
+    {% endfor %}
+{% else %}
+    {% for text in texts %}
+        <li>{{ text }}</li>
+    {% endfor %}
+{% endif %}
+
diff --git a/src/curriculum/templates/curriculum/snippets/course_box.html b/src/curriculum/templates/curriculum/snippets/course_box.html
new file mode 100755 (executable)
index 0000000..f1bd074
--- /dev/null
@@ -0,0 +1,35 @@
+{% for level, types in lessons.items %}
+{% if level.slug == "liceum" %}
+    <p><strong>{{ course }}</strong>: poziom zaawansowany
+        <span class="section-links"><a href="#top">wróć do spisu treści</a></span>
+    </p>
+{% endif %}
+<section class="section-level section-level-{{ level.slug }}">
+    {% spaceless %}
+    {% for lesson_type, lesson_list in types.items %}
+        <section class="section-type section-type-{{ lesson_type }}">
+            {% if lesson_type == 'synthetic' %}
+                <h1>Lekcje syntetyczne</h1>
+            {% elif lesson_type == 'project' %}
+                <h1>Projekty</h1>
+            {% else %}
+                <h1>Lekcje z pełnych kursów</h1>
+            {% endif %}
+            {% if lesson_list %}
+            <ul class="section-lessons link-list">
+                {% for lesson in lesson_list %}
+                    <li class="section-lesson">
+                        <a href="{{ lesson.get_absolute_url }}">{{ lesson }}{% if lesson_type == 'synthetic' %}
+                            <br/>(przegląd całego tematu „{{ lesson.section }}” w 45 minut)
+                        {% endif %}</a>
+                    </li>
+                {% endfor %}
+            </ul>
+            {% else %}
+                <p>(W przygotowaniu)</p>
+            {% endif %}
+        </section>
+    {% endfor %}
+    {% endspaceless %}
+</section>
+{% endfor %}
diff --git a/src/curriculum/templates/curriculum/snippets/course_boxes.html b/src/curriculum/templates/curriculum/snippets/course_boxes.html
new file mode 100755 (executable)
index 0000000..c998121
--- /dev/null
@@ -0,0 +1,8 @@
+{% load course_box from curriculum_tags %}
+{% for course in object_list %}
+    <div class="section-links">
+        <a href="#top">wróć do spisu treści</a>
+    </div>
+    <h3 id='{{ course.slug }}'>{{ course }}</h3>
+    {% course_box course %}
+{% endfor %}
diff --git a/src/curriculum/templates/curriculum/snippets/course_boxes_toc.html b/src/curriculum/templates/curriculum/snippets/course_boxes_toc.html
new file mode 100755 (executable)
index 0000000..0c22785
--- /dev/null
@@ -0,0 +1,14 @@
+{% url "catalogue_lessons" as lessons_url %}
+{% for level, course_list in object_list %}
+<section class="levelth" style="float: left;">{{ level }}:
+<ul class="link-list">
+        {% for course in course_list %}
+            <li><a href="{{ lessons_url }}#{{ level.slug }}_{{ course.slug }}">
+            {% if accusative %}
+                {{ course.accusative }}{% else %}
+                {{ course|lower }}{% endif %}</a>
+                </li>
+        {% endfor %}
+</ul>
+</section>
+{% endfor %}
diff --git a/src/curriculum/templates/curriculum/snippets/curriculum.html b/src/curriculum/templates/curriculum/snippets/curriculum.html
new file mode 100755 (executable)
index 0000000..a499a88
--- /dev/null
@@ -0,0 +1,17 @@
+{% if currset %}
+    {% for what, types in currset.items %}
+        <li>
+            {{ what.0 }}, {{ what.1 }}<br/>
+            {% for type, currs in types.items %}
+                {{ type }}:<br>
+                {% for curr in currs %}
+                    {{ curr.title }}<br>
+                {% endfor %}
+            {% endfor %}
+        </li>
+    {% endfor %}
+{% else %}
+    {% for identifier in identifiers %}
+        <li>{{ identifier }}</li>
+    {% endfor %}
+{% endif %}
diff --git a/src/curriculum/templatetags/__init__.py b/src/curriculum/templatetags/__init__.py
new file mode 100755 (executable)
index 0000000..e69de29
diff --git a/src/curriculum/templatetags/curriculum_tags.py b/src/curriculum/templatetags/curriculum_tags.py
new file mode 100755 (executable)
index 0000000..9525aec
--- /dev/null
@@ -0,0 +1,99 @@
+# -*- coding: utf-8 -*-
+from django import template
+from django.utils.datastructures import SortedDict
+from ..models import Competence, Curriculum, CurriculumCourse
+from catalogue.models import Lesson
+
+register = template.Library()
+
+
+@register.inclusion_tag("curriculum/snippets/competence.html")
+def competence(texts, level):
+    try:
+        comps = [Competence.from_text(text) for text in texts]
+    except:
+        # WTF
+        return {'texts': texts}
+    return {
+        'comps': comps,
+        'level': level,
+    }
+
+
+@register.inclusion_tag("curriculum/snippets/curriculum.html")
+def curriculum(identifiers, new=False):
+    # shouldn't be needed, but is
+    identifiers = [id for id in identifiers if id]
+    try:
+        currs = [Curriculum.objects.get(identifier__iexact=identifier.replace(' ', ''))
+                 for identifier in identifiers]
+    except Curriculum.DoesNotExist:
+        return {'identifiers': identifiers}
+
+    currset = SortedDict()
+    for curr in currs:
+        k = curr.course, curr.level.verbose
+        if k not in currset:
+            currset[k] = SortedDict()
+        typename = Curriculum.TYPES[curr.type]
+        if typename not in currset[k]:
+            currset[k][typename] = []
+        currset[k][typename].append(curr)
+
+    return {
+        'currset': currset,
+        'new': new,
+    }
+    
+
+@register.filter
+def url_for_level(comp, level):
+    try:
+        return comp.url_for_level(level)
+    except:
+        # WTF
+        return comp.get_absolute_url()
+
+
+@register.inclusion_tag("curriculum/snippets/course_box.html")
+def course_box(course):
+    lessons = SortedDict()
+    for lesson in course.lesson_set.all():
+        if lesson.level not in lessons:
+            newdict = SortedDict()
+            newdict['synthetic'] = []
+            newdict['course'] = []
+            lessons[lesson.level] = newdict
+        if lesson.type not in lessons[lesson.level]:
+            lessons[lesson.level][lesson.type] = []
+        lessons[lesson.level][lesson.type].append(lesson)
+    return {
+        "course": course,
+        "lessons": lessons,
+    }
+
+
+@register.inclusion_tag("curriculum/snippets/course_boxes.html")
+def course_boxes():
+    return {'object_list': CurriculumCourse.objects.all()}
+
+
+@register.inclusion_tag("curriculum/snippets/course_boxes_toc.html")
+def course_boxes_toc(accusative=False):
+    last = None, None
+    object_list = []
+    lessons = Lesson.curriculum_courses.through.objects\
+        .select_related('lesson__level', 'curriculumcourse')\
+        .order_by('lesson__level', 'curriculumcourse')
+    for l in lessons:
+        level, course = l.lesson.level, l.curriculumcourse
+        if (level, course) == last:
+            continue
+        if level != last[0]:
+            object_list.append((level, []))
+        object_list[-1][1].append(course)
+        last = (level, course)
+    return {
+        'object_list': object_list,
+        'accusative': accusative,
+    }
diff --git a/src/curriculum/tests.py b/src/curriculum/tests.py
new file mode 100644 (file)
index 0000000..b967c44
--- /dev/null
@@ -0,0 +1,17 @@
+# -*- coding: utf-8 -*-
+"""
+This file demonstrates writing tests using the unittest module. These will pass
+when you run "manage.py test".
+
+Replace this with more appropriate tests for your application.
+"""
+
+from django.test import TestCase
+
+
+class SimpleTest(TestCase):
+    def test_basic_addition(self):
+        """
+        Tests that 1 + 1 always equals 2.
+        """
+        self.assertEqual(1 + 1, 2)
diff --git a/src/curriculum/urls.py b/src/curriculum/urls.py
new file mode 100755 (executable)
index 0000000..7553a66
--- /dev/null
@@ -0,0 +1,9 @@
+# -*- coding: utf-8 -*-
+from django.conf.urls import patterns, url
+from .views import CompetenceDetailView, CompetencesView
+
+urlpatterns = patterns(
+    '',
+    url(r'^$', CompetencesView.as_view(), name='curriculum'),
+    url(r'^(?P<slug>[^/]+)/$', CompetenceDetailView.as_view(), name='curriculum_competence'),
+)
diff --git a/src/curriculum/views.py b/src/curriculum/views.py
new file mode 100644 (file)
index 0000000..25606f1
--- /dev/null
@@ -0,0 +1,66 @@
+# -*- coding: utf-8
+from django.db import models
+from django.views.generic import DetailView, ListView
+from django.utils.datastructures import SortedDict
+from django.utils.translation import ugettext as _
+
+from .models import Competence, Section, Level, CompetenceLevel
+
+
+class CompetenceDetailView(DetailView):
+    model = Competence
+
+
+class CompetencesView(ListView):
+    model = Competence
+
+    def get_context_data(self, **kwargs):
+        context = super(CompetencesView, self).get_context_data(**kwargs)
+        
+        context['levels'] = SortedDict()
+        for level in Level.objects.all():
+            context['levels'].setdefault(level.group, []).append(level)
+
+        context['sections'] = Section.objects.all()
+
+        errors = {}
+
+        try:
+            level = Level.objects.get(slug=self.request.GET.get('level'))
+        except Level.DoesNotExist:
+            level = None
+        context['level'] = level
+
+        comp_ids = set()
+        for c in self.request.GET.getlist('c'):
+            try:
+                comp_ids.add(int(c))
+            except ValueError:
+                pass
+        context['comp_ids'] = comp_ids
+        sect_ids = set()
+        for c in self.request.GET.getlist('s'):
+            try:
+                sect_ids.add(int(c))
+            except ValueError:
+                pass
+        context['sect_ids'] = sect_ids
+
+        if not (comp_ids or sect_ids):
+            if level:
+                errors["competences"] = _('You must select at least one competency from the list.')
+        elif level is None:
+            errors["level"] = _('You must select at least one education level.')
+        else:
+            chosen_competences = SortedDict()
+            for competence in Competence.objects.filter(
+                    models.Q(pk__in=comp_ids) | models.Q(section__pk__in=sect_ids)):
+                try:
+                    competence.for_level_ = competence.for_level(level)
+                except CompetenceLevel.DoesNotExist:
+                    pass
+                chosen_competences.setdefault(competence.section, []).append(competence)
+            context['chosen_competences'] = chosen_competences
+
+        context["errors"] = errors
+        return context
diff --git a/src/edumed/__init__.py b/src/edumed/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/src/edumed/contact_forms.py b/src/edumed/contact_forms.py
new file mode 100644 (file)
index 0000000..88d2c84
--- /dev/null
@@ -0,0 +1,873 @@
+# -*- coding: utf-8 -*-
+import re
+
+from django import forms
+from django.forms.formsets import BaseFormSet
+from django.utils.safestring import mark_safe
+from markdown2 import Markdown
+
+from contact.fields import HeaderField
+from contact.forms import ContactForm
+from django.core.mail import send_mail
+from django.core.exceptions import ValidationError
+from django.core.validators import validate_email
+from django.template.loader import render_to_string
+from django.utils.translation import ugettext_lazy as _
+
+from edumed.contact_forms_test import TestForm, CollegiumTestForm
+
+LINK_PATTERNS = [
+    (re.compile(r'((http|ftp|https)://([\w_-]+(?:(?:\.[\w_-]+)+))([\w.,;@?^=%&:/~+#-]*[\w@?^=%&/~+#-])?)'),
+     r'\1')
+]
+
+markdown = Markdown(extras=["link-patterns", 'code-friendly'], link_patterns=LINK_PATTERNS)
+
+WOJEWODZTWA = (
+    u'dolnośląskie',
+    u'kujawsko-pomorskie',
+    u'lubelskie',
+    u'lubuskie',
+    u'łódzkie',
+    u'małopolskie',
+    u'mazowieckie',
+    u'opolskie',
+    u'podkarpackie',
+    u'podlaskie',
+    u'pomorskie',
+    u'śląskie',
+    u'świętokrzyskie',
+    u'warmińsko-mazurskie',
+    u'wielkopolskie',
+    u'zachodniopomorskie',
+)
+
+WOJEWODZTWO_CHOICES = [(u'', u'(wybierz)')] + [(w, w) for w in WOJEWODZTWA]
+
+
+def make_data_processing(middle_text):
+    return mark_safe(u'''\
+Administratorem danych osobowych jest Fundacja Nowoczesna Polska (ul. Marszałkowska 84/92 lok. 125, 00-514 Warszawa). \
+Podanie danych osobowych jest dobrowolne. %s Osobom, których dane są zbierane, przysługuje prawo dostępu do treści \
+swoich danych oraz ich poprawiania. Więcej informacji w <a href="https://nowoczesnapolska.org.pl/prywatnosc/">\
+polityce prywatności</a>.''' % middle_text)
+
+
+class SuggestionForm(ContactForm):
+    form_tag = 'sugestie'
+    form_title = u"Zgłoś sugestię"
+    admin_list = ['podpis', 'contact', 'temat']
+    data_processing = make_data_processing(u'Dane są przetwarzane w zakresie niezbędnym do obsługi zgłoszenia.')
+
+    contact = forms.EmailField(label=u'E-mail', max_length=128, required=False)
+    podpis = forms.CharField(label=u'Podpis', max_length=128, required=False)
+    temat = forms.CharField(label=u'Temat zgłoszenia', max_length=255)
+    tresc = forms.CharField(label=u'Treść', widget=forms.Textarea, max_length=1800)
+
+
+class CooperateForm(ContactForm):
+    form_tag = 'wspolpraca'
+    form_title = u"Bądź z nami w kontakcie"
+    admin_list = ['contact']
+    mailing = True
+    data_processing = make_data_processing(
+        u'Dane są przetwarzane w zakresie niezbędnym do wysyłania newslettera odbiorcom.')
+    submit_label = u'Wyślij'
+
+    contact = forms.EmailField(label=u'E-mail', max_length=128)
+
+
+class ContestForm(ContactForm):
+    disabled = True
+    form_tag = 'konkurs'
+    form_title = u"Zgłoś się do konkursu"
+    admin_list = ['nazwisko', 'instytucja', 'tytul']
+    mailing_field = 'zgoda_informacje'
+
+    nazwisko = forms.CharField(label=u'Imię i nazwisko', max_length=128)
+    contact = forms.EmailField(label=u'Adres e-mail', max_length=128)
+    instytucja = forms.CharField(label=u'Instytucja (nazwa, adres)', widget=forms.Textarea, max_length=1000)
+    tytul = forms.CharField(
+        label=u'Tytuł przeprowadzonej lekcji',
+        help_text=u'proszę wymienić wszystkie, jeśli zostały przeprowadzone więcej niż jedne zajęcia',
+        widget=forms.Textarea, max_length=1000)
+    uczestnicy = forms.CharField(label=u'Liczba uczestników', max_length=64)
+    trudnosci = forms.CharField(
+        label=u'Czy w trakcie zajęć pojawiły się jakieś trudności? Jeśli tak, to jakie?',
+        widget=forms.Textarea, max_length=2000)
+    pomocne = forms.CharField(
+        label=u'Co w materiałach okazało się najbardziej pomocne w przygotowaniu i prowadzeniu lekcji?',
+        widget=forms.Textarea, max_length=2000)
+    nieprzydatne = forms.CharField(
+        label=u'Co w materiałach okazało się nieprzydatne w przygotowaniu i prowadzeniu lekcji?',
+        widget=forms.Textarea, max_length=2000)
+    poprawic = forms.CharField(
+        label=u'Jak możemy poprawić serwis edukacjamedialna.edu.pl?',
+        widget=forms.Textarea, max_length=2000, required=False)
+    inne = forms.CharField(label=u'Inne uwagi i komentarze', widget=forms.Textarea, max_length=2000, required=False)
+    zgoda_regulamin = forms.BooleanField(
+        label=u'Znam i akceptuję regulamin konkursu Medialog.',
+        help_text=u'Zobacz <a href="/media/chunks/attachment/Regulamin_konkursu_MediaLog_1.pdf">'
+                  u'regulamin konkursu MediaLog</a>.')
+    zgoda_informacje = forms.BooleanField(
+        label=u'Wyrażam zgodę na otrzymywanie informacji od Fundacji Nowoczesna Polska związanych z edukacją medialną.',
+        required=False
+    )
+
+
+class UdzialForm(ContactForm):
+    disabled = True
+    form_tag = 'udzial'
+    form_title = u"Udział"
+    admin_list = ['nazwisko', 'miejscowosc', 'instytucja']
+
+    nazwisko = forms.CharField(label=u'Imię i nazwisko', max_length=128)
+    miejscowosc = forms.CharField(label=u'Miejscowość', max_length=128)
+    instytucja = forms.CharField(label=u'Nazwa organizacji/instytucji', max_length=128)
+    contact = forms.EmailField(label=u'Adres e-mail', max_length=128)
+    telefon = forms.CharField(label=u'Telefon', max_length=32)
+    uczestnicy = forms.IntegerField(label=u'Przewidywana liczba uczestników zajęć')
+
+
+class WTEMStudentForm(forms.Form):
+    first_name = forms.CharField(label=u'Imię', max_length=128)
+    last_name = forms.CharField(label=u'Nazwisko', max_length=128)
+    email = forms.EmailField(label=u'Adres e-mail', max_length=128)
+    form_tag = "student"
+
+
+class NonEmptyBaseFormSet(BaseFormSet):
+    """
+    Won't allow formset_factory to be submitted with no forms
+    """
+    def clean(self):
+        for form in self.forms:
+            if form.cleaned_data:
+                return
+        forms.ValidationError(u"Proszę podać dane przynajmniej jednej osoby.")
+
+
+class WTEMForm(ContactForm):
+    disabled = True
+    disabled_template = 'wtem/disabled_contact_form.html'
+    form_tag = "wtem"
+    old_form_tags = ["wtem2013", "wtem2014"]
+    form_title = u"WTEM - rejestracja uczestników"
+    submit_label = u"Wyślij zgłoszenie"
+    admin_list = ['imie', 'nazwisko', 'institution']
+    form_formsets = {
+        'student': forms.formsets.formset_factory(
+            WTEMStudentForm, formset=NonEmptyBaseFormSet, max_num=5, validate_max=True, extra=5),
+    }
+    mailing_field = 'zgoda_informacje'
+
+    contact = forms.EmailField(label=u'Adres e-mail opiekuna/opiekunki', max_length=128)
+    imie = forms.CharField(label=u'Imię', max_length=128)
+    nazwisko = forms.CharField(label=u'Nazwisko', max_length=128)
+    function = forms.CharField(label=u'Pełniona funkcja', max_length=255)
+    institution = forms.CharField(label=u'Nazwa instytucji', max_length=255)
+    institution_address = forms.CharField(label=u'Adres instytucji', widget=forms.Textarea, max_length=1000)
+    institution_email = forms.EmailField(label=u'Adres e-mail instytucji', max_length=128)
+    institution_phone = forms.CharField(label=u'Telefon do instytucji', max_length=32)
+    institution_www = forms.URLField(label=u'Strona WWW instytucji', max_length=255, required=False)
+
+    zgoda_regulamin = forms.BooleanField(
+        label=u'Znam i akceptuję regulamin Wielkiego Turnieju Edukacji Medialnej.',
+        help_text=u'Zobacz <a href="/media/chunks/attachment/regulamin_III_edycja.pdf">'
+                  u'regulamin Wielkiego Turnieju Edukacji Medialnej</a>.'
+    )
+    zgoda_dane = forms.BooleanField(
+        label=u'Wyrażam zgodę na przetwarzanie moich danych osobowych oraz danych osobowych moich podopiecznych.',
+        # help_text=u'Zobacz <a href="/media/chunks/attachment/Oswiadczenie_o_danych_osobowych.pdf">'
+        # 'pełną treść oświadczenia</a>.'
+    )
+
+    potw_uczniowie = forms.BooleanField(
+        label=u'Potwierdzam, że zgłoszeni Uczestnicy/Uczestniczki w chwili rejestracji są '
+              u'uczniami/uczennicami szkoły ponadgimnazjalnej.',
+    )
+    zgoda_informacje = forms.BooleanField(
+        label=u'Wyrażam zgodę na otrzymywanie informacji od Fundacji Nowoczesna Polska '
+              u'związanych z edukacją medialną.',
+        required=False
+    )
+
+    extract_types = (dict(slug='extended', label=_('extended')),)
+
+    @staticmethod
+    def get_extract_fields(contact, extract_type_slug):
+        fields = contact.body.keys()
+        fields.pop(fields.index('student'))
+        fields.extend(['contact', 'student_first_name', 'student_last_name', 'student_email'])
+        return fields
+
+    @staticmethod
+    def get_extract_records(keys, contact, extract_type_slug):
+        toret = [dict()]
+        for field_name in keys:
+            if field_name.startswith('student_'):
+                continue
+            if field_name == 'contact':
+                val = contact.contact
+            else:
+                val = contact.body[field_name]
+            toret[0][field_name] = val
+        
+        current = toret[0]
+        for student in contact.body['student']:
+            for attr in ('first_name', 'last_name', 'email'):
+                current['student_' + attr] = student[attr]
+            if current not in toret:
+                toret.append(current)
+            current = dict()
+        return toret
+
+    def save(self, request, formsets=None):
+        contact = super(WTEMForm, self).save(request, formsets)
+
+        mail_subject = render_to_string('contact/wtem/student_mail_subject.html').strip()
+        mail_body = render_to_string('contact/wtem/student_mail_body.html')
+        for formset in formsets or []:
+            for f in formset.forms:
+                email = f.cleaned_data.get('email', None)
+                try:
+                    validate_email(email)
+                except ValidationError:
+                    pass
+                else:
+                    send_mail(mail_subject, mail_body, 'edukacjamedialna@nowoczesnapolska.org.pl', [email],
+                              fail_silently=True)
+
+        return contact
+
+
+class CommissionForm(forms.Form):
+    name = forms.CharField(label=u'Imię i nazwisko Członka Komisji', max_length=128)
+    form_tag = "commission"
+
+
+class OlimpiadaForm(ContactForm):
+    disabled = True
+    disabled_template = 'wtem/disabled_contact_form.html'
+    form_tag = "olimpiada"
+    old_form_tags = ["olimpiada-2016"]
+    form_title = u"Olimpiada Cyfrowa - Elektroniczny System Zgłoszeń"
+    submit_label = u"Wyślij zgłoszenie"
+    admin_list = ['nazwisko', 'school']
+    form_formsets = {
+        'student': forms.formsets.formset_factory(WTEMStudentForm, formset=NonEmptyBaseFormSet),
+        'commission': forms.formsets.formset_factory(CommissionForm, formset=BaseFormSet),
+    }
+
+    contact = forms.EmailField(label=u'Adres e-mail Przewodniczącego/Przewodniczącej', max_length=128)
+    przewodniczacy = forms.CharField(label=u'Imię i nazwisko Przewodniczącego/Przewodniczącej', max_length=128)
+    school = forms.CharField(label=u'Nazwa szkoły', max_length=255)
+    school_address = forms.CharField(label=u'Adres szkoły', widget=forms.Textarea, max_length=1000)
+    school_email = forms.EmailField(label=u'Adres e-mail szkoły', max_length=128)
+    school_phone = forms.CharField(label=u'Numer telefonu szkoły', max_length=32)
+    school_www = forms.URLField(label=u'Strona WWW szkoły', max_length=255, required=False)
+
+    zgoda_regulamin = forms.BooleanField(
+        label=u'Znam i akceptuję Regulamin Olimpiady Cyfrowej.',
+        help_text=u'Zobacz <a href="https://olimpiadacyfrowa.pl/regulamin/" target="_blank">'
+                  u'regulamin Olimpiady Cyfrowej</a>.'
+    )
+    zgoda_dane = forms.BooleanField(
+        label=u'Oświadczam, że wyrażam zgodę na przetwarzanie danych osobowych zawartych w niniejszym formularzu '
+              u'zgłoszeniowym przez Fundację Nowoczesna Polska (administratora danych) z siedzibą w Warszawie (00-514) '
+              u'przy ul. Marszałkowskiej 84/92 lok. 125 na potrzeby organizacji Olimpiady Cyfrowej. Jednocześnie '
+              u'oświadczam, że zostałam/em poinformowana/y o tym, że mam prawo wglądu w treść swoich danych '
+              u'i możliwość ich poprawiania oraz że ich podanie jest dobrowolne, ale niezbędne do dokonania '
+              u'zgłoszenia.')
+
+    extract_types = (dict(slug='extended', label=_('extended')),)
+
+    @staticmethod
+    def get_extract_fields(contact, extract_type_slug):
+        fields = contact.body.keys()
+        if 'student' in fields:
+            fields.remove('student')
+        fields.extend(['contact', 'student_first_name', 'student_last_name', 'student_email'])
+        return fields
+
+    @staticmethod
+    def get_extract_records(keys, contact, extract_type_slug):
+        toret = [{}]
+        for field_name in keys:
+            if field_name.startswith('student_'):
+                continue
+            if field_name == 'contact':
+                val = contact.contact
+            else:
+                val = contact.body[field_name]
+            toret[0][field_name] = val
+
+        current = toret[0]
+        if 'student' in contact.body:
+            for student in contact.body['student']:
+                for attr in ('first_name', 'last_name', 'email'):
+                    current['student_' + attr] = student[attr]
+                if current not in toret:
+                    toret.append(current)
+                current = {}
+        return toret
+
+    def save(self, request, formsets=None):
+        contact = super(OlimpiadaForm, self).save(request, formsets)
+
+        mail_subject = render_to_string('contact/olimpiada/student_mail_subject.html').strip()
+        mail_body = render_to_string('contact/olimpiada/student_mail_body.html')
+        for formset in formsets or []:
+            if formset.prefix == 'student':
+                for f in formset.forms:
+                    email = f.cleaned_data.get('email', None)
+                    try:
+                        validate_email(email)
+                    except ValidationError:
+                        pass
+                    else:
+                        send_mail(mail_subject, mail_body, 'edukacjamedialna@nowoczesnapolska.org.pl', [email],
+                                  fail_silently=True)
+
+        return contact
+
+
+class MILForm(ContactForm):
+    disabled = True
+    form_tag = 'mil'
+    form_title = _('Share your thoughts on the "Media and information literacy competencies catalogue"')
+    submit_label = _('Submit')
+    base_template = 'base_mil.html'
+    site_name = site_domain = 'katalog.nowoczesnapolska.org.pl'
+
+    name = forms.CharField(label=_('Name and Surname'), max_length=255)
+    contact = forms.EmailField(label=_('E-mail'), max_length=255)
+
+    institution = forms.CharField(label=_('Institution'), widget=forms.Textarea, max_length=8192)
+
+    question_stages = forms.CharField(
+        label=_('What do you think about the proposed educational stages classification?'),
+        widget=forms.Textarea,
+        max_length=255,
+        required=False)
+
+    question_fields = forms.CharField(
+        label=_('What do you think about the proposed thematic fields?'),
+        widget=forms.Textarea,
+        max_length=255,
+        required=False)
+
+    question_left_out = forms.CharField(
+        label=_('What important areas of media and information literacy have been left out?'),
+        widget=forms.Textarea,
+        max_length=255,
+        required=False)
+
+    other = forms.CharField(
+        label=_('Other suggestions and comments'),
+        widget=forms.Textarea,
+        max_length=255,
+        required=False)
+
+
+class TEMForm(ContactForm):
+    disabled = True
+    form_tag = 'tem'
+    form_title = u"TEM - szkolenie dla trenerów edukacji medialnej"
+    admin_list = ['imie', 'nazwisko', 'instytucja', 'contact']
+    mailing_field = 'zgoda_informacje'
+
+    imie = forms.CharField(label=u'Imię', max_length=128)
+    nazwisko = forms.CharField(label=u'Nazwisko', max_length=128)
+    contact = forms.EmailField(label=u'E-mail', max_length=128)
+    telefon = forms.CharField(label=u'Tel. kontaktowy', max_length=128)
+    instytucja = forms.CharField(label=u'Instytucja', max_length=256)
+    adres = forms.CharField(label=u'Adres', widget=forms.Textarea, max_length=1000)
+    stanowisko = forms.CharField(label=u'Stanowisko', max_length=256)
+    doswiadczenie = forms.CharField(
+        label=u'Jakie jest Pani/Pana doświadczenie w zakresie edukacji medialnej?',
+        widget=forms.Textarea, max_length=500, help_text=u'(max 500 znaków)')
+    dlaczego = forms.CharField(
+        label=u'Dlaczego chce Pani/Pan wziąć udział w szkoleniu?',
+        widget=forms.Textarea, max_length=500, help_text=u'(max 500 znaków)')
+    jak_wykorzystac = forms.CharField(
+        label=u'Jak zamierza Pan/Pani wykorzystać wiedzę zdobytą w czasie szkolenia?',
+        widget=forms.Textarea, max_length=500, help_text=u'(max 500 znaków)')
+
+    zajecia = forms.BooleanField(
+        label=u'W okresie wrzesień-październik 2015 r. przeprowadzę min. 2 godziny zajęć edukacji medialnej '
+              u'z wybraną grupą dzieci lub młodzieży.', required=True)
+    zgoda_informacje = forms.BooleanField(
+        label=u'Wyrażam zgodę na otrzymywanie informacji od Fundacji Nowoczesna Polska '
+              u'związanych z edukacją medialną.', required=False)
+
+
+class SuperwizjaForm(ContactForm):
+    disabled = True
+    form_tag = 'superwizja'
+    form_title = u"Informacje o zajęciach"
+    admin_list = ['nazwisko', 'contact', 'skype', 'temat']
+    submit_label = u'Wyślij'
+
+    nazwisko = forms.CharField(label=u'Imię i nazwisko', max_length=1024)
+    contact = forms.CharField(label=u'E-mail kontaktowy', required=False)
+    skype = forms.CharField(label=u'Nazwa użytkownika Skype', max_length=255)
+    temat = forms.CharField(label=u'Temat zajęć', max_length=1024)
+    termin = forms.CharField(label=u'Termin zajęć', max_length=1024)
+    czas_trwania = forms.CharField(label=u'Czas trwania zajęć', max_length=1024)
+    miejsce = forms.CharField(label=u'Miejsce prowadzenia zajęć', max_length=1024)
+    rodzaj = forms.ChoiceField(
+        label=u'Rodzaj zajęć', widget=forms.RadioSelect,
+        choices=[('jednorazowe', 'jednorazowe'), ('w ramach cyklu', 'w ramach cyklu')])
+    cykl = forms.CharField(label=u'Jeśli w ramach cyklu, to podaj jego temat i czas trwania', required=False)
+    sposob = forms.ChoiceField(
+        label=u'Sposób prowadzenia zajęć', widget=forms.RadioSelect,
+        choices=[('samodzielnie', 'samodzielnie'), (u'z drugą osobą', 'z drugą osobą')])
+    wrazenia = forms.CharField(
+        label=u'Opisz Twoje ogólne wrażenia po warsztacie.', widget=forms.Textarea, max_length=4096)
+    opiekun = forms.CharField(
+        label=u'Czy opiekun grupy był obecny podczas zajęć? Jeśli tak, opisz krótko jego rolę.',
+        widget=forms.Textarea, max_length=4096)
+    grupa = forms.CharField(
+        label=u'Opisz krótko grupę uczestników zajęć (wiek, liczba osób, czy to pierwszy kontakt z grupą).',
+        widget=forms.Textarea, max_length=4096)
+    cel = forms.CharField(
+        label=u'Jaki był założony cel zajęć? Dlaczego wybrałaś/eś taki cel?', widget=forms.Textarea, max_length=4096)
+    ewaluacja = forms.CharField(
+        label=u'W jaki sposób sprawdziłeś/aś, czy cel zajęć został zrealizowany? Opisz krótko efekty zajęć.',
+        widget=forms.Textarea, max_length=4096)
+    # header
+    przygotowania = forms.CharField(
+        label=u'Opisz w punktach proces przygotowania się do zajęć.', widget=forms.Textarea, max_length=4096)
+    przygotowania_trudnosci = forms.CharField(
+        label=u'Co na etapie przygotowań sprawiło Ci największą trudność?', widget=forms.Textarea, max_length=4096)
+    przygotowania_pomoc = forms.CharField(
+        label=u'Co było pomocne w przygotowaniu zajęć? '
+              u'(Czy korzystałaś/eś z materiałów z serwisu edukacjamedialna.edu.pl? Jeśli tak, to jakich?)',
+        widget=forms.Textarea, max_length=4096)
+    narzedzia = forms.CharField(
+        label=u'Jakie narzędzie/a planowałaś/eś wykorzystać, a jakie wykorzystałaś/eś?',
+        widget=forms.Textarea, max_length=4096)
+    struktura = forms.CharField(
+        label=u'Opisz w punktach strukturę zajęć. '
+              u'Zaznacz ile czasu planowałaś/eś na każdą część, a ile czasu faktycznie Ci to zajęło.',
+        widget=forms.Textarea, max_length=4096)
+    prowadzenie_trudnosci = forms.CharField(
+        label=u'Co sprawiało Ci trudność w prowadzeniu zajęć?', widget=forms.Textarea, max_length=4096)
+    prowadzenie_pomoc = forms.CharField(
+        label=u'Co było pomocne w prowadzeniu zajęć?', widget=forms.Textarea, max_length=4096)
+    kontrakt = forms.CharField(
+        label=u'W jakiej formie został zawarty kontrakt z uczestnikami? Jakie zasady zostały przyjęte? '
+              u'Czy w trakcie zajęć Ty bądź uczestnicy odwoływaliście się do kontraktu?',
+        widget=forms.Textarea, max_length=4096)
+    trudne_sytuacje = forms.CharField(
+        label=u'Czy podczas zajęć miały miejsce tzw. „trudne sytuacje”. '
+              u'Jak na nie zareagowałaś/eś? Czy potrzebowałabyś/łbyś czegoś w związku z nimi?',
+        widget=forms.Textarea, max_length=4096)
+    informacje_zwrotne = forms.CharField(
+        label=u'Czy zbierałaś/eś informacje zwrotne od uczestników? Jeśli tak, na co zwrócili uwagę? '
+              u'W jaki sposób zbierałaś/eś informacje zwrotne?', widget=forms.Textarea, max_length=4096)
+
+    mocne_strony = forms.CharField(
+        label=u'Opisz w punktach mocne strony przeprowadzonych zajęć.', widget=forms.Textarea, max_length=4096)
+    zmiany = forms.CharField(
+        label=u'Opisz w punktach, co byś zmienił(a) na przyszłość.', widget=forms.Textarea, max_length=4096)
+    potrzeby = forms.CharField(
+        label=u'Czy potrzebowałbyś/łbyś czegoś przed następnymi zajęciami?', widget=forms.Textarea, max_length=4096)
+    uwagi = forms.CharField(label=u'Inne uwagi', widget=forms.Textarea, max_length=4096, required=False)
+
+
+def textarea_field(label, max_length=500):
+    return forms.CharField(
+        label=label, widget=forms.Textarea, max_length=max_length, help_text=u'(do %s znaków)' % max_length)
+
+
+class CybernauciForm(ContactForm):
+    disabled = True
+    disabled_template = 'contact/disabled_contact_form.html'
+    form_tag = 'trenerzy-cybernauci2017'
+    old_form_tags = ['trenerzy-cybernauci']
+    form_title = u"Cybernauci – szkolenie dla trenerów"
+    admin_list = ['nazwisko', 'instytucja', 'contact']
+    submit_label = u'Wyślij'
+    mailing_field = 'zgoda_newsletter'
+
+    nazwisko = forms.CharField(label=u'Imię i nazwisko', max_length=1024)
+    adres = forms.CharField(label=u'Adres zamieszkania')
+    wojewodztwo = forms.ChoiceField(label=u'Województwo', choices=WOJEWODZTWO_CHOICES)
+    contact = forms.CharField(label=u'Adres e-mail')
+    telefon = forms.CharField(label=u'Telefon kontaktowy', max_length=32)
+    dlaczego = textarea_field(
+        label=u'Proszę opisać, dlaczego chce Pan/Pani zostać Emisariuszem Bezpiecznego Internetu.')
+    grupy = forms.MultipleChoiceField(
+        label=u'Proszę wskazać, dla których grup realizował Pan/realizowała Pani zajęcia warsztatowe',
+        widget=forms.CheckboxSelectMultiple,
+        choices=[
+            ('Uczniowie klas 1-3', 'Uczniowie klas 1-3'),
+            ('Uczniowie klas 4-6', 'Uczniowie klas 4-6'),
+            ('Uczniowie szkół gimnazjalnych', 'Uczniowie szkół gimnazjalnych'),
+            ('Uczniowie szkół ponadgimnazjalnych', 'Uczniowie szkół ponadgimnazjalnych'),
+            ('Nauczyciele', 'Nauczyciele'),
+            ('Rodzice', 'Rodzice'),
+        ])
+    doswiadczenie_grupy = textarea_field(
+        label=u'Proszę opisać swoje doświadczenie w pracy warsztatowej z grupami docelowymi Projektu '
+              u'(dziećmi, młodzieżą, osobami dorosłymi: nauczycielami, rodzicami).',
+        max_length=750)
+    doswiadczenie_edumed = textarea_field(
+        label=u'Jakie jest Pana/Pani doświadczenie w zakresie edukacji medialnej, '
+              u'zwłaszcza w zakresie bezpieczeństwa w Internecie i korzystania z TIK? '
+              u'Skąd czerpie Pan/Pani wiedzę w tym zakresie? W jakich projektach brał '
+              u'Pan/brała Pani udział dotychczas?',
+        max_length=750)
+    szkolenia = textarea_field(
+        label=u'Proszę wymienić studia, szkolenia albo kursy (maks. 5 najważniejszych) '
+              u'powiązane z tematyką Projektu, w których Pan/Pani uczestniczył/ła, '
+              u'w tym dane na temat instytucji czy osoby prowadzącej (z JEDNOZDANIOWYM '
+              u'omówieniem i terminami, w których się odbyły).')
+    realizacje = textarea_field(
+        label=u'Proszę opisać swoje doświadczenie w zakresie realizacji działań w lokalnym środowisku '
+              u'szkolnym (np. na terenie gminy/powiatu/województwa).')
+    cel = textarea_field(
+        label=u'Proszę opisać, jaką wiedzę i umiejętności chce Pan/Pani zdobyć '
+              u'lub doskonalić poprzez uczestnictwo w Szkoleniu trenerskim.')
+    skad = forms.CharField(label=u'Skąd dowiedział/dowiedziała się Pan/Pani o projekcie „Cybernauci”?')
+    zgoda_regulamin = forms.BooleanField(
+        label=u'Oświadczam, że zapoznałem/zapoznałam się z Regulaminem Rekrutacji '
+              u'i Uczestnictwa w Projekcie „Cybernauci – kompleksowy projekt '
+              u'kształtowania bezpiecznych zachowań w sieci” i akceptuję jego warunki.',
+        help_text=u'Zobacz <a href="https://cybernauci.edu.pl/wp-content/uploads/2017/04/'
+                  u'regulamin_Cybernauci_szkolenie_trenerskie_2017.pdf">regulamin</a>.')
+    zgoda_dane = forms.BooleanField(
+        label=u'Wyrażam zgodę na przetwarzanie moich danych osobowych zawartych '
+              u'w niniejszym dokumencie dla potrzeb niezbędnych do realizacji Projektu '
+              u'„Cybernauci – kompleksowy projekt kształtowania bezpiecznych zachowań '
+              u'w sieci”  zgodnie z ustawą z dnia 29.08.1997 roku o Ochronie Danych '
+              u'Osobowych (Dz. U. z 2002 r. Nr 101, poz. 926 z późniejszymi zmianami).')
+    zgoda_niekaralnosc = forms.BooleanField(
+        label=u'W przypadku zakwalifikowania się na kurs zobowiązuję się '
+              u'do dostarczenia świadectwa o niekaralności – najpóźniej w dniu rozpoczęcia Szkolenia.')
+    zgoda_newsletter = forms.BooleanField(
+        required=False,
+        label=u'Chcę otrzymywać newsletter Edukacja Medialna.')
+    cv = forms.FileField(
+        label=u'Wgraj plik CV.',
+        help_text=u'Prosimy o nazwanie pliku swoim imieniem i nazwiskiem. Preferowany format: PDF.')
+
+
+class WLEMForm(ContactForm):
+    disabled = True
+    form_tag = 'wlem'
+    form_title = u"WLEM - szkolenie dla warszawskich liderów edukacji medialnej"
+    admin_list = ['nazwisko', 'instytucja', 'contact']
+    submit_label = u'Wyślij'
+    mailing_field = 'zgoda_newsletter'
+
+    nazwisko = forms.CharField(label=u'Imię i nazwisko', max_length=128)
+    contact = forms.CharField(label=u'Adres e-mail')
+    telefon = forms.CharField(label=u'Tel. kontaktowy', max_length=32)
+    instytucja = forms.CharField(label=u'Instytucja', max_length=128)
+    instytucja_adres = forms.CharField(label=u'Adres (instytucji)', max_length=1024)
+    stanowisko = forms.CharField(label=u'Stanowisko', max_length=256)
+    doswiadczenie = forms.CharField(
+        label=u'Jakie jest Pani/Pana doświadczenie w zakresie edukacji medialnej?',
+        widget=forms.Textarea, max_length=4096)
+    dlaczego = forms.CharField(
+        label=u'Dlaczego chce Pani/Pan wziąć udział w szkoleniu?',
+        widget=forms.Textarea, max_length=4096)
+    cel = forms.CharField(
+        label=u'Jaką wiedzę i umiejętności chce Pan/Pani zdobyć lub doskonalić poprzez uczestnictwo w szkoleniu?',
+        widget=forms.Textarea, max_length=4096)
+    jak_wykorzystac = forms.CharField(
+        label=u'Jak zamierza Pan/Pani wykorzystać wiedzę i umiejętności zdobyte w czasie szkolenia?',
+        widget=forms.Textarea, max_length=4096)
+    zgoda_zajecia = forms.BooleanField(
+        label=u'W okresie lipiec-październik 2016 r. przeprowadzę min. 2 godziny zajęć '
+              u'edukacji medialnej z grupą warszawiaków.')
+    zgoda_dane = forms.BooleanField(
+        label=u'Wyrażam zgodę na przetwarzanie moich danych osobowych zawartych '
+              u'w niniejszym dokumencie dla potrzeb niezbędnych do realizacji Projektu '
+              u'„Warszawscy Liderzy Edukacji Medialnej” zgodnie z ustawą z dnia 29.08.1997 '
+              u'roku o Ochronie Danych Osobowych (Dz. U. z 2002 r. Nr 101, poz. 926 '
+              u'z późniejszymi zmianami).')
+    zgoda_newsletter = forms.BooleanField(
+        required=False,
+        label=u'Wyrażam zgodę na otrzymywanie informacji od Fundacji Nowoczesna Polska '
+              u'związanych z edukacją medialną.')
+
+
+def ordered_textarea_field(start, pre_label=u'', label=u'', max_length=500):
+    return textarea_field(
+        mark_safe(u'%s<ol type="a" start="%s"><li>%s</li></ol>' % (pre_label, start, label)),
+        max_length=max_length)
+
+
+def simple_choices(*choices):
+    return tuple((choice, choice) for choice in choices)
+
+
+class CybernauciAnkietaForm(ContactForm):
+    def __init__(self, *args, **kwargs):
+        super(CybernauciAnkietaForm, self).__init__(*args, **kwargs)
+        self.label_suffix = ''
+
+    disabled = True
+    form_tag = 'cybernauci-ankieta-trenera-2017'
+    old_form_tags = ['cybernauci-ankieta-trenera']
+    form_title = u"Cybernauci – ankieta trenerska"
+    nazwisko = forms.CharField(label=u'Imię i nazwisko', max_length=128)
+    contact = forms.CharField(label=u'Adres e-mail')
+    pyt1a = ordered_textarea_field(
+        1, pre_label=u'1. W kontekście planowanego szkolenia jakie są Twoje oczekiwania w zakresie:',
+        label=u'przekazywanej wiedzy')
+    pyt1b = ordered_textarea_field(2, label=u'tematyki szkoleń z bezpieczeństwa w sieci')
+    pyt1c = ordered_textarea_field(3, label=u'materiałów dydaktycznych')
+    pyt1d = ordered_textarea_field(4, label=u'organizacji  i prowadzenia szkoleń w projekcie')
+    pyt1e = ordered_textarea_field(5, label=u'umiejętności trenerskich')
+    pyt1f = ordered_textarea_field(6, label=u'inne, jakie?')
+    pyt2 = textarea_field(u'2. W których tematach z obszaru bezpieczeństwa w sieci czujesz się najpewniej? '
+                          u'Dlaczego?')
+    pyt3 = textarea_field(u'3. Które z tematów znasz słabej lub których nie znasz zupełnie?')
+    pyt4 = textarea_field(u'4. Jakie są Twoje mocne strony jako osoby prowadzącej warsztaty?')
+    pyt5 = textarea_field(u'5. Nad jakimi elementami pracy trenerskiej chciałbyś/chciałabyś popracować?')
+    pyt6 = textarea_field(u'6. Co jest dla Ciebie najważniejsze w pracy z grupą? '
+                          u'Na co zwracasz uwagę w tym obszarze jako osoba prowadząca warsztaty?')
+    pyt7 = textarea_field(
+        u'7. Jakie są Twoje największe obawy wobec realizacji szkoleń w placówkach oświatowych?')
+    pyt8a = ordered_textarea_field(
+        1, pre_label=u'8. Opisz szczegółowo doświadczenie z różnymi grupami:', label=u'rodzice')
+    pyt8b = ordered_textarea_field(2, label=u'nauczyciele')
+    pyt8c = ordered_textarea_field(3, label=u'młodzież ponadgimnazjalna')
+    pyt8d = ordered_textarea_field(4, label=u'młodzież gimnazjalna')
+    pyt8e = ordered_textarea_field(5, label=u'dzieci i młodzież szkół podstawowych')
+    pyt9 = textarea_field(
+        u'9. Z jakimi grupami wiekowymi najlepiej Ci się współpracuje? '
+        u'Umiejętności w zakresie pracy z którą grupą najbardziej chciałabyś/chciałbyś zdobyć/doskonalić?')
+    pyt10 = textarea_field(
+        u'10. W jaki sposób na co dzień dbasz o swój rozwój jako trenera/trenerki, '
+        u'osoby prowadzącej warsztaty czy inne formy szkoleniowe?')
+    pyt11 = textarea_field(u'11. Jakie są Twoje potrzeby żywieniowe?')
+    pyt12 = forms.ChoiceField(
+        label=u'12. Jak przyjedziesz do Wilgi?',
+        widget=forms.RadioSelect,
+        choices=simple_choices(
+            u'publiczna komunikacja do/z Warszawy (i wesoły bus do/z Wilgi)',
+            u'publiczna komunikacja do/z Wilgi',
+            u'samochód prywatny'))
+
+
+class SciezkiKopernikaForm(ContactForm):
+    form_tag = 'sciezki-kopernika'
+    form_title = u'Formularz zgłoszeniowy na warsztaty'
+    disabled = True
+
+    nazwisko = forms.CharField(label=u'Imię i nazwisko uczestnika/uczestniczki', max_length=128)
+    rok_urodzenia = forms.IntegerField(label=u'Rok urodzenia')
+    adres_dom = forms.CharField(label=u'Adres zamieszkania – ulica i numer', max_length=128)
+    adres_poczta = forms.CharField(label=u'Adres zamieszkania – kod pocztowy i miejscowość', max_length=128)
+    contact = forms.EmailField(label=u'Adres e-mail')
+    szkola = forms.CharField(label=u'Nazwa szkoły', max_length=128)
+    adres_szkola = forms.CharField(label=u'Adres szkoły – ulica i numer', max_length=128)
+    poczta_szkola = forms.CharField(label=u'Adres szkoły – kod pocztowy i miejscowość', max_length=128)
+    opiekun = forms.CharField(label=u'Imię i nazwisko rodzica/opiekuna', max_length=128)
+    adres_opiekun = forms.CharField(label=u'Adres zamieszkania rodzica/opiekuna – ulica i numer', max_length=128)
+    poczta_opiekun = forms.CharField(
+        label=u'Adres zamieszkania rodzica/opiekuna – kod pocztowy i miejscowość', max_length=128)
+    telefon_opiekun = forms.CharField(label=u'Numer telefonu rodzica/opiekuna', max_length=32)
+    email_opiekun = forms.EmailField(label=u'Adres e-mail rodzica/opiekuna', max_length=32)
+    specjalne_potrzeby = forms.ChoiceField(
+        label=u'Czy uczestnik/uczestniczka ma specjalne potrzeby wynikające z niepełnosprawności', required=True,
+        choices=[('tak', 'tak'), ('nie', 'nie')], widget=forms.RadioSelect)
+    zgoda_regulamin = forms.BooleanField(
+        label=mark_safe(
+            u'Oświadczam, że zapoznałem/am się z <a href="/media/chunks/attachment/Regulamin.pdf" target="_blank">'
+            u'Regulaminem udziału w projekcie</a> '
+            u'i spełniam kryteria kwalifikowalności do udziału w projekcie.'))
+
+
+class CollegiumMlodychForm(ContactForm):
+    form_tag = 'collegium-mlodych'
+    form_title = u'Formularz zgłoszeniowy na warsztaty'
+    disabled = True
+    disabled_template = 'contact/collegium-mlodych/on_hold.html'
+
+    nazwisko = forms.CharField(label=u'Imię i nazwisko uczestnika/uczestniczki', max_length=128)
+    pesel = forms.CharField(label=u'PESEL', max_length=11)
+    adres_dom = forms.CharField(label=u'Adres zamieszkania – ulica i numer', max_length=128)
+    adres_poczta = forms.CharField(label=u'Adres zamieszkania – kod pocztowy i miejscowość', max_length=128)
+    contact = forms.EmailField(label=u'Adres e-mail')
+    szkola = forms.CharField(label=u'Nazwa szkoły', max_length=128)
+    adres_szkola = forms.CharField(label=u'Adres szkoły – ulica i numer', max_length=128)
+    poczta_szkola = forms.CharField(label=u'Adres szkoły – kod pocztowy i miejscowość', max_length=128)
+    opiekun = forms.CharField(label=u'Imię i nazwisko rodzica/opiekuna prawnego', max_length=128)
+    telefon_opiekun = forms.CharField(label=u'Numer telefonu rodzica/opiekuna prawnego', max_length=32)
+    email_opiekun = forms.EmailField(label=u'Adres e-mail rodzica/opiekuna prawnego')
+    specjalne_potrzeby = forms.ChoiceField(
+        label=u'Czy uczestnik/uczestniczka ma specjalne potrzeby wynikające z niepełnosprawności',
+        choices=[('tak', 'tak'), ('nie', 'nie')], widget=forms.RadioSelect)
+    skad = forms.CharField(label=u'Skąd dowiedziałeś/aś się o warsztatach?')
+    zgoda_regulamin = forms.BooleanField(
+        label=mark_safe(
+            u'Oświadczam, że zapoznałem/am się z <a href="/media/chunks/attachment/REGULAMIN-UCZESTNICTWA-W-PROJEKCIE_aktualizacja.pdf" target="_blank">'
+            u'Regulaminem udziału w projekcie</a> '
+            u'i spełniam kryteria kwalifikowalności do udziału w projekcie.'))
+
+
+class SciezkiKopernikaTestForm(TestForm):
+    def __init__(self, *args, **kwargs):
+        super(SciezkiKopernikaTestForm, self).__init__(*args, **kwargs)
+        self.label_suffix = ''
+
+    result_page = True
+    form_tag = 'sciezki-kopernika-test'
+    form_title = u'Test wiedzy w zakresie edukacji medialnej i cyfrowej'
+    submit_label = u'Wyślij'
+
+    contact = forms.EmailField(label=u'Adres e-mail, na który przyślemy informację o wynikach')
+    head1 = HeaderField(
+        label=u'Test powstał w ramach projektu "Collegium Młodych - media i technologie" realizowany w ramach '
+              u'III Osi priorytetowej: Szkolnictwo wyższe dla gospodarki i rozwoju, Działanie 3.1 Kompetencje '
+              u'w szkolnictwie wyższym Programu Operacyjnego Wiedza Edukacja Rozwój, współfinansowanego przez '
+              u'Unię Europejską w ramach Europejskiego Funduszu Społecznego. Nr umowy POWR.03.01.00-00-C078/16-00.')
+
+    @classmethod
+    def results(cls, contact):
+        fields = cls().fields
+
+        def get_idx(choices, answer):
+            return dict((score, i) for i, (score, text) in enumerate(choices))[answer]
+
+        def question_data(i):
+            field = 'pyt%s' % i
+            choices = fields[field].choices
+            score = contact.body[field]
+            chosen_idx = get_idx(choices, score)
+            correct_idx = get_idx(choices, 2)
+            return {
+                'score': score,
+                'chosen_idx': chosen_idx,
+                'correct_idx': correct_idx,
+                'chosen': 'abc'[chosen_idx],
+                'correct': 'abc'[correct_idx],
+                'label': fields[field].label,
+                'comment': mark_safe(markdown.convert(cls.ANSWER_COMMENTS[i-1][chosen_idx])),
+                'answers': [(text, a_score == score, a_score == 2) for a_score, text in choices],
+            }
+        question_count = 20
+        questions = [question_data(i) for i in xrange(1, question_count + 1)]
+        points = sum(question['score'] for question in questions)
+        return {'questions': questions, 'points': points/2., 'total': question_count}
+
+
+class CollegiumMlodychTestForm(CollegiumTestForm):
+    def __init__(self, *args, **kwargs):
+        super(CollegiumMlodychTestForm, self).__init__(*args, **kwargs)
+        self.label_suffix = ''
+
+    result_page = True
+    form_tag = 'collegium-mlodych-test'
+    form_title = u'Test wiedzy w zakresie edukacji medialnej i cyfrowej'
+    submit_label = u'Wyślij'
+
+    contact = forms.EmailField(label=u'Adres e-mail, na który przyślemy informację o wynikach')
+
+    @classmethod
+    def results(cls, contact):
+        fields = cls().fields
+
+        def question_data(i):
+            field = 'pyt%s' % i
+            choices = fields[field].choices
+            answers = contact.body[field]
+            answer_data = []
+            for answer in answers:
+                idx = answer // 10
+                answer_data.append(
+                    {
+                        'score': answer % 10,
+                        'index': idx,
+                        'letter': 'abcdef'[idx],
+                        'comment': mark_safe(markdown.convert(cls.ANSWER_COMMENTS[i-1][idx])),
+                    })
+            correct = [answer // 10 for answer, text in choices if answer % 10 == 1]
+            return {
+                'answer_data': answer_data,
+                'correct': correct,
+                'correct_letters': ['abcdef'[idx] for idx in correct],
+                'label': fields[field].label,
+                'answers': [(text, a_score in answers, a_score % 10 == 1) for a_score, text in choices],
+                'full_match': set(answer['index'] for answer in answer_data) == set(correct)
+            }
+        question_count = 20
+        questions = [question_data(i) for i in xrange(1, question_count + 1)]
+        points = sum(1 for question in questions if question['full_match'])
+        return {'questions': questions, 'points': points, 'total': question_count}
+
+
+class ESEMWarszawaForm(ContactForm):
+    form_tag = 'emels-warszawa'
+    form_title = u"Ja i młodzież w cyfrowym świecie"
+    admin_list = ['imie', 'nazwisko', 'instytucja', 'contact']
+    submit_label = u'Wyślij'
+    mailing_field = 'zgoda_newsletter'
+    disabled = True
+    disabled_template = 'contact/disabled_contact_form.html'
+
+    imie = forms.CharField(label=u'Imię', max_length=128)
+    nazwisko = forms.CharField(label=u'Nazwisko', max_length=128)
+    contact = forms.EmailField(
+        label=u'Adres e-mail', max_length=128, help_text=u'Wyślemy na niego informacje organizacyjne.')
+    telefon = forms.CharField(
+        label=u'Numer telefonu', max_length=20,
+        help_text=u'Liczba miejsc na warsztatach jest ograniczona, będziemy telefonicznie potwierdzać '
+                  u'obecność, a w przypadku rezygnacji chcielibyśmy móc udostępnić miejsce kolejnej '
+                  u'zainteresowanej osobie.')
+    motywacja = forms.CharField(
+        label=u'W jaki sposób wykorzystasz wiedzę zdobytą na warsztatach?', max_length=1000,
+        widget=forms.Textarea)
+    instytucja = forms.CharField(label=u'Organizacja/instytucja', max_length=255)
+    zgoda_newsletter = forms.BooleanField(
+        required=False,
+        label=u'Chcę otrzymywać newsletter Edukacja medialna.')
+
+
+class ESEMGdanskForm(ESEMWarszawaForm):
+    form_tag = 'emels-gdansk'
+
+
+class MisjaCybernautowForm(ContactForm):
+    form_tag = 'misja-cybernautow'
+    form_title = u"Misja Cybernautów"
+    submit_label = u'Zapisz'
+    updatable = True
+    contact = forms.EmailField(label=u'Adres e-mail', max_length=128)
+    szkola = forms.CharField(label=u'Szkoła, do której chodzicie', max_length=255)
+    zespol = forms.CharField(label=u'Nazwa zespołu', max_length=255)
+    zdjecie_warszawa = forms.FileField(
+        label=u'Dołączcie zdjęcie pokazujące, że jesteście dziś w Warszawie', required=False)
+    zdjecie_planetarium = forms.FileField(
+        label=u'Dołączcie zdjęcie grupy na scenie przy planetarium', required=False)
+    zdjecie_zasady = forms.FileField(
+        label=u'Dołączcie zdjęcie napisanych przez Was zasad bezpiecznego korzystania z internetu', required=False)
+    zdjecie_piasek = forms.FileField(
+        label=u'Dołączcie zdjęcie zdjęcie notatki zrobionej na piasku', required=False)
+    sonda = forms.CharField(
+        widget=forms.Textarea, max_length=1000, required=False,
+        label=u'Jaki macie wnioski z sondy zrobionej w BUW-ie?')
+    fasada = forms.FileField(
+        label=u'Dołączcie zdjęcie kodu programu umieszczonego na fasadzie BUW-u', required=False)
+    ochrona = forms.CharField(
+        label=u'Jakie są Wasze pomysły na ochronę przed zagrożeniami na podstawie filmiku z kanału '
+              u'„To już jutro” na YouTube',
+        widget=forms.Textarea, max_length=1000, required=False)
+    obraz = forms.CharField(
+        label=u'Który obraz z Galerii Sztuki Polskiej wybraliście? Załączcie link', required=False, max_length=255)
+    haslo = forms.CharField(
+        label=mark_safe(u'Jaka jest Wasza propozycja mocne hasło, które stworzyliście i sprawdziliście na stronie '
+                        u'<a href="https://howsecureismypassword.net" target="_blank">'
+                        u'https://howsecureismypassword.net</a>?'),
+        required=False, max_length=255)
+    syrenka = forms.FileField(
+        label=u'Dołaczcie zdjęcie pomysłu podpisu na pomniku Syrenki', required=False)
+    mem = forms.FileField(label=u'Dołączcie stworzony mem', required=False)
+    gif = forms.FileField(label=u'Dołączcie stworzony gif', required=False)
diff --git a/src/edumed/contact_forms_test.py b/src/edumed/contact_forms_test.py
new file mode 100644 (file)
index 0000000..ebfe2fd
--- /dev/null
@@ -0,0 +1,1312 @@
+# -*- coding: utf-8 -*-
+from django import forms
+from django.utils.safestring import mark_safe
+
+from contact.forms import ContactForm
+
+
+def quiz_question(label, choices):
+    return forms.TypedChoiceField(label=label, choices=choices, coerce=int, widget=forms.RadioSelect)
+
+
+def quiz_question_multiple(label, choices):
+    return forms.TypedMultipleChoiceField(label=label, choices=choices, coerce=int, widget=forms.CheckboxSelectMultiple)
+
+
+def make_link(text, url):
+    return u'<a href="%s">%s</a>' % (url, text)
+
+
+class TestForm(ContactForm):
+    pyt1 = quiz_question(
+        label=u'1. Na stronie portalu internetowego pod jednym z artykułów opublikowano komentarz o treści '
+              u'„Nie wszyscy muzułmanie to terroryści, ale wszyscy terroryści to muzułmanie”. '
+              u'Komentarz podlega moderacji i powinien:',
+        choices=[
+            (1, u'zostać zachowany, ponieważ jest prywatną opinią korzystającą z wolności słowa,'),
+            (0, u'zostać zachowany, ponieważ informuje o fakcie,'),
+            (2, u'zostać usunięty, ponieważ jest wprowadzającą w błąd interpretacją faktów.'),
+        ])
+    pyt2 = quiz_question(
+        label=u'2. Aby przygotować podcast, należy posiadać przynajmniej:',
+        choices=[
+            (0, u'półprofesjonalny mikrofon radiowy, z wbudowanym interfejsem dźwiękowym, '
+                u'komercyjne oprogramowanie typu DAW, średnio-zaawansowane umiejętności cyfrowej obróbki dźwięku,'),
+            (1, u'urządzenie do nagrywania dźwięku, laptop, oprogramowanie dedykowane do tworzenia podcastów,'),
+            (2, u'urządzenie do nagrywania dźwięku, podstawowe oprogramowanie do edycji dźwięku, '
+                u'podstawowe umiejętności cyfrowej obróbki dźwięku.')])
+    pyt3 = quiz_question(
+        label=u'3. Muzeum cyfrowe chce udostępnić skan XIV-wiecznego kodeksu. '
+              u'Zgodnym z ideą domeny publicznej sposobem jego udostępnienia będzie:',
+        choices=[
+            (0, u'udostępnienie go na licencji Creative Commons,'),
+            (2, u'udostępnienie go bez licencji z czytelnym wskazaniem praw do dowolnego wykorzystania,'),
+            (1, u'udostępnienie go w pliku jakości produkcyjnej.')])
+    pyt4 = quiz_question(
+        label=u'4. Aby uniknąć możliwości podejrzenia przez niepowołane osoby, jakie strony internetowe '
+              u'odwiedzałaś/eś ostatnio, powinieneś/powinnaś:',
+        choices=[
+            (0, u'ustawić opcję otwierania nowej sesji przeglądarki bez wyświetlania ostatnio używanych kart '
+                u'oraz regularnie czyścić historię wyszukiwania,'),
+            (2, u'wylogowywać się lub blokować ekran za każdym razem, kiedy odchodzisz od komputera, tabletu '
+                u'lub odkładasz gdzieś telefon, regularnie czyścić dane zgromadzone przez przeglądarkę internetową,'),
+            (1, u'wylogowywać się lub blokować ekran za każdym razem, kiedy odchodzisz od komputera, tabletu '
+                u'lub odkładasz gdzieś telefon, regularnie czyścić historię przeglądanych stron.')])
+    pyt5 = quiz_question(
+        label=u'5. Komentarz opublikowany w Internecie ma taką samą wartość bez względu na to, '
+              u'czy jest anonimowy czy podpisany imieniem i nazwiskiem:',
+        choices=[
+            (0, u'tak, ze względu na zasadę wolności słowa,'),
+            (2, u'to zależy od jego treści i kontekstu, w którym go opublikowano,'),
+            (1, u'tak, z punktu widzenia odpowiedzialności prawnej.')])
+    pyt6 = quiz_question(
+        label=u'6. Wraz z grupą osób zamierzasz przygotować cyfrową opowieść (narrację) na temat współczesnych '
+              u'nastolatków i ich stosunku do szkoły. Żeby praca była efektywna, a jej rezultat efektowny, warto '
+              u'zorganizować wspólną pracę w następujących krokach:',
+        choices=[
+            (2, u'przeprowadzić wspólną dyskusję odnośnie możliwych tematów opowieści, wybrać jeden, ustalić, '
+                u'co należy zrobić, podzielić zadania w grupie i przygotować scenariusz narracji '
+                u'(opisać poszczególne sceny, co się w nich znajdzie, co będzie potrzebne do ich przygotowania),'),
+            (0, u'zgromadzić jak najwięcej materiałów wideo i zdjęć, wybrać oprogramowanie do obróbki wideo i wspólnie '
+                u'decydować o kolejności scen i zawartości opowieści,'),
+            (1, u'wybrać temat opowieści, zgromadzić jak najwięcej filmików i zdjęć, podzielić się zadaniami w grupie, '
+                u'zmontować narrację z części przygotowanych przez uczestników zespołu.')])
+    pyt7 = quiz_question(
+        label=u'7. Firma telekomunikacyjna wykorzystuje boty do automatycznego odpowiadania na pytania klientów '
+              u'zadawane w serwisie społecznościowym. Boty zwracają się do wszystkich po imieniu. Kiedy użytkownik, '
+              u'który sobie tego nie życzy, wyraża swoje niezadowolenie z takiej formy rozmowy, firma powinna:',
+        choices=[
+            (2, u'przeprosić użytkownika, szanując preferowane przez niego reguły komunikacji,'),
+            (0, u'zignorować użytkownika odwołując się do zasad netykiety,'),
+            (1, u'zareagować zgodnie z wypracowanymi wewnętrznie zasadami komunikacji.')])
+    pyt8 = quiz_question(
+        label=u'8. Jesteś członkiem/członkinią grupy, która przygotowuje aplikację mającą ułatwić osobom '
+              u'z niepełnosprawnościami poruszanie się po Twojej miejscowości. Oprogramowanie będzie m.in. informować, '
+              u'czy przy określonej instytucji, firmie, sklepie, znajdują się miejsca parkingowe dla osób '
+              u'z niepełnosprawnościami i ile ich jest. Aby aplikacja działała prawidłowo, powinieneś/powinnaś:',
+        choices=[
+            (1, u'przygotować listę najważniejszych obiektów w Twoim mieście i skontaktować się z ich administracją, '
+                u'pytając o liczbę miejsc parkingowych,'),
+            (0, u'poszukać informacji o dostępnych miejscach parkingowych na stronach instytucji, firm i sklepów,'),
+            (2, u'skontaktować się z administracją obiektów, o których będzie informować aplikacja, udać się również '
+                u'do tych obiektów, aby potwierdzić ilość dostępnych miejsc, spróbować zgromadzić informacje o tym, '
+                u'jak często miejsca parkingowe są zajmowane przez ludzi pełnosprawnych.')])
+    pyt9 = quiz_question(
+        label=u'9. Pojęcie „niewidzialnej pracy” może dotyczyć:',
+        choices=[
+            (2, u'moderatorów mediów społecznościowych zatrudnianych w krajach o niskich kosztach pracy,'),
+            (1, u'użytkowników serwisów społecznościowych publikujących codziennie i bez wynagrodzenia własne '
+                u'materiały w tym serwisie,'),
+            (0, u'informatyków budujących rozwiązania IT dla firm.')])
+
+    pyt10 = quiz_question(
+        label=u'10. Możesz uważać, że informacje, do których docierasz, są wiarygodne, ponieważ:',
+        choices=[
+            (1, u'pojawiają się w wielu telewizyjnych serwisach informacyjnych, na profilach społecznościowych '
+                u'moich znajomych i w różnorodnych internetowych serwisach informacyjnych, wszędzie przedstawiane '
+                u'są w podobny sposób,'),
+            (2, u'pojawiają się w wielu serwisach informacyjnych, na profilach moich znajomych, zawierają odnośniki '
+                u'do oryginalnych źródeł, do których można dotrzeć,'),
+            (0, u'pojawiają się na profilach wielu moich znajomych w serwisach społecznościowych i '
+                u'w kilku internetowych serwisach informacyjnych.')])
+    pyt11 = quiz_question(
+        label=u'11. W pewnym mieście prokuratura bada umowy z wykonawcami projektów budżetu obywatelskiego. '
+              u'Nikomu, jak dotąd, nie postawiono zarzutów. Która postać tytułu newsa opublikowanego '
+              u'na lokalnym portalu internetowym będzie najbardziej zgodna z zasadami etyki dziennikarskiej?',
+        choices=[
+            (1, u'„Budżet obywatelski: niejasne umowy z wykonawcami?”,'),
+            (2, u'„Prokuratura zbada umowy z wykonawcami projektów budżetu obywatelskiego.”,'),
+            (0, u'„Zobacz, które firmy mogły obłowić się na projektach budżetu obywatelskiego!”.')])
+    pyt12 = quiz_question(
+        label=u'12. Dołączyłeś/aś do grupy, która zbiera informacje o problemach dotyczących młodych ludzi '
+              u'w Twojej okolicy. Zamierzacie zaprezentować zgromadzone informacje w interesujący sposób, '
+              u'tak by zainteresować lokalne media, służby miejskie, zwykłych obywateli i Waszych rówieśników. '
+              u'Grupa nie ma możliwości regularnego spotykania się, dlatego wybraliście pracę wyłącznie '
+              u'przez Internet. Który zestaw narzędzi pozwoli Wam na jak najlepszą, wspólną pracę?',
+        choices=[
+            (0, u'mail grupowy, komunikator tekstowy (np. Messenger), oprogramowanie do tworzenia podcastów, '
+                u'stacjonarne narzędzie do tworzenia prezentacji (np. Power Point),'),
+            (1, u'mail grupowy, komunikator tekstowy zespołu (np. Slack), narzędzie do kolektywnego tworzenia '
+                u'map myśli (np. Coggle), blog redagowany przez wszystkich uczestników projektu, aplikacja do '
+                u'synchronizowania plików w chmurze (np. Dropbox), narzędzie do grupowej komunikacji za pomocą wideo '
+                u'(np. Skype),'),
+            (2, u'aplikacja do zarządzania zadaniami zespołu i terminami do wykonania (np. Wunderlist), '
+                u'narzędzie do tworzenia kolektywnych notatek (np. OneNote) lub wspólnej pracy z tekstem '
+                u'(np. EtherPad, Google Dokumenty), grupa w serwisie społecznościowym lub tekstowy komunikator '
+                u'zespołu (np. Messenger lub Slack), narzędzia do gromadzenia lub prezentowania materiałów '
+                u'(np. wspólny blog, kanał w serwisie społecznościowym).')])
+    pyt13 = quiz_question(
+        label=u'13. Poniżej podano wybrane cechy hasła opublikowanego w Wikipedii. '
+              u'Która z nich jest najbardziej pomocna przy analizie jakości hasła?',
+        choices=[
+            (0, u'liczba edycji hasła,'),
+            (1, u'długość i struktura hasła,'),
+            (2, u'obecność i jakość przypisów.')])
+    pyt14 = quiz_question(
+        label=u'14. Na przeglądanej stronie internetowej znalazłeś/aś interesującą grafikę, którą chciał(a)byś '
+              u'wykorzystać w przygotowywanej cyfrowej narracji. Nie jest ona jednak podpisana. Co robisz?',
+        choices=[
+            (0, u'podpisuję grafikę adresem strony, na której ją znalazłem/am,'),
+            (1, u'korzystam z opcji wyszukiwania obrazem w wyszukiwarce grafiki, chcąc znaleźć inne strony, '
+                u'gdzie pojawiła się grafika,'),
+            (2, u'korzystam z opcji wyszukiwania obrazem, a jeśli to się nie powiedzie, skontaktuję się '
+                u'z administratorem strony, na której znalazłem/am grafikę, pytając o autora; przeglądam także '
+                u'informacje o stronie, szukając ewentualnych informacji o zasadach publikacji treści; być może '
+                u'autor informuje, że wszystkie grafiki są jego autorstwa.')])
+    pyt15 = quiz_question(
+        label=mark_safe(
+            u'15. W nieistniejącym języku programowania TEST dana jest funkcja zapisana w następujący sposób:'
+            u'<p><code>funkcja f(a) { wyświetl a + b;<br>'
+            u'}</code></p>'
+            u'<strong>Przeczytaj uważnie kod i zastanów się, jak działa ta funkcja.'
+            u'Główną wadą tego kodu jest przetwarzanie brakującego argumentu:</strong>'),
+        choices=[
+            (2, u'b,'),
+            (1, u'b będącego dowolną liczbą,'),
+            (0, u'f.')])
+    pyt16 = quiz_question(
+        label=u'16. Przygotowujesz teledysk do utworu nagranego przez Twój zespół. Efekt swojej pracy opublikujesz '
+              u'na kanale zespołu na YouTube. Teledysk nie może łamać praw autorskich, w przeciwnym razie zostanie '
+              u'usunięty z serwisu. W teledysku możesz wykorzystać zdjęcia, ikony, fragmenty filmów:',
+        choices=[
+            (1, mark_safe(
+                u'znalezionych w wyszukiwarce serwisu Flickr na licencji %s, przygotowanych przez Ciebie, '
+                u'ściągniętych z serwisu %s,' % (
+                    make_link(u'CC BY-SA', 'https://www.flickr.com/creativecommons/by-sa-2.0/'),
+                    make_link(u'The Noun Project', 'https://thenounproject.com')))),
+            (2, mark_safe(
+                u'znalezionych w wyszukiwarce serwisu Flickr na licencji %s, przygotowanych przez Ciebie, '
+                u'ściągniętych z %s,' % (
+                    make_link(u'CC-BY', 'https://www.flickr.com/creativecommons/by-2.0/'),
+                    make_link(u'serwisu ze zdjęciami NASA',
+                              'https://www.nasa.gov/multimedia/imagegallery/index.html')))),
+            (0, mark_safe(
+                u'znalezionych w wyszukiwarce serwisu Flickr na licencji %s, przygotowanych przez Ciebie, '
+                u'ściągniętych z wyszukiwarki grafiki Google.' %
+                make_link('CC-BY-NC', 'https://www.flickr.com/creativecommons/by-nc-2.0/')))])
+    pyt17 = quiz_question(
+        label=mark_safe(
+            u'17. Muzeum cyfrowe udostępniło skan druku propagandowego z pierwszej połowy XVII w. '
+            u'w humorystyczny sposób przedstawiający strony angielskiej wojny domowej (trwającej z przerwami '
+            u'między 1642 a 1651 rokiem):'
+            u'<p><a href="https://commons.wikimedia.org/wiki/File:Engl-Bürgerkrieg.JPG">'
+            u'<img src="https://upload.wikimedia.org/wikipedia/commons/c/c6/Engl-B%C3%BCrgerkrieg.JPG"></a></p>'
+            u'<p><a href="https://commons.wikimedia.org/wiki/File:Engl-Bürgerkrieg.JPG">'
+            u'https://commons.wikimedia.org/wiki/File:Engl-Bürgerkrieg.JPG</a></p>'
+            u'<strong>Najlepszym zestawem tagów dla osoby katalogującej pliki cyfrowe w muzeum, '
+            u'a równocześnie najbardziej użytecznym dla użytkowników przeszukujących stronę '
+            u'zestawem słów kluczowych opisujących ten obiekt będzie:</strong>'),
+        choices=[
+            (2, u'Anglia, wojna domowa, karykatura, propaganda,'),
+            (0, u'komiks, śmiech, Anglicy, Wielka Brytania, psy,'),
+            (1, u'Angielska Wojna Domowa 1642-1651, propaganda.')])
+    pyt18 = quiz_question(
+        label=u'18. Podczas wycieczki szkolnej zrobiłaś/eś sporo zdjęć znajomym, w różnych sytuacjach. '
+              u'Masz również dostęp do wielu fotografii, które przygotowali Twoi koledzy i koleżanki. '
+              u'Zamierzasz niektóre z nich zamieścić na swoim kanale w serwisie społecznościowym. Możesz opublikować:',
+        choices=[
+            (0, u'zdjęcia prezentujące selfie (o ile nie przedstawiają więcej niż dwóch osób), '
+                u'zdjęcia grupy podczas zwiedzania, zdjęcia, które ktoś zrobił Tobie na tle zwiedzanych obiektów, '
+                u'zdjęcia, na których ludzie się uśmiechają i cieszą, że robisz im zdjęcie,'),
+            (1, u'zdjęcia prezentujące selfie (ale tylko Twoje), zdjęcia pokazujące w oddali grupę na tle '
+                u'zwiedzanych obiektów, zdjęcia, zdjęcia na których widać tylko Ciebie, na tle zwiedzanych obiektów,'),
+            (2, u'zdjęcia prezentujące selfie (na których jesteś Ty, ale również inne osoby, które potwierdziły, '
+                u'że możesz opublikować fotografie), zdjęcia na których widać tylko Ciebie '
+                u'i masz zgodę na ich publikację od osoby, która wykonała fotografię, '
+                u'wykonane przez Ciebie zdjęcia zwiedzanych obiektów.')])
+    pyt19 = quiz_question(
+        label=u'19. Korzystając z sieci, natrafiamy na różne interesujące informacje. '
+              u'Pojawiają się w wielu serwisach informacyjnych, społecznościowych, w postaci reklam '
+              u'dołączanych do materiałów wideo, reklam zamieszczonych w tekstach itp. '
+              u'Na co warto zwracać uwagę, podczas codziennego korzystania z mediów, '
+              u'żeby efektywnie wykorzystać czas spędzony w Internecie?',
+        choices=[
+            (1, u'zaplanować czas spędzany na korzystaniu z mediów i starać się trzymać swojego planu, '
+                u'nie unikasz jednak nagłych rozmów przez komunikator, oglądania postów, '
+                u'zdjęć i filmików dodawanych przez znajomych,'),
+            (0, u'zaplanować, co będziesz robił(a), ale traktujesz to jako ramę działania, wiesz, '
+                u'że po drodze pojawi się wiele interesujących informacji, z których skorzystasz,'),
+            (2, u'zaplanować czas spędzany na korzystaniu z mediów i rejestrować, co, '
+                u'kiedy i przez ile czasu robisz, np. instalując aplikację do mierzenia czasu spędzanego w sieci. '
+                u'Następnie analizujesz zebrane informacje i starasz się określić, co robisz zbyt często '
+                u'i jakie rzeczy odciągają Twoją uwagę od tych zaplanowanych.')])
+    pyt20 = quiz_question(
+        label=u'20. Blokująca reklamy wtyczka do przeglądarki działa w następujący sposób:',
+        choices=[
+            (0, u'analizuje treść tekstów oraz obrazków i blokuje te, które zawierają reklamy,'),
+            (1, u'blokuje wyświetlanie plików reklam zanim wyświetli je przeglądarka,'),
+            (2, u'blokuje komunikację przeglądarki z serwerami publikującymi reklamy.')])
+
+    ANSWER_COMMENTS = [
+        (
+            u"Stwierdzenie „Nie wszyscy muzułmanie to terroryści, ale wszyscy terroryści to muzułmanie” nie "
+            u"odzwierciedla faktów. O ile prawdą jest, że „Nie wszyscy muzułmanie to terroryści”, to błędnym "
+            u"założeniem jest, że „wszyscy terroryści są muzułmanami”. Terroryzm jako akt agresji fizycznej wymierzony"
+            u" przeciwko innym osobom nie jest domeną tej, czy innej religii. Wynika on często z fundamentalistycznych "
+            u"postaw i może pojawić się w różnych kontekstach politycznych i społecznych, a nie tylko religijnych. "
+            u"Z drugiej strony, każdemu użytkownikowi Internetu przysługuje wolność słowa, która oznacza prawo "
+            u"do publicznego wyrażania własnych poglądów w przestrzenie publicznej. Zachęca do tego zwłaszcza możliwość"
+            u" zostawiania komentarzy pod różnego rodzaju artykułami. Należy liczyć się z tym, że część z nich może "
+            u"wprowadzać w błąd. Jeśli przyjmiemy interpretację, zgodnie z którą wpis użytkownika na portalu "
+            u"internetowym jest opinią, to mamy prawo do jego zachowania.\n"
+            u"Jeśli chcesz pogłębić swoją wiedzę na temat „terroryzmu” możesz przeczytać artykuł "
+            u"pt. „Zjawisko terroryzmu”: "
+            u"http://www.ies.krakow.pl/wydawnictwo/prokuratura/pdf/2012/07-08/11resztak.pdf.\n"
+            u"\n"
+            u"O prawie do wolności wypowiedzi w Internecie i zagrożeniach związanych z jego ograniczeniem możesz "
+            u"przeczytać w komentarzu prawnika pt. „Masz prawo swobodnie wypowiadać się w Internecie, tak samo jak "
+            u"wyjść z domu i chodzić po ulicach!”: "
+            u"http://prawokultury.pl/newsy/masz-prawo-swobodnie-wypowiadac-sie-w-internecie-t/.",
+
+            u"Stwierdzenie „Nie wszyscy muzułmanie to terroryści, ale wszyscy terroryści to muzułmanie” nie "
+            u"odzwierciedla faktów. W tym przypadku należy odróżnić fakt, czyli coś co naprawdę się wydarzyło, "
+            u"od opinii, która określa nasz sąd na temat wybranych przez nas kwestii. O ile prawdą jest, że "
+            u"„Nie wszyscy muzułmanie to terroryści”, to błędnym założeniem jest, że „wszyscy terroryści są "
+            u"muzułmanami”. Terroryzm jako akt agresji fizycznej wymierzony przeciwko innym osobom nie jest domeną "
+            u"tej, czy innej religii. Wynika on często z fundamentalistycznych postaw i może pojawić się w różnych "
+            u"kontekstach politycznych i społecznych, a nie tylko religijnych. Zachowanie wpisu zawierającego powyższą "
+            u"treść może wprowadzać w błąd jego czytelników ponieważ nie odnosi się do faktów, dlatego najlepszą opcją "
+            u"jest jego usunięcie.\n"
+            u"\n"
+            u"Jeśli chcesz pogłębić swoją wiedzę na temat „terroryzmu” możesz przeczytać artykuł "
+            u"pt. „Zjawisko terroryzmu”: "
+            u"http://www.ies.krakow.pl/wydawnictwo/prokuratura/pdf/2012/07-08/11resztak.pdf.",
+
+            u"Stwierdzenie „Nie wszyscy muzułmanie to terroryści, ale wszyscy terroryści to muzułmanie” "
+            u"nie odzwierciedla faktów i jest błędną ich interpretacją W tym przypadku należy odróżnić fakt, "
+            u"czyli coś, co naprawdę się wydarzyło, od opinii, która określa nasz sąd na temat wybranych przez nas "
+            u"kwestii. O ile prawdą jest, że „Nie wszyscy muzułmanie to terroryści”, to błędnym założeniem jest, że "
+            u"„wszyscy terroryści są muzułmanami”. Terroryzm jako akt agresji fizycznej wymierzony przeciwko innym "
+            u"osobom nie jest domeną tej, czy innej religii. Wynika on często z fundamentalistycznych postaw i może "
+            u"pojawić się w różnych kontekstach politycznych i społecznych, a nie tylko religijnych. Zachowanie wpisu "
+            u"zawierającego powyższą treść może wprowadzać w błąd jego czytelników, dlatego najlepszą opcją jest jego "
+            u"usunięcie.\n"
+            u"\n"
+            u"Jeśli chcesz pogłębić swoją wiedzę na temat „terroryzmu” możesz przeczytać artykuł "
+            u"pt. „Zjawisko terroryzmu”: "
+            u"http://www.ies.krakow.pl/wydawnictwo/prokuratura/pdf/2012/07-08/11resztak.pdf."),
+        (
+            u"Wymienione narzędzia i umiejętności brzmią bardzo profesjonalnie, a ich wartość wydaje się być "
+            u"bardzo wysoka. Jeśli każdy zakładałby, że wszystkie one są potrzebne do rozpoczęcia nagrywania audycji, "
+            u"nigdy by tego nie zrobił.\n"
+            u"\n"
+            u"Tak jak nie od razu Rzym zbudowano, tak nie od razu trzeba nagrywać w profesjonalnym studio. Nawet "
+            u"zawodowi podcasterzy od czegoś musieli zacząć – w większości od mikrofonu wbudowanego w komputer. Prawie "
+            u"każdy młody człowiek ma w ręku znacznie doskonalsze narzędzie, jakim jest smartfon. W Internecie można "
+            u"łatwo znaleźć darmowe oprogramowanie do obróbki dźwięku i tutoriale, które pomogą w tworzeniu podcastu.\n"
+            u"\n"
+            u"O tym, jak zacząć tworzyć podcast, nie wydając nawet złotówki przeczytasz tu: "
+            u"https://malawielkafirma.pl/wlasny-podcast-za-darmo/.",
+
+            u"Wymienione narzędzia i umiejętności brzmią profesjonalnie, nie wszyscy mogą pozwolić sobie na taki "
+            u"zakup. Ale czy faktycznie jest to konieczne? Jeśli każdy zakładałby, że wszystkie one są potrzebne do "
+            u"rozpoczęcia nagrywania audycji, nigdy by tego nie zrobił. Do przygotowania podcastu nie trzeba "
+            u"wykorzystywać komputera. Potrzebne jest urządzenie, które pozwoli na nagrywanie dźwięku i jego "
+            u"podstawową obróbkę (może to być zatem także smartfon).\n"
+            u"\n"
+            u"O tym, jak zacząć tworzyć podcast nie wydając nawet złotówki przeczytasz tu: "
+            u"https://malawielkafirma.pl/wlasny-podcast-za-darmo/.",
+
+            u"Urządzenie do nagrywania dźwięku i możliwość jego podstawowej edycji (zarówno jeśli chodzi o dostępne "
+            u"oprogramowanie, jak i posiadane umiejętności), to wystarczający początek. Z czasem, jeśli tworzenie "
+            u"podcastu okaże się pasją, można zdecydować się na poszerzenie wachlarza narzędzi, którymi będzie się "
+            u"posługiwać.\n"
+            u"\n"
+            u"O tym, jak zacząć tworzyć podcast nie wydając nawet złotówki przeczytasz tu: "
+            u"https://malawielkafirma.pl/wlasny-podcast-za-darmo/."),
+        (
+            u"Utwory powstałe w czasach kiedy nie obowiązywały prawa autorskie należą do tak zwanej domeny publicznej. "
+            u"Domeną publiczną oznaczany tę twórczość i te utwory, do których wygasły majątkowe prawa autorskie, "
+            u"więc żadna licencja nie ma w tym przypadku zastosowania. Poprzez publikowanie utworu na licencjach "
+            u"Creative Commons przekazujemy informację o tym, że chcemy dzielić się swoimi utworami (w szerszym bądź "
+            u"węższym zakresie). Zasada ta nie dotyczy wszystkich licencji CC. Tą, która dają największą dowolność "
+            u"korzystania z utworu, jest licencja CC BY (Creative Commons Uznanie Autorstwa).\n"
+            u"Mówiąc inaczej, łatwiej nam jest wykorzystywać zdjęcia, obrazy, czy też muzykę na licencji CC "
+            u"do własnych celów (np. w prezentacji lub na swojej stronie internetowej), ponieważ nie musimy prosić "
+            u"autora o pozwolenie na ich użytkowanie – wszystko oczywiście zależy od rodzaju licencji CC, a tych jest "
+            u"kilka. Warto wcześniej się z nimi zapoznać na stronie: https://creativecommons.pl.\n"
+            u"\n"
+            u"Z definicją domeny publicznej można zapoznać się na stronie: "
+            u"http://domenapubliczna.org/co-to-jest-domena-publiczna/.\n"
+            u"\n"
+            u"Więcej o prawach autorskich można przeczytać w Ustawie z dnia 4 lutego 1994 r. o prawie autorskich "
+            u"i prawach pokrewnych: "
+            u"http://isap.sejm.gov.pl/Download?id=WDU19940240083&type=3 "
+            u"oraz na stronie http://prawokultury.pl.",
+
+            u"XIV-wieczny kodeks powstał w czasach, w których nie obowiązywały tak zwane prawa autorskie. "
+            u"Z tego względu jego udostępnienie i rozpowszechnianie w jakikolwiek sposób jest dozwolone bez podawania "
+            u"licencji, ponieważ kodeks ten należy już do domeny publicznej. Prawa autorskie to zbiór reguł "
+            u"dotyczących praw osobistych i majątkowych, jakie nam przysługują przy utworach (np. zdjęciach, muzyce), "
+            u"który stworzyliśmy osobiście. Z kolei domeną publiczną określamy tę twórczość i te utwory, z których "
+            u"możemy korzystać w dowolny sposób, ponieważ prawa autorskie wygasły (minęło 70 lat od śmierci ich "
+            u"twórców) lub utwory powstały wtedy, kiedy prawa autorskie nie istniały.\n"
+            u"\n"
+            u"O idei udostępniania utworów na zasadach licencji Creative Commons można przeczytać na stronie: "
+            u"https://creativecommons.pl.\n"
+            u"\n"
+            u"Z definicją domeny publicznej można zapoznać się na stronie: "
+            u"http://domenapubliczna.org/co-to-jest-domena-publiczna/.\n"
+            u"\n"
+            u"Więcej o prawa autorskich można przeczytać w Ustawie z dnia 4 lutego 1994 r. o prawie autorskich "
+            u"i prawach pokrewnych: http://isap.sejm.gov.pl/Download?id=WDU19940240083&type=3 oraz na stronie "
+            u"http://prawokultury.pl.",
+
+            u"Ważne jest, aby wszystkie dokumenty o znaczeniu historycznym udostępnianie były odbiorcom w jak "
+            u"najlepszej jakości produkcyjnej. W przypadku XIV-wiecznego kodeksu oznacza to, że muzeum cyfrowe powinno "
+            u"postarać się o zeskanowanie dokumenty w wysokiej rozdzielczości, która umożliwi dokładne zaznajomienie "
+            u"się z jego treścią szerokim rzeszom odbiorców. Jednak idea domeny publicznej zakłada przede wszystkim "
+            u"możliwość korzystania z udostępnianego utworu bez ograniczeń wynikających z praw autorskich. Domeną "
+            u"publiczną określamy tę twórczość i te utwory, z których możemy korzystać w dowolny sposób, ponieważ "
+            u"prawa autorskie dawno wygasły lub powstały wtedy, kiedy prawa autorskie nie istniały. Prawa autorskie to "
+            u"zbiór reguł dotyczących praw jakie nam przysługują przy utworach (np. zdjęciach, muzyce), które "
+            u"stworzyliśmy osobiście. Na przykład jedną z ważniejszych kwestii dotyczących praw autorskich jest "
+            u"pobieranie opłat za każdorazowe użycie skomponowanego przez nas utworu.\n"
+            u"\n"
+            u"O idei udostępniania utworów na zasadach licencji Creative Commons można przeczytać na stronie: "
+            u"https://creativecommons.pl.\n"
+            u"\n"
+            u"Z definicją domeny publicznej można zapoznać się na stronie: "
+            u"http://domenapubliczna.org/co-to-jest-domena-publiczna/.\n"
+            u"\n"
+            u"Więcej o prawa autorskich można przeczytać w Ustawie z dnia 4 lutego 1994 r. o prawie autorskich "
+            u"i prawach pokrewnych: http://isap.sejm.gov.pl/Download?id=WDU19940240083&type=3 oraz na stronie "
+            u"http://prawokultury.pl."),
+        (
+            u"Zastosowanie takich metod ochrony swojej prywatności nie gwarantuje skutecznego działania. "
+            u"Komputer odnotowuje nasze działania na różne sposoby – historia odwiedzanych stron to tylko jeden "
+            u"z nich. Dane zapisane w formularzach, „ciasteczka” (niewielkie informacje, wysyłane przez serwis "
+            u"internetowy, który odwiedzamy i zapisywane na urządzeniu końcowym – komputerze, laptopie, smartfonie – "
+            u"z którego korzystamy podczas przeglądania stron internetowych: http://wszystkoociasteczkach.pl/) "
+            u"pozwolą zainteresowanej osobie ustalić, co robiłeś. Ważne jest także chronienie swoich kont i ich danych,"
+            u" zawsze pamiętaj o wylogowaniu się i zablokowaniu komputera, jeśli odchodzisz od niego na chwilę.\n"
+            u"\n"
+            u"Pamiętaj także, że jeśli korzystasz ze swojego konta Google na wielu urządzeniach, sam serwis tworzy "
+            u"synchronizowaną historię aktywności. Jak ją usunąć, dowiesz się tu:\n"
+            u"https://support.google.com/websearch/answer/54068?hl=pl&ref_topic=1638123.\n"
+            u"\n"
+            u"Więcej o ochronie prywatności w Internecie dowiesz się tu: https://panoptykon.org/ i tu: "
+            u"http://www.saferinternet.pl/pl/ochrona-prywatnosci.",
+
+            u"Kompleksowe stosowanie różnych metod ochrony swojej prywatności pozwala nam na zachowanie prywatności w "
+            u"Internecie. Pamiętanie o tym, że komputer odnotowuje nasze działania na różne sposoby – historia "
+            u"odwiedzanych stron to tylko jeden z nich – to istotny element skutecznej ochrony. Dane zapisane w "
+            u"formularzach, „ciasteczka” (niewielkie informacje, wysyłane przez serwis internetowy, który odwiedzamy i "
+            u"zapisywane na urządzeniu końcowym – komputerze, laptopie, smartfonie – z którego korzystamy podczas "
+            u"przeglądania stron internetowych: http://wszystkoociasteczkach.pl/) pozwolą zainteresowanej osobie "
+            u"ustalić, co robiłeś, dlatego usuwanie historii i wszystkich pozostałych danych gromadzonych przez "
+            u"przeglądarkę to czynności, które są niezbędne. Ważne jest także chronienie swoich kont i ich danych, "
+            u"zawsze pamiętaj o wylogowaniu się i zablokowaniu komputera, jeśli odchodzisz od niego na chwilę.\n"
+            u"\n"
+            u"Pamiętaj także, że jeśli korzystasz ze swojego konta Google na wielu urządzeniach, sam serwis Google "
+            u"tworzy synchronizowaną historię aktywności. Jak ją usunąć, dowiesz się tu:\n"
+            u"https://support.google.com/websearch/answer/54068?hl=pl&ref_topic=1638123.\n"
+            u"\n"
+            u"\n"
+            u"Więcej o ochronie prywatności w Internecie dowiesz się tu:\n"
+            u"http://www.saferinternet.pl/pl/ochrona-prywatnosci.",
+
+            u"Kompleksowe stosowanie różnych metod ochrony swojej prywatności pozwala nam na zachowanie prywatności "
+            u"w Internecie. Pamiętanie o tym, że komputer odnotowuje nasze działania na różne sposoby – historia "
+            u"odwiedzanych stron to tylko jeden z nich – to istotny element skutecznej ochrony. Dane zapisane "
+            u"w formularzach, „ciasteczka” (niewielkie informacje, wysyłane przez serwis internetowy, który odwiedzamy "
+            u"i zapisywane na urządzeniu końcowym – komputerze, laptopie, smartfonie – z którego korzystamy podczas "
+            u"przeglądania stron internetowych: http://wszystkoociasteczkach.pl/) pozwolą zainteresowanej osobie "
+            u"ustalić, co robiłeś. Dlatego usuwanie historii nie wystarczy, konieczne jest kasowanie wszystkich "
+            u"pozostałych danych gromadzonych przez przeglądarkę. Ważne jest także chronienie swoich kont i ich "
+            u"danych, zawsze pamiętaj o wylogowaniu się i zablokowaniu komputera, jeśli odchodzisz od niego na chwilę."
+            u"\n"
+            u"\n"
+            u"Pamiętaj także, że jeśli korzystasz ze swojego konta Google na wielu urządzeniach, sam serwis Google "
+            u"tworzy synchronizowaną historię aktywności. Jak ją usunąć, dowiesz się tu:\n"
+            u"https://support.google.com/websearch/answer/54068?hl=pl&ref_topic=1638123.\n"
+            u"\n"
+            u"Więcej o ochronie prywatności w Internecie dowiesz się tu:\n"
+            u"http://www.saferinternet.pl/pl/ochrona-prywatnosci."),
+        (
+            u"Wolność słowa oznacza przede wszystkim nasze prawo do wyrażania swoich własnych poglądów i w przypadku "
+            u"skorzystania z tej wolności nie ma większego znaczenia czy swoje poglądy wyrażamy anonimowo, "
+            u"czy też podpisujemy się pod nimi imieniem i nazwiskiem. Wolność słowa nie ma związku z wartością "
+            u"komentarzy w Internecie. Z drugiej strony jednak należy pamiętać, że korzystanie z wolności słowa "
+            u"nie oznacza, że nie możemy czuć się odpowiedzialni za swoje opinie wyrażane w Internecie i publikować "
+            u"na przykład obraźliwe komentarze. Poza tym pełna anonimowość w sieci nie istnieje – jeśli zrobimy coś "
+            u"złego w Internecie, to łatwo będzie można nas namierzyć.\n"
+            u"\n"
+            u"Z tematem problematyki wolności w Internecie można zapoznać się w artykule "
+            u"pt. „Problem wolności w Internecie”: "
+            u"http://www.ujk.edu.pl/infotezy/ojs/index.php/infotezy/about/submissions#authorGuidelines.",
+
+            u"To, czy wartość komentarza opublikowanego w Internecie zależy od jego podpisania przez autora, wynika "
+            u"z kontekstu, treści i często miejsca, w którym się ten komentarz znajduje. Wartość komentarza możemy "
+            u"na przykład łatwo ocenić wtedy, kiedy jesteśmy w stanie zidentyfikować osobę, która go umieszcza w "
+            u"Internecie. Ma to szczególne znaczenie, jeśli dana osoba jest uznanym ekspertem w dziedzinie, w której "
+            u"się wypowiada. Bywają jednak sytuacje, w których anonimowe komentarze bywają również wartościowe. "
+            u"Można to zaobserwować w sytuacjach, w których anonimowy komentarz dostarcza nam informacji, które "
+            u"nie mogłyby zostać rozpowszechnione w inny sposób, jak tylko właśnie anonimowo – na przykład "
+            u"udostępnienie informacji w Internecie o trudnych warunkach pracy w pewnej firmie pod imieniem "
+            u"i nazwiskiem mogłoby zaszkodzić autorowi, który prawdopodobnie straciłby pracę. Pamiętajmy jednak "
+            u"o tym, aby każdy komentarz w Internecie weryfikować we własnym zakresie i że nigdy nie istnieje pełna "
+            u"anonimowość w sieci.\n"
+            u"\n"
+            u"Z tematem problematyki wolności w Internecie można zapoznać się w artykule "
+            u"pt. „Problem wolności w Internecie”: "
+            u"http://www.ujk.edu.pl/infotezy/ojs/index.php/infotezy/about/submissions#authorGuidelines.",
+
+            u"Odpowiedzialność prawna to konsekwencje, jakie możemy ponieść w wyniku złamania prawa. Z punktu widzenia "
+            u"odpowiedzialności prawnej nie ma znaczenia czy komentarz w Internecie jest anonimowy, czy też podpisany "
+            u"imieniem i nazwiskiem. Na przykład za pomówienie kogoś w Internecie kodeks karny przewiduje różnego "
+            u"rodzaju kary, w tym więzienie. Jeśli osoba pomawiająca dokonała tego czynu używając anonimowych danych, "
+            u"to i tak na wniosek prokuratury prowadzącej śledztwo administrator strony, na której doszło do "
+            u"pomówienia ma obowiązek udostępnić adres IP użytkownika (numer służący identyfikacji komputerów i innych "
+            u"urządzeń w sieci). A stąd już prosta droga do uzyskania dokładnych danych adresowych osoby pomawiającej."
+            u"\n"
+            u"\n"
+            u"Na temat odpowiedzialności prawnej za komentarze umieszczane w Internecie można przeczytać w artykule "
+            u"pt. „Ten komentarz mnie obraża. Co mam zrobić?” "
+            u"https://panoptykon.org/wiadomosc/ten-komentarz-mnie-obraza-co-mam-zrobic."),
+        (
+            u"Oryginalny pomysł i scenariusz – oparte na własnych odczuciach, czyli „twórcze, a nie odtwórcze” to "
+            u"najważniejszy etap opowiadania historii. Im więcej własnych idei i koncepcji włożycie w opowiadaną "
+            u"historię, tym będzie Wam bliższa, i tym lepiej będzie przemawiała do jej odbiorców. I, co także bardzo "
+            u"ważne, historia, którą wymyślicie sami, na pewno nie będzie naruszać niczyich praw autorskich…\n"
+            u"\n"
+            u"Ważne są także kolejne kroki, które podejmiecie. Po wyborze tematu musicie podzielić się zadaniami, "
+            u"aby każdy element zadania był wykonany. Jeśli tego nie zrobicie, w grupie szybko zapanuje chaos – "
+            u"jednymi sprawami zajmie się kilka osób, a innymi – nikt. Warto też opracować harmonogram, aby ze "
+            u"wszystkim zdążyć na czas. Podczas realizacji zadania bądźcie w stałym kontakcie, żeby na bieżąco "
+            u"wymieniać się uwagami na temat wspólnej pracy.\n"
+            u"\n"
+            u"Więcej o tym, jak zorganizować wspólną pracę, znaleźć można tutaj: "
+            u"https://edukacjamedialna.edu.pl/lekcje/sieciowa-wspolpraca/ i tutaj: "
+            u"https://edukacjamedialna.edu.pl/lekcje/dokumentacja-i-narracje-cyfrowe/.",
+
+            u"Jeśli nie zaczniecie pracy od zastanowienia się nad tym, jaką historię chcecie opowiedzieć, nie dacie "
+            u"sobie szansy, aby opowiadała ona o rzeczach ważnych dla Was. Stworzycie – zamiast własnej historii – "
+            u"zbitek cudzych opowieści. Oryginalny pomysł i scenariusz – oparte na własnych odczuciach, czyli "
+            u"„twórcze, a nie odtwórcze” to najważniejszy etap opowiadania historii. Im więcej własnych idei "
+            u"i koncepcji włożycie w opowiadaną historię, tym będzie Wam bliższa, i tym lepiej będzie przemawiała "
+            u"do jej odbiorców. I, co także bardzo ważne, historia, którą wymyślicie sami, na pewno nie będzie "
+            u"naruszać niczyich praw autorskich…\n"
+            u"\n"
+            u"Ważne są także kolejne kroki, które podejmiecie. Po wyborze tematu musicie podzielić się zadaniami, "
+            u"aby każdy element zadania był wykonany. Jeśli tego nie zrobicie, w grupie szybko zapanuje chaos – "
+            u"jednymi sprawami zajmie się kilka osób, a innymi – nikt. Warto też opracować harmonogram, aby ze "
+            u"wszystkim zdążyć na czas. Podczas realizacji zadania bądźcie w stałym kontakcie, aby na bieżąco "
+            u"wymieniać się uwagami na temat wspólnej pracy.\n"
+            u"\n"
+            u"Więcej o tym, jak zorganizować wspólną pracę, znaleźć można tutaj: "
+            u"https://edukacjamedialna.edu.pl/lekcje/sieciowa-wspolpraca/ i tutaj: "
+            u"https://edukacjamedialna.edu.pl/lekcje/dokumentacja-i-narracje-cyfrowe/.",
+
+            u"Temat opowieści, który wybieracie razem, jest jednocześnie jej początkiem. Jeśli zrodzi się w dyskusji "
+            u"między Wami, to dacie sobie możliwość opowiedzenia własnej historii. Jeśli jednak na tym "
+            u"poprzestaniecie, wykorzystując cudze filmiki i zdjęcia, nie będzie ona wyłącznie Wasza, bowiem będziecie "
+            u"opowiadać cudzymi słowami i obrazami. Oryginalny pomysł i scenariusz – oparte na własnych pomysłach, "
+            u"czyli „twórcze, a nie odtwórcze” to najważniejszy etap opowiadania historii. Im więcej własnych idei "
+            u"i koncepcji włożycie w opowiadaną historię, tym będzie Wam bliższa, i tym lepiej będzie przemawiała "
+            u"do jej odbiorców. I, co także bardzo ważne, historia, którą wymyślicie sami, na pewno nie będzie "
+            u"naruszać niczyich praw autorskich…\n"
+            u"\n"
+            u"Ważne są także kolejne kroki, które podejmiecie. Po wyborze tematu musicie podzielić się zadaniami, "
+            u"aby każdy element zadania był wykonany. Jeśli tego nie zrobicie, w grupie szybko zapanuje chaos – "
+            u"jednymi sprawami zajmie się kilka osób, a innymi – nikt. Warto też opracować harmonogram, aby ze "
+            u"wszystkim zdążyć na czas. Podczas realizacji zadania bądźcie w stałym kontakcie, aby na bieżąco "
+            u"wymieniać się uwagami na temat wspólnej pracy.\n"
+            u"\n"
+            u"Więcej o tym, jak zorganizować wspólną pracę, znaleźć można tutaj: "
+            u"https://edukacjamedialna.edu.pl/lekcje/sieciowa-wspolpraca/ i tutaj: "
+            u"https://edukacjamedialna.edu.pl/lekcje/dokumentacja-i-narracje-cyfrowe/."),
+        (
+            u"Korzystając z Internetu i komunikując się z innymi użytkownikami możemy odnieść wrażenie, że użytkownicy "
+            u"zwracają się do siebie w bardzo bezpośredni sposób. Nie można jednak nikogo zmuszać do zaakceptowania "
+            u"powszechnych reguł komunikacji w Internecie, jeśli w rzeczywistości na co dzień dana osoba nie stosuje "
+            u"nieformalnej komunikacji w kontaktach z nieznajomymi, w tym również przedstawicielami różnych firm "
+            u"i organizacji. Trudno nam sobie w rzeczywistości niewirtualnej wyobrazić pracownika jakiejś firmy, "
+            u"który po imieniu odpowiada nam na zadane przez nas pytania. Najlepszą reakcja firmy na zaistniały "
+            u"problem jest więc przeproszenie użytkownika za bezpośredni i nieformalny zwrot po imieniu.\n"
+            u"\n"
+            u"Prof. Jerzy Bralczyk o netykiecie: https://www.youtube.com/watch?v=thwUHPXbBoo.\n"
+            u"\n"
+            u"O zwracaniu się w Internecie do innych użytkowników per „pani” / „pan” można posłuchać na kanale "
+            u"„Czas Gentelmanów”: https://www.youtube.com/watch?v=A8qznS7LjQY.",
+
+            u"Korzystając z Internetu i komunikując się z innymi użytkownikami możemy odnieść wrażenie, że użytkownicy "
+            u"zwracają się do siebie w bardzo bezpośredni sposób. Nie można jednak nikogo zmuszać do zaakceptowania "
+            u"powszechnych reguł komunikacji w Internecie, zwłaszcza, jeśli w rzeczywistości na co dzień dana osoba "
+            u"nie stosuje nieformalnej komunikacji w kontaktach z nieznajomymi, w tym również przedstawicielami "
+            u"różnych firm i organizacji. Trudno nam w rzeczywistości niewirtualnej wyobrazić sobie pracownika "
+            u"jakiejś firmy, który po imieniu odpowiada nam na zadane przez nas pytania. Najlepszą reakcją firmy "
+            u"na zaistniały problem jest więc przeproszenie użytkownika za bezpośredni formalny zwrot po imieniu. "
+            u"Pod żadnym pozorem nie powinna ignorować użytkownika odwołując się do zasady netykiety, czyli zbioru "
+            u"zasad porozumiewania się w Internecie. Chociaż zgodnie z jej zasadami, przyjęte jest zwracanie się "
+            u"do siebie po imieniu, to nie możemy innym narzucać własnych reguł komunikacji. Dotyczy to przede "
+            u"wszystkim firm, które komunikują się w Internecie ze swoimi klientami.\n"
+            u"\n"
+            u"Prof. Jerzy Bralczyk o netykiecie: https://www.youtube.com/watch?v=thwUHPXbBoo.\n"
+            u"\n"
+            u"O zwracaniu się w Internecie do innych użytkowników per „pani” / „pan” można posłuchać na kanale "
+            u"„Czas Gentelmanów”: https://www.youtube.com/watch?v=A8qznS7LjQY.",
+
+            u"Korzystając z Internetu i komunikując się z innymi użytkownikami możemy odnieść wrażenie, że użytkownicy "
+            u"zwracają się do siebie w bardzo bezpośredni sposób. Nie można jednak nikogo zmuszać do zaakceptowania "
+            u"powszechnych reguł komunikacji w Internecie, jeśli w rzeczywistości na co dzień dana osoba stosuje "
+            u"formalna komunikację w kontaktach z osobami nieznajomymi, w tym również przedstawicielami różnych firm "
+            u"i organizacji. Trudno nam sobie w rzeczywistości niewirtualnej wyobrazić pracownika jakiejś firmy, "
+            u"który po imieniu odpowiada nam na zadane przez nas pytania. Poprawną reakcją firmy na zaistniały problem "
+            u"w komunikacji internetowej jest działanie zgodne z wypracowanymi wewnętrznie zasadami komunikacji. "
+            u"Stanowią one coś na wzór kodeksu opracowanego przez daną firmę, który mówi pracownikom firmy, "
+            u"jak należy zachowywać się w kontaktach z klientami. Niezależnie od zasad obowiązujących w firmie, "
+            u"najlepszym rozwiązaniem będzie przeproszenie urażonego użytkownika.\n"
+            u"\n"
+            u"Prof. Jerzy Bralczyk o netykiecie: https://www.youtube.com/watch?v=thwUHPXbBoo.\n"
+            u"\n"
+            u"O zwracaniu się w Internecie do innych użytkowników per „pani” / „pan” można posłuchać na kanale "
+            u"„Czas Gentelmanów”: https://www.youtube.com/watch?v=A8qznS7LjQY."),
+        (
+            u"Krytyczne podejście do informacji to jedna z najważniejszych umiejętności we współczesnym świecie, "
+            u"w którym informacja otacza nas i dociera zewsząd. Przy tworzeniu aplikacji warto skontaktować się "
+            u"z administracją, aby ustalić liczbę dostępnych miejsc. Pamiętaj jednak, że osoba udzielająca informacji "
+            u"może nie mieć pełnej wiedzy – lub popełnić błąd. Dobrze byłoby zweryfikować otrzymane informacje "
+            u"osobiście (aby Twoje dane pochodziły z więcej niż jednego źródła).\n"
+            u"\n"
+            u"Więcej o tym, dlaczego warto weryfikować informacje, dowiesz się tu:\n"
+            u"https://www.youtube.com/watch?v=ZHHmEi9VAbY.\n"
+            u"\n"
+            u"Więcej o weryfikacji informacji w Internecie dowiesz się stąd:\n"
+            u"http://www.heuristic.pl/blog/internet/Wiarygodnosc-informacji-zamieszczanych-w-Internecie;204.html.",
+
+            u"Krytyczne podejście do informacji to jedna z najważniejszych umiejętności we współczesnym świecie, "
+            u"w którym informacja otacza nas i dociera zewsząd. Ważne jest, aby uzyskana przez Ciebie informacja była "
+            u"aktualna i najlepiej, aby pochodziła z więcej niż jednego źródła. Dlatego optymalnym rozwiązaniem byłoby "
+            u"sprawdzenie danych ze strony (która mogła dawno nie być aktualizowana), na przykład poprzez kontakt "
+            u"z administracją oraz osobiste udanie się na miejsce i sprawdzenie uzyskanych odpowiedzi.\n"
+            u"\n"
+            u"Więcej o tym, dlaczego warto weryfikować informacje dowiesz się tu:\n"
+            u"https://www.youtube.com/watch?v=ZHHmEi9VAbY.\n"
+            u"\n"
+            u"Więcej o weryfikacji informacji w Internecie dowiesz się stąd:\n"
+            u"http://www.heuristic.pl/blog/internet/Wiarygodnosc-informacji-zamieszczanych-w-Internecie;204.html.",
+
+            u"Krytyczne podejście do informacji to jedna z najważniejszych umiejętności we współczesnym świecie, "
+            u"w którym informacja otacza nas i dociera zewsząd. Ważne jest, aby uzyskana przez Ciebie informacja była "
+            u"aktualna, wiarygodna i wyczerpująca. Dlatego optymalnym rozwiązaniem jest właśnie kontakt "
+            u"z administracją oraz osobiste udanie się na miejsce i sprawdzenie uzyskanych odpowiedzi. Ważne jest "
+            u"także sprawdzenie, jakie okoliczności mogą wpływać na stan „formalny” badanej rzeczywistości – "
+            u"częstotliwość łamania przepisów przez pełnosprawnych kierowców stanowi taką incydentalną okoliczność, "
+            u"której częste występowanie może całkowicie zniweczyć sens używania aplikacji, jeśli nie zostanie "
+            u"uwzględnione w jej działaniu.\n"
+            u"\n"
+            u"Więcej o tym, dlaczego warto weryfikować informacje dowiesz się tu:\n"
+            u"https://www.youtube.com/watch?v=ZHHmEi9VAbY.\n"
+            u"\n"
+            u"Więcej o weryfikacji informacji w Internecie dowiesz się tu:\n"
+            u"http://www.heuristic.pl/blog/internet/Wiarygodnosc-informacji-zamieszczanych-w-Internecie;204.html."),
+        (
+            u"Niewidzialna praca to między innymi praca wykonywana na rzecz swojej rodziny / wolontariat. Chociaż "
+            u"zazwyczaj kojarzona jest z pracą w domu (na przykład kobiety opiekujące się dziećmi), to odnosi się też "
+            u"do „szarych pracowników” wielkich korporacji, którzy stoją za sukcesem tych przedsiębiorstw, w tym "
+            u"moderatorów mediów społecznościowych, których rola jest niezastąpiona i niezbędna dla sprawnego "
+            u"funkcjonowania biznesu.\n"
+            u"„Niewidzialną pracą” można nazwać również aktywność użytkowników mediów społecznościowych, którzy "
+            u"poprzez komentarze pod wpisami i newsami podtrzymują zainteresowanie innych użytkowników, a co za tym "
+            u"idzie zwiększają zainteresowanie potencjalnych reklamodawców.\n"
+            u"\n"
+            u"O niewidzialnej pracy można przeczytać w artykule pt. „Niewidzialna praca o wielkiej mocy”: "
+            u"http://www.praca.pl/poradniki/rynek-pracy/niewidzialna-praca-o-wielkiej-mocy_pr-1711.html.",
+
+            u"Niewidzialna praca to między innymi praca wykonywana na rzecz swojej rodziny / wolontariat. Chociaż "
+            u"zazwyczaj kojarzona jest z pracą w domu (na przykład kobiety opiekujące się dziećmi), to odnosi się też "
+            u"do „szarych pracowników” wielkich korporacji, którzy stoją za sukcesem tych przedsiębiorstw, w tym "
+            u"moderatorów mediów społecznościowych, których rola jest niezastąpiona i niezastąpiona i niezbędna dla "
+            u"sprawnego funkcjonowania biznesu.\n"
+            u"„Niewidzialną pracą” można nazwać również aktywność użytkowników mediów społecznościowych, którzy "
+            u"poprzez komentarze pod wpisami i newsami oraz udostępnianie różnego rodzaju treści podtrzymują "
+            u"zainteresowanie innych użytkowników, a co za tym idzie zwiększają zainteresowanie potencjalnych "
+            u"reklamodawców.\n"
+            u"\n"
+            u"O niewidzialnej pracy można przeczytać w artykule pt. „Niewidzialna praca o wielkiej mocy”: "
+            u"http://www.praca.pl/poradniki/rynek-pracy/niewidzialna-praca-o-wielkiej-mocy_pr-1711.html.",
+
+            u"Niewidzialna praca to między innymi praca wykonywana na rzecz swojej rodziny / wolontariat. Chociaż "
+            u"zazwyczaj kojarzona jest z pracą w domu (na przykład kobiety opiekujące się dziećmi), to odnosi się "
+            u"też do „szarych pracowników” wielkich korporacji, którzy stoją za sukcesem tych przedsiębiorstw, "
+            u"w tym moderatorów mediów społecznościowych, których rola jest niezastąpiona i niezbędna dla sprawnego "
+            u"funkcjonowania biznesu.\n"
+            u"„Niewidzialną pracą” można nazwać również aktywność użytkowników mediów społecznościowych, którzy "
+            u"poprzez komentarze pod wpisami i newsami podtrzymują zainteresowanie innych użytkowników, a co za tym "
+            u"idzie zwiększają zainteresowanie potencjalnych reklamodawców.\n"
+            u"Z całą pewnością informatycy budujący rozwiązania IT dla firm nie są osobami wykonującymi „niewidzialną "
+            u"pracę”, chociażby z tego względu, że swoją pracę wykonują najczęściej poza domem, jej efekty są "
+            u"dostrzegane i doceniane oraz pobierają za nią wysokie wynagrodzenia (pracownicy IT są jedną z najlepiej "
+            u"opłacanych grup zawodowych na całym świecie).\n"
+            u"\n"
+            u"O niewidzialnej pracy można przeczytać w artykule pt. „Niewidzialna praca o wielkiej mocy”: "
+            u"http://www.praca.pl/poradniki/rynek-pracy/niewidzialna-praca-o-wielkiej-mocy_pr-1711.html."),
+        (
+            u"Informacja nazywana jest we współczesnym świecie „zasobem strategicznym”. Pozwala działać, planować, "
+            u"podejmować decyzje w świadomy sposób – i z prawdopodobieństwem osiągnięcia dobrych skutków. Jednak, "
+            u"aby informacja spełniała takie funkcje, musi być wiarygodna, aktualna, kompletna. Jej wiarygodność "
+            u"należy zatem sprawdzać i weryfikować. Jeśli pojawia się w więcej niż jednym źródle, rośnie "
+            u"prawdopodobieństwo, że nie jest manipulacją ani dezinformacją. Czasami zdarza się, że kolejne media "
+            u"bezmyślnie powtarzają informację za tym, kto podał ją jako pierwszy, i trafia ona do wielu odbiorców, "
+            u"ostatecznie okazuje się nieprawdziwa. Bez dotarcia do jej właściwego, oryginalnego źródła, trudno mieć "
+            u"100-procentową pewność, że mamy do czynienia z wartościową informacją.",
+
+            u"Informacja nazywana jest we współczesnym świecie „zasobem strategicznym”. Pozwala działać, planować, "
+            u"podejmować decyzje w świadomy sposób – i z prawdopodobieństwem osiągnięcia dobrych skutków. Jednak, aby "
+            u"informacja spełnia takie funkcje, musi być wiarygodna, aktualna, kompletna. Jej wiarygodność należy "
+            u"zatem sprawdzać i weryfikować. Jeśli pojawia się w więcej niż jednym źródle, rośnie prawdopodobieństwo, "
+            u"że nie jest manipulacją ani dezinformacją. Jeśli dodatkowo informacja potwierdzona jest możliwością "
+            u"dotarcia do oryginalnego jej źródła, zamiast opracowania lub interpretacji, można z wysokim "
+            u"prawdopodobieństwem zakładać, że jest prawdziwa.",
+
+            u"Informacja nazywana jest we współczesnym świecie „zasobem strategicznym”. Pozwala działać, planować, "
+            u"podejmować decyzje w świadomy sposób – i z prawdopodobieństwem osiągnięcia dobrych skutków. Jednak, aby "
+            u"informacja spełnia takie funkcje, musi być wiarygodna, aktualna, kompletna. Informacja pochodząca "
+            u"jedynie z serwisów społecznościowych i nielicznych portali informacyjnych, a także nie można ustalić jej "
+            u"oryginalnego źródła, nie wolno zakładać, że jest prawdziwa. Możemy pozwolić wprowadzić się w błąd – "
+            u"a nasi znajomi, na których profilach społecznościowych będziemy się opierać, mogą nawet nie mieć "
+            u"świadomości, że rozprzestrzeniają nieprawdziwe informacje.\n"
+            u"\n"
+            u"O potencjalnych konsekwencjach fałszywych informacji w prawdziwym świecie przeczytasz tu:\n"
+            u"https://www.wprost.pl/swiat/10030588/"
+            u"Facebook-wplynal-na-wynik-amerykanskich-wyborow-Zuckerberg-komentuje.html."),
+        (
+            u"Samo podjęcie czynności kontrolnych przez prokuraturę nie musi oznaczać, że umowy podpisywane "
+            u"z wykonawcami budżetu obywatelskiego odbyły się z naruszeniem prawa. Każdy z nas może paść ofiarą "
+            u"niesłusznych oskarżeń, dlatego powinno unikać się ocen dotyczących ewentualnej winy. Dopóki zarzuty "
+            u"postawione przez prokuraturę (jeśli w ogóle zostaną postawione) nie zostaną uprawomocnione wyrokiem "
+            u"sądowym, obowiązuje tzw. domniemanie niewinności. Tytuł zastosowanego newsa jest akceptowalny, ponieważ "
+            u"nie rozstrzyga ewentualnej winy wykonawców budżetu obywatelskiego. Niestety, z drugiej strony "
+            u"sformułowanie „niejasne umowy” sugeruje pewnego rodzaju nieprawidłowości. Dziennikarze tworzący newsy "
+            u"powinni działać zgodnie z etyką zawodową. Są oni zobowiązani do rzetelnego informowania o faktach "
+            u"i unikaniu prasowych przekłamań, nie tylko w treści newsów, ale również w ich tytułach. Bywa jednak tak, "
+            u"że dziennikarze tworzący tytuły wiadomości manipulują nami, aby podstępnie zmusić nas do zaznajomienia "
+            u"się z ich treścią. Robią to najczęściej w celu wygenerowania dodatkowych zysków z reklam, które "
+            u"pojawiają się obok treści wiadomości. To zjawisko nosi nazwę „clickbait”.\n"
+            u"\n"
+            u"Jeśli chcesz dowiedzieć się czym jest dokładnie „clickbait” posłuchaj audycji pt. „Clickbait w sieci, "
+            u"czyli kto chce cię oszukać”: "
+            u"http://www.polskieradio.pl/9/3850/Artykul/1665036,Clickbait-w-sieci-czyli-kto-chce-cie-oszukac.\n"
+            u"\n"
+            u"W celu zapoznania się ze standardami pracy dziennikarskiej warto przeczytać:\n"
+            u"Kartę Etyczną Mediów: http://www.dziennikarzerp.pl/wp-content/uploads/2010/06/karta_dziennikarzy.pdf.\n"
+            u"Kodeks etyki dziennikarskiej Stowarzyszenia Dziennikarzy Polskich: "
+            u"http://sdp.pl/s/kodeks-etyki-dziennikarskiej-sdp.\n"
+            u"Dziennikarski kodeks obyczajowy Stowarzyszenia Dziennikarzy RP: "
+            u"http://www.dziennikarzerp.pl/wp-content/uploads/2010/06/kodeks.pdf.",
+
+            u"Zastosowanie takiego tytułu jest najlepsze, ponieważ stwierdza tylko pewien fakt, a jednocześnie "
+            u"nie przesądza o rezultatach działań kontrolnych prokuratury. Samo podjęcie czynności kontrolnych "
+            u"przez prokuraturę nie musi oznaczać, że umowy podpisywane z wykonawcami budżetu obywatelskiego odbyły "
+            u"się z naruszeniem prawa. Każdy z nas może paść ofiarą niesłusznych oskarżeń, dlatego powinno unikać się "
+            u"skrajnych ocen dotyczących ewentualnej winy. Dopóki zarzuty postawione przez prokuraturę (jeśli w ogóle "
+            u"zostaną postawione) nie zostaną uprawomocnione wyrokiem sądowym obowiązuje tzw. domniemanie niewinności. "
+            u"Tytuł zastosowanego newsa jest poprawny i zgodny z etyką zawodową dziennikarza. Pamiętajmy, "
+            u"że dziennikarze zobowiązani są do rzetelnego informowania o faktach i unikaniu prasowych przekłamań, "
+            u"nie tylko w treści newsów, ale również w ich tytułach.\n"
+            u"\n"
+            u"W celu zapoznania się ze standardami pracy dziennikarskiej warto przeczytać:\n"
+            u"Kartę Etyczną Mediów: http://www.dziennikarzerp.pl/wp-content/uploads/2010/06/karta_dziennikarzy.pdf.\n"
+            u"Kodeks etyki dziennikarskiej Stowarzyszenia Dziennikarzy Polskich: "
+            u"http://sdp.pl/s/kodeks-etyki-dziennikarskiej-sdp.\n"
+            u"Dziennikarski kodeks obyczajowy Stowarzyszenia Dziennikarzy RP: "
+            u"http://www.dziennikarzerp.pl/wp-content/uploads/2010/06/kodeks.pdf.",
+
+            u"Zastosowanie takiego tytułu wprowadza tylko niepotrzebny zamęt i nosi znamiona manipulacji skierowanej "
+            u"wobec czytelników. Taki tytuł może być krzywdzący dla wykonawców, ponieważ wprost sugeruje ich winę. "
+            u"Samo podjęcie czynności kontrolnych przez prokuraturę nie musi oznaczać, że umowy podpisywane "
+            u"z wykonawcami budżetu obywatelskiego odbyły się z naruszeniem prawa. Każdy z nas może paść ofiarą "
+            u"niesłusznych oskarżeń, dlatego powinno unikać się skrajnych ocen dotyczących ewentualnej winy. "
+            u"Dopóki zarzuty postawione przez prokuraturę (jeśli w ogóle zostaną postawione) nie zostaną "
+            u"uprawomocnione wyrokiem sądowym obowiązuje tzw. domniemanie niewinności. Tytuł zastosowanego newsa jest "
+            u"nieakceptowalny, ponieważ zakłada winę, której nie udowodniono. Dziennikarze tworzący newsy powinni "
+            u"działać zgodnie z etyką zawodową. Są oni zobowiązani do rzetelnego informowania o faktach i unikaniu "
+            u"prasowych przekłamań, nie tylko w treści newsów, ale również w ich tytułach. Bywa jednak tak, że "
+            u"dziennikarze tworzący tytuły wiadomości manipulują nami, aby podstępnie zmusić nas do zaznajomienia się "
+            u"z ich treścią. Robią to najczęściej w celu wygenerowania dodatkowych zysków z reklam, które pojawiają "
+            u"się obok treści wiadomości. To zjawisko nosi nazwę „clickbait”.\n"
+            u"\n"
+            u"Jeśli chcesz dowiedzieć się czym jest dokładnie „clickbait” posłuchaj audycji pt. „Clickbait w sieci, "
+            u"czyli kto chce cię oszukać”: "
+            u"http://www.polskieradio.pl/9/3850/Artykul/1665036,Clickbait-w-sieci-czyli-kto-chce-cie-oszukac.\n"
+            u"\n"
+            u"W celu zapoznania się ze standardami pracy dziennikarskiej warto przeczytać:\n"
+            u"Kartę Etyczną Mediów: http://www.dziennikarzerp.pl/wp-content/uploads/2010/06/karta_dziennikarzy.pdf.\n"
+            u"Kodeks etyki dziennikarskiej Stowarzyszenia Dziennikarzy Polskich: "
+            u"http://sdp.pl/s/kodeks-etyki-dziennikarskiej-sdp.\n"
+            u"Dziennikarski kodeks obyczajowy Stowarzyszenia Dziennikarzy RP: "
+            u"http://www.dziennikarzerp.pl/wp-content/uploads/2010/06/kodeks.pdf."),
+        (
+            u"Wymienione w odpowiedzi narzędzia służą raczej dystrybucji informacji i prezentowaniu własnych wniosków "
+            u"/ przemyśleń (Power Point lub podcast), a nie pracy w grupie. Stosowane przy realizacji projektu "
+            u"narzędzia muszą pozwalać na komunikację zwrotną, wymianę myśli i ustalenia – a także wprowadzanie "
+            u"zmian w tworzonych treściach (muszą zatem pozwalać na tworzenie treści w formie wspólnie realizowanego "
+            u"procesu, a nie prezentować je statycznie).\n"
+            u"\n"
+            u"Informacje o komunikacji w projektach znajdziesz tu:\n"
+            u"http://www.ptzp.org.pl/files/konferencje/kzz/artyk_pdf_2017/T1/t1_200.pdf.",
+
+            u"Wymienione w odpowiedzi narzędzia służą wspólnej pracy nad projektem, mogą jednak nie pozwalać "
+            u"na przykład na pełne śledzenie chronologii wypowiedzi i ustaleń (Coggle) lub też odnotowanie efektów "
+            u"i ustaleń (Skype). Stosowane przy realizacji Waszego projektu narzędzia muszą pozwalać na komunikację "
+            u"zwrotną, wymianę myśli i ustalenia – a także wprowadzanie zmian w tworzonych treściach (muszą zatem "
+            u"pozwalać na tworzenie treści w formie wspólnie realizowanego procesu, a nie prezentować je statycznie) "
+            u"i umożliwiać śledzenie historii dokonywanych ustaleń i wprowadzanych zmian.\n"
+            u"\n"
+            u"Informacje o komunikacji w projektach znajdziesz tu:\n"
+            u"http://www.ptzp.org.pl/files/konferencje/kzz/artyk_pdf_2017/T1/t1_200.pdf.",
+
+            u"Wybrane narzędzia powinny doskonale odpowiedzieć na potrzeby współpracy przy realizacji projektu. "
+            u"Pozwalają zarówno na zarządzanie wewnątrz projektu (Wunderlist), jak i wspólne tworzenie koncepcji "
+            u"opracowywanego dzieła (OneNote, Google Docs). Szybka, grupowa komunikacja, uwzględniająca wszystkich "
+            u"uczestników projektu, zachowująca historię konwersacji, pozwala nie tylko na dokonywanie ustaleń, "
+            u"ale i odnoszenie się do nich w przyszłości.\n"
+            u"\n"
+            u"Informacje o komunikacji w projektach znajdziesz tu:\n"
+            u"http://www.ptzp.org.pl/files/konferencje/kzz/artyk_pdf_2017/T1/t1_200.pdf."),
+        (
+            u"Liczba edycji hasła na Wikipedii nie jest wskaźnikiem jego jakości. Przy niektórych hasłach, szczególnie "
+            u"społecznie drażliwych i kontrowersyjnych, liczba edycji może wynikać z braku zgody społeczności "
+            u"wikipedystów co do jednej neutralnej definicji. Przyczyną dużej liczby edycji bywa również zamierzone "
+            u"i złośliwe działanie internautów, którzy stosując tzw. trolling zmieniają znaczenie danego hasła, "
+            u"obniżając jego wartość merytoryczną lub przedstawiając skrajny punkt widzenia. Liczba edycji może "
+            u"wynikać też ze zmieniającej się stale wiedzy na temat danego zjawiska.\n"
+            u"\n"
+            u"Na temat oceny jakości haseł tworzonych na Wikipedii można przeczytać tutaj: "
+            u"https://pl.wikipedia.org/wiki/Wikipedia:Ocena_jakości.",
+
+            u"Długość hasła na Wikipedii może być dobry miernikiem jego jakości, ale też niewystarczającym. "
+            u"Podobnie z jego strukturą. Nawet jeśli hasło zawiera odpowiedni wstęp definicyjny oraz dalsze "
+            u"skonkretyzowanie omawianej problematyki, nie oznacza to automatycznie, że mamy do czynienia z hasłem "
+            u"wysokiej jakości. Długość i odpowiednia struktura nie będą niosły ze sobą wartości, jeśli hasło "
+            u"nie będzie zawierało odpowiednich przypisów i odnośników do innych rzetelnych źródeł, w których "
+            u"potwierdzone są tezy i informacje zawarte w opisie hasła. Po zapoznaniu się z interesującym hasłem "
+            u"warto zawsze sprawdzić źródła, do których się ono odnosi. Sama obecność odnośników nie oznacza, że są "
+            u"one aktualne i rzetelne.\n"
+            u"\n"
+            u"Na temat oceny jakości haseł tworzonych na Wikipedii można przeczytać tutaj: "
+            u"https://pl.wikipedia.org/wiki/Wikipedia:Ocena_jakości.",
+
+            u"Ani liczba edycji hasła, ani jego długość i struktura nie ma znaczenia dla jego jakości, jeśli w opisie "
+            u"hasła nie znajdziemy odpowiednich przypisów. To źródła, do których odnosi się opis hasła, stanowią "
+            u"przede wszystkim o jego wartości merytorycznej. Należy jednak pamiętać, że sama obecność odnośników "
+            u"jeszcze nic nie znaczy, warto samemu sprawdzić, czy są one aktualne i odnoszą do rzetelnej wiedzy.\n"
+            u"Na temat oceny jakości haseł tworzonych na Wikipedii można przeczytać tutaj: "
+            u"https://pl.wikipedia.org/wiki/Wikipedia:Ocena_jakości."),
+        (
+            u"Ochrona praw autorskich oraz przestrzeganie przepisów i norm związanych z tymi prawami jest szczególnie "
+            u"istotna w cyfrowym świecie, w którym skopiowanie cudzego pomysłu wymaga często jedynie zastosowanie "
+            u"funkcji „Kopiuj – Wklej”. Wykorzystanie podpisanej grafiki z podaniem jedynie adresu strony nie "
+            u"gwarantuje ochrony praw jej autora – grafika mogła znaleźć się na stronie w sposób niezgodny z prawem, "
+            u"z naruszeniem praw jej autora, poza tym autor interesującej nas grafiki ma prawo do bycia docenionym "
+            u"poprzez podanie imienia i nazwiska lub pseudonimu. Dlatego, jeśli masz wątpliwości, zrób co możesz, "
+            u"aby ustalić jej pierwotne źródło i autora i sprawdzić, czy pozwolił on na jej wykorzystywanie przez inne "
+            u"osoby.\n"
+            u"\n"
+            u"O tym, że nawet wielkie firmy popełniają plagiaty przeczytasz tu:\n"
+            u"http://noizz.pl/lifestyle/"
+            u"zara-kopiuje-grafiki-artystki-my-jestesmy-znani-a-ty-nie-odpowiadaja-prawnicy-firmy/p9y17wp.\n"
+            u"\n"
+            u"O ochronie praw autorskich więcej dowiesz się tu: http://prawokultury.pl.",
+
+            u"Ochrona praw autorskich oraz przestrzeganie przepisów i norm związanych z tymi prawami jest szczególnie "
+            u"istotna w cyfrowym świecie, w którym skopiowanie cudzego pomysłu wymaga często jedynie zastosowanie "
+            u"funkcji „Kopiuj – Wklej”. Wykorzystanie podpisanej grafiki z podaniem jedynie adresu strony "
+            u"nie gwarantuje ochrony praw jej autora – grafika mogła znaleźć się na stronie w sposób niezgodny "
+            u"z prawem, z naruszeniem praw jej autora. Z takiego jednego naruszenia mogą rodzić się kolejne – "
+            u"grafika może być zamieszczana przez administratorów kolejnych stron. Dlatego, jeśli masz wątpliwości, "
+            u"zrób co możesz, aby ustalić jej pierwotne źródło i autora i sprawdzić, czy pozwolił on na jej "
+            u"wykorzystywanie przez inne osoby.\n"
+            u"\n"
+            u"O ochronie praw autorskich więcej dowiesz się tu: http://prawokultury.pl.",
+
+            u"Ochrona praw autorskich oraz przestrzeganie przepisów i norm związanych z tymi prawami jest szczególnie "
+            u"istotna w cyfrowym świecie, w którym skopiowanie cudzego pomysłu wymaga często jedynie zastosowanie "
+            u"funkcji „Kopiuj – Wklej”. Wykorzystanie podpisanej grafiki z podaniem jedynie adresu strony "
+            u"nie gwarantuje ochrony praw jej autora – grafika mogła znaleźć się na stronie w sposób niezgodny "
+            u"z prawem, z naruszeniem praw jej autora. Zrobienie wszystkiego, co możliwe, aby ustalić jej pierwotne "
+            u"źródło i autora i sprawdzić, czy pozwolił on na jej wykorzystywanie przez inne osoby, sprawia, "
+            u"że zachowujemy się nie tylko fair w stosunku do autora, ale także przestrzegamy obowiązujących w tym "
+            u"zakresie przepisów.\n"
+            u"\n"
+            u"O ochronie praw autorskich więcej dowiesz się tu: http://prawokultury.pl."),
+        (
+            u"Przedstawiona w kodzie funkcja zawiera niepełną listę argumentów. Zadaniem funkcji f(a) jest "
+            u"wyświetlenie sumy argumentu „a” oraz argumentu „b”. Niestety, sama funkcja pozwala określić wyłącznie "
+            u"argument „a” – z tego względu jej zapis jest niezgodny z zadaniem, które ma zrealizować. Główną wadą "
+            u"tego kodu jest więc przetwarzanie brakującego argumentu „b”.",
+
+            u"Przedstawiona w kodzie funkcja zawiera niepełną listę argumentów. Zadaniem funkcji f(a) jest "
+            u"wyświetlenie sumy argumentu „a” oraz argumentu „b”. Niestety, sama funkcja pozwala określić wyłącznie "
+            u"argument „a” – z tego względu jej zapis jest niezgodny z zadaniem, które ma zrealizować. Odpowiedź ta "
+            u"jest niepoprawna, ponieważ funkcja nie określa, czy argument zarówno „a” jak i „b” muszą mieć charakter "
+            u"liczbowy. Mogą mieć również charakter łańcuchowy (tj. tekstowy).",
+
+            u"Jest to błędna odpowiedź, ponieważ litera „f” w podanym kodzie nie oznacza argumentów funkcji. Argument "
+            u"funkcji oznaczony jest literą „a” i znajduje się w nawiasie. Litera „f” oznacza funkcje, która w tym "
+            u"przypadku przetwarza argument „a”. Ponadto przedstawiona w kodzie funkcja zawiera niepełną listę "
+            u"argumentów. Zadaniem przedstawione funkcji f(a) jest wyświetlenie sumy argumentu „a” oraz argumentu „b”. "
+            u"Niestety, sama funkcja pozwala określić wyłącznie argument „a” – z tego względu jej zapis jest niezgodny "
+            u"z zadaniem, które ma zrealizować.\n"
+            u"\n"
+            u"O definicji funkcji na przykładzie języka programowania C można przeczytać tutaj: "
+            u"https://pl.wikibooks.org/wiki/C/Funkcje#cite_note-1."),
+        (
+            u"Licencje Creative Commons pozwalają zastąpić tradycyjny model ochrony praw autorskich „Wszystkie prawa "
+            u"zastrzeżone” zasadą „Pewne prawa zastrzeżone” – przy jednoczesnym poszanowaniu zasad prawa autorskiego "
+            u"(http://creativecommons.pl/poznaj-licencje-creative-commons/). Licencja CC-BY-SA pozwala na kopiowanie, "
+            u"zmienianie, rozprowadzanie, przedstawianie i wykonywanie utworu oraz utworów zależnych, które muszą być "
+            u"opublikowane na tej samej licencji. Musisz jednak zwrócić uwagę na to, jaka licencja obowiązuje "
+            u"dla materiałów ściągniętych z serwisu The Noun Project, aby nie naruszyć praw ich autorów.",
+
+            u"Licencje Creative Commons pozwalają zastąpić tradycyjny model ochrony praw autorskich „Wszystkie prawa "
+            u"zastrzeżone” zasadą „Pewne prawa zastrzeżone” – przy jednoczesnym poszanowaniu zasad prawa autorskiego "
+            u"(http://creativecommons.pl/poznaj-licencje-creative-commons/). Licencja CC-BY pozwala na kopiowanie, "
+            u"zmienianie, rozprowadzanie, przedstawianie i wykonywanie utworu jedynie pod warunkiem oznaczenia "
+            u"autorstwa i gwarantuje najszersze swobody licencjobiorcy. Materiały z serwisu NASA należą natomiast – "
+            u"jak wszystkie dzieła stworzone przez rząd federalny USA – do domeny publicznej, która daje wszystkim "
+            u"nieograniczone prawo do dzieł, których wykorzystanie nie podlega restrykcjom i ograniczeniom, ponieważ "
+            u"prawa majątkowe do twórczości wygasły lub twórczość ta nigdy nie była lub nie jest przedmiotem prawa "
+            u"autorskiego (http://domenapubliczna.org/co-to-jest-domena-publiczna/).",
+
+            u"Wykorzystanie materiałów ściągniętych z wyszukiwarki grafiki Google, bez sprawdzenia ich pochodzenia, "
+            u"udzielonej przez twórcę licencji oraz bez znajomości praw, jakie przysługują przy ich użyciu, w znacznej "
+            u"większości mogą narazić Cię na zarzut nieuprawnionego wykorzystania cudzej twórczości, a zatem "
+            u"naruszenia praw autorskich. Wyszukiwarka Google umożliwia filtrowanie wyników m.in. na podstawie "
+            u"licencji, na jakiej zostały udostępnione materiały. Opcję tę znajdziesz w zakładce Narzędzia – Prawa do "
+            u"użytkowania."),
+        (
+            u"Podczas wyszukiwaniu w Internecie obiektów takich jak zdjęcia lub grafiki istotna jest nie tyle liczba "
+            u"słów kluczowych, co ich trafność. Wybrane przez Ciebie słowa kluczowe zawierają odniesienie do "
+            u"wydarzenia historycznego, miejsca, formy przekazu – są więc one wyczerpujące i pozwolą otrzymać "
+            u"najlepsze rezultaty odnoszące się do poszukiwanego przez nas obiektu.",
+
+            u"Podczas wyszukiwaniu w Internecie obiektów takich jak zdjęcia lub grafiki istotna jest nie tyle liczba "
+            u"słów kluczowych, co ich trafność. Wybrane przez Ciebie słowa kluczowe zawierają odniesienia wyłącznie "
+            u"do miejsca związanego z wydarzeniem oraz jego zawartości wizualnej – są więc one niewyczerpujące i "
+            u"nie pozwolą uzyskać najlepszych rezultatów odnoszących się do poszukiwanego przez nas obiektu. Brakuje "
+            u"przede wszystkim odniesienia do samego wydarzenia, czyli angielskiej wojny domowej w latach 1642-1651.",
+
+            u"Podczas wyszukiwaniu w Internecie obiektów takich jak zdjęcia lub grafiki istotna jest nie tyle liczba "
+            u"słów kluczowych, co ich trafność. Wybrane przez Ciebie słowa kluczowe zawierają odniesienia do miejsca "
+            u"związanego z wydarzeniem, okresu oraz jego formy – są one trafne, a co za tym idzie powinniśmy uzyskać "
+            u"rezultat odnoszący się do poszukiwanego przez nas obiektu. Warto jednak poszerzyć zakres słów kluczowych "
+            u"o dodatkowe informacje, na przykład użyć hasła „karykatura”. Dodatkowe słowa mogą zwiększyć skuteczność "
+            u"naszych poszukiwań."),
+        (
+            u"Ochrona praw jednostki w Internecie dotyczy różnych aspektów naszego funkcjonowania w przestrzeni "
+            u"cyfrowej. Jedną z nich jest ochrona naszych praw do stworzonego dzieła, a zatem naszych praw autorskich. "
+            u"Nie można zatem wykorzystywać bez pozwolenia niczyich zdjęć do tworzenia własnej relacji z wydarzeń, "
+            u"nawet organizowanych i przeżytych wspólnie.\n"
+            u"\n"
+            u"Co więcej, ludzie mają prawo do samodzielnego decydowania o tym, w jaki sposób ich wizerunek będzie "
+            u"upubliczniony. Dlatego zanim zamieścisz zdjęcie innej osoby, nawet wspólne selfie, upewnij się, "
+            u"że sfotografowana osoba wyraża zgodę na zamieszczenie zdjęcia w Internecie.\n"
+            u"\n"
+            u"Więcej o ochronie wizerunku dowiesz się tu:\n"
+            u"https://portal.uw.edu.pl/web/ado/ochrona-wizerunku.",
+
+            u"Ochrona praw jednostki w Internecie dotyczy różnych aspektów naszego funkcjonowania w przestrzeni "
+            u"cyfrowej. Jedną z nich jest ochrona naszych praw do stworzonego dzieła, a zatem naszych praw autorskich. "
+            u"Nie można zatem wykorzystywać bez pozwolenia niczyich zdjęć do tworzenia własnej relacji z wydarzeń, "
+            u"nawet organizowanych i przeżytych wspólnie. Zanim wykorzystasz czyjeś zdjęcie – nawet takie, na którym "
+            u"jesteś – zapytaj o zgodę jego autorkę / autora o możliwość jego wykorzystania.",
+
+            u"Ochrona praw jednostki w Internecie dotyczy różnych aspektów naszego funkcjonowania w przestrzeni "
+            u"cyfrowej. Jedną z nich jest ochrona naszych praw do stworzonego dzieła, a zatem naszych praw autorskich. "
+            u"Nie można zatem wykorzystywać bez pozwolenia niczyich zdjęć do tworzenia własnej relacji z wydarzeń, "
+            u"nawet organizowanych i przeżytych wspólnie. Jeśli jednak uzyskałeś zgodę autorki / autora na "
+            u"publikowanie zdjęć, możesz to bez wahania zrobić. Co więcej, ludzie mają prawo do samodzielnego "
+            u"decydowania o tym, w jaki sposób ich wizerunek będzie upubliczniony. Jeśli jednak przed publikacją "
+            u"zdjęcia upewniłeś się, że sfotografowana osoba wyraża na zamieszczenie zdjęcia w Internecie zgodę, "
+            u"również możesz bez wątpliwości zamieścić zdjęcie.\n"
+            u"\n"
+            u"Więcej o ochronie wizerunku dowiesz się tu:\n"
+            u"https://portal.uw.edu.pl/web/ado/ochrona-wizerunku."),
+        (
+            u"Internet to niemal nieskończone źródło informacji, edukacji, rozrywki. Często trudno jest zapanować nad "
+            u"otwieraniem kolejnych, coraz bardziej interesujących (jak się może zdawać), stron. Zachowanie dyscypliny "
+            u"i świadomości własnych działań – oraz świadomości upływającego czasu – pozwala na zarządzanie własnym "
+            u"czasem i efektywne wykorzystanie narzędzia, jakim jest światowa sieć. Warto pamiętać, że taka dyscyplina "
+            u"bywa trudna, szczególnie jeśli bez żadnego zastanowienia będziesz pozwalać na to, aby kolejne bodźce "
+            u"odrywały Cię od realizowania zaplanowanych działań.\n"
+            u"\n"
+            u"Więcej o zarządzaniu czasem dowiesz się tu:\n"
+            u"http://michalpasterski.pl/2012/06/zarzadzanie-czasem-w-5-cwiczeniach/.\n"
+            u"\n"
+            u"Co nas denerwuje i rozprasza i jak sobie z tym radzić? Zajrzyj tu:\n"
+            u"http://gazetapraca.pl/gazetapraca/1,95288,13425980,Co_nas_denerwuje__co_nas_rozprasza.html.\n"
+            u"\n"
+            u"Pomidor pomoże? Prosty sposób na zarządzanie czasem znajdziesz tu:\n"
+            u"http://projektantczasu.pl/technika-pomodoro-pommodoro-pomidora/.",
+
+            u"Internet to niemal nieskończone źródło informacji, edukacji, rozrywki. Często trudno jest zapanować nad "
+            u"otwieraniem kolejnych, coraz bardziej interesujących (jak się może zdawać), stron. Zachowanie dyscypliny "
+            u"i świadomości własnych działań – oraz świadomości upływającego czasu – pozwala na zarządzanie własnym "
+            u"czasem i efektywne wykorzystanie narzędzia, jakim jest światowa sieć. Jeśli nie narzucisz sam sobie "
+            u"granic i nie będziesz świadomie panował nad podejmowanymi działaniami, Twój plan nigdy się nie ziści.\n"
+            u"\n"
+            u"Więcej o zarządzaniu czasem dowiesz się tu:\n"
+            u"http://michalpasterski.pl/2012/06/zarzadzanie-czasem-w-5-cwiczeniach/.\n"
+            u"\n"
+            u"Co nas denerwuje i rozprasza i jak sobie z tym radzić? Zajrzyj tu:\n"
+            u"http://gazetapraca.pl/gazetapraca/1,95288,13425980,Co_nas_denerwuje__co_nas_rozprasza.html.\n"
+            u"\n"
+            u"Pomidor pomoże? Prosty sposób na zarządzanie czasem znajdziesz tu:\n"
+            u"http://projektantczasu.pl/technika-pomodoro-pommodoro-pomidora/.",
+
+            u"Internet to niemal nieskończone źródło informacji, edukacji, rozrywki. Często trudno jest zapanować nad "
+            u"otwieraniem kolejnych, coraz bardziej interesujących (jak się może zdawać), stron. Zachowanie dyscypliny "
+            u"i świadomości własnych działań – oraz świadomości upływającego czasu – pozwala na zarządzanie własnym "
+            u"czasem i efektywne wykorzystanie narzędzia, jakim jest światowa sieć. Wykorzystanie zewnętrznych "
+            u"narzędzi, które pozwalają nam obiektywnie oceniać własne zachowania i dokonywać ich stosownej korekty – "
+            u"jeśli to niezbędne – to sposób nie tylko na efektywne działanie, ale i na zwiększenie prawdopodobieństwa "
+            u"osiągnięcia sukcesu w podejmowanych przedsięwzięciach.\n"
+            u"\n"
+            u"Więcej o zarządzaniu czasem dowiesz się tu:\n"
+            u"http://michalpasterski.pl/2012/06/zarzadzanie-czasem-w-5-cwiczeniach/.\n"
+            u"\n"
+            u"Co nas denerwuje i rozprasza i jak sobie z tym radzić? Zajrzyj tu:\n"
+            u"http://gazetapraca.pl/gazetapraca/1,95288,13425980,Co_nas_denerwuje__co_nas_rozprasza.html.\n"
+            u"\n"
+            u"Pomidor pomoże? Prosty sposób na zarządzanie czasem znajdziesz tu:\n"
+            u"http://projektantczasu.pl/technika-pomodoro-pommodoro-pomidora/."),
+        (
+            u"Wtyczki do przeglądarek, których zadaniem jest blokowanie reklam, nie analizują treści zawartych "
+            u"na stronach internetowych. Jeśli posiadałyby taką funkcjonalność, to zapewne odczulibyśmy spowolnienie "
+            u"w działaniu przeglądarki internetowej. Wtyczki blokujące reklamy działają w oparciu o listę plików "
+            u"graficznych, animacji i wyskakujących okien. To przede wszystkim sam użytkownik decyduje, jakie elementy "
+            u"strony mają podlegać zablokowaniu w oparciu o zdefiniowane obiekty.\n"
+            u"\n"
+            u"O mechanizmie blokowania reklam można przeczytać na stronie producenta najpopularniejszej wtyczki "
+            u"Adblock Plus: https://adblockplus.org/en/about.",
+
+            u"Faktycznie, korzystając z wtyczki blokującej reklamy zauważymy, że reklamy te nie wyświetlają się nam "
+            u"podczas użytkowania przeglądarki. Co więcej nasza przeglądarka nie tylko nie wyświetla nam zablokowanych "
+            u"reklam, ale wcześniej przerywa komunikację z serwerami, które odpowiadają za ich publikacje. Za to, jaki "
+            u"serwer powinien być niedopuszczony do komunikacji z przeglądarką, odpowiada sam użytkownik. Wtyczki "
+            u"blokujące reklamy działają bowiem w oparciu o listę plików graficznych, animacji i wyskakujących okien. "
+            u"To przede wszystkim sam użytkownik decyduje, jakie elementy strony mają znaleźć się na stronie i "
+            u"podlegać zablokowaniu.\n"
+            u"\n"
+            u"O mechanizmie blokowania reklam można przeczytać na stronie producenta najpopularniejszej wtyczki "
+            u"Adblock Plus: https://adblockplus.org/en/about.",
+
+            u"Przeglądarka internetowa z zainstalowaną wtyczką nie tylko nie wyświetla nam zablokowane reklamy, "
+            u"ale przede wszystkim blokuję komunikację z serwerami, które odpowiadają za ich publikacje. Za to, "
+            u"jaki serwer powinien być niedopuszczony do komunikacji z przeglądarką, odpowiada sam użytkownik. Wtyczki "
+            u"blokujące reklamy działają bowiem w oparciu o listę plików graficznych, animacji i wyskakujących okien. "
+            u"To przede wszystkim sam użytkownik decyduje, jakie elementy strony mają znaleźć się na stronie "
+            u"i podlegać zablokowaniu. Wtyczka nie tylko zablokuje te elementy, ale również nie dopuści do komunikacji "
+            u"z serwerami odpowiedzialnymi za ich treść.\n"
+            u"\n"
+            u"O mechanizmie blokowania reklam można przeczytać na stronie producenta najpopularniejszej wtyczki "
+            u"Adblock Plus: https://adblockplus.org/en/about."),
+    ]
+
+
+class CollegiumTestForm(ContactForm):
+    pyt1 = quiz_question_multiple(
+        label=u'1. Crowdfunding to inaczej:',
+        choices=[
+            (01, u'finansowanie społecznościowe'),
+            (10, u'finansowanie wydawnicze'),
+            (20, u'finansowanie przez wielkie wytwórnie'),
+            (30, u'finansowanie wielkich sponsorów')])
+    pyt2 = quiz_question_multiple(
+        label=u'2. Powracające problemy z dostępem do internetu u danego usługodawcy to materiał '
+              u'na reklamację telekomunikacyjną składaną do:',
+        choices=[
+            (01, u'Urzędu Komunikacji Elektronicznej'),
+            (10, u'Urzędu Kontroli Skarbowej'),
+            (20, u'Urzędu Marszałkowskiego'),
+            (30, u'Urzędu Ochrony Państwa')])
+    pyt3 = quiz_question_multiple(
+        label=u'3. Śledzone przez firmę zachowanie internauty w internecie:',
+        choices=[
+            (01, u'zdradzać może preferencje internauty'),
+            (11, u'zdradzać może cechy osobowości internauty'),
+            (21, u'możliwe jest dzięki programom komputerowym'),
+            (31, u'pozwala emitować wstępnie dopasowane oferty na ekranie komputera internauty'),
+            (41, u'pozwala badać reakcję na reklamy'),
+            (50, u'żadna z powyższych odpowiedzi nie jest prawdziwa')])
+    pyt4 = quiz_question_multiple(
+        label=u'4. Profilowanie nie wiąże się z:',
+        choices=[
+            (00, u'kategoryzowaniem ludzi według cech i zachowań'),
+            (10, u'doborem reklam do użytkownika pod kątem wieku i płci'),
+            (20, u'doborem reklam do użytkownika pod kątem wykonanych przez niego polubień i kliknięć'),
+            (31, u'żadna z powyższych odpowiedzi nie jest prawidłowa')])
+    pyt5 = quiz_question_multiple(
+        label=u'5. Dobór reklam do użytkownika nie jest w internecie możliwy na podstawie:',
+        choices=[
+            (00, u'produktów oglądanych w sklepach internetowych'),
+            (10, u'słów wyszukiwanych w wyszukiwarkach'),
+            (20, u'treści e-maili w usługach poczty elektronicznej'),
+            (31, u'żadna z powyższych odpowiedzi nie jest prawidłowa')])
+    pyt6 = quiz_question_multiple(
+        label=u'6. Jeżeli sąd odmówi osobie poniżej 16 roku życia prawa dostępu do informacji publicznej, '
+              u'a informacja ta jest dla zainteresowanej osoby subiektywnie ważna, to jaki kolejny krok warto wykonać?',
+        choices=[
+            (00, u'zrezygnować z uzyskania dostępu do informacji publicznej'),
+            (10, u'odłożyć wniosek o dostęp do informacji publicznej do ukończenia 18 roku życia'),
+            (21, u'udać się po pomoc do Rzecznika Praw Obywatelskich'),
+            (30, u'żadne z powyższych')])
+    pyt7 = quiz_question_multiple(
+        label=u'7. W przypadku, gdy informacje o sprzęcie w sklepie internetowym są niepełne, a sprzedawca '
+              u'konsekwentnie wprowadza klientów indywidualnych w błąd, gdzie warto kierować się po pomoc?',
+        choices=[
+            (01, u'Urząd Ochrony Konkurencji i Konsumentów'),
+            (10, u'Urząd Kontroli Skarbowej'),
+            (20, u'Urząd do Spraw Cudzoziemców'),
+            (30, u'Urząd Ochrony Państwa')])
+    pyt8 = quiz_question_multiple(
+        label=u'8. W ramach dozwolonego użytku wolno nam bez zgody twórcy przygotować spektakl teatralny '
+              u'i wystawić go w szkole oraz:',
+        choices=[
+            (00, u'Sprzedawać widzom bilety, a zysk przeznaczyć na zakup sprzętu uczniowskiego koła naukowego'),
+            (10, u'Sprzedawać widzom bilety, a zysk podzielić pomiędzy występujących artystów'),
+            (20, u'Nagrać spektakl i udostępnić go wszystkim za darmo w internecie'),
+            (30, u'Nagrać spektakl i udostępniać go odpłatnie w internecie'),
+            (41, u'Żadna z odpowiedzi nie jest prawidłowa')])
+    pyt9 = quiz_question_multiple(
+        label=u'9. Osoby niepełnosprawne często korzystają z nietypowych narzędzi. Osoby niewidome w internecie '
+              u'surfują posługując się specjalnymi “gadającymi” przeglądarkami. Osoby nie mogące korzystać z rąk '
+              u'mają specjalne urządzenia umożliwiające nawigację po stronach lub systemy rozpoznawania głosu. '
+              u'Zestaw norm dzięki którym strony internetowe są przyjazne dla osób niepełnosprawnych to:',
+        choices=[
+            (00, u'IDPD – Internet for Disabled People Directive'),
+            (11, u'WCAG – Web Content Accessibility Guidelines'),
+            (20, u'HTTP – HyperText Markup Language'),
+            (30, u'EAA – European Accessibility Act')])
+    pyt10 = quiz_question_multiple(
+        label=u'10. Dane osobowe są chronione mocą prawa, ale niektóre z nich uznaje się za dane wrażliwe i poddaje '
+              u'dodatkowym rygorom, m.in. nie wolno ich przetwarzać bez naszej pisemnej zgody lub w celu innym '
+              u'niż szczegółowo określony. Do danych wrażliwych zaliczamy:',
+        choices=[
+            (01, u'pochodzenie rasowe lub etniczne'),
+            (11, u'przynależność partyjną'),
+            (21, u'dane o stanie zdrowia'),
+            (30, u'numer PESEL')])
+    pyt11 = quiz_question_multiple(
+        label=u'11. Majątkowe prawa autorskie są ograniczone w czasie. Kiedy wygasną utwór przechodzi '
+              u'do domeny publicznej i staje się własnością wspólną. Dzieje się to:',
+        choices=[
+            (00, u'50 lat po śmierci twórcy (ze skutkiem na koniec roku kalendarzowego)'),
+            (10, u' 50 lat po pierwszym rozpowszechnieniu dzieła, jeśli twórca był anonimowy'),
+            (21, u'70 lat po śmierci twórcy (ze skutkiem na koniec roku kalendarzowego)'),
+            (31, u'70 lat po pierwszym rozpowszechnieniu dzieła, jeśli miało ono miejsce po śmierci twórcy')])
+    pyt12 = quiz_question_multiple(
+        label=u'12. Wszystkim twórcom przysługują autorskie prawa osobiste, które – w przeciwieństwie '
+              u'do praw majątkowych – są wieczne i niezbywalne. Zaliczamy do nich:',
+        choices=[
+            (01, u'Prawo do rozpoznania autorstwa'),
+            (11, u'Prawo do decyzji o pierwszym rozpowszechnieniu dzieła'),
+            (21, u'Prawo do zachowania integralności utworu'),
+            (30, u'Prawo do wycofania utworu z obiegu')])
+    pyt13 = quiz_question_multiple(
+        label=u'13. Telewizje utrzymują się przede wszystkim z reklam emitowanych w trakcie trwania programów. '
+              u'Przepisy prawa:',
+        choices=[
+            (00, u'nie regulują sposobu w jaki sposób reklamy te są wyświetlane, decyduje o tym nadawca '
+                u'kierując się rachunkiem ekonomicznym, tj. wybiera takie formy wyświetlania reklam, '
+                u'które są najbardziej zyskowne'),
+            (11, u'ograniczają typ reklam które można emitować ze względu na ich treść lub reklamowane produkty – '
+                u'np. nie wolno przedstawiać w pozytywnym świetle ludzi niszczących środowisko naturalne '
+                u'lub reklamować gry w kości'),
+            (20, u'zabraniają reklamowania produktów w treści filmów'),
+            (31, u'uniemożliwiają telewizji publicznej przerywanie filmów reklamami')])
+    pyt14 = quiz_question_multiple(
+        label=u'14. Urzędy które zajmują się ochroną praw obywateli w mediach cyfrowych to:',
+        choices=[
+            (01, u'Rzecznik Praw Obywatelskich'),
+            (10, u'Minister Cyfryzacji'),
+            (21, u'Rzecznik Praw Dziecka'),
+            (31, u'Urząd Ochrony Danych Osobowych')])
+    pyt15 = quiz_question_multiple(
+        label=u'15. W odniesieniu do internetu tak zwane prawo do zapomnienia to:',
+        choices=[
+            (00, u'Prawo niewysłania w Unii Europejskiej e-maila z potwierdzeniem udziału bez podania przyczyny'),
+            (10, u'Prawo niewysłania w Unii Europejskiej e-maila z potwierdzeniem udziału z podaniem zapomnienia '
+                u'jako przyczyny'),
+            (21, u'Prawo każdego obywatela Unii Europejskiej do zażądania usunięcia jego imienia i nazwiska '
+                u'z wyszukiwarki internetowej'),
+            (30, u'Prawo każdego obywatela Unii Europejskiej do założenia konta w serwisie społecznościowym'),
+            (40, u'Prawo każdego obywatela Unii Europejskiej do zapomnienia adresu wyszukiwarki internetowej '
+                u'albo serwisu społecznościowego')])
+    pyt16 = quiz_question_multiple(
+        label=u'16. Autorskie prawa osobiste chronią twórców utworów bezterminowo i bezwarunkowo. Zaliczamy do nich:',
+        choices=[
+            (01, u'prawo do oznaczania utworu imieniem i nazwiskiem twórcy'),
+            (10, u'zakaz parodiowania utworu bez zgody twórcy'),
+            (21, u'prawo do zachowania integralności utworu (czyli np. obowiązek wiernego cytowania)'),
+            (30, u'prawo do wycofania utworu z obiegu'),
+            (41, u'prawo do decyzji o pierwszym rozpowszechnieniu utworu'),
+            (50, u'zakaz kopiowania utworu bez zgody twórcy')])
+    pyt17 = quiz_question_multiple(
+        label=u'17. Wykonałeś/wykonałaś remiks cudzych utworów. W jakich sytuacjach możesz rozpowszechnić swój utwór?',
+        choices=[
+            (01, u'mam zgodę autora/autorki oryginalnego utworu'),
+            (10, u'materiały do remiksu zostały ściągnięte z serwisu do przechowywania plików'),
+            (20, u'wykorzystane piosenki przesłała mi na Facebooku koleżanka'),
+            (31, u'zezwala na to licencja, na której są opublikowane wykorzystane utwory'),
+            (41, u'wykorzystane w remiksie utwory są dostępne w domenie publicznej (minęło 70 lat od śmierci autora)'),
+            (50, u'utwory użyte w remiksie były udostępnione do odsłuchania na stronach twórców w formie plików mp3')])
+    pyt18 = quiz_question_multiple(
+        label=u'18. Chcesz dowiedzieć się, co sklep internetowy robi z twoimi danymi osobowymi. '
+              u'Gdzie szukasz tej informacji?',
+        choices=[
+            (00, u'w zakładce „O nas”'),
+            (10, u'w zakładce „Twój profil”'),
+            (21, u'w „Polityce prywatności”'),
+            (30, u'w „Regulaminie zakupów”')])
+    pyt19 = quiz_question_multiple(
+        label=u'19. Czy możesz opublikować niekomercyjnie remiks wierszy dostępnych w bibliotece internetowej '
+              u'Wolne Lektury?',
+        choices=[
+            (00, u'nie mogę'),
+            (10, u'mogę, ale dopiero kiedy uzyskam zgodę autorów/autorek lub ich spadkobierców'),
+            (20, u'mogę, uiściłem/-am opłaty na rzecz Funduszu Promocji Twórczości'),
+            (31, u'mogę, wiersze z biblioteki Wolne Lektury znajdują się w domenie publicznej '
+                u'albo publikowane są na licencji CC BY-SA 3.0, która umożliwia taką publikację')])
+    pyt20 = quiz_question_multiple(
+        label=u'20. Na co NIE pozwala ci dozwolony użytek?',
+        choices=[
+            (01, u'na sprzedawanie kopii płyt z muzyką twojego ulubionego zespołu'),
+            (10, u'na oglądanie filmu pobranego z internetu'),
+            (20, u'na nagranie serialu na płytę i obejrzenie go z rodziną'),
+            (30, u'żadna z odpowiedzi nie jest prawidłowa')])
+
+    ANSWER_COMMENTS = [
+        (
+            u'Początków crowfoundingu można szukać już XVIII wieku, jednak jego największy rozwój przypada na czasy kiedy funkcjonował już internet. Dzięki powstającym internetowym społecznościom możliwe było stworzenie modelu płatności opartego na niewielkich wpłatach od dużej liczby osób. Finansowanie społecznościowe pomaga zapaleńcom, niszowym twórcom czy organizacjom pozarządowym w zbieraniu pieniędzy na cele, które znajdują poparcie w oczach pewnej społeczności. W ramach crowdfoundingu osoby angażujące się finansowo w dany projekt otrzymują coś w zamian. Może to być np. dostęp do wersji testowej wynalazku czy przedpremierowy pokaz filmu, na powstanie których wpłaciło się pieniądze. Zasada nagradzania osób wpłacających w ramach crowdfoundingu zwykle opiera się na tym, że im więcej ktoś wpłaci pieniędzy na dany projekt tym bardziej atrakcyjną formę wynagrodzenia otrzymuje.',
+            u'Jeśli chcesz wydać np. książkę możesz to zrobić podpisując umowę z wydawnictwem, które płaci za druk, skład, korektę i inne czynności niezbędne do pojawienia się książki na rynku. Wydawnictwo autorowi płaci wynagrodzenie w postaci ustalonego umownie procentu od ceny książki. Jednak to nie jedyny sposób na wydanie książki. Coraz popularniejszy jest trend selfpublishingu (tj. samodzielne wydanie książki) oraz crowdfoundingu, w ramach którego społeczność przekazuje na pewien cel finanse. Finansowanie społecznościowe pomaga m.in. twórcom w zbieraniu pieniędzy na cele, które znajdują poparcie w oczach pewnej społeczności. W ramach crowdfoundingu osoby angażujące się finansowo w dany projekt otrzymują coś w zamian. Zasada nagradzania osób wpłacających w ramach crowdfoundingu zwykle opiera się na tym, że im więcej ktoś wpłaci pieniędzy na dany projekt tym bardziej atrakcyjną formę wynagrodzenia otrzymuje np. podziękowania we wstępie do książki czy też zniżkę na zakup książki po jej wydaniu.',
+            u'Chcąc wydać swoją własną płytę albo wyprodukować film możesz wejść we współpracę z dużą wytwórnią – płytową czy filmową. Ona pokryje wszelkie koszty związane z powstaniem, dystrybucja i sprzedażą Twojego dzieła. Jednak to nie jedyny sposób na wydanie własnej płyty czy stworzenie swojego filmu. Coraz popularniejszy jest trend zwany crowdfoundingiem, w ramach którego społeczność przekazuje na pewien cel finanse. Finansowanie społecznościowe pomaga m.in. twórcom w zbieraniu pieniędzy na cele, które znajdują poparcie w oczach pewnej społeczności. W ramach crowdfoundingu osoby angażujące się finansowo w dany projekt otrzymują coś w zamian. Zasada nagradzania osób wpłacających w ramach crowdfoundingu zwykle opiera się na tym, że im więcej ktoś wpłaci pieniędzy na dany projekt tym bardziej atrakcyjną formę wynagrodzenia otrzymuje np. ekskluzywny materiał z nagrania płyty płyty czy też zaproszenie na przedpremierowy pokaz filmu.',
+            u'Sponsoring to jeden z bardziej popularnych sposobów zdobywania pieniędzy na prowadzenie działań z zakresu sportu czy kultury. Pozyskiwanie sponsorów w postaci dużych marek, które wykładają pieniądze na dany cel w zamian za promocję ich firmy np. podczas wydarzenia nie jest jednak zadaniem łatwym. Nie tylko dotarcie do sponsorów jest trudne, ale również cały proces pozyskania finansowania ze względu na wewnętrzną politykę firmy, strategię czy wizerunek marki. Dlatego też na znaczeniu nabiera trend crowdfoundingu, w ramach którego społeczność przekazuje na pewien cel finanse. Finansowanie społecznościowe pomaga m.in. twórcom czy organizatorom eventów w zbieraniu pieniędzy na cele, które znajdują poparcie w oczach pewnej społeczności. W ramach crowdfoundingu osoby angażujące się finansowo w dany projekt otrzymują coś w zamian. Zasada nagradzania osób wpłacających w ramach crowdfoundingu zwykle opiera się na tym, że im więcej ktoś wpłaci pieniędzy na dany projekt tym bardziej atrakcyjną formę wynagrodzenia otrzymuje np. podziękowanie ustne w trakcie wydarzenia czy możliwość wystąpienia podczas wydarzenia.',
+        ),
+        (
+            u'Urząd Komunikacji Elektronicznej, w skrócie UKE, to organ regulujący działalność telekomunikacyjną, pocztową, gospodarkę zasobami częstotliwości oraz kontrolny spełniania wymagań dotyczących kompatybilności elektromagnetycznej. Dlatego też w sytuacji problemów z dostępem do internetu u danego dostawcy, która związana jest bezpośrednio z usługami telekomunikacyjnymi to właśnie ten Urząd będzie właściwym do złożenia reklamacji.',
+            u'Urząd Kontroli Skarbowej chroni interesy i prawa majątkowe Skarbu Państwa. Prowadząc kontrole dba o zapewnienie skuteczności wykonywania zobowiązań podatkowych i innych należności stanowiących dochód do budżetu państwa. Bada także czy gospodarowanie mieniem państwowym jest zgodne z prawem, przeciwdziała i zwalcza naruszeniom prawa w tym zakresie. Jak widać więc Urząd ten nie ma wiele wspólnego z reklamacjami telekomunikacyjnymi. W celu złożenia takiej reklamacji należy się udać do UKE – Urzędu Komunikacji Elektronicznej.',
+            u'Urząd Marszałkowski jest organem pomocniczym marszałka województwa. Dzięki niemu możliwa jest obsługa kadrowa, prawna, techniczna, organizacyjna i ekspercka komisji organów wykonawczych w województwie tj. zarządu i marszałka oraz uchwałodawczych - sejmiku województwa. Urząd Marszałkowski nie rozpatruje skarg ani reklamacji telekomunikacyjnych. W celu złożenia takiej reklamacji należy udać się do UKE – Urzędu Komunikacji Elektronicznej.',
+            u'Jest to organizacja będąca częścią służb specjalnych RP. Jej pracownicy są odpowiedzialni za zapewnienie bezpieczeństwa i obronności kraju, czy też zapobieganie różnorodnym przestępstwom, które mogą mieć konsekwencje w skali całego kraju. UOP nie rozpatruje skarg telekomunikacyjnych. Dlatego chcąc złożyć reklamację należy udać się do UKE, czyli Urzędu Komunikacji Elektronicznej.'
+        ),
+        (
+            u'Śledząc IP danego komputera można odczytywać preferencje czy też poznawać osobowość internauty. Wiadomo bowiem jakie strony odwiedza, w co klika, co kupuje, jakie posty lajkuje na Facebooku. Internet to kopalnia wiedzy o użytkownikach sieci. Gromadzone online dane nazywane są Big Data, a ich analizę umożliwia rozwój specjalnego oprogramowania i sztucznej inteligencji. Maszyny analizują dane, a następnie wysnuwają wnioski i dopasowują np. przekaz marketingowy i reklamowy do preferencji internauty. Pozwalają także na badanie reakcji odbiorcy na prezentowany przekaz. Wszystko to odbywa się za pomocą maszyn, dlatego też nie musisz martwić się, że jesteś pod stałą obserwacją.',
+            u'Śledząc IP danego komputera można odczytywać preferencje czy też poznawać osobowość internauty. Wiadomo bowiem jakie strony odwiedza, w co klika, co kupuje, jakie posty lajkuje na Facebooku. Internet to kopalnia wiedzy o użytkownikach sieci. Gromadzone online dane nazywane są Big Data, a ich analizę umożliwia rozwój specjalnego oprogramowania i sztucznej inteligencji. Maszyny analizują dane, a następnie wysnuwają wnioski i dopasowują np. przekaz marketingowy i reklamowy do preferencji internauty. Pozwalają także na badanie reakcji odbiorcy na prezentowany przekaz. Wszystko to odbywa się za pomocą maszyn, dlatego też nie musisz martwić się, że jesteś pod stałą obserwacją.',
+            u'Śledząc IP danego komputera można odczytywać preferencje czy też poznawać osobowość internauty. Wiadomo bowiem jakie strony odwiedza, w co klika, co kupuje, jakie posty lajkuje na Facebooku. Internet to kopalnia wiedzy o użytkownikach sieci. Gromadzone online dane nazywane są Big Data, a ich analizę umożliwia rozwój specjalnego oprogramowania i sztucznej inteligencji. Maszyny analizują dane, a następnie wysnuwają wnioski i dopasowują np. przekaz marketingowy i reklamowy do preferencji internauty. Pozwalają także na badanie reakcji odbiorcy na prezentowany przekaz. Wszystko to odbywa się za pomocą maszyn, dlatego też nie musisz martwić się, że jesteś pod stałą obserwacją.',
+            u'Śledząc IP danego komputera można odczytywać preferencje czy też poznawać osobowość internauty. Wiadomo bowiem jakie strony odwiedza, w co klika, co kupuje, jakie posty lajkuje na Facebooku. Internet to kopalnia wiedzy o użytkownikach sieci. Gromadzone online dane nazywane są Big Data, a ich analizę umożliwia rozwój specjalnego oprogramowania i sztucznej inteligencji. Maszyny analizują dane, a następnie wysnuwają wnioski i dopasowują np. przekaz marketingowy i reklamowy do preferencji internauty. Pozwalają także na badanie reakcji odbiorcy na prezentowany przekaz. Wszystko to odbywa się za pomocą maszyn, dlatego też nie musisz martwić się, że jesteś pod stałą obserwacją.',
+            u'Śledząc IP danego komputera można odczytywać preferencje czy też poznawać osobowość internauty. Wiadomo bowiem jakie strony odwiedza, w co klika, co kupuje, jakie posty lajkuje na Facebooku. Internet to kopalnia wiedzy o użytkownikach sieci. Gromadzone online dane nazywane są Big Data, a ich analizę umożliwia rozwój specjalnego oprogramowania i sztucznej inteligencji. Maszyny analizują dane, a następnie wysnuwają wnioski i dopasowują np. przekaz marketingowy i reklamowy do preferencji internauty. Pozwalają także na badanie reakcji odbiorcy na prezentowany przekaz. Wszystko to odbywa się za pomocą maszyn, dlatego też nie musisz martwić się, że jesteś pod stałą obserwacją.',
+            u'Śledząc IP danego komputera można odczytywać preferencje czy też poznawać osobowość internauty. Wiadomo bowiem jakie strony odwiedza, w co klika, co kupuje, jakie posty lajkuje na Facebooku. Internet to kopalnia wiedzy o użytkownikach sieci. Gromadzone online dane nazywane są Big Data, a ich analizę umożliwia rozwój specjalnego oprogramowania i sztucznej inteligencji. Maszyny analizują dane, a następnie wysnuwają wnioski i dopasowują np. przekaz marketingowy i reklamowy do preferencji internauty. Pozwalają także na badanie reakcji odbiorcy na prezentowany przekaz. Wszystko to odbywa się za pomocą maszyn, dlatego też nie musisz martwić się, że jesteś pod stałą obserwacją.',
+        ),
+        (
+            u'Profilowanie w internecie jest stosowane w większości procesów marketingowych. Dzięki czemu można poprzez kategoryzowanie ludzi według cech i zachowań, danych demograficznych i wielu innych czynników dopasować do niego spersonalizowany komunikat reklamowy. Jest to proces, który nie wymaga zgody użytkownika internetu. Zgodnie z rozporządzeniem RODO, które wchodzi w życie wraz z początkiem 2018 roku zabronione jest profilowanie prowadzące do dyskryminacji np. ze względu na rasę.',
+            u'Profilowanie w internecie jest stosowane w większości procesów marketingowych. Dzięki czemu można poprzez kategoryzowanie ludzi według cech i zachowań, danych demograficznych i wielu innych czynników dopasować do niego spersonalizowany komunikat reklamowy. Jest to proces, który nie wymaga zgody użytkownika internetu. Zgodnie z rozporządzeniem RODO, które wchodzi w życie wraz z początkiem 2018 roku zabronione jest profilowanie prowadzące do dyskryminacji np. ze względu na rasę.',
+            u'Profilowanie w internecie jest stosowane w większości procesów marketingowych. Dzięki czemu można poprzez kategoryzowanie ludzi według cech i zachowań, danych demograficznych i wielu innych czynników dopasować do niego spersonalizowany komunikat reklamowy. Jest to proces, który nie wymaga zgody użytkownika internetu. Zgodnie z rozporządzeniem RODO, które wchodzi w życie wraz z początkiem 2018 roku zabronione jest profilowanie prowadzące do dyskryminacji np. ze względu na rasę.',
+            u'Profilowanie w internecie jest stosowane w większości procesów marketingowych. Dzięki czemu można poprzez kategoryzowanie ludzi według cech i zachowań, danych demograficznych i wielu innych czynników dopasować do niego spersonalizowany komunikat reklamowy. Jest to proces, który nie wymaga zgody użytkownika internetu. Zgodnie z rozporządzeniem RODO, które wchodzi w życie wraz z początkiem 2018 roku zabronione jest profilowanie prowadzące do dyskryminacji np. ze względu na rasę. To sprawia, że wszystkie powyższe odpowiedzi są związane z profilowaniem. Odpowiadając na pytanie, które nie są związane z tematem należało więc zaznaczyć odpowiedź żadna z powyższych odpowiedzi nie jest prawdziwa.',
+        ),
+        (
+            u'Personalizacja i dobór reklam do indywidualnego użytkownika w internecie odbywa się na podstawie jego zachowań w sieci – stron internetowych, które odwiedzał, słów wyszukiwanych w wyszukiwarkach, treści e-mail w usługach poczty elektronicznych, produktów oglądanych w sklepach. Dane te są przetwarzane, a następnie analizowane tak aby dobrać przekaz komunikatu reklamowego do potrzeb internauty.',
+            u'Personalizacja i dobór reklam do indywidualnego użytkownika w internecie odbywa się na podstawie jego zachowań w sieci – stron internetowych, które odwiedzał, słów wyszukiwanych w wyszukiwarkach, treści e-mail w usługach poczty elektronicznych, produktów oglądanych w sklepach. Dane te są przetwarzane, a następnie analizowane tak aby dobrać przekaz komunikatu reklamowego do potrzeb internauty.',
+            u'Personalizacja i dobór reklam do indywidualnego użytkownika w internecie odbywa się na podstawie jego zachowań w sieci – stron internetowych, które odwiedzał, słów wyszukiwanych w wyszukiwarkach, treści e-mail w usługach poczty elektronicznych, produktów oglądanych w sklepach. Dane te są przetwarzane, a następnie analizowane tak aby dobrać przekaz komunikatu reklamowego do potrzeb internauty.',
+            u'Personalizacja i dobór reklam do indywidualnego użytkownika w internecie odbywa się na podstawie jego zachowań w sieci – stron internetowych, które odwiedzał, słów wyszukiwanych w wyszukiwarkach, treści e-mail w usługach poczty elektronicznych, produktów oglądanych w sklepach. Dane te są przetwarzane, a następnie analizowane tak aby dobrać przekaz komunikatu reklamowego do potrzeb internauty. Dlatego też dobór reklam jest możliwy na podstawie wszystkich wymienionych działań użytkownika sieci. Odpowiadając na to pytanie należy więc zaznaczyć odpowiedź: żadna z powyższych odpowiedzi nie jest prawidłowa.',
+        ),
+        (
+            u'Prawo dostępu do informacji publicznej jest prawem człowieka i przysługuje każdemu. W prawodawstwie polskim regulacje dotyczące dostępu do informacji publicznej zawarte są w Konstytucji RP (art. 61) wg której prawo dostępu do informacji publicznej posiada każdy. Również osoby nieletnie. Dlatego jeśli osobie poniżej 16 roku życia został odmówiony dostęp do informacji publicznej należy zgłosić się do Rzecznika Praw Obywatelskich z prośbą o pomoc.',
+            u'Prawo dostępu do informacji publicznej jest prawem człowieka i przysługuje każdemu. W prawodawstwie polskim regulacje dotyczące dostępu do informacji publicznej zawarte są w Konstytucji RP (art. 61) wg której prawo dostępu do informacji publicznej posiada każdy. Również osoby nieletnie. Dlatego jeśli osobie poniżej 16 roku życia został odmówiony dostęp do informacji publicznej należy zgłosić się do Rzecznika Praw Obywatelskich z prośbą o pomoc.',
+            u'Prawo dostępu do informacji publicznej jest prawem człowieka i przysługuje każdemu. W prawodawstwie polskim regulacje dotyczące dostępu do informacji publicznej zawarte są w Konstytucji RP (art. 61) wg której prawo dostępu do informacji publicznej posiada każdy. Również osoby nieletnie. Dlatego jeśli osobie poniżej 16 roku życia został odmówiony dostęp do informacji publicznej należy zgłosić się do Rzecznika Praw Obywatelskich z prośbą o pomoc.',
+            u'Prawo dostępu do informacji publicznej jest prawem człowieka i przysługuje każdemu. W prawodawstwie polskim regulacje dotyczące dostępu do informacji publicznej zawarte są w Konstytucji RP (art. 61) wg której prawo dostępu do informacji publicznej posiada każdy. Również osoby nieletnie. Dlatego jeśli osobie poniżej 16 roku życia został odmówiony dostęp do informacji publicznej należy zgłosić się do Rzecznika Praw Obywatelskich z prośbą o pomoc.',
+        ),
+        (
+            u'Jak sama nazwa wskazuje UOKiK za zadanie ma ochronę konsumentów przed niewłaściwymi praktykami ze strony producentów i sprzedawców. Celowe wprowadzanie w błąd jest działaniem na szkodę konsumenta, dlatego też każdy kto jest ofiarą niewłaściwych praktyk, szkodliwych dla interesu konsumenta może skierować się do UOKiK z prośbą o pomoc.',
+            u'Urząd Kontroli Skarbowej chroni interesy i prawa majątkowe Skarbu Państwa. Prowadząc kontrole dba o zapewnienie skuteczności wykonywania zobowiązań podatkowych i innych należności stanowiących dochód do budżetu państwa. Bada także czy gospodarowanie mieniem państwowym jest zgodne z prawem, przeciwdziała i zwalcza naruszeniom prawa w tym zakresie. Urząd ten nie zajmuje się sprawami konsumenckimi. W celu rozwiązania opisanego w pytaniu problemu należy udać się do Urzędu Ochrony Konkurencji i Konsumentów.',
+            u'Jak można przeczytać na stronie Urzędu do Spraw Cudzoziemców powstał on „by zapewnić kompleksową i profesjonalną obsługę w zakresie legalizacji pobytu i udzielenia ochrony cudzoziemców przebywających na terytorium Rzeczpospolitej Polskiej.” Kwestie związane z ochroną praw konsumenckich nie leżą w kompetencjach urzędu. Aby uzyskać właściwą pomoc należy zgłosić się do Urzędu Ochrony Konkurencji i Konsumentów.',
+            u'Jest to organizacja będąca częścią służb specjalnych RP. Jej pracownicy są odpowiedzialni za zapewnienie bezpieczeństwa i obronności kraju, czy też zapobieganie różnorodnym przestępstwom, które mogą mieć konsekwencje w skali całego kraju. UOP nie rozpatruje skarg konsumenckich. Aby uzyskać pomoc w opisanym w pytaniu przykładzie należy zgłosić się do UOKiK – Urzędu Ochrony Konkurencji i Konsumentów.',
+        ),
+        (
+            u'Zgodnie z art. 31 ust. 2 prawa autorskiego "Wolno nieodpłatnie publicznie wykonywać lub odtwarzać przy pomocy urządzeń lub nośników znajdujących się w tym samym miejscu co publiczność rozpowszechnione utwory podczas imprez szkolnych oraz akademickich, jeżeli nie łączy się z tym osiąganie pośrednio lub bezpośrednio korzyści majątkowej i artyści wykonawcy oraz osoby odtwarzające utwory nie otrzymują wynagrodzenia." Przygotowanie spektaklu teatralnego i jego wystawienie w szkole będzie w rozumieniu prawa autorskiego "wykonaniem utworu", zatem nie można w tej sytuacji osiągać żadnych korzyści majątkowych, niezależnie od tego na co miałyby być przeznaczone zdobyte środki.',
+            u'Zgodnie z art. 31 ust. 2 prawa autorskiego "Wolno nieodpłatnie publicznie wykonywać lub odtwarzać przy pomocy urządzeń lub nośników znajdujących się w tym samym miejscu co publiczność rozpowszechnione utwory podczas imprez szkolnych oraz akademickich, jeżeli nie łączy się z tym osiąganie pośrednio lub bezpośrednio korzyści majątkowej i artyści wykonawcy oraz osoby odtwarzające utwory nie otrzymują wynagrodzenia." Przygotowanie spektaklu teatralnego i jego wystawienie w szkole będzie w rozumieniu prawa autorskiego "wykonaniem utworu", zatem nie można w tej sytuacji osiągać żadnych korzyści majątkowych, niezależnie od tego na co miałyby być przeznaczone zdobyte środki.',
+            u'Udostępnianie w internecie spektaklu wykracza poza ramy prawne publicznego wykonywania utworu, zatem odpowiedź ta jest błędna.',
+            u'Udostępnianie w internecie spektaklu wykracza poza ramy prawne publicznego wykonywania utworu, zatem odpowiedź ta jest błędna.',
+            u'Zgodnie z art. 31 ust. 2 prawa autorskiego "Wolno nieodpłatnie publicznie wykonywać lub odtwarzać przy pomocy urządzeń lub nośników znajdujących się w tym samym miejscu co publiczność rozpowszechnione utwory podczas imprez szkolnych oraz akademickich, jeżeli nie łączy się z tym osiąganie pośrednio lub bezpośrednio korzyści majątkowej i artyści wykonawcy oraz osoby odtwarzające utwory nie otrzymują wynagrodzenia." Przygotowanie spektaklu teatralnego i jego wystawienie w szkole będzie w rozumieniu prawa autorskiego "wykonaniem utworu", zatem nie można w tej sytuacji osiągać żadnych korzyści majątkowych, niezależnie od tego na co miałyby być przeznaczone zdobyte środki. Z kolei udostępnianie w internecie spektaklu wykracza poza ramy prawne publicznego wykonywania utworu, zatem żadna z odpowiedzi nie jest poprawna.',
+        ),
+        (
+            u'Ta dyrektywa unijna dotyczy dostępności stron internetowych i aplikacji dla osób niepełnosprawnych. Jednak dotyczy tylko stron z sektora poublicznego. Opisane w pytaniu mechanizmy normuje Web Content Accessibillity Guidelines.',
+            u'Dokument będący wytycznymi dotyczącymi ułatwień w dostępie do treści publikowanych w internecie normuje zasady tworzenia stron internetowych na potrzeby osób niepełnosprawnych, tak aby treści online były dostępne dla wszystkich. Wśród zasad pojawiających się w WCAG i dokumentach rozszerzających jego zapisy pojawiają się m.in. takie zalecenia: wszystkie pliki dźwiękowe powinny być uzupełnione o transkrypcję dźwiękową czy też wszystkie pliki wideo powinny być uzupełnione o napisy dla osób niesłyszących. To właśnie w WCAG można znaleźć zestaw norm dzięki, którym strony internetowe są przyjazne dla osób niepełnosprawnych.',
+            u'Protokół ten odpowiedzialny jest za przesyłanie dokumentów hipertekstowych w sieci WWW. Nie jest to ani zestaw norm, ani tym bardziej norm określających zasady tworzenia stron internetowych tak aby były przyjazne niepełnosprawnym. Wspomniane zasady znajdują się w dokumencie o nazwie WCAG – Web Content Accessibillity Guidelines.',
+            u'Europejski Akt o Dostępności to kolejny krok do ułatwienia życia osobom niepełnosprawnym. Dzięki tym normom uniijnym sprzęty elektroniczne – komputery, smartfony czy nawet bankomaty ale też chociażby proces zakupów przez internet ma być dostosowany do potrzeb osób niepełnosprawnych. To bardzo ważny dokument jednak nie określa on zasad tworzenia stron internetowych tak aby były one dopasowane do potrzeb osób niepełnosprawnych. Normy te zawarte są w WCAG – Web Content Accessibillity Guidelines.',
+        ),
+        (
+            u'Ustawa o ochronie danych osobowych z dnia 29 sierpnia 1997 roku szczegółowo określa jakie dane zalicza się do danych wrażliwych. Są to informacje dotyczące pochodzenia rasowego lub etnicznego, poglądów politycznych, przekonań religijnych lub filozoficznych, przynależności wyznaniowej, partyjnej lub związkowej, stanu zdrowia, kodu genetycznego, nałogów lub życia seksualnego, skazań, orzeczeń o ukaraniu i mandatów karnych, orzeczeń wydanych w postępowaniu sądowych lub administracyjnym. Co ważne od maja 2018 definicja danych wrażliwych ulegnie zmianie!',
+            u'Ustawa o ochronie danych osobowych z dnia 29 sierpnia 1997 roku szczegółowo określa jakie dane zalicza się do danych wrażliwych. Są to informacje dotyczące pochodzenia rasowego lub etnicznego, poglądów politycznych, przekonań religijnych lub filozoficznych, przynależności wyznaniowej, partyjnej lub związkowej, stanu zdrowia, kodu genetycznego, nałogów lub życia seksualnego, skazań, orzeczeń o ukaraniu i mandatów karnych, orzeczeń wydanych w postępowaniu sądowych lub administracyjnym. Co ważne od maja 2018 definicja danych wrażliwych ulegnie zmianie!',
+            u'Ustawa o ochronie danych osobowych z dnia 29 sierpnia 1997 roku szczegółowo określa jakie dane zalicza się do danych wrażliwych. Są to informacje dotyczące pochodzenia rasowego lub etnicznego, poglądów politycznych, przekonań religijnych lub filozoficznych, przynależności wyznaniowej, partyjnej lub związkowej, stanu zdrowia, kodu genetycznego, nałogów lub życia seksualnego, skazań, orzeczeń o ukaraniu i mandatów karnych, orzeczeń wydanych w postępowaniu sądowych lub administracyjnym. Co ważne od maja 2018 definicja danych wrażliwych ulegnie zmianie!',
+            u'Ustawa o ochronie danych osobowych z dnia 29 sierpnia 1997 roku szczegółowo określa jakie dane zalicza się do danych wrażliwych. Są to informacje dotyczące pochodzenia rasowego lub etnicznego, poglądów politycznych, przekonań religijnych lub filozoficznych, przynależności wyznaniowej, partyjnej lub związkowej, stanu zdrowia, kodu genetycznego, nałogów lub życia seksualnego, skazań, orzeczeń o ukaraniu i mandatów karnych, orzeczeń wydanych w postępowaniu sądowych lub administracyjnym. Co ważne od maja 2018 definicja danych wrażliwych ulegnie zmianie! Jednak numer PESEL nie należy, ani nie będzie należał do kategorii danych wrażliwych.',
+        ),
+        (
+            u'Zgodnie z treścią art. 36 Ustawy o prawie autorskim i prawach pokrewnych majątkowe prawa autorskie wygasają z upływem lat siedemdziesięciu od: od śmierci twórcy, a do utworów współautorskich - od śmierci współtwórcy, który przeżył pozostałych; w odniesieniu do utworu, którego twórca nie jest znany - od daty pierwszego rozpowszechnienia, chyba że pseudonim nie pozostawia wątpliwości co do tożsamości autora lub jeżeli autor ujawnił swoją tożsamość; w odniesieniu do utworu, do którego autorskie prawa majątkowe przysługują z mocy ustawy innej osobie niż twórca - od daty rozpowszechnienia utworu, a gdy utwór nie został rozpowszechniony - od daty jego ustalenia; w odniesieniu do utworu audiowizualnego - od śmierci najpóźniej zmarłej z wymienionych osób: głównego reżysera, autora scenariusza, autora dialogów, kompozytora muzyki skomponowanej do utworu audiowizualnego; w odniesieniu do utworu słowno-muzycznego, jeżeli utwór słowny i utwór muzyczny zostały stworzone specjalnie dla danego utworu słowno-muzycznego - od śmierci później zmarłej z wymienionych osób: autora utworu słownego albo kompozytora utworu muzycznego.',
+            u'Zgodnie z treścią art. 36 Ustawy o prawie autorskim i prawach pokrewnych majątkowe prawa autorskie  wygasają z upływem lat siedemdziesięciu od: od śmierci twórcy, a do utworów współautorskich - od śmierci współtwórcy, który przeżył pozostałych; w odniesieniu do utworu, którego twórca nie jest znany - od daty pierwszego rozpowszechnienia, chyba że pseudonim nie pozostawia wątpliwości co do tożsamości autora lub jeżeli autor ujawnił swoją tożsamość; w odniesieniu do utworu, do którego autorskie prawa majątkowe przysługują z mocy ustawy innej osobie niż twórca - od daty rozpowszechnienia utworu, a gdy utwór nie został rozpowszechniony - od daty jego ustalenia; w odniesieniu do utworu audiowizualnego - od śmierci najpóźniej zmarłej z wymienionych osób: głównego reżysera, autora scenariusza, autora dialogów, kompozytora muzyki skomponowanej do utworu audiowizualnego; w odniesieniu do utworu słowno-muzycznego, jeżeli utwór słowny i utwór muzyczny zostały stworzone specjalnie dla danego utworu słowno-muzycznego - od śmierci później zmarłej z wymienionych osób: autora utworu słownego albo kompozytora utworu muzycznego.',
+            u'Zgodnie z treścią art. 36 Ustawy o prawie autorskim i prawach pokrewnych majątkowe prawa autorskie  wygasają z upływem lat siedemdziesięciu od: od śmierci twórcy, a do utworów współautorskich - od śmierci współtwórcy, który przeżył pozostałych; w odniesieniu do utworu, którego twórca nie jest znany - od daty pierwszego rozpowszechnienia, chyba że pseudonim nie pozostawia wątpliwości co do tożsamości autora lub jeżeli autor ujawnił swoją tożsamość; w odniesieniu do utworu, do którego autorskie prawa majątkowe przysługują z mocy ustawy innej osobie niż twórca - od daty rozpowszechnienia utworu, a gdy utwór nie został rozpowszechniony - od daty jego ustalenia; w odniesieniu do utworu audiowizualnego - od śmierci najpóźniej zmarłej z wymienionych osób: głównego reżysera, autora scenariusza, autora dialogów, kompozytora muzyki skomponowanej do utworu audiowizualnego; w odniesieniu do utworu słowno-muzycznego, jeżeli utwór słowny i utwór muzyczny zostały stworzone specjalnie dla danego utworu słowno-muzycznego - od śmierci później zmarłej z wymienionych osób: autora utworu słownego albo kompozytora utworu muzycznego.',
+            u'Zgodnie z treścią art. 36 Ustawy o prawie autorskim i prawach pokrewnych majątkowe prawa autorskie  wygasają z upływem lat siedemdziesięciu od: od śmierci twórcy, a do utworów współautorskich - od śmierci współtwórcy, który przeżył pozostałych; w odniesieniu do utworu, którego twórca nie jest znany - od daty pierwszego rozpowszechnienia, chyba że pseudonim nie pozostawia wątpliwości co do tożsamości autora lub jeżeli autor ujawnił swoją tożsamość; w odniesieniu do utworu, do którego autorskie prawa majątkowe przysługują z mocy ustawy innej osobie niż twórca - od daty rozpowszechnienia utworu, a gdy utwór nie został rozpowszechniony - od daty jego ustalenia; w odniesieniu do utworu audiowizualnego - od śmierci najpóźniej zmarłej z wymienionych osób: głównego reżysera, autora scenariusza, autora dialogów, kompozytora muzyki skomponowanej do utworu audiowizualnego; w odniesieniu do utworu słowno-muzycznego, jeżeli utwór słowny i utwór muzyczny zostały stworzone specjalnie dla danego utworu słowno-muzycznego - od śmierci później zmarłej z wymienionych osób: autora utworu słownego albo kompozytora utworu muzycznego.',
+        ),
+        (
+            u'Zgodnie z treścią artykułu 16 ustawy o prawie autorskim i prawach pokrewnych katalog autorskich praw to między innymi uprawnienia do autorstwa utworu, oznaczenia go swoim imieniem i nazwiskiem, pod pseudonimem lub anonimowo, nienaruszalności treści utworu, integralności, decyzji o pierwszym udostępnieniu utworu publiczności czy też nadzoru nad sposobem korzystania z utworu.',
+            u'Zgodnie z treścią artykułu 16 ustawy o prawie autorskim i prawach pokrewnych katalog autorskich praw to między innymi uprawnienia do autorstwa utworu, oznaczenia go swoim imieniem i nazwiskiem, pod pseudonimem lub anonimowo, nienaruszalności treści utworu, integralności, decyzji o pierwszym udostępnieniu utworu publiczności czy też nadzoru nad sposobem korzystania z utworu.',
+            u'Zgodnie z treścią artykułu 16 ustawy o prawie autorskim i prawach pokrewnych katalog autorskich praw to między innymi uprawnienia do autorstwa utworu, oznaczenia go swoim imieniem i nazwiskiem, pod pseudonimem lub anonimowo, nienaruszalności treści utworu, integralności, decyzji o pierwszym udostępnieniu utworu publiczności czy też nadzoru nad sposobem korzystania z utworu.',
+            u'Zgodnie z treścią artykułu 16 ustawy o prawie autorskim i prawach pokrewnych katalog autorskich praw to między innymi uprawnienia do autorstwa utworu, oznaczenia go swoim imieniem i nazwiskiem, pod pseudonimem lub anonimowo, nienaruszalności treści utworu, integralności, decyzji o pierwszym udostępnieniu utworu publiczności czy też nadzoru nad sposobem korzystania z utworu. Do katalogu praw nie przynależy jednak prawo do wycofania utworu z obiegu.',
+        ),
+        (
+            u'Regulacje dotyczące zasad wyświetlania reklam w Polsce, zawarte zostały w Ustawie o Radiofonii  i Telewizji. Ustawa określa m.in. to jak powinny być wyświetlane reklamy, jakie reklamy są zakazane, czy też określają jakie zasady wyświetlania reklam obowiązują w telewizji publicznej.',
+            u'Regulacje dotyczące zasad wyświetlania  reklam w Polsce, zawarte zostały w Ustawie o Radiofonii  I Telewizji. Ustawa określa m.in. to jak powinny być wyświetlane reklamy, jakie reklamy są zakazane m.in. te które ukazują ludzi niszczących środowisko w pozytywnym świetle, czy też określają jakie zasady wyświetlania reklam obowiązują w telewizji publicznej. ',
+
+            u'Regulacje dotyczące zasad wyświetlania reklam w Polsce, zawarte zostały w Ustawie o Radiofonii  I Telewizji. Ustawa określa m.in. to jak powinny być wyświetlane reklamy, jakie reklamy są zakazane, czy też określają jakie zasady wyświetlania reklam obowiązują w telewizji publicznej. Działania takie jak reklamowanie produktów w treści filmów, zwane potocznie lokowaniem produktu jest dozwolone prawnie. Jednak program powinien zawierać stosowną adnotację, która informuje widza o tym, że audycja zawierała lokowanie produktu. ',
+
+            u'Regulacje dotyczące zasad wyświetlania reklam w Polsce, zawarte zostały w Ustawie o Radiofonii  I Telewizji. Ustawa określa m.in. to jak powinny być wyświetlane reklamy, jakie reklamy są zakazane, czy też określają jakie zasady wyświetlania reklam obowiązują w telewizji publicznej. Regulacje prawne uniemożliwiają telewizji publicznej np. przerywanie filmów reklamami. ',
+        ),
+        (
+            u'Rzecznik Praw Obywatelskich stoi na straży wolności, praw człowieka i obywatela, niezależnie od tego do jakiego obszaru życia odnoszą się wspomniane prawa i wolności. Zatem również jeśli w mediach cyfrowych łamane są zagwarantowane w Konstytucji i innych aktach prawnych prawa i wolności Rzecznik Praw Obywatelskich powinien zareagować.',
+            u'Minister Cyfryzacji i podlegające mu ministerstwo wprowadzają zmiany, które za zadanie mają pogłębiać rozwój cyfryzacji w Polsce. Choć wprowadzane przez Ministerstwo rozwiązania powinny być zgodne z Konstytucją i powinny chronić praw obywateli to Minister nie jest organem, przed którym można dociekać swoich praw w mediach cyfrowych.',
+            u'Rzecznik stoi na straży praw dziecka. Ponieważ osoby niepełnoletnie są ogromną grupą użytkowników internetu, również w mediach cyfrowych ich gwarantowane w Konstytucji i innych aktach prawnych prawa powinny być respektowane, o co dba Rzecznik Praw Dziecka.',
+            u'UODO bardzo szczegółowo określa zasady związane z ochroną danych osobowych w ramach mediów cyfrowych, dbając w ten sposób o prawa obywateli w określonym zakresie.',
+        ),
+        (
+            u'Mówi się, że internet nie zapomina. A jednak w ramach ochrony danych osobowych, w prawodawstwie funkcjonuje pojęcie takie jak Prawo do zapomnienia. Pozwala ono na zażądanie usunięcia imienia i nazwiska konkretnej osoby z wyszukiwarki internetowej. W maju 2016 roku Europejski Trybunał Praw Człowieka zmusił Google do respektowania tego prawa. Jednak nie każdy z wniosków, które wpływają do Google jest rozpatrywany pozytywnie, ponieważ samo Google kieruje się prawem do informacji i wolności słowa. Przez co prawo do zapomnienia, choć jest rozpatrywane, nie zawsze musi zakończyć się po myśli osoby składającej żądanie.',
+            u'Mówi się, że internet nie zapomina. A jednak w ramach ochrony danych osobowych, w prawodawstwie funkcjonuje pojęcie takie jak Prawo do zapomnienia. Pozwala ono na zażądanie usunięcia imienia i nazwiska konkretnej osoby z wyszukiwarki internetowej. W maju 2016 roku Europejski Trybunał Praw Człowieka zmusił Google do respektowania tego prawa. Jednak nie każdy z wniosków, które wpływają do Google jest rozpatrywany pozytywnie, ponieważ samo Google kieruje się prawem do informacji i wolności słowa. Przez co prawo do zapomnienia, choć jest rozpatrywane, nie zawsze musi zakończyć się po myśli osoby składającej żądanie.',
+            u'Mówi się, że internet nie zapomina. A jednak w ramach ochrony danych osobowych, w prawodawstwie funkcjonuje pojęcie takie jak Prawo do zapomnienia. Pozwala ono na zażądanie usunięcia imienia i nazwiska konkretnej osoby z wyszukiwarki internetowej. W maju 2016 roku Europejski Trybunał Praw Człowieka zmusił Google do respektowania tego prawa. Jednak nie każdy z wniosków, które wpływają do Google jest rozpatrywany pozytywnie, ponieważ samo Google kieruje się prawem do informacji i wolności słowa. Przez co prawo do zapomnienia, choć jest rozpatrywane, nie zawsze musi zakończyć się po myśli osoby składającej żądanie.',
+            u'Mówi się, że internet nie zapomina. A jednak w ramach ochrony danych osobowych, w prawodawstwie funkcjonuje pojęcie takie jak Prawo do zapomnienia. Pozwala ono na zażądanie usunięcia imienia i nazwiska konkretnej osoby z wyszukiwarki internetowej. W maju 2016 roku Europejski Trybunał Praw Człowieka zmusił Google do respektowania tego prawa. Jednak nie każdy z wniosków, które wpływają do Google jest rozpatrywany pozytywnie, ponieważ samo Google kieruje się prawem do informacji i wolności słowa. Przez co prawo do zapomnienia, choć jest rozpatrywane, nie zawsze musi zakończyć się po myśli osoby składającej żądanie.',
+            u'Mówi się, że internet nie zapomina. A jednak w ramach ochrony danych osobowych, w prawodawstwie funkcjonuje pojęcie takie jak Prawo do zapomnienia. Pozwala ono na zażądanie usunięcia imienia i nazwiska konkretnej osoby z wyszukiwarki internetowej. W maju 2016 roku Europejski Trybunał Praw Człowieka zmusił Google do respektowania tego prawa. Jednak nie każdy z wniosków, które wpływają do Google jest rozpatrywany pozytywnie, ponieważ samo Google kieruje się prawem do informacji i wolności słowa. Przez co prawo do zapomnienia, choć jest rozpatrywane nie zawsze musi zakończyć się po myśli osoby składającej żądanie.',
+        ),
+        (
+            u'Zgodnie z treścią artykułu 16 ustawy o prawie autorskim i prawach pokrewnych katalog autorskich praw to między innymi uprawnienia do autorstwa utworu, oznaczenia go swoim imieniem i nazwiskiem, pod pseudonimem lub anonimowo, nienaruszalności treści utworu, integralności, decyzji o pierwszym udostępnieniu utworu publiczności czy też nadzoru nad sposobem korzystania z utworu.',
+            u'Artykuł 29 ustawy o prawie autorskim mówi, że wolno korzystać z utworów na potrzeby parodii, pastiszu lub karykatury, w zakresie uzasadnionym prawami tych gatunków twórczości. Zatem prawo nie chroni autorów przed parodiowaniem ich dzieł.',
+            u'Zgodnie z treścią artykułu 16 ustawy o prawie autorskim i prawach pokrewnych katalog autorskich praw to między innymi uprawnienia do autorstwa utworu, oznaczenia go swoim imieniem i nazwiskiem, pod pseudonimem lub anonimowo, nienaruszalności treści utworu, integralności, decyzji o pierwszym udostępnieniu utworu publiczności czy też nadzoru nad sposobem korzystania z utworu. ',
+            u'Zgodnie z treścią artykułu 16 ustawy o prawie autorskim i prawach pokrewnych katalog autorskich praw to między innymi uprawnienia do autorstwa utworu, oznaczenia go swoim imieniem i nazwiskiem, pod pseudonimem lub anonimowo, nienaruszalności treści utworu, integralności, decyzji o pierwszym udostępnieniu utworu publiczności czy też nadzoru nad sposobem korzystania z utworu. Do katalogu praw nie przynależy jednak prawo do wycofania utworu z obiegu. ',
+            u'Zgodnie z treścią artykułu 16 ustawy o prawie autorskim i prawach pokrewnych katalog autorskich praw to między innymi uprawnienia do autorstwa utworu, oznaczenia go swoim imieniem i nazwiskiem, pod pseudonimem lub anonimowo, nienaruszalności treści utworu, integralności, decyzji o pierwszym udostępnieniu utworu publiczności czy też nadzoru nad sposobem korzystania z utworu. ',
+            u'Autorskie prawa osobiste nie obejmują zakazu kopiowania utworu bez zgody twórcy. Dlatego też ta odpowiedź jest błędna. Zgodnie z treścią artykułu 16 ustawy o prawie autorskim i prawach pokrewnych katalog autorskich praw to między innymi uprawnienia do autorstwa utworu, oznaczenia go swoim imieniem i nazwiskiem, pod pseudonimem lub anonimowo, nienaruszalności treści utworu, integralności, decyzji o pierwszym udostępnieniu utworu publiczności czy też nadzoru nad sposobem korzystania z utworu. ',
+        ),
+        (
+            u'Remiks to stworzenie nowego utworu wykorzystując przy tym już istniejące dzieła. Poprzez zestawienie wybranych elementów, tworzeniu kolaży czy zmienianie uporządkowanych części.  Fragmenty innych utworów wykorzystywać można, a następnie rozpowszechniać pod wieloma warunkami m.in. wówczas gdy posiada się zgodę autora/autorki oryginalnego utworu, zezwala na to licencja, wygasły majątkowe prawa autorskie, czyli minęło 70 lat od śmierci autora, przez co utwory są dostępne w domenie publicznej.',
+            u'Remiks to stworzenie nowego utworu wykorzystując przy tym już istniejące dzieła. Poprzez zestawienie wybranych elementów, tworzeniu kolaży czy zmienianie uporządkowanych części.  Fragmenty innych utworów wykorzystywać można, a następnie rozpowszechniać pod wieloma warunkami m.in. wówczas gdy posiada się zgodę autora/autorki oryginalnego utworu, zezwala na to licencja, wygasły majątkowe prawa autorskie, czyli minęło 70 lat od śmierci autora, przez co utwory są dostępne w domenie publicznej. Ściągnięcie materiałów z serwisu do przechowywania plików nie daje prawa do ich rozpowszechniania. ',
+            u'Remiks to stworzenie nowego utworu wykorzystując przy tym już istniejące dzieła. Poprzez zestawienie wybranych elementów, tworzeniu kolaży czy zmienianie uporządkowanych części.  Fragmenty innych utworów wykorzystywać można, a następnie rozpowszechniać pod wieloma warunkami m.in. wówczas gdy posiada się zgodę autora/autorki oryginalnego utworu, zezwala na to licencja, wygasły majątkowe prawa autorskie, czyli minęło 70 lat od śmierci autora, przez co utwory są dostępne w domenie publicznej. Dostęp do utworu poprzez media społecznościowe nie daje gwarancji, że można z niego korzystać i go rozpowszechniać.',
+            u'Remiks to stworzenie nowego utworu wykorzystując przy tym już istniejące dzieła. Poprzez zestawienie wybranych elementów, tworzeniu kolaży czy zmienianie uporządkowanych części.  Fragmenty innych utworów wykorzystywać można, a następnie rozpowszechniać pod wieloma warunkami m.in. wówczas gdy posiada się zgodę autora/autorki oryginalnego utworu, zezwala na to licencja, wygasły majątkowe prawa autorskie, czyli minęło 70 lat od śmierci autora, przez co utwory są dostępne w domenie publicznej.',
+            u'Remiks to stworzenie nowego utworu wykorzystując przy tym już istniejące dzieła. Poprzez zestawienie wybranych elementów, tworzeniu kolaży czy zmienianie uporządkowanych części.  Fragmenty innych utworów wykorzystywać można, a następnie rozpowszechniać pod wieloma warunkami m.in. wówczas gdy posiada się zgodę autora/autorki oryginalnego utworu, zezwala na to licencja, wygasły majątkowe prawa autorskie, czyli minęło 70 lat od śmierci autora, przez co utwory są dostępne w domenie publicznej.',
+            u'Remiks to stworzenie nowego utworu wykorzystując przy tym już istniejące dzieła. Poprzez zestawienie wybranych elementów, tworzeniu kolaży czy zmienianie uporządkowanych części.  Fragmenty innych utworów wykorzystywać można, a następnie rozpowszechniać pod wieloma warunkami m.in. wówczas gdy posiada się zgodę autora/autorki oryginalnego utworu, zezwala na to licencja, wygasły majątkowe prawa autorskie, czyli minęło 70 lat od śmierci autora, przez co utwory są dostępne w domenie publicznej. Udostępnienie plików MP3, nawet przez twórców nie uprawnia do rozpowszechniania zremiksowanego utworu.',
+        ),
+        (
+            u'Dane osobowe są chronione i istnieją specjalne przepisy normujące to w jakim zakresie można pobierać i przetwarzać dane osobowe. Ze względu na to każdy sklep internetowy musi udostępniać  informacje o tym co robi z danymi swoich użytkowników. Takie informacje znajdują się w ramach tzw. polityki prywatności. ',
+            u'Dane osobowe są chronione i istnieją specjalne przepisy normujące to w jakim zakresie można pobierać i przetwarzać dane osobowe. Ze względu na to każdy sklep internetowy musi udostępniać  informacje o tym co robi z danymi swoich użytkowników. Takie informacje znajdują się w ramach tzw. polityki prywatności. ',
+            u'Dane osobowe są chronione i istnieją specjalne przepisy normujące to w jakim zakresie można pobierać i przetwarzać dane osobowe. Ze względu na to każdy sklep internetowy musi udostępniać  informacje o tym co robi z danymi swoich użytkowników. Takie informacje znajdują się w ramach tzw. polityki prywatności. ',
+            u'Dane osobowe są chronione i istnieją specjalne przepisy normujące to w jakim zakresie można pobierać i przetwarzać dane osobowe. Ze względu na to każdy sklep internetowy musi udostępniać  informacje o tym co robi z danymi swoich użytkowników. Takie informacje znajdują się w ramach tzw. polityki prywatności. Nie każdy sklep musi natomiast posiadać regulamin. Choć jest to pożądane przez klientów i zwiększa wiarygodność e-sklepu.',
+        ),
+        (
+            u'Wiersze z biblioteki Wolne Lektury znajdują się w domenie publicznej albo publikowane są na licencji CC BY-SA 3.0, która umożliwia taką publikację. Wspomniana licencja Creative Commons zezwala na dzielenie się, tj. kopiowanie i rozpowszechnianie utworów na tej licencji w dowolnym medium i formacie oraz adaptacje, czyli remiksy na bazie utworu dla dowolnego celu, także komercyjnego. W domenie publicznej znajdują się zaś utwory, co do których majątkowe prawa autorskie albo wygasły albo nie były nigdy objęte prawem autorskim. Z tego też względu bez problemu można publikować niekomercyjnie remiks wspomnianych w pytaniu wierszy.',
+            u'Wiersze z biblioteki Wolne Lektury znajdują się w domenie publicznej albo publikowane są na licencji CC BY-SA 3.0, która umożliwia taką publikację. Wspomniana licencja Creative Commons zezwala na dzielenie się, tj. kopiowanie i rozpowszechnianie utworów na tej licencji w dowolnym medium i formacie oraz adaptacje, czyli remiksy na bazie utworu dla dowolnego celu, także komercyjnego. W domenie publicznej znajdują się zaś utwory, co do których majątkowe prawa autorskie albo wygasły albo nie były nigdy objęte prawem autorskim. Z tego też względu bez problemu można publikować niekomercyjnie remiks wspomnianych w pytaniu wierszy. ',
+            u'Wiersze z biblioteki Wolne Lektury znajdują się w domenie publicznej albo publikowane są na licencji CC BY-SA 3.0, która umożliwia taką publikację. Wspomniana licencja Creative Commons zezwala na dzielenie się, tj. kopiowanie i rozpowszechnianie utworów na tej licencji w dowolnym medium i formacie oraz adaptacje, czyli remiksy na bazie utworu dla dowolnego celu, także komercyjnego. W domenie publicznej znajdują się zaś utwory, co do których majątkowe prawa autorskie albo wygasły albo nie były nigdy objęte prawem autorskim. Z tego też względu bez problemu można publikować niekomercyjnie remiks wspomnianych w pytaniu wierszy. Nie jest do tego potrzebne wnoszenie żadnych dodatkowych opłat.',
+            u'Wiersze z biblioteki Wolne Lektury znajdują się w domenie publicznej albo publikowane są na licencji CC BY-SA 3.0, która umożliwia taką publikację. Wspomniana licencja Creative Commons zezwala na dzielenie się, tj. kopiowanie i rozpowszechnianie utworów na tej licencji w dowolnym medium i formacie oraz adaptacje, czyli remiksy na bazie utworu dla dowolnego celu, także komercyjnego. W domenie publicznej znajdują się zaś utwory, co do których majątkowe prawa autorskie albo wygasły albo nie były nigdy objęte prawem autorskim. Z tego też względu bez problemu można publikować niekomercyjnie remiks wspomnianych w pytaniu wierszy.',
+        ),
+        (
+            u'Dozwolony użytek to określenie w polskim prawie autorskim na ustawowe ograniczenie treści wyłącznych praw autorskich, które to określa ustawa o prawie autorskim i prawach pokrewnych. Prawo rozgranicza dozwolony użytek na ten realizowany w zakresie prywatnym oraz publicznym. W ramach dozwolonego użytku prywatnego w większości przypadków nie można wnosić roszczeń finansowych związanych z majątkowym prawem autorskim. Użytkownik może bez zgody twórcy nieodpłatnie korzystać z już rozpowszechnionego utworu, a także udostępniać go nieodpłatnie określonej grupie osób. Zatem sprzedaż kopii płyt z muzyką jest według prawa związanego z dozwolonym użytkiem zabronione. ',
+            u'Dozwolony użytek to określenie w polskim prawie autorskim na ustawowe ograniczenie treści wyłącznych praw autorskich, które to określa ustawa o prawie autorskim i prawach pokrewnych. Prawo rozgranicza dozwolony użytek na ten realizowany w zakresie prywatnym oraz publicznym. W ramach dozwolonego użytku prywatnego w większości przypadków nie można wnosić roszczeń finansowych związanych z majątkowym prawem autorskim. Użytkownik może bez zgody twórcy nieodpłatnie korzystać z już rozpowszechnionego utworu, a także udostępniać go nieodpłatnie określonej grupie osób. Nawet w sytuacji gdy film został pobrany z nielegalnego internetowego źródła, oglądanie go nie jest zabronione właśnie ze względu na dozwolony użytek prywatny.',
+            u'Dozwolony użytek to określenie w polskim prawie autorskim na ustawowe ograniczenie treści wyłącznych praw autorskich, które to określa ustawa o prawie autorskim i prawach pokrewnych. Prawo rozgranicza dozwolony użytek na ten realizowany w zakresie prywatnym oraz publicznym. W ramach dozwolonego użytku prywatnego w większości przypadków nie można wnosić roszczeń finansowych związanych z majątkowym prawem autorskim. Użytkownik może bez zgody twórcy nieodpłatnie korzystać z już rozpowszechnionego utworu, a także udostępniać go nieodpłatnie określonej grupie osób – w tym także rodzinie.',
+            u'Dozwolony użytek to określenie w polskim prawie autorskim na ustawowe ograniczenie treści wyłącznych praw autorskich, które to określa ustawa o prawie autorskim i prawach pokrewnych. Prawo rozgranicza dozwolony użytek na ten realizowany w zakresie prywatnym oraz publicznym. W ramach dozwolonego użytku prywatnego w większości przypadków nie można wnosić roszczeń finansowych związanych z majątkowym prawem autorskim. Użytkownik może bez zgody twórcy nieodpłatnie korzystać z już rozpowszechnionego utworu, a także udostępniać go nieodpłatnie określonej grupie osób.',
+        )
+    ]
diff --git a/src/edumed/context_processors.py b/src/edumed/context_processors.py
new file mode 100644 (file)
index 0000000..ed57c24
--- /dev/null
@@ -0,0 +1,4 @@
+# -*- coding: utf-8 -*-
+def base_template(request):
+    base_template = 'base_mil.html' if request.META.get('HTTP_HOST').startswith('katalog') else 'base.html'
+    return dict(base_template = base_template)
diff --git a/src/edumed/forms.py b/src/edumed/forms.py
new file mode 100644 (file)
index 0000000..650197b
--- /dev/null
@@ -0,0 +1,17 @@
+# -*- coding: utf-8 -*-
+from django import forms
+from django.utils.translation import ugettext_lazy as _
+from pybb.forms import EditProfileForm
+from pybb import util
+
+
+class AvatarlessEditProfileForm(EditProfileForm):
+    signature = forms.CharField(
+        widget=forms.Textarea(attrs={'rows': 2, 'cols:': 60}),
+        required=False,
+        label=_('Signature')
+    )
+
+    class Meta:
+        model = util.get_pybb_profile_model()
+        fields = ['signature', 'time_zone', 'language', 'show_signatures']
diff --git a/src/edumed/forum.py b/src/edumed/forum.py
new file mode 100644 (file)
index 0000000..86cfb0c
--- /dev/null
@@ -0,0 +1,25 @@
+# -*- coding: utf-8 -*-
+from pybb.permissions import DefaultPermissionHandler
+
+
+class ForumPermissionHandler(DefaultPermissionHandler):
+    def may_post_as_admin(self, user):
+        """ return True if `user` may post as admin """
+        return False
+
+    def may_create_topic(self, user, forum):
+        """ return True if `user` is allowed to create a new topic in `forum` """
+        return user.is_authenticated()
+
+    def may_create_post(self, user, topic):
+        """ return True if `user` is allowed to create a new post in `topic` """
+
+        if topic.forum.hidden and (not user.is_staff):
+            # if topic is hidden, only staff may post
+            return False
+
+        if topic.closed and (not user.is_staff):
+            # if topic is closed, only staff may post
+            return False
+
+        return user.is_authenticated()
diff --git a/src/edumed/locale-contrib/django.pot b/src/edumed/locale-contrib/django.pot
new file mode 100644 (file)
index 0000000..c231cd9
--- /dev/null
@@ -0,0 +1,715 @@
+# Translations template for PROJECT.
+# Copyright (C) 2013 ORGANIZATION
+# This file is distributed under the same license as the PROJECT project.
+# FIRST AUTHOR <EMAIL@ADDRESS>, 2013.
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: PROJECT VERSION\n"
+"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
+"POT-Creation-Date: 2013-08-09 11:40+0200\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
+"Language-Team: LANGUAGE <LL@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=utf-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Generated-By: Babel 1.3\n"
+
+#: pybb/admin.py:40
+#: pybb/admin.py:66
+#: pybb/admin.py:94
+#: pybb/admin.py:116
+msgid "Additional options"
+msgstr ""
+
+#: pybb/admin.py:99
+#: pybb/models.py:254
+msgid "Message"
+msgstr ""
+
+#: pybb/admin.py:130
+msgid "View post"
+msgstr ""
+
+#: pybb/admin.py:135
+msgid "Edit post"
+msgstr ""
+
+#: pybb/feeds.py:25
+#: pybb/feeds.py:26
+#: pybb/templates/pybb/base.html:12
+msgid "Latest posts on forum"
+msgstr ""
+
+#: pybb/feeds.py:35
+#: pybb/feeds.py:36
+#: pybb/templates/pybb/base.html:13
+msgid "Latest topics on forum"
+msgstr ""
+
+#: pybb/forms.py:27
+msgid "Attachment is too big"
+msgstr ""
+
+#: pybb/forms.py:47
+#, python-format
+msgid "You cant add more than %s answers for poll"
+msgstr ""
+
+#: pybb/forms.py:49
+msgid "Add two or more answers for this poll"
+msgstr ""
+
+#: pybb/forms.py:109
+msgid "Polls question is required when adding a poll"
+msgstr ""
+
+#: pybb/forms.py:192
+#, python-format
+msgid "Avatar is too large, max size: %s bytes"
+msgstr ""
+
+#: pybb/models.py:68
+#: pybb/models.py:99
+msgid "Name"
+msgstr ""
+
+#: pybb/models.py:69
+#: pybb/models.py:100
+msgid "Position"
+msgstr ""
+
+#: pybb/models.py:70
+#: pybb/models.py:106
+#: pybb/templates/pybb/category.html:5
+#: pybb/templates/pybb/category.html:28
+msgid "Hidden"
+msgstr ""
+
+#: pybb/models.py:71
+msgid "If checked, this category will be visible only for staff"
+msgstr ""
+
+#: pybb/models.py:76
+#: pybb/models.py:98
+msgid "Category"
+msgstr ""
+
+#: pybb/models.py:77
+msgid "Categories"
+msgstr ""
+
+#: pybb/models.py:101
+msgid "Description"
+msgstr ""
+
+#: pybb/models.py:102
+msgid "Moderators"
+msgstr ""
+
+#: pybb/models.py:103
+#: pybb/models.py:165
+#: pybb/models.py:270
+msgid "Updated"
+msgstr ""
+
+#: pybb/models.py:104
+#: pybb/models.py:172
+#: pybb/models.py:357
+msgid "Post count"
+msgstr ""
+
+#: pybb/models.py:105
+msgid "Topic count"
+msgstr ""
+
+#: pybb/models.py:108
+msgid "Headline"
+msgstr ""
+
+#: pybb/models.py:112
+#: pybb/models.py:162
+#: pybb/templates/pybb/category.html:10
+msgid "Forum"
+msgstr ""
+
+#: pybb/models.py:113
+msgid "Forums"
+msgstr ""
+
+#: pybb/models.py:157
+msgid "None"
+msgstr ""
+
+#: pybb/models.py:158
+msgid "Single answer"
+msgstr ""
+
+#: pybb/models.py:159
+msgid "Multiple answers"
+msgstr ""
+
+#: pybb/models.py:163
+msgid "Subject"
+msgstr ""
+
+#: pybb/models.py:164
+#: pybb/models.py:269
+msgid "Created"
+msgstr ""
+
+#: pybb/models.py:166
+#: pybb/models.py:268
+#: pybb/models.py:381
+#: pybb/models.py:512
+#: pybb/templates/pybb/mail_templates/subscription_email_body.html:3
+msgid "User"
+msgstr ""
+
+#: pybb/models.py:167
+msgid "Views count"
+msgstr ""
+
+#: pybb/models.py:168
+#: pybb/templates/pybb/topic_list.html:27
+msgid "Sticky"
+msgstr ""
+
+#: pybb/models.py:169
+#: pybb/templates/pybb/topic_list.html:28
+msgid "Closed"
+msgstr ""
+
+#: pybb/models.py:170
+#: pybb/templates/pybb/topic.html:92
+msgid "Subscribers"
+msgstr ""
+
+#: pybb/models.py:174
+#: pybb/models.py:272
+msgid "On moderation"
+msgstr ""
+
+#: pybb/models.py:175
+msgid "Poll type"
+msgstr ""
+
+#: pybb/models.py:176
+msgid "Poll question"
+msgstr ""
+
+#: pybb/models.py:180
+#: pybb/models.py:267
+#: pybb/models.py:489
+#: pybb/templates/pybb/topic_list.html:7
+msgid "Topic"
+msgstr ""
+
+#: pybb/models.py:181
+#: pybb/templates/pybb/category.html:13
+msgid "Topics"
+msgstr ""
+
+#: pybb/models.py:255
+msgid "HTML version"
+msgstr ""
+
+#: pybb/models.py:256
+msgid "Text version"
+msgstr ""
+
+#: pybb/models.py:271
+msgid "User IP"
+msgstr ""
+
+#: pybb/models.py:276
+#: pybb/models.py:397
+msgid "Post"
+msgstr ""
+
+#: pybb/models.py:277
+#: pybb/templates/pybb/category.html:16
+#: pybb/templates/pybb/topic_list.html:10
+msgid "Posts"
+msgstr ""
+
+#: pybb/models.py:346
+msgid "Signature"
+msgstr ""
+
+#: pybb/models.py:348
+msgid "Signature HTML Version"
+msgstr ""
+
+#: pybb/models.py:350
+msgid "Time zone"
+msgstr ""
+
+#: pybb/models.py:352
+msgid "Language"
+msgstr ""
+
+#: pybb/models.py:355
+msgid "Show signatures"
+msgstr ""
+
+#: pybb/models.py:358
+msgid "Avatar"
+msgstr ""
+
+#: pybb/models.py:360
+msgid "Automatically subscribe"
+msgstr ""
+
+#: pybb/models.py:361
+msgid "Automatically subscribe to topics that you answer"
+msgstr ""
+
+#: pybb/models.py:384
+msgid "Profile"
+msgstr ""
+
+#: pybb/models.py:385
+msgid "Profiles"
+msgstr ""
+
+#: pybb/models.py:394
+#: pybb/templates/pybb/post_template.html:73
+msgid "Attachment"
+msgstr ""
+
+#: pybb/models.py:395
+msgid "Attachments"
+msgstr ""
+
+#: pybb/models.py:398
+msgid "Size"
+msgstr ""
+
+#: pybb/models.py:399
+msgid "File"
+msgstr ""
+
+#: pybb/models.py:447
+msgid "Topic read tracker"
+msgstr ""
+
+#: pybb/models.py:448
+msgid "Topic read trackers"
+msgstr ""
+
+#: pybb/models.py:483
+msgid "Forum read tracker"
+msgstr ""
+
+#: pybb/models.py:484
+msgid "Forum read trackers"
+msgstr ""
+
+#: pybb/models.py:490
+msgid "Text"
+msgstr ""
+
+#: pybb/models.py:493
+#: pybb/models.py:511
+msgid "Poll answer"
+msgstr ""
+
+#: pybb/models.py:494
+msgid "Polls answers"
+msgstr ""
+
+#: pybb/models.py:516
+msgid "Poll answer user"
+msgstr ""
+
+#: pybb/models.py:517
+msgid "Polls answers users"
+msgstr ""
+
+#: pybb/util.py:58
+msgid "Can't get profile for anonymous user"
+msgstr ""
+
+#: pybb/views.py:648
+msgid "All forums marked as read"
+msgstr ""
+
+#: pybb/views.py:668
+msgid "User successfuly blocked"
+msgstr ""
+
+#: pybb/templates/pybb/_button_new_topic.html:2
+#: pybb/templates/pybb/add_post.html:24
+msgid "New topic"
+msgstr ""
+
+#: pybb/templates/pybb/_button_save.html:1
+msgid "Save"
+msgstr ""
+
+#: pybb/templates/pybb/_button_submit.html:1
+msgid "Submit"
+msgstr ""
+
+#: pybb/templates/pybb/_markitup.html:15
+msgid "Bold"
+msgstr ""
+
+#: pybb/templates/pybb/_markitup.html:16
+msgid "Italic"
+msgstr ""
+
+#: pybb/templates/pybb/_markitup.html:17
+msgid "Underline"
+msgstr ""
+
+#: pybb/templates/pybb/_markitup.html:18
+msgid "Stroke"
+msgstr ""
+
+#: pybb/templates/pybb/_markitup.html:20
+msgid "Picture"
+msgstr ""
+
+#: pybb/templates/pybb/_markitup.html:21
+msgid "Link"
+msgstr ""
+
+#: pybb/templates/pybb/_markitup.html:23
+msgid "Bulleted list"
+msgstr ""
+
+#: pybb/templates/pybb/_markitup.html:24
+msgid "Numeric list"
+msgstr ""
+
+#: pybb/templates/pybb/_markitup.html:25
+msgid "List item"
+msgstr ""
+
+#: pybb/templates/pybb/_markitup.html:27
+msgid "Quotes"
+msgstr ""
+
+#: pybb/templates/pybb/_markitup.html:28
+msgid "Code"
+msgstr ""
+
+#: pybb/templates/pybb/_markitup.html:30
+msgid "Clean"
+msgstr ""
+
+#: pybb/templates/pybb/_markitup.html:31
+msgid "Preview"
+msgstr ""
+
+#: pybb/templates/pybb/_need_to_login_message.html:3
+msgid "Register"
+msgstr ""
+
+#: pybb/templates/pybb/_need_to_login_message.html:3
+msgid "or"
+msgstr ""
+
+#: pybb/templates/pybb/_need_to_login_message.html:3
+msgid "login"
+msgstr ""
+
+#: pybb/templates/pybb/_need_to_login_message.html:3
+msgid "to create to post a reply"
+msgstr ""
+
+#: pybb/templates/pybb/add_post.html:24
+msgid "New reply"
+msgstr ""
+
+#: pybb/templates/pybb/attachments_formset.html:4
+msgid "Add attachments"
+msgstr ""
+
+#: pybb/templates/pybb/attachments_formset.html:10
+#: pybb/templates/pybb/edit_profile.html:27
+msgid "delete"
+msgstr ""
+
+#: pybb/templates/pybb/breadcrumb.html:5
+msgid "Home"
+msgstr ""
+
+#: pybb/templates/pybb/category.html:19
+msgid "Last posts"
+msgstr ""
+
+#: pybb/templates/pybb/category.html:44
+msgid "No forums created"
+msgstr ""
+
+#: pybb/templates/pybb/category.html:45
+msgid "Add forum now"
+msgstr ""
+
+#: pybb/templates/pybb/delete_post.html:5
+msgid "Are you sure you want to delete this message?"
+msgstr ""
+
+#: pybb/templates/pybb/delete_post.html:12
+msgid "No, take me back"
+msgstr ""
+
+#: pybb/templates/pybb/delete_post.html:13
+msgid "Yes, I am sure"
+msgstr ""
+
+#: pybb/templates/pybb/edit_post.html:4
+#: pybb/templates/pybb/edit_post.html:13
+msgid "Editing the post"
+msgstr ""
+
+#: pybb/templates/pybb/edit_profile.html:7
+#: pybb/templates/pybb/edit_profile.html:10
+#: pybb/templates/pybb/edit_profile.html:15
+msgid "Profile editing"
+msgstr ""
+
+#: pybb/templates/pybb/edit_profile.html:20
+msgid "Subscriptions on topics"
+msgstr ""
+
+#: pybb/templates/pybb/index.html:19
+msgid "Forum categories are not created"
+msgstr ""
+
+#: pybb/templates/pybb/index.html:20
+msgid "Add a category now"
+msgstr ""
+
+#: pybb/templates/pybb/index.html:25
+#: pybb/templates/pybb/latest_topics.html:7
+#: pybb/templates/pybb/latest_topics.html:17
+msgid "Last updates in topics"
+msgstr ""
+
+#: pybb/templates/pybb/index.html:28
+msgid "Mark all forums as read"
+msgstr ""
+
+#: pybb/templates/pybb/latest_topics.html:10
+msgid "\"Last updates in topics\""
+msgstr ""
+
+#: pybb/templates/pybb/latest_topics.html:33
+msgid "Mark all topics as read"
+msgstr ""
+
+#: pybb/templates/pybb/pagination.html:7
+msgid "previous page"
+msgstr ""
+
+#: pybb/templates/pybb/pagination.html:21
+msgid "next page"
+msgstr ""
+
+#: pybb/templates/pybb/poll.html:5
+msgid "Poll"
+msgstr ""
+
+#: pybb/templates/pybb/poll.html:37
+msgid "'Cancel my poll vote'"
+msgstr ""
+
+#: pybb/templates/pybb/poll_edit_form.html:7
+msgid "Poll answers"
+msgstr ""
+
+#: pybb/templates/pybb/poll_edit_form.html:20
+msgid "remove answer"
+msgstr ""
+
+#: pybb/templates/pybb/poll_edit_form.html:21
+msgid "add answer"
+msgstr ""
+
+#: pybb/templates/pybb/post_template.html:25
+msgid "Rank"
+msgstr ""
+
+#: pybb/templates/pybb/post_template.html:38
+#: pybb/templates/pybb/user.html:41
+msgid "Edit"
+msgstr ""
+
+#: pybb/templates/pybb/post_template.html:42
+msgid "Delete post?"
+msgstr ""
+
+#: pybb/templates/pybb/post_template.html:43
+msgid "Delete"
+msgstr ""
+
+#: pybb/templates/pybb/post_template.html:45
+msgid "Approve post"
+msgstr ""
+
+#: pybb/templates/pybb/post_template.html:50
+#: pybb/templates/pybb/topic.html:63
+msgid "Admin"
+msgstr ""
+
+#: pybb/templates/pybb/post_template.html:66
+msgid "Edited"
+msgstr ""
+
+#: pybb/templates/pybb/post_template.html:78
+msgid "quote"
+msgstr ""
+
+#: pybb/templates/pybb/topic.html:24
+#: pybb/templates/pybb/topic.html:44
+#: pybb/templates/pybb/user_posts.html:8
+msgid "'Posts'"
+msgstr ""
+
+#: pybb/templates/pybb/topic.html:52
+msgid "Unstick topic"
+msgstr ""
+
+#: pybb/templates/pybb/topic.html:54
+msgid "Stick topic"
+msgstr ""
+
+#: pybb/templates/pybb/topic.html:58
+msgid "Open topic"
+msgstr ""
+
+#: pybb/templates/pybb/topic.html:60
+msgid "Close topic"
+msgstr ""
+
+#: pybb/templates/pybb/topic.html:66
+msgid "Merge topics"
+msgstr ""
+
+#: pybb/templates/pybb/topic.html:71
+msgid "Unsubscribe"
+msgstr ""
+
+#: pybb/templates/pybb/topic.html:73
+msgid "Subscribe"
+msgstr ""
+
+#: pybb/templates/pybb/topic_list.html:13
+msgid "Views"
+msgstr ""
+
+#: pybb/templates/pybb/topic_list.html:16
+msgid "Last post"
+msgstr ""
+
+#: pybb/templates/pybb/topic_list.html:26
+msgid "Go to first unread post"
+msgstr ""
+
+#: pybb/templates/pybb/topic_list.html:32
+msgid "pages"
+msgstr ""
+
+#: pybb/templates/pybb/user.html:15
+msgid "Statistics"
+msgstr ""
+
+#: pybb/templates/pybb/user.html:18
+msgid "Number of topics"
+msgstr ""
+
+#: pybb/templates/pybb/user.html:24
+msgid "Number of posts"
+msgstr ""
+
+#: pybb/templates/pybb/user.html:28
+msgid "Date of registration"
+msgstr ""
+
+#: pybb/templates/pybb/user.html:35
+msgid "Block"
+msgstr ""
+
+#: pybb/templates/pybb/user.html:36
+msgid "Block and delete all messages"
+msgstr ""
+
+#: pybb/templates/pybb/user_posts.html:13
+msgid "All posts created by"
+msgstr ""
+
+#: pybb/templates/pybb/user_topics.html:8
+msgid "'Topics'"
+msgstr ""
+
+#: pybb/templates/pybb/user_topics.html:11
+#: pybb/templates/pybb/user_topics.html:15
+msgid "All topics created by"
+msgstr ""
+
+#: pybb/templates/pybb/users.html:8
+msgid "Users"
+msgstr ""
+
+#: pybb/templates/pybb/users.html:12
+msgid "Search"
+msgstr ""
+
+#: pybb/templates/pybb/users.html:24
+msgid "'Users'"
+msgstr ""
+
+#: pybb/templates/pybb/mail_templates/subscription_email_body.html:3
+msgid "replied in topic to which you are subscribed."
+msgstr ""
+
+#: pybb/templates/pybb/mail_templates/subscription_email_body.html:4
+msgid "Link to post:"
+msgstr ""
+
+#: pybb/templates/pybb/mail_templates/subscription_email_body.html:5
+msgid "Link to topic:"
+msgstr ""
+
+#: pybb/templates/pybb/mail_templates/subscription_email_body.html:8
+msgid ""
+"If you don't want to recive notifications on new messages in this topic "
+"visit following link:"
+msgstr ""
+
+#: pybb/templates/pybb/mail_templates/subscription_email_subject.html:2
+msgid "New answer in topic that you subscribed."
+msgstr ""
+
+#: pybb/templatetags/pybb_tags.py:61
+msgid "seconds ago,seconds ago,seconds ago"
+msgstr ""
+
+#: pybb/templatetags/pybb_tags.py:64
+msgid "seconds ago"
+msgstr ""
+
+#: pybb/templatetags/pybb_tags.py:70
+msgid "minutes ago,minutes ago,minutes ago"
+msgstr ""
+
+#: pybb/templatetags/pybb_tags.py:73
+msgid "minutes ago"
+msgstr ""
+
+#: pybb/templatetags/pybb_tags.py:83
+#, python-format
+msgid "today, %s"
+msgstr ""
+
+#: pybb/templatetags/pybb_tags.py:85
+#, python-format
+msgid "yesterday, %s"
+msgstr ""
+
diff --git a/src/edumed/locale-contrib/pl/LC_MESSAGES/django.mo b/src/edumed/locale-contrib/pl/LC_MESSAGES/django.mo
new file mode 100644 (file)
index 0000000..dce9c5a
Binary files /dev/null and b/src/edumed/locale-contrib/pl/LC_MESSAGES/django.mo differ
diff --git a/src/edumed/locale-contrib/pl/LC_MESSAGES/django.po b/src/edumed/locale-contrib/pl/LC_MESSAGES/django.po
new file mode 100644 (file)
index 0000000..f2768dd
--- /dev/null
@@ -0,0 +1,677 @@
+# Polish translations for PROJECT.
+# Copyright (C) 2013 ORGANIZATION
+# This file is distributed under the same license as the PROJECT project.
+# FIRST AUTHOR <EMAIL@ADDRESS>, 2013.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: PROJECT VERSION\n"
+"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
+"POT-Creation-Date: 2013-08-09 11:40+0200\n"
+"PO-Revision-Date: 2013-08-09 12:17+0100\n"
+"Last-Translator: Radek Czajka <radoslaw.czajka@nowoczesnapolska.org.pl>\n"
+"Language-Team: pl <LL@li.org>\n"
+"Plural-Forms: nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 "
+"|| n%100>=20) ? 1 : 2);\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=utf-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Generated-By: Babel 1.3\n"
+"X-Generator: Poedit 1.5.4\n"
+
+#: pybb/admin.py:40 pybb/admin.py:66 pybb/admin.py:94 pybb/admin.py:116
+msgid "Additional options"
+msgstr ""
+
+#: pybb/admin.py:99 pybb/models.py:254
+msgid "Message"
+msgstr ""
+
+#: pybb/admin.py:130
+msgid "View post"
+msgstr ""
+
+#: pybb/admin.py:135
+msgid "Edit post"
+msgstr ""
+
+#: pybb/feeds.py:25 pybb/feeds.py:26 pybb/templates/pybb/base.html:12
+msgid "Latest posts on forum"
+msgstr ""
+
+#: pybb/feeds.py:35 pybb/feeds.py:36 pybb/templates/pybb/base.html:13
+msgid "Latest topics on forum"
+msgstr ""
+
+#: pybb/forms.py:27
+msgid "Attachment is too big"
+msgstr ""
+
+#: pybb/forms.py:47
+#, python-format
+msgid "You cant add more than %s answers for poll"
+msgstr ""
+
+#: pybb/forms.py:49
+msgid "Add two or more answers for this poll"
+msgstr ""
+
+#: pybb/forms.py:109
+msgid "Polls question is required when adding a poll"
+msgstr ""
+
+#: pybb/forms.py:192
+#, python-format
+msgid "Avatar is too large, max size: %s bytes"
+msgstr ""
+
+#: pybb/models.py:68 pybb/models.py:99
+msgid "Name"
+msgstr ""
+
+#: pybb/models.py:69 pybb/models.py:100
+msgid "Position"
+msgstr ""
+
+#: pybb/models.py:70 pybb/models.py:106 pybb/templates/pybb/category.html:5
+#: pybb/templates/pybb/category.html:28
+msgid "Hidden"
+msgstr ""
+
+#: pybb/models.py:71
+msgid "If checked, this category will be visible only for staff"
+msgstr ""
+
+#: pybb/models.py:76 pybb/models.py:98
+msgid "Category"
+msgstr ""
+
+#: pybb/models.py:77
+msgid "Categories"
+msgstr ""
+
+#: pybb/models.py:101
+msgid "Description"
+msgstr ""
+
+#: pybb/models.py:102
+msgid "Moderators"
+msgstr ""
+
+#: pybb/models.py:103 pybb/models.py:165 pybb/models.py:270
+msgid "Updated"
+msgstr ""
+
+#: pybb/models.py:104 pybb/models.py:172 pybb/models.py:357
+msgid "Post count"
+msgstr ""
+
+#: pybb/models.py:105
+msgid "Topic count"
+msgstr ""
+
+#: pybb/models.py:108
+msgid "Headline"
+msgstr ""
+
+#: pybb/models.py:112 pybb/models.py:162 pybb/templates/pybb/category.html:10
+msgid "Forum"
+msgstr ""
+
+#: pybb/models.py:113
+msgid "Forums"
+msgstr ""
+
+#: pybb/models.py:157
+msgid "None"
+msgstr ""
+
+#: pybb/models.py:158
+msgid "Single answer"
+msgstr ""
+
+#: pybb/models.py:159
+msgid "Multiple answers"
+msgstr ""
+
+#: pybb/models.py:163
+msgid "Subject"
+msgstr ""
+
+#: pybb/models.py:164 pybb/models.py:269
+msgid "Created"
+msgstr ""
+
+#: pybb/models.py:166 pybb/models.py:268 pybb/models.py:381 pybb/models.py:512
+#: pybb/templates/pybb/mail_templates/subscription_email_body.html:3
+msgid "User"
+msgstr ""
+
+#: pybb/models.py:167
+msgid "Views count"
+msgstr ""
+
+#: pybb/models.py:168 pybb/templates/pybb/topic_list.html:27
+msgid "Sticky"
+msgstr ""
+
+#: pybb/models.py:169 pybb/templates/pybb/topic_list.html:28
+msgid "Closed"
+msgstr ""
+
+#: pybb/models.py:170 pybb/templates/pybb/topic.html:92
+msgid "Subscribers"
+msgstr ""
+
+#: pybb/models.py:174 pybb/models.py:272
+msgid "On moderation"
+msgstr ""
+
+#: pybb/models.py:175
+msgid "Poll type"
+msgstr ""
+
+#: pybb/models.py:176
+msgid "Poll question"
+msgstr ""
+
+#: pybb/models.py:180 pybb/models.py:267 pybb/models.py:489
+#: pybb/templates/pybb/topic_list.html:7
+msgid "Topic"
+msgstr ""
+
+#: pybb/models.py:181 pybb/templates/pybb/category.html:13
+msgid "Topics"
+msgstr ""
+
+#: pybb/models.py:255
+msgid "HTML version"
+msgstr ""
+
+#: pybb/models.py:256
+msgid "Text version"
+msgstr ""
+
+#: pybb/models.py:271
+msgid "User IP"
+msgstr ""
+
+#: pybb/models.py:276 pybb/models.py:397
+msgid "Post"
+msgstr ""
+
+#: pybb/models.py:277 pybb/templates/pybb/category.html:16
+#: pybb/templates/pybb/topic_list.html:10
+msgid "Posts"
+msgstr ""
+
+#: pybb/models.py:346
+msgid "Signature"
+msgstr "Podpis"
+
+#: pybb/models.py:348
+msgid "Signature HTML Version"
+msgstr ""
+
+#: pybb/models.py:350
+msgid "Time zone"
+msgstr ""
+
+#: pybb/models.py:352
+msgid "Language"
+msgstr ""
+
+#: pybb/models.py:355
+msgid "Show signatures"
+msgstr ""
+
+#: pybb/models.py:358
+msgid "Avatar"
+msgstr ""
+
+#: pybb/models.py:360
+msgid "Automatically subscribe"
+msgstr ""
+
+#: pybb/models.py:361
+msgid "Automatically subscribe to topics that you answer"
+msgstr ""
+
+#: pybb/models.py:384
+msgid "Profile"
+msgstr ""
+
+#: pybb/models.py:385
+msgid "Profiles"
+msgstr ""
+
+#: pybb/models.py:394 pybb/templates/pybb/post_template.html:73
+msgid "Attachment"
+msgstr ""
+
+#: pybb/models.py:395
+msgid "Attachments"
+msgstr ""
+
+#: pybb/models.py:398
+msgid "Size"
+msgstr ""
+
+#: pybb/models.py:399
+msgid "File"
+msgstr ""
+
+#: pybb/models.py:447
+msgid "Topic read tracker"
+msgstr ""
+
+#: pybb/models.py:448
+msgid "Topic read trackers"
+msgstr ""
+
+#: pybb/models.py:483
+msgid "Forum read tracker"
+msgstr ""
+
+#: pybb/models.py:484
+msgid "Forum read trackers"
+msgstr ""
+
+#: pybb/models.py:490
+msgid "Text"
+msgstr ""
+
+#: pybb/models.py:493 pybb/models.py:511
+msgid "Poll answer"
+msgstr ""
+
+#: pybb/models.py:494
+msgid "Polls answers"
+msgstr ""
+
+#: pybb/models.py:516
+msgid "Poll answer user"
+msgstr ""
+
+#: pybb/models.py:517
+msgid "Polls answers users"
+msgstr ""
+
+#: pybb/util.py:58
+msgid "Can't get profile for anonymous user"
+msgstr ""
+
+#: pybb/views.py:648
+msgid "All forums marked as read"
+msgstr ""
+
+#: pybb/views.py:668
+msgid "User successfuly blocked"
+msgstr ""
+
+#: pybb/templates/pybb/_button_new_topic.html:2
+#: pybb/templates/pybb/add_post.html:24
+msgid "New topic"
+msgstr ""
+
+#: pybb/templates/pybb/_button_save.html:1
+msgid "Save"
+msgstr ""
+
+#: pybb/templates/pybb/_button_submit.html:1
+msgid "Submit"
+msgstr ""
+
+#: pybb/templates/pybb/_markitup.html:15
+msgid "Bold"
+msgstr "Pogrubienie"
+
+#: pybb/templates/pybb/_markitup.html:16
+msgid "Italic"
+msgstr "Kursywa"
+
+#: pybb/templates/pybb/_markitup.html:17
+msgid "Underline"
+msgstr "Podkreślenie"
+
+#: pybb/templates/pybb/_markitup.html:18
+msgid "Stroke"
+msgstr "Przekreślenie"
+
+#: pybb/templates/pybb/_markitup.html:20
+msgid "Picture"
+msgstr "Obrazek"
+
+#: pybb/templates/pybb/_markitup.html:21
+msgid "Link"
+msgstr ""
+
+#: pybb/templates/pybb/_markitup.html:23
+msgid "Bulleted list"
+msgstr "Lista wypunktowana"
+
+#: pybb/templates/pybb/_markitup.html:24
+msgid "Numeric list"
+msgstr "Lista numerowana"
+
+#: pybb/templates/pybb/_markitup.html:25
+msgid "List item"
+msgstr "Element listy"
+
+#: pybb/templates/pybb/_markitup.html:27
+msgid "Quotes"
+msgstr "Cytat"
+
+#: pybb/templates/pybb/_markitup.html:28
+msgid "Code"
+msgstr "Kod"
+
+#: pybb/templates/pybb/_markitup.html:30
+msgid "Clean"
+msgstr ""
+
+#: pybb/templates/pybb/_markitup.html:31
+msgid "Preview"
+msgstr "Podgląd"
+
+#: pybb/templates/pybb/_need_to_login_message.html:3
+msgid "Register"
+msgstr ""
+
+#: pybb/templates/pybb/_need_to_login_message.html:3
+msgid "or"
+msgstr ""
+
+#: pybb/templates/pybb/_need_to_login_message.html:3
+msgid "login"
+msgstr ""
+
+#: pybb/templates/pybb/_need_to_login_message.html:3
+msgid "to create to post a reply"
+msgstr ""
+
+#: pybb/templates/pybb/add_post.html:24
+msgid "New reply"
+msgstr ""
+
+#: pybb/templates/pybb/attachments_formset.html:4
+msgid "Add attachments"
+msgstr ""
+
+#: pybb/templates/pybb/attachments_formset.html:10
+#: pybb/templates/pybb/edit_profile.html:27
+msgid "delete"
+msgstr ""
+
+#: pybb/templates/pybb/breadcrumb.html:5
+msgid "Home"
+msgstr ""
+
+#: pybb/templates/pybb/category.html:19
+msgid "Last posts"
+msgstr ""
+
+#: pybb/templates/pybb/category.html:44
+msgid "No forums created"
+msgstr ""
+
+#: pybb/templates/pybb/category.html:45
+msgid "Add forum now"
+msgstr ""
+
+#: pybb/templates/pybb/delete_post.html:5
+msgid "Are you sure you want to delete this message?"
+msgstr ""
+
+#: pybb/templates/pybb/delete_post.html:12
+msgid "No, take me back"
+msgstr ""
+
+#: pybb/templates/pybb/delete_post.html:13
+msgid "Yes, I am sure"
+msgstr ""
+
+#: pybb/templates/pybb/edit_post.html:4 pybb/templates/pybb/edit_post.html:13
+msgid "Editing the post"
+msgstr ""
+
+#: pybb/templates/pybb/edit_profile.html:7
+#: pybb/templates/pybb/edit_profile.html:10
+#: pybb/templates/pybb/edit_profile.html:15
+msgid "Profile editing"
+msgstr ""
+
+#: pybb/templates/pybb/edit_profile.html:20
+msgid "Subscriptions on topics"
+msgstr ""
+
+#: pybb/templates/pybb/index.html:19
+msgid "Forum categories are not created"
+msgstr ""
+
+#: pybb/templates/pybb/index.html:20
+msgid "Add a category now"
+msgstr ""
+
+#: pybb/templates/pybb/index.html:25 pybb/templates/pybb/latest_topics.html:7
+#: pybb/templates/pybb/latest_topics.html:17
+msgid "Last updates in topics"
+msgstr "Ostatnio modyfikowane tematy"
+
+#: pybb/templates/pybb/index.html:28
+msgid "Mark all forums as read"
+msgstr ""
+
+#: pybb/templates/pybb/latest_topics.html:10
+msgid "\"Last updates in topics\""
+msgstr ""
+
+#: pybb/templates/pybb/latest_topics.html:33
+msgid "Mark all topics as read"
+msgstr "Oznacz wszystkie tematy jako przeczytane"
+
+#: pybb/templates/pybb/pagination.html:7
+msgid "previous page"
+msgstr ""
+
+#: pybb/templates/pybb/pagination.html:21
+msgid "next page"
+msgstr ""
+
+#: pybb/templates/pybb/poll.html:5
+msgid "Poll"
+msgstr ""
+
+#: pybb/templates/pybb/poll.html:37
+msgid "'Cancel my poll vote'"
+msgstr "Anuluj mój głos w ankiecie"
+
+#: pybb/templates/pybb/poll_edit_form.html:7
+msgid "Poll answers"
+msgstr ""
+
+#: pybb/templates/pybb/poll_edit_form.html:20
+msgid "remove answer"
+msgstr ""
+
+#: pybb/templates/pybb/poll_edit_form.html:21
+msgid "add answer"
+msgstr ""
+
+#: pybb/templates/pybb/post_template.html:25
+msgid "Rank"
+msgstr ""
+
+#: pybb/templates/pybb/post_template.html:38 pybb/templates/pybb/user.html:41
+msgid "Edit"
+msgstr ""
+
+#: pybb/templates/pybb/post_template.html:42
+msgid "Delete post?"
+msgstr ""
+
+#: pybb/templates/pybb/post_template.html:43
+msgid "Delete"
+msgstr ""
+
+#: pybb/templates/pybb/post_template.html:45
+msgid "Approve post"
+msgstr ""
+
+#: pybb/templates/pybb/post_template.html:50 pybb/templates/pybb/topic.html:63
+msgid "Admin"
+msgstr ""
+
+#: pybb/templates/pybb/post_template.html:66
+msgid "Edited"
+msgstr ""
+
+#: pybb/templates/pybb/post_template.html:78
+msgid "quote"
+msgstr ""
+
+#: pybb/templates/pybb/topic.html:24 pybb/templates/pybb/topic.html:44
+#: pybb/templates/pybb/user_posts.html:8
+msgid "'Posts'"
+msgstr "'Posty'"
+
+#: pybb/templates/pybb/topic.html:52
+msgid "Unstick topic"
+msgstr ""
+
+#: pybb/templates/pybb/topic.html:54
+msgid "Stick topic"
+msgstr ""
+
+#: pybb/templates/pybb/topic.html:58
+msgid "Open topic"
+msgstr ""
+
+#: pybb/templates/pybb/topic.html:60
+msgid "Close topic"
+msgstr ""
+
+#: pybb/templates/pybb/topic.html:66
+msgid "Merge topics"
+msgstr "Połącz wątki"
+
+#: pybb/templates/pybb/topic.html:71
+msgid "Unsubscribe"
+msgstr ""
+
+#: pybb/templates/pybb/topic.html:73
+msgid "Subscribe"
+msgstr ""
+
+#: pybb/templates/pybb/topic_list.html:13
+msgid "Views"
+msgstr ""
+
+#: pybb/templates/pybb/topic_list.html:16
+msgid "Last post"
+msgstr ""
+
+#: pybb/templates/pybb/topic_list.html:26
+msgid "Go to first unread post"
+msgstr "Zobacz pierwszy nieprzeczytany post"
+
+#: pybb/templates/pybb/topic_list.html:32
+msgid "pages"
+msgstr ""
+
+#: pybb/templates/pybb/user.html:15
+msgid "Statistics"
+msgstr ""
+
+#: pybb/templates/pybb/user.html:18
+msgid "Number of topics"
+msgstr ""
+
+#: pybb/templates/pybb/user.html:24
+msgid "Number of posts"
+msgstr ""
+
+#: pybb/templates/pybb/user.html:28
+msgid "Date of registration"
+msgstr ""
+
+#: pybb/templates/pybb/user.html:35
+msgid "Block"
+msgstr ""
+
+#: pybb/templates/pybb/user.html:36
+msgid "Block and delete all messages"
+msgstr "Zablokuj i usuń wszystkie posty"
+
+#: pybb/templates/pybb/user_posts.html:13
+msgid "All posts created by"
+msgstr "Wszystkie posty utworzone przez"
+
+#: pybb/templates/pybb/user_topics.html:8
+msgid "'Topics'"
+msgstr "'Tematy'"
+
+#: pybb/templates/pybb/user_topics.html:11
+#: pybb/templates/pybb/user_topics.html:15
+msgid "All topics created by"
+msgstr ""
+
+#: pybb/templates/pybb/users.html:8
+msgid "Users"
+msgstr ""
+
+#: pybb/templates/pybb/users.html:12
+msgid "Search"
+msgstr ""
+
+#: pybb/templates/pybb/users.html:24
+msgid "'Users'"
+msgstr "'Użytkownicy'"
+
+#: pybb/templates/pybb/mail_templates/subscription_email_body.html:3
+msgid "replied in topic to which you are subscribed."
+msgstr ""
+
+#: pybb/templates/pybb/mail_templates/subscription_email_body.html:4
+msgid "Link to post:"
+msgstr ""
+
+#: pybb/templates/pybb/mail_templates/subscription_email_body.html:5
+msgid "Link to topic:"
+msgstr ""
+
+#: pybb/templates/pybb/mail_templates/subscription_email_body.html:8
+msgid ""
+"If you don't want to recive notifications on new messages in this topic "
+"visit following link:"
+msgstr ""
+
+#: pybb/templates/pybb/mail_templates/subscription_email_subject.html:2
+msgid "New answer in topic that you subscribed."
+msgstr ""
+
+#: pybb/templatetags/pybb_tags.py:61
+msgid "seconds ago,seconds ago,seconds ago"
+msgstr ""
+
+#: pybb/templatetags/pybb_tags.py:64
+msgid "seconds ago"
+msgstr ""
+
+#: pybb/templatetags/pybb_tags.py:70
+msgid "minutes ago,minutes ago,minutes ago"
+msgstr ""
+
+#: pybb/templatetags/pybb_tags.py:73
+msgid "minutes ago"
+msgstr ""
+
+#: pybb/templatetags/pybb_tags.py:83
+#, python-format
+msgid "today, %s"
+msgstr ""
+
+#: pybb/templatetags/pybb_tags.py:85
+#, python-format
+msgid "yesterday, %s"
+msgstr ""
diff --git a/src/edumed/locale/pl/LC_MESSAGES/django.mo b/src/edumed/locale/pl/LC_MESSAGES/django.mo
new file mode 100644 (file)
index 0000000..89f7535
Binary files /dev/null and b/src/edumed/locale/pl/LC_MESSAGES/django.mo differ
diff --git a/src/edumed/locale/pl/LC_MESSAGES/django.po b/src/edumed/locale/pl/LC_MESSAGES/django.po
new file mode 100644 (file)
index 0000000..c35be11
--- /dev/null
@@ -0,0 +1,109 @@
+# 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: 2013-11-05 10:12+0100\n"
+"PO-Revision-Date: 2012-11-19 15:58+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"
+
+#: contact_forms.py:131
+msgid "extended"
+msgstr "rozszerzony"
+
+#: contact_forms.py:160
+msgid ""
+"Share your thoughts on the \"Media and information literacy competencies "
+"catalogue\""
+msgstr " Podziel się uwagami na temat Katalogu Kompetencji "
+
+#: contact_forms.py:161
+msgid "Submit"
+msgstr "Zgłoś"
+
+#: contact_forms.py:165
+msgid "Name and Surname"
+msgstr "Imię i nazwisko"
+
+#: contact_forms.py:166
+msgid "E-mail"
+msgstr "Adres e-mail"
+
+#: contact_forms.py:168
+msgid "Institution"
+msgstr "Instytucja"
+
+#: contact_forms.py:171
+msgid "What do you think about the proposed educational stages classification?"
+msgstr "Co sądzisz o zaproponowanym podziale na etapy edukacyjne?"
+
+#: contact_forms.py:178
+msgid "What do you think about the proposed thematic fields?"
+msgstr "Co sądzisz o zaproponowanym podziale na obszary tematyczne?"
+
+#: contact_forms.py:185
+msgid ""
+"What important areas of media and information literacy have been left out?"
+msgstr ""
+"Jakie ważne obszary edukacji medialnej i informacyjnej zostały Twoim zdaniem "
+"niewystarczająco pogłębione lub pominięto je w ogóle?"
+
+#: contact_forms.py:192
+msgid "Other suggestions and comments"
+msgstr "Inne uwagi i sugestie"
+
+#: forms.py:11
+msgid "Signature"
+msgstr ""
+
+#: templates/404.html:4 templates/404.html.py:8 templates/404_mil.html:4
+#: templates/404_mil.html.py:8
+msgid "Page not found"
+msgstr "Strona nie znaleziona"
+
+#: templates/404.html:11 templates/404_mil.html:11
+msgid "The page you were looking for doesn't exist."
+msgstr "Strona której szukasz nie została znaleziona."
+
+#: templates/base_forum.html:7
+msgid "Forum search"
+msgstr "Szukaj na forum"
+
+#: templates/base_mil.html:9
+msgid "About Catalogue"
+msgstr "O katalogu"
+
+#: templates/base_mil.html:10
+msgid "Competencies"
+msgstr "Kompetencje"
+
+#: templates/base_mil.html:11
+msgid "Take Part"
+msgstr "Weź udział"
+
+#: templates/base_mil.html:15
+msgid "Contact"
+msgstr "Kontakt"
+
+#: templates/pybb/_need_to_login_message.html:2
+msgid "Login"
+msgstr ""
+
+#: templates/pybb/_need_to_login_message.html:2
+msgid "register"
+msgstr ""
+
+#: templates/pybb/_need_to_login_message.html:2
+msgid "to create to post a reply"
+msgstr ""
diff --git a/src/edumed/milurls.py b/src/edumed/milurls.py
new file mode 100644 (file)
index 0000000..dea2558
--- /dev/null
@@ -0,0 +1,28 @@
+# -*- coding: utf-8 -*-
+from django.conf.urls import include, url, patterns
+from django.conf import settings
+
+from fnpdjango.utils.urls import i18n_patterns
+from .views import mil_home_view, mil_contact_view, mil_knowledge_base_view
+
+
+urlpatterns = i18n_patterns(
+    '',
+    url(r'^$', mil_home_view, name="mil_home"),
+    url(r'^kompetencje/', include('curriculum.urls')),
+    url(r'^wez-udzial/', include('comment.urls')),
+    url(r'^zglos/', include('contact.urls')),
+    url(r'^kontakt/$', mil_contact_view, name='mil_contact'),
+    url(r'^bazawiedzy/(?P<url>.*)$', mil_knowledge_base_view,
+        name="knowledge_base"),
+)
+
+handler404 = 'edumed.views.mil_404_view'
+
+if settings.DEBUG:
+    urlpatterns += patterns(
+        '',
+        url(r'^media/(?P<path>.*)$', 'django.views.static.serve', {
+            'document_root': settings.MEDIA_ROOT,
+        }),
+    )
diff --git a/src/edumed/settings/__init__.py b/src/edumed/settings/__init__.py
new file mode 100644 (file)
index 0000000..4a75df0
--- /dev/null
@@ -0,0 +1,21 @@
+# -*- coding: utf-8 -*-
+
+from .paths import *
+from .basic import *
+from .apps import *
+from .locale import *
+from .search import *
+from .auth import *
+from .cache import *
+from .context import *
+from .logging import *
+from .middleware import *
+from .contrib import *
+from .static import *
+from .custom import *
+
+# Load localsettings, if they exist
+try:
+    from edumed.localsettings import *
+except ImportError:
+    pass
\ No newline at end of file
diff --git a/src/edumed/settings/apps.py b/src/edumed/settings/apps.py
new file mode 100644 (file)
index 0000000..04835b5
--- /dev/null
@@ -0,0 +1,42 @@
+# -*- coding: utf-8 -*-
+
+INSTALLED_APPS = (
+    'edumed',
+    'curriculum',
+    'catalogue',
+    'comment',
+    'wtem',
+    'publishers',
+    'api',
+
+    'fnpdjango',
+    'south',
+    'pipeline',
+    'django_extensions',
+    # Disable, if not using Piwik.
+    'piwik',
+    # Disable, if not using CAS.
+    'honeypot',
+    'django_cas',
+    'sponsors',
+    'haystack',
+    'chunks',
+    'contact',
+    'forum',
+    'pybb',
+    'django_libravatar',
+    'sorl.thumbnail',
+    'subdomains',
+    'piston',
+
+    'django.contrib.auth',
+    'django.contrib.contenttypes',
+    'django.contrib.sessions',
+    'django.contrib.sites',
+    'django.contrib.messages',
+    'django.contrib.staticfiles',
+    'django.contrib.admin',
+    'django.contrib.admindocs',
+    'django.contrib.flatpages',
+    'django.contrib.humanize'
+)
diff --git a/src/edumed/settings/auth.py b/src/edumed/settings/auth.py
new file mode 100644 (file)
index 0000000..35c74c4
--- /dev/null
@@ -0,0 +1,8 @@
+# -*- coding: utf-8 -*-
+from .apps import INSTALLED_APPS
+
+if 'django_cas' in INSTALLED_APPS:
+    AUTHENTICATION_BACKENDS = (
+        'django.contrib.auth.backends.ModelBackend',
+        'fnpdjango.auth_backends.AttrCASBackend',
+    )
diff --git a/src/edumed/settings/basic.py b/src/edumed/settings/basic.py
new file mode 100644 (file)
index 0000000..3e553b3
--- /dev/null
@@ -0,0 +1,43 @@
+# -*- coding: utf-8 -*-
+import os.path
+
+from .paths import PROJECT_DIR
+
+DEBUG = False
+TEMPLATE_DEBUG = DEBUG
+
+DATABASES = {
+    'default': {
+        'ENGINE': 'django.db.backends.sqlite3',  # Add 'postgresql_psycopg2', 'mysql', 'sqlite3' or 'oracle'.
+        'NAME': os.path.join(PROJECT_DIR, 'dev.db'),                      # 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.
+        'PORT': '',                      # Set to empty string for default. Not used with sqlite3.
+    }
+}
+
+SITE_ID = 1
+
+# List of callables that know how to import templates from various sources.
+TEMPLATE_LOADERS = (
+    'django.template.loaders.filesystem.Loader',
+    'django.template.loaders.app_directories.Loader',
+    # 'django.template.loaders.eggs.Loader',
+)
+
+ROOT_URLCONF = 'edumed.urls'
+
+SUBDOMAIN_URLCONFS = {
+    None: 'edumed.urls',
+    'katalog': 'edumed.milurls',
+}
+
+# Python dotted path to the WSGI application used by Django's runserver.
+WSGI_APPLICATION = 'edumed.wsgi.application'
+
+TEMPLATE_DIRS = (
+    # Put strings here, like "/home/html/django_templates" or "C:/www/django/templates".
+    # Always use forward slashes, even on Windows.
+    # Don't forget to use absolute paths, not relative paths.
+)
diff --git a/src/edumed/settings/cache.py b/src/edumed/settings/cache.py
new file mode 100644 (file)
index 0000000..3079b6c
--- /dev/null
@@ -0,0 +1,11 @@
+# -*- coding: utf-8 -*-
+
+CACHES = {
+    'default': {
+        'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache',
+        'LOCATION': '127.0.0.1:11211',
+        'KEY_PREFIX': 'edumed',
+    }
+}
+
+CACHE_MIDDLEWARE_ANONYMOUS_ONLY = True
diff --git a/src/edumed/settings/context.py b/src/edumed/settings/context.py
new file mode 100644 (file)
index 0000000..bff5838
--- /dev/null
@@ -0,0 +1,15 @@
+# -*- coding: utf-8 -*-
+from edumed.utils import process_app_deps
+
+TEMPLATE_CONTEXT_PROCESSORS = process_app_deps((
+    ("django.contrib.auth.context_processors.auth", "django.contrib.auth"),
+    "django.core.context_processors.debug",
+    "django.core.context_processors.i18n",
+    "django.core.context_processors.media",
+    "django.core.context_processors.static",
+    "django.core.context_processors.tz",
+    ("django.contrib.messages.context_processors.messages", 'django.contrib.messages'),
+    "django.core.context_processors.request",
+    'pybb.context_processors.processor',
+    'edumed.context_processors.base_template',
+))
diff --git a/src/edumed/settings/contrib.py b/src/edumed/settings/contrib.py
new file mode 100644 (file)
index 0000000..d7ea957
--- /dev/null
@@ -0,0 +1,18 @@
+# -*- coding: utf-8 -*-
+
+CAS_SERVER_URL = 'http://logowanie.nowoczesnapolska.org.pl/cas/'
+CAS_VERSION = '3'
+
+SPONSORS_THUMB_WIDTH = 100
+SPONSORS_THUMB_HEIGHT = 56
+
+PYBB_TEMPLATE = "base_forum.html"
+PYBB_SMILES = {}
+PYBB_ENABLE_ANONYMOUS_POST = False
+
+PYBB_DEFAULT_TITLE = u'Forum'
+PYBB_DEFAULT_TIME_ZONE = 1
+PYBB_PERMISSION_HANDLER = 'edumed.forum.ForumPermissionHandler'
+
+THUMBNAIL_ENGINE = 'sorl.thumbnail.engines.convert_engine.Engine'
+THUMBNAIL_CONVERT = 'convert -density 300 -background white -alpha off'
diff --git a/src/edumed/settings/custom.py b/src/edumed/settings/custom.py
new file mode 100644 (file)
index 0000000..a2fc281
--- /dev/null
@@ -0,0 +1,3 @@
+# -*- coding: utf-8 -*-
+
+CONTACT_FORMS_MODULE = 'edumed.contact_forms'
diff --git a/src/edumed/settings/locale.py b/src/edumed/settings/locale.py
new file mode 100644 (file)
index 0000000..cfe4cc1
--- /dev/null
@@ -0,0 +1,40 @@
+# -*- coding: utf-8 -*-
+import os.path
+
+from .paths import PROJECT_DIR
+
+LANGUAGES = (
+    ('pl', u'polski'),
+    ('en', u'English'),
+)
+
+# Local time zone for this installation. Choices can be found here:
+# http://en.wikipedia.org/wiki/List_of_tz_zones_by_name
+# although not all choices may be available on all operating systems.
+# On Unix systems, a value of None will cause Django to use the same
+# timezone as the operating system.
+# If running in a Windows environment this must be set to the same as your
+# system time zone.
+TIME_ZONE = None
+
+# Language code for this installation. All choices can be found here:
+# http://www.i18nguy.com/unicode/language-identifiers.html
+LANGUAGE_CODE = 'pl'
+
+# If you set this to False, Django will make some optimizations so as not
+# to load the internationalization machinery.
+USE_I18N = True
+
+# If you set this to False, Django will not format dates, numbers and
+# calendars according to the current locale.
+USE_L10N = True
+
+# If you set this to False, Django will not use timezone-aware datetimes.
+USE_TZ = True
+
+CONTRIB_LOCALE_APPS = (
+    'pybb',
+)
+LOCALE_PATHS = (
+    os.path.join(PROJECT_DIR, 'edumed/locale-contrib'),
+)
diff --git a/src/edumed/settings/logging.py b/src/edumed/settings/logging.py
new file mode 100644 (file)
index 0000000..ea3ad61
--- /dev/null
@@ -0,0 +1,29 @@
+# -*- coding: utf-8 -*-
+# A sample logging configuration. The only tangible logging
+# performed by this configuration is to send an email to
+# the site admins on every HTTP 500 error when DEBUG=False.
+# See http://docs.djangoproject.com/en/dev/topics/logging for
+# more details on how to customize your logging configuration.
+LOGGING = {
+    'version': 1,
+    'disable_existing_loggers': False,
+    'filters': {
+        'require_debug_false': {
+            '()': 'django.utils.log.RequireDebugFalse'
+        }
+    },
+    'handlers': {
+        'mail_admins': {
+            'level': 'ERROR',
+            'filters': ['require_debug_false'],
+            'class': 'django.utils.log.AdminEmailHandler'
+        }
+    },
+    'loggers': {
+        'django.request': {
+            'handlers': ['mail_admins'],
+            'level': 'ERROR',
+            'propagate': True,
+        },
+    }
+}
diff --git a/src/edumed/settings/middleware.py b/src/edumed/settings/middleware.py
new file mode 100644 (file)
index 0000000..3dc3278
--- /dev/null
@@ -0,0 +1,24 @@
+# -*- coding: utf-8 -*-
+from edumed.utils import process_app_deps
+
+MIDDLEWARE_CLASSES = process_app_deps((
+    'django.middleware.cache.UpdateCacheMiddleware',
+    ('django.contrib.sessions.middleware.SessionMiddleware', 'django.contrib.sessions'),
+    # 'django.middleware.locale.LocaleMiddleware',
+    'subdomains.middleware.SubdomainURLRoutingMiddleware',
+    'fnpdjango.middleware.URLLocaleMiddleware',
+
+    'django.middleware.common.CommonMiddleware',
+    'django.middleware.csrf.CsrfViewMiddleware',
+    ('django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.auth'),
+    ('django_cas.middleware.CASMiddleware', 'django_cas'),
+    ('django.contrib.messages.middleware.MessageMiddleware', 'django.contrib.messages'),
+    # Uncomment the next line for simple clickjacking protection:
+    # 'django.middleware.clickjacking.XFrameOptionsMiddleware',
+    ('pagination.middleware.PaginationMiddleware', 'pagination'),
+    'django.middleware.cache.FetchFromCacheMiddleware',
+    'fnpdjango.middleware.SetRemoteAddrFromXRealIP',
+    'pybb.middleware.PybbMiddleware',
+    'forum.middleware.ForumMiddleware',
+    'wtem.middleware.ThreadLocalMiddleware'
+))
diff --git a/src/edumed/settings/paths.py b/src/edumed/settings/paths.py
new file mode 100644 (file)
index 0000000..55d7b9e
--- /dev/null
@@ -0,0 +1,4 @@
+# -*- coding: utf-8 -*-
+import os.path
+
+PROJECT_DIR = os.path.dirname(os.path.abspath(os.path.dirname(__file__)))
diff --git a/src/edumed/settings/search.py b/src/edumed/settings/search.py
new file mode 100644 (file)
index 0000000..f54983b
--- /dev/null
@@ -0,0 +1,8 @@
+# -*- coding: utf-8 -*-
+
+HAYSTACK_CONNECTIONS = {
+    'default': {
+        'ENGINE': 'haystack.backends.solr_backend.SolrEngine',
+        'URL': 'http://127.0.0.1:8983/solr/edumed'
+    },
+}
diff --git a/src/edumed/settings/static.py b/src/edumed/settings/static.py
new file mode 100644 (file)
index 0000000..a2f2c05
--- /dev/null
@@ -0,0 +1,73 @@
+# -*- coding: utf-8 -*-
+import os.path
+
+from .paths import PROJECT_DIR
+
+MEDIA_ROOT = os.path.join(PROJECT_DIR, 'media/')
+MEDIA_URL = '/media/'
+STATIC_ROOT = os.path.join(PROJECT_DIR, 'static/')
+STATIC_URL = '/static/'
+
+STATICFILES_FINDERS = (
+    'django.contrib.staticfiles.finders.FileSystemFinder',
+    'django.contrib.staticfiles.finders.AppDirectoriesFinder',
+    # 'django.contrib.staticfiles.finders.DefaultStorageFinder',
+)
+
+STATICFILES_STORAGE = 'fnpdjango.utils.pipeline_storage.GzipPipelineCachedStorage'
+PIPELINE_CSS_COMPRESSOR = None
+PIPELINE_JS_COMPRESSOR = None
+PIPELINE_CSS = {
+    'base': {
+        'source_filenames': (
+          'css/base.scss',
+          'css/main.scss',
+          'css/form.scss',
+          'catalogue/css/carousel.scss',
+          'catalogue/css/layout.scss',
+          'catalogue/css/lesson.scss',
+          'catalogue/css/exercise.scss',
+          'catalogue/css/section_list.scss',
+          'curriculum/curriculum.scss',
+          'jquery/colorbox/colorbox.css',
+          'fnpdjango/annoy/annoy.css',
+
+          'css/forum.scss',
+          'css/mil.scss'
+        ),
+        'output_filename': 'compressed/base.css',
+    },
+}
+PIPELINE_JS = {
+    'base': {
+        'source_filenames': (
+            'catalogue/js/jquery-ui-1.10.0.custom.js',
+            'catalogue/js/jquery.cycle.all.js',
+            'jquery/colorbox/jquery.colorbox-min.js',
+            'jquery/colorbox/jquery.colorbox-pl.js',
+            'catalogue/js/carousel.js',
+            'catalogue/js/edumed.js',
+            'catalogue/js/lesson.js',
+            'catalogue/js/lesson-list.js',
+            'sponsors/js/sponsors.js',
+            'curriculum/curriculum.js',
+            'js/formset.js',
+            'pybb/js/pybbjs.js',
+            'fnpdjango/annoy/annoy.js',
+        ),
+        'output_filename': 'compressed/base.js',
+    },
+    'wtem': {
+        'source_filenames': (
+            'catalogue/js/jquery-ui-1.10.0.custom.js',
+            'wtem/edumed.js',
+            'wtem/wtem.js',
+            'wtem/json2.js'
+        ),
+        'output_filename': 'compressed/wtem.js'
+    },
+}
+
+PIPELINE_COMPILERS = (
+  'pipeline.compilers.sass.SASSCompiler',
+)
diff --git a/src/edumed/static/css/_mixins.scss b/src/edumed/static/css/_mixins.scss
new file mode 100644 (file)
index 0000000..6b9499c
--- /dev/null
@@ -0,0 +1,7 @@
+@import "vars";
+
+@mixin base-font {
+    font-family: Dosis;
+    background: white;
+    color: $ciemny;
+}
\ No newline at end of file
diff --git a/src/edumed/static/css/_vars.scss b/src/edumed/static/css/_vars.scss
new file mode 100644 (file)
index 0000000..a502ca4
--- /dev/null
@@ -0,0 +1,4 @@
+$px: .0625em;
+$oranji: #ed7831;
+$ciemny: #363a3e;
+$zielony: #16a487;
\ No newline at end of file
diff --git a/src/edumed/static/css/base.css b/src/edumed/static/css/base.css
new file mode 100644 (file)
index 0000000..5ab583d
--- /dev/null
@@ -0,0 +1,250 @@
+@charset "UTF-8";
+@import url(//fonts.googleapis.com/css?family=Dosis:400,700&subset=latin,latin-ext);
+a {
+  text-decoration: none;
+  color: #ed7831; }
+  a img {
+    border: 0;
+    padding: 0; }
+
+body {
+  font-family: Dosis;
+  background: white;
+  color: #363a3e;
+  margin: 0; }
+
+.clr {
+  clear: both; }
+
+#banners {
+  margin: 0 auto;
+  width: 58.75em; }
+  #banners > a {
+    display: block;
+    width: 100%; }
+  #banners img {
+    display: block;
+    margin: 0 auto;
+    width: 100%; }
+
+#header-wrapper {
+  background-image: url(../img/header-bar.png);
+  background-repeat: repeat-x;
+  background-position: 0 100%; }
+
+header.main {
+  margin: 0 auto 1.4375em;
+  width: 58.75em;
+  padding: 1.8125em 0.625em 0; }
+  header.main #logo {
+    float: left;
+    margin-bottom: 1.25em; }
+    header.main #logo img {
+      vertical-align: middle; }
+  header.main #organizer {
+    float: right;
+    font-size: .75em;
+    color: #777; }
+    header.main #organizer img {
+      margin-top: .5em; }
+  header.main nav ul {
+    padding: 0;
+    position: absolute;
+    left: 15em; }
+  header.main nav li {
+    list-style: none;
+    display: inline-block;
+    text-transform: uppercase;
+    margin: 0 .5em;
+    text-align: center;
+    /*position:relative;*/ }
+  header.main nav a {
+    color: #363a3e;
+    display: block;
+    vertical-align: bottom;
+    font-size: .85em; }
+  header.main nav a:hover {
+    color: #ed7831; }
+  header.main nav a:before {
+    content: " ";
+    display: block;
+    margin-bottom: .8em;
+    width: 2.75em;
+    height: 2.125em;
+    text-align: center;
+    margin: auto;
+    margin-bottom: .8em; }
+  header.main nav .menu-lekcje:before {
+    background: url(../img/menu/lekcje.png) no-repeat 0 0;
+    background-size: 100%; }
+  header.main nav .menu-kompetencje:before {
+    background: url(../img/menu/kompetencje.png) no-repeat 0 0;
+    background-size: 100%; }
+  header.main nav .menu-olimpiada:before {
+    background: url(../img/menu/olimpiada.png) no-repeat 0 0;
+    background-size: 100%; }
+  header.main nav .menu-trener:before {
+    background: url(../img/menu/dla-trenera.png) no-repeat 0 0;
+    background-size: 100%; }
+  header.main nav .menu-kurs:before {
+    background: url(../img/menu/dla-ucznia.png) no-repeat 0 0;
+    background-size: 100%; }
+  header.main nav .menu-o-nas:before {
+    background: url(../img/menu/o-nas.png) no-repeat 0 0;
+    background-size: 100%; }
+  header.main nav .menu-lekcje:hover:before {
+    background: url(../img/menu/lekcje_active.png) no-repeat 0 0;
+    background-size: 100%; }
+  header.main nav .menu-kompetencje:hover:before {
+    background: url(../img/menu/kompetencje_active.png) no-repeat 0 0;
+    background-size: 100%; }
+  header.main nav .menu-olimpiada:hover:before {
+    background: url(../img/menu/olimpiada_active.png) no-repeat 0 0;
+    background-size: 100%; }
+  header.main nav .menu-trener:hover:before {
+    background: url(../img/menu/dla-trenera_active.png) no-repeat 0 0;
+    background-size: 100%; }
+  header.main nav .menu-kurs:hover:before {
+    background: url(../img/menu/dla-ucznia_active.png) no-repeat 0 0;
+    background-size: 100%; }
+  header.main nav .menu-o-nas:hover:before {
+    background: url(../img/menu/o-nas_active.png) no-repeat 0 0;
+    background-size: 100%; }
+  header.main nav .menu-oc-program:before {
+    background: url(../img/menu/olimpiada/program.png) no-repeat 0 0;
+    background-size: 100%; }
+  header.main nav .menu-oc-harmonogram:before {
+    background: url(../img/menu/olimpiada/harmonogram.png) no-repeat 0 0;
+    background-size: 100%; }
+  header.main nav .menu-oc-regulamin:before {
+    background: url(../img/menu/olimpiada/regulamin.png) no-repeat 0 0;
+    background-size: 100%; }
+  header.main nav .menu-oc-literatura:before {
+    background: url(../img/menu/olimpiada/literatura.png) no-repeat 0 0;
+    background-size: 100%; }
+  header.main nav .menu-oc-komitet:before {
+    background: url(../img/menu/olimpiada/komitet.png) no-repeat 0 0;
+    background-size: 100%; }
+  header.main nav .menu-oc-kontakt:before {
+    background: url(../img/menu/olimpiada/kontakt.png) no-repeat 0 0;
+    background-size: 100%; }
+  header.main nav .menu-oc-program:hover:before {
+    background: url(../img/menu/olimpiada/program_active.png) no-repeat 0 0;
+    background-size: 100%; }
+  header.main nav .menu-oc-harmonogram:hover:before {
+    background: url(../img/menu/olimpiada/harmonogram_active.png) no-repeat 0 0;
+    background-size: 100%; }
+  header.main nav .menu-oc-regulamin:hover:before {
+    background: url(../img/menu/olimpiada/regulamin_active.png) no-repeat 0 0;
+    background-size: 100%; }
+  header.main nav .menu-oc-literatura:hover:before {
+    background: url(../img/menu/olimpiada/literatura_active.png) no-repeat 0 0;
+    background-size: 100%; }
+  header.main nav .menu-oc-komitet:hover:before {
+    background: url(../img/menu/olimpiada/komitet_active.png) no-repeat 0 0;
+    background-size: 100%; }
+  header.main nav .menu-oc-kontakt:hover:before {
+    background: url(../img/menu/olimpiada/kontakt_active.png) no-repeat 0 0;
+    background-size: 100%; }
+  header.main #tagline {
+    clear: both;
+    float: left;
+    background-color: white;
+    /* Extend padded background .*/
+    padding: 0 0.625em;
+    margin-left: -0.625em;
+    font-size: .9em;
+    color: #363a3e; }
+  header.main #search {
+    float: right;
+    background-color: white;
+    /* Extend padded background .*/
+    padding: 2px 0.625em 0;
+    margin-right: -0.625em; }
+
+#content {
+  width: 58.75em;
+  padding: 0 0.625em;
+  margin: auto;
+  position: relative; }
+
+footer.main {
+  clear: both;
+  border-top: 1px solid #c9ccce;
+  width: 58.75em;
+  padding: 0.2em 0.625em;
+  margin: 2.5em auto 1em auto;
+  color: #9a9c9e; }
+  footer.main p {
+    font-size: .75em; }
+  footer.main .footer-item {
+    float: left;
+    margin-right: 1.25em;
+    width: 13.75em; }
+  footer.main .sponsors-column {
+    float: left;
+    margin-left: 1.25em;
+    width: 6.25em; }
+    footer.main .sponsors-column p {
+      font-size: .75em; }
+  footer.main .footer-extra p {
+    margin-top: 0; }
+
+#search {
+  font-size: .8em; }
+  #search input, #search button {
+    font-family: Dosis;
+    font-size: .9em;
+    vertical-align: bottom;
+    border: 1px solid #c9ccce;
+    padding: 0;
+    margin: 0;
+    line-height: .9em; }
+  #search input {
+    border-right-width: 0;
+    height: 16px;
+    width: 16em;
+    padding-left: 1.3em; }
+  #search button {
+    height: 18px;
+    width: 1.8em; }
+    #search button span {
+      position: relative;
+      top: -1px; }
+  #search input::-webkit-input-placeholder {
+    text-transform: uppercase; }
+  #search input:-moz-placeholder {
+    text-transform: uppercase; }
+  #search input::-moz-placeholder {
+    text-transform: uppercase; }
+  #search input::-ms-placeholder {
+    text-transform: uppercase; }
+
+.link-list {
+  list-style: none;
+  padding: 0; }
+  .link-list li {
+    margin-bottom: .5em; }
+  .link-list a:before {
+    content: "→";
+    margin-right: .5em; }
+  .link-list a {
+    color: #363a3e; }
+  .link-list a:hover {
+    color: #ed7831; }
+
+.link-list-colored a {
+  color: #ed7831; }
+
+.plain {
+  margin: 0;
+  padding: 0;
+  list-style: none; }
+  .plain li {
+    margin: 1em 0; }
+
+.flatpage img {
+  border: 0.3125em solid #eee;
+  margin: 1.3em; }
+
+/*# sourceMappingURL=base.css.map */
diff --git a/src/edumed/static/css/base.scss b/src/edumed/static/css/base.scss
new file mode 100644 (file)
index 0000000..b87a3e8
--- /dev/null
@@ -0,0 +1,280 @@
+@import url(//fonts.googleapis.com/css?family=Dosis:400,700&subset=latin,latin-ext);
+
+@import "vars";
+@import "mixins";
+
+
+a {
+    text-decoration: none;
+    color: $oranji;
+    img {
+        border: 0;
+        padding: 0;
+    }
+}
+
+body {
+    @include base-font;
+    margin: 0;
+}
+.clr {
+    clear: both;
+}
+
+#banners {
+    margin: 0 auto;
+    width: 58.75em;
+
+    > a {
+        display: block;
+        width: 100%;
+    }
+
+    img {
+        display: block;
+        margin: 0 auto;
+        width: 100%;
+    }
+}
+#header-wrapper {
+    background-image: url(../img/header-bar.png);
+    background-repeat: repeat-x;
+    background-position: 0 100%;
+}
+header.main {
+    margin: 0 auto 23*$px;
+    width: 940*$px;
+    padding: 29*$px 10*$px 0;
+
+    #header-top {
+    }
+
+    #logo {
+        float: left;
+        margin-bottom: 20*$px;
+        img {
+            vertical-align: middle;
+        }
+    }
+    #organizer {
+        float: right;
+        font-size: .75em;
+        color: #777;
+        
+        img {
+            margin-top: .5em;
+        }
+    }
+
+
+
+    nav {
+        ul {
+            padding: 0;
+            position: absolute;
+            left: 15em;
+        }
+        li {
+            list-style: none;
+            display: inline-block;
+            text-transform: uppercase;
+            margin: 0 .5em;
+            text-align: center;
+            /*position:relative;*/
+        }
+        a {
+            color: $ciemny;
+            display: block;
+            vertical-align: bottom;
+            font-size: .85em;
+        }
+        a:hover {
+            color: $oranji;
+        }
+
+        a:before {
+            content: " ";
+            display: block;
+            margin-bottom: .8em;
+            width: 44*$px;
+            height: 34*$px;
+            text-align:center;
+            margin: auto;
+            margin-bottom: .8em;
+        }
+        .menu-lekcje:before { background: url(../img/menu/lekcje.png) no-repeat 0 0; background-size: 100%;}
+        .menu-kompetencje:before { background: url(../img/menu/kompetencje.png) no-repeat 0 0; background-size: 100%;}
+        .menu-olimpiada:before { background: url(../img/menu/olimpiada.png) no-repeat 0 0; background-size: 100%;}
+        .menu-trener:before { background: url(../img/menu/dla-trenera.png) no-repeat 0 0; background-size: 100%;}
+        .menu-kurs:before { background: url(../img/menu/dla-ucznia.png) no-repeat 0 0; background-size: 100%;}
+        .menu-o-nas:before { background: url(../img/menu/o-nas.png) no-repeat 0 0; background-size: 100%;}
+
+        .menu-lekcje:hover:before { background: url(../img/menu/lekcje_active.png) no-repeat 0 0; background-size: 100%;}
+        .menu-kompetencje:hover:before { background: url(../img/menu/kompetencje_active.png) no-repeat 0 0; background-size: 100%;}
+        .menu-olimpiada:hover:before { background: url(../img/menu/olimpiada_active.png) no-repeat 0 0; background-size: 100%;}
+        .menu-trener:hover:before { background: url(../img/menu/dla-trenera_active.png) no-repeat 0 0; background-size: 100%;}
+        .menu-kurs:hover:before { background: url(../img/menu/dla-ucznia_active.png) no-repeat 0 0; background-size: 100%;}
+        .menu-o-nas:hover:before { background: url(../img/menu/o-nas_active.png) no-repeat 0 0; background-size: 100%;}
+
+        .menu-oc-program:before { background: url(../img/menu/olimpiada/program.png) no-repeat 0 0; background-size: 100%;}
+        .menu-oc-harmonogram:before { background: url(../img/menu/olimpiada/harmonogram.png) no-repeat 0 0; background-size: 100%;}
+        .menu-oc-regulamin:before { background: url(../img/menu/olimpiada/regulamin.png) no-repeat 0 0; background-size: 100%;}
+        .menu-oc-literatura:before { background: url(../img/menu/olimpiada/literatura.png) no-repeat 0 0; background-size: 100%;}
+        .menu-oc-komitet:before { background: url(../img/menu/olimpiada/komitet.png) no-repeat 0 0; background-size: 100%;}
+        .menu-oc-kontakt:before { background: url(../img/menu/olimpiada/kontakt.png) no-repeat 0 0; background-size: 100%;}
+        .menu-oc-program:hover:before {
+            background: url(../img/menu/olimpiada/program_active.png) no-repeat 0 0; background-size: 100%;}
+        .menu-oc-harmonogram:hover:before {
+            background: url(../img/menu/olimpiada/harmonogram_active.png) no-repeat 0 0; background-size: 100%;}
+        .menu-oc-regulamin:hover:before {
+            background: url(../img/menu/olimpiada/regulamin_active.png) no-repeat 0 0; background-size: 100%;}
+        .menu-oc-literatura:hover:before {
+            background: url(../img/menu/olimpiada/literatura_active.png) no-repeat 0 0; background-size: 100%;}
+        .menu-oc-komitet:hover:before {
+            background: url(../img/menu/olimpiada/komitet_active.png) no-repeat 0 0; background-size: 100%;}
+        .menu-oc-kontakt:hover:before {
+            background: url(../img/menu/olimpiada/kontakt_active.png) no-repeat 0 0; background-size: 100%;}
+    }
+
+    #tagline {
+        clear: both;
+        float: left;
+        background-color: white;
+        /* Extend padded background .*/
+        padding: 0 10*$px;
+        margin-left: -10*$px;
+        font-size: .9em;
+        color: $ciemny;
+    }
+    #search {
+        float: right;
+        background-color: white;
+        /* Extend padded background .*/
+        padding: 2px 10*$px 0;
+        margin-right: -10*$px;
+    }
+}
+
+
+#content {
+    width: 940 * $px;
+    padding: 0 10 * $px;
+    margin: auto;
+    position: relative;
+}
+
+
+footer.main {
+    clear: both;
+    border-top: 1px solid #c9ccce;
+    width: 940 * $px;
+    padding: .2em 10 * $px;
+    margin: 40*$px auto 1em auto;
+    color: #9a9c9e;
+
+    p {
+        font-size: .75em;
+    }
+    .footer-item {
+        float: left;
+        margin-right: 20 * $px;
+        width: 220 * $px;
+    }
+    .sponsors-column {
+        float: left;
+        margin-left: 20 * $px;
+        width: 100 * $px;
+        p {
+            font-size: .75em;
+        }
+    }
+    .footer-extra p {
+        margin-top: 0;
+    }
+}
+
+
+#search {
+    font-size: .8em;
+
+    input, button {
+        font-family: Dosis;
+        font-size: .9em;
+        vertical-align:bottom;
+        border: 1px solid #c9ccce;
+        padding: 0;
+        margin: 0;
+        line-height: .9em;
+    }
+    input {
+        border-right-width: 0;
+        height: 16px;
+        width: 16em;
+        padding-left: 1.3em;
+    }
+    button {
+        height: 18px;
+        width: 1.8em;
+        span {
+            position:relative;
+            top: -1px;
+        }
+    }
+
+    input::-webkit-input-placeholder {
+        text-transform: uppercase;
+    }
+    input:-moz-placeholder {
+        text-transform: uppercase;
+    }
+    input::-moz-placeholder {
+        text-transform: uppercase;
+    }
+    input::-ms-placeholder {
+        text-transform: uppercase;
+    }
+
+}
+
+
+.link-list {
+    list-style: none;
+    padding: 0;
+
+    li {
+        margin-bottom: .5em;
+    }
+
+    a:before {
+        content: "→";
+        margin-right: .5em;
+    }
+    a {
+        color: $ciemny;
+    }
+    a:hover {
+        color: $oranji;
+    }
+}
+.link-list-colored {
+    a {
+        color: $oranji;
+    }
+}
+
+
+.plain {
+    margin: 0;
+    padding: 0;
+    list-style: none;
+    li {
+        margin: 1em 0;
+    }
+}
+
+.flatpage {
+    img {
+        border: 5*$px solid #eee;
+        margin: 1.3em;
+    }
+}
diff --git a/src/edumed/static/css/form.css b/src/edumed/static/css/form.css
new file mode 100644 (file)
index 0000000..5699dd6
--- /dev/null
@@ -0,0 +1,25 @@
+.submit-form th, .submit-form td {
+  padding: .3em;
+  vertical-align: top;
+  text-align: left; }
+.submit-form ul {
+  padding: 0;
+  list-style: none;
+  margin: 0; }
+.submit-form th {
+  min-width: 4em;
+  max-width: 16em;
+  font-weight: normal; }
+.submit-form .required th label:before, .submit-form .required > label:before {
+  content: "* ";
+  color: red; }
+.submit-form p.required {
+  font-weight: bold; }
+.submit-form .errorlist {
+  padding: 0 0 0 1em;
+  margin: 0;
+  color: red; }
+.submit-form .form-footer {
+  font-size: smaller; }
+
+/*# sourceMappingURL=form.css.map */
diff --git a/src/edumed/static/css/form.scss b/src/edumed/static/css/form.scss
new file mode 100755 (executable)
index 0000000..90ad634
--- /dev/null
@@ -0,0 +1,32 @@
+.submit-form {
+    th, td {
+        padding: .3em;
+        vertical-align: top;
+        text-align: left;
+    }
+    ul {
+        padding: 0;
+        list-style: none;
+        margin: 0;
+    }
+    th {
+        min-width: 4em;
+        max-width: 16em;
+        font-weight: normal;
+    }
+    .required th label:before, .required>label:before {
+        content: "* ";
+        color: red;
+    }
+    p.required {
+        font-weight: bold;
+    }
+    .errorlist {
+        padding: 0 0 0 1em;
+        margin: 0;
+        color: red;
+    }
+    .form-footer {
+        font-size: smaller;
+    }
+}
diff --git a/src/edumed/static/css/forum.css b/src/edumed/static/css/forum.css
new file mode 100644 (file)
index 0000000..1c0b056
--- /dev/null
@@ -0,0 +1,89 @@
+ul.breadcrumb {
+  margin: 0;
+  padding: 0;
+  list-style: none; }
+  ul.breadcrumb li {
+    display: inline; }
+
+.forum-body {
+  position: relative;
+  /* --- Unread --- */
+  /* --- Moderation --- */
+  /* --- Mini pagination --- */ }
+  .forum-body .search-result em {
+    background-color: yellow; }
+  .forum-body .pagination ul {
+    margin: 0;
+    padding: 0;
+    list-style: none; }
+    .forum-body .pagination ul li {
+      display: inline-block; }
+      .forum-body .pagination ul li a {
+        display: block;
+        padding: .5em; }
+    .forum-body .pagination ul .disabled a {
+      color: black; }
+  .forum-body .table {
+    width: 100%;
+    margin: 1em 0; }
+  .forum-body .forum-description {
+    margin: 5px; }
+  .forum-body .forum-row, .forum-body .topic-row {
+    width: 100%; }
+  .forum-body .forum-name, .forum-body .topic-name {
+    width: 40%;
+    text-align: left; }
+  .forum-body .forum-topic-count, .forum-body .forum-post-count, .forum-body .topic-post-count, .forum-body .topic-view-count {
+    width: 10%;
+    text-align: center; }
+  .forum-body .forum-last-post, .forum-body .topic-last-post {
+    width: 32%;
+    text-align: center; }
+  .forum-body .first-unread-post-link, .forum-body .first-unread-post-link:hover {
+    text-decoration: none; }
+  .forum-body .post:nth-child(4n+4) {
+    background-color: #eaeaea; }
+  .forum-body .post-header {
+    padding: 3px 0 3px 20px; }
+    .forum-body .post-header th {
+      text-align: left; }
+  .forum-body .post-info {
+    width: 200px;
+    padding: 10px; }
+    .forum-body .post-info .post-author {
+      padding: 5px 0; }
+  .forum-body .post-content {
+    vertical-align: top;
+    padding: 10px; }
+  .forum-body .post-signature {
+    color: #CCC;
+    margin-top: 15px;
+    border-top: 1px dotted #cccccc;
+    display: block; }
+  .forum-body .post-related {
+    margin-top: 20px; }
+  .forum-body .forum-headline {
+    margin-top: 10px; }
+  .forum-body .attachments-form {
+    padding-bottom: 15px; }
+  .forum-body .attachment-link {
+    border-bottom: 1px dotted; }
+  .forum-body .state-indicator {
+    display: block;
+    float: left;
+    height: 10px;
+    width: 10px;
+    margin: 3px 5px; }
+  .forum-body .topic-unread a, .forum-body .forum-unread a {
+    font-weight: bold; }
+  .forum-body .on-moderation {
+    background: #ffcccc; }
+  .forum-body .mini-pagination {
+    padding: 3px 0 3px 10px; }
+  .forum-body .post-form input, .forum-body .post-form textarea {
+    font-family: Dosis;
+    background: white;
+    color: #363a3e;
+    font-size: 1.6em; }
+  .forum-body .post-form #id_name {
+    width: 698px; }
diff --git a/src/edumed/static/css/forum.scss b/src/edumed/static/css/forum.scss
new file mode 100755 (executable)
index 0000000..e1a3d58
--- /dev/null
@@ -0,0 +1,180 @@
+@import "mixins";
+
+
+ul.breadcrumb {
+    margin: 0;
+    padding: 0;
+    list-style: none;
+    li {
+        display: inline;
+    }
+}
+
+
+
+.forum-body {
+
+    position: relative;
+
+    .search-result {
+        em {
+            background-color: yellow;
+        }
+    }
+
+    .pagination {
+        ul {
+            margin: 0;
+            padding: 0;
+            list-style: none;
+
+            li {
+                display: inline-block;
+                a {
+                    display: block;
+                    padding: .5em;
+                }
+            }
+
+            .disabled {
+                a {
+                    color: black;
+                }
+            }
+        }
+    }
+
+    .table {
+        width: 100%;
+        margin: 1em 0;
+    }
+
+    .forum-description {
+        margin: 5px;
+    }
+
+    .forum-row, .topic-row {
+        width: 100%;
+    }
+
+    .forum-name, .topic-name {
+        width: 40%;
+        text-align: left;
+    }
+
+    .forum-topic-count, .forum-post-count, .topic-post-count, .topic-view-count {
+        width: 10%;
+        text-align: center;
+    }
+
+    .forum-last-post, .topic-last-post {
+        width: 32%;
+        text-align: center;
+    }
+
+    .first-unread-post-link, .first-unread-post-link:hover {
+        text-decoration: none;
+    }
+
+
+
+    .post:nth-child(4n+4) {
+        background-color: lighten(#D0D0D0 , 10%);
+    }
+
+    .post-header {
+       padding: 3px 0 3px 20px;
+       th {
+            text-align: left;
+       }
+    }
+
+    .post-info {
+        width: 200px;
+        padding: 10px;
+
+        .avatar {
+
+        }
+
+        .post-author {
+            padding: 5px 0;
+        }
+
+        .post-extra-info {
+        }
+
+        .post-controls {
+        }
+    }
+
+    .post-content {
+        vertical-align: top;
+        padding: 10px;
+    }
+
+    .post-signature {
+        color: #CCC;
+        margin-top: 15px;
+        border-top: 1px dotted #CCC;
+        display: block;
+    }
+
+    .post-related {
+        margin-top: 20px;
+    }
+
+
+
+
+    .forum-headline {
+        margin-top: 10px;
+    }
+
+    .attachments-form {
+        padding-bottom: 15px;
+    }
+
+    .attachment-link {
+        border-bottom: 1px dotted;
+    }
+
+    /* --- Unread --- */
+
+    .state-indicator {
+        display: block;
+        float: left;
+        height: 10px;
+        width: 10px;
+        margin: 3px 5px;
+    }
+
+    .topic-unread, .forum-unread {
+        a {
+            font-weight: bold;
+        }
+        .state-indicator {
+        }
+    }
+
+    /* --- Moderation --- */
+    .on-moderation {
+        background: #ffcccc;
+    }
+
+    /* --- Mini pagination --- */
+    .mini-pagination {
+        padding: 3px 0 3px 10px;
+    }
+
+
+    .post-form {
+        input, textarea {
+            @include base-font;
+            font-size: 1.6em;
+        }
+        #id_name {
+            width: 698px;
+        }
+    }
+}
diff --git a/src/edumed/static/css/main.css b/src/edumed/static/css/main.css
new file mode 100644 (file)
index 0000000..98dadef
--- /dev/null
@@ -0,0 +1,168 @@
+#main-promobox {
+  float: right;
+  width: 12.5em;
+  height: 11.6875em; }
+  #main-promobox a {
+    background: #16a487;
+    padding: 1em 0.625em;
+    border-radius: 0.9375em;
+    display: block;
+    margin-bottom: 1em;
+    width: 11.25em;
+    float: left; }
+    #main-promobox a:last-of-type {
+      margin-bottom: 0; }
+  #main-promobox h1 {
+    background: #16a487;
+    padding: 1em 0.625em;
+    border-radius: 0.9375em;
+    color: white;
+    margin: 0;
+    text-transform: uppercase;
+    font-size: .9em;
+    width: 12.625em;
+    float: left;
+    padding-top: 1.25em;
+    padding-bottom: 1.25em;
+    border-bottom-right-radius: 0;
+    border-bottom-left-radius: 0; }
+  #main-promobox h1:before {
+    content: url(/static/img/icons/announce_white.png);
+    margin-right: 1.2em;
+    vertical-align: top; }
+  #main-promobox h2 {
+    color: white;
+    font-size: .9em;
+    /*margin: 1.1em 0 0 0;*/
+    margin: 0;
+    font-weight: normal;
+    text-transform: uppercase; }
+  #main-promobox p {
+    color: #363a3e;
+    font-size: .8em;
+    line-height: 1.15em;
+    margin: .3em 0; }
+
+#main-sections {
+  clear: both;
+  float: left;
+  margin-top: 1.2em;
+  width: 43.75em; }
+  #main-sections h1 {
+    font-size: .9em;
+    margin: 0 0 0 1.25em;
+    text-transform: uppercase; }
+  #main-sections ul {
+    margin: -0.1875em 0 0 -1.25em;
+    padding: 0;
+    list-style: none; }
+    #main-sections ul li {
+      margin-top: 1.25em;
+      margin-left: 1.25em;
+      float: left;
+      height: 5.625em;
+      border-radius: 0.9375em; }
+      #main-sections ul li a {
+        color: white;
+        text-transform: uppercase;
+        height: 5em;
+        display: table;
+        padding: 5px; }
+        #main-sections ul li a .in-box {
+          font-size: .9em;
+          height: 100%;
+          width: 100%;
+          display: table-cell;
+          vertical-align: middle;
+          border: 1px solid transparent;
+          border-radius: 0.625em;
+          padding: 0 1em; }
+          #main-sections ul li a .in-box .name {
+            display: block;
+            font-size: 1.5em;
+            line-height: 1em;
+            margin-bottom: .2em; }
+      #main-sections ul li a:hover .in-box {
+        border: 1px solid white; }
+    #main-sections ul .box1 {
+      background-color: #adaeaf; }
+    #main-sections ul .box2 {
+      background-color: #f8b323; }
+    #main-sections ul .box3 {
+      background-color: #16a487; }
+    #main-sections ul .box4 {
+      background-color: #5e6165; }
+    #main-sections ul .box5 {
+      background-color: #f8b323; }
+    #main-sections ul .box6 {
+      background-color: #363a3e; }
+    #main-sections ul .box7 {
+      background-color: #adaeaf; }
+    #main-sections ul .box8 {
+      background-color: #ed7831; }
+
+#main-howto {
+  float: right;
+  margin-top: 1.2em;
+  width: 13.75em; }
+  #main-howto h1 {
+    font-size: .9em;
+    margin: 0 0 0 1.4em;
+    text-transform: uppercase; }
+  #main-howto ul {
+    margin: 1.0625em 0 1.0625em 1.4em; }
+    #main-howto ul li {
+      font-size: .9em;
+      text-transform: uppercase;
+      line-height: 1.25em; }
+    #main-howto ul a:before {
+      height: 1.25em; }
+    #main-howto ul .knowledge:before {
+      content: url(/static/img/icons/knowledge_dark.png); }
+    #main-howto ul .activity:before {
+      content: url(/static/img/icons/activity_dark.png); }
+    #main-howto ul .lesson-plan:before {
+      content: url(/static/img/icons/lesson-plan_dark.png); }
+    #main-howto ul .reference:before {
+      content: url(/static/img/icons/reference_dark.png); }
+    #main-howto ul .knowledge:hover:before {
+      content: url(/static/img/icons/knowledge_orange.png); }
+    #main-howto ul .activity:hover:before {
+      content: url(/static/img/icons/activity_orange.png); }
+    #main-howto ul .lesson-plan:hover:before {
+      content: url(/static/img/icons/lesson-plan_orange.png); }
+    #main-howto ul .reference:hover:before {
+      content: url(/static/img/icons/reference_orange.png); }
+  #main-howto p {
+    margin: 0 0 1.875em 1.4em; }
+  #main-howto .side-banner img {
+    display: block;
+    width: 100%;
+    margin-bottom: 0.2em; }
+
+#main-chosen {
+  clear: left;
+  float: left;
+  margin-top: 2em; }
+  #main-chosen h1 {
+    font-size: .9em;
+    margin: 0 0 1em 1.25em;
+    text-transform: uppercase; }
+  #main-chosen .levelth {
+    margin-left: 1.25em; }
+
+#main-tools {
+  clear: both; }
+  #main-tools .main-tools-box {
+    float: left;
+    margin-top: 1.5em;
+    margin-right: 1.25em;
+    width: 17.5em; }
+    #main-tools .main-tools-box h1 {
+      margin: 0;
+      font-size: .9em;
+      text-transform: uppercase; }
+    #main-tools .main-tools-box ul, #main-tools .main-tools-box ol {
+      margin: 1.1em 0 0 0;
+      font-size: .9em;
+      line-height: 1.15em; }
diff --git a/src/edumed/static/css/main.scss b/src/edumed/static/css/main.scss
new file mode 100755 (executable)
index 0000000..8d21b1d
--- /dev/null
@@ -0,0 +1,241 @@
+$px: .0625em;
+
+$horiz_padding: 10*$px;
+$width_offset: 20*$px;
+
+@mixin main-promobox-shape() {
+  background: #16a487;
+  padding: 1em $horiz_padding;
+  border-radius: 15*$px;
+}
+
+#main-promobox {
+  float: right;
+
+  width: 220*$px - $width_offset;
+  height: 235*$px - 2 * 1.5em;
+
+  a {
+    @include main-promobox-shape();
+
+    display: block;
+    margin-bottom: 1em;
+    width: 220*$px - $width_offset - 2*$horiz_padding;
+    float: left;
+
+    &:last-of-type {
+      margin-bottom: 0;
+    }
+  }
+  h1 {
+    @include main-promobox-shape();
+
+    color: white;
+    margin: 0;
+    text-transform: uppercase;
+    font-size: .9em;
+    width: 222*$px - 2 * $horiz_padding;
+    float: left;
+    padding-top: 1.25em;
+    padding-bottom: 1.25em;
+    border-bottom-right-radius: 0;
+    border-bottom-left-radius: 0;
+  }
+  h1:before {
+    content: url(/static/img/icons/announce_white.png);
+    margin-right: 1.2em;
+    vertical-align: top;
+  }
+  h2 {
+    color: white;
+    font-size: .9em;
+    /*margin: 1.1em 0 0 0;*/
+    margin: 0;
+    font-weight: normal;
+    text-transform: uppercase;
+  }
+  p {
+    color: #363a3e;
+    font-size: .8em;
+    line-height: 1.15em;
+    margin: .3em 0;
+  }
+}
+
+#main-sections {
+  clear: both;
+  float: left;
+  margin-top: 1.2em;
+  width: 700*$px;
+
+  h1 {
+    font-size: .9em;
+    margin: 0 0 0 20*$px;
+    text-transform: uppercase;
+  }
+
+  ul {
+    margin: -3*$px 0 0 -20*$px;
+    padding: 0;
+    list-style: none;
+
+    li {
+      margin-top: 20*$px;
+      margin-left: 20*$px;
+      float: left;
+      height: 90*$px;
+      border-radius: 15*$px;
+
+      a {
+        color: white;
+        text-transform: uppercase;
+        height: 80*$px;
+        display: table;
+        padding: 5px;
+
+        .in-box {
+          font-size: .9em;
+          height: 100%;
+          width: 100%;
+          display: table-cell;
+          vertical-align: middle;
+          border: 1px solid transparent;
+          border-radius: 10*$px;
+          padding: 0 16*$px;
+
+          .name {
+            display: block;
+            font-size: 1.5em;
+            line-height: 1em;
+            margin-bottom: .2em;
+          }
+        }
+      }
+      a:hover .in-box {
+        border: 1px solid white;
+      }
+    }
+    .box1 {
+      background-color: #adaeaf;
+    }
+    .box2 {
+      background-color: #f8b323;
+    }
+    .box3 {
+      background-color: #16a487;
+    }
+    .box4 {
+      background-color: #5e6165;
+    }
+    // .box5 {background-color: #16a487;}
+    .box5 {
+      background-color: #f8b323;
+    }
+    .box6 {
+      background-color: #363a3e;
+    }
+    .box7 {
+      background-color: #adaeaf;
+    }
+    .box8 {
+      background-color: #ed7831;
+    }
+  }
+}
+
+#main-howto {
+  float: right;
+  margin-top: 1.2em;
+  width: 220*$px;
+
+  h1 {
+    font-size: .9em;
+    margin: 0 0 0 1.4em;
+    text-transform: uppercase;
+  }
+
+  ul {
+    margin: 17*$px 0 17*$px 1.4em;
+
+    li {
+      font-size: .9em;
+      text-transform: uppercase;
+      line-height: 1.25em;
+    }
+    a:before {
+      height: 20*$px;
+    }
+
+    .knowledge:before {
+      content: url(/static/img/icons/knowledge_dark.png);
+    }
+    .activity:before {
+      content: url(/static/img/icons/activity_dark.png);
+    }
+    .lesson-plan:before {
+      content: url(/static/img/icons/lesson-plan_dark.png);
+    }
+    .reference:before {
+      content: url(/static/img/icons/reference_dark.png);
+    }
+    .knowledge:hover:before {
+      content: url(/static/img/icons/knowledge_orange.png);
+    }
+    .activity:hover:before {
+      content: url(/static/img/icons/activity_orange.png);
+    }
+    .lesson-plan:hover:before {
+      content: url(/static/img/icons/lesson-plan_orange.png);
+    }
+    .reference:hover:before {
+      content: url(/static/img/icons/reference_orange.png);
+    }
+
+  }
+  p {
+    margin: 0 0 30*$px 1.4em;
+  }
+  .side-banner img {
+    display: block;
+    width: 100%;
+    margin-bottom: 0.2em;
+  }
+}
+
+#main-chosen {
+  clear: left;
+  float: left;
+  margin-top: 2em;
+
+  h1 {
+    font-size: .9em;
+    margin: 0 0 1em 20*$px;
+    text-transform: uppercase;
+  }
+
+  .levelth {
+    margin-left: 20*$px;
+  }
+}
+
+#main-tools {
+  clear: both;
+  .main-tools-box {
+    float: left;
+    margin-top: 1.5em;
+    margin-right: 20*$px;
+    width: 280*$px;
+
+    h1 {
+      margin: 0;
+      font-size: .9em;
+      text-transform: uppercase;
+    }
+
+    ul, ol {
+      margin: 1.1em 0 0 0;
+      font-size: .9em;
+      line-height: 1.15em;
+    }
+  }
+}
diff --git a/src/edumed/static/css/mil.css b/src/edumed/static/css/mil.css
new file mode 100644 (file)
index 0000000..3d9bbbe
--- /dev/null
@@ -0,0 +1,47 @@
+header.header-mil {
+  background-color: #f47b3b; }
+  header.header-mil #organizer {
+    color: white;
+    float: none;
+    position: absolute;
+    top: 10px;
+    right: 12px; }
+  header.header-mil nav ul {
+    margin-top: 0; }
+    header.header-mil nav ul li {
+      vertical-align: text-bottom; }
+  header.header-mil nav a, header.header-mil nav a:hover {
+    color: white; }
+  header.header-mil nav a:before {
+    content: " ";
+    display: block;
+    margin-bottom: .8em;
+    width: 5.5em;
+    height: 4.25em;
+    text-align: center;
+    margin: auto;
+    margin-bottom: .8em; }
+  header.header-mil nav .menu-consultations:before {
+    background: url(../img/menu/mil/consultations.png) no-repeat 0 0;
+    background-size: 100%; }
+  header.header-mil nav .menu-takepart:before {
+    background: url(../img/menu/mil/takepart.png) no-repeat 0 0;
+    background-size: 100%; }
+  header.header-mil nav .menu-knowledgebase:before {
+    background: url(../img/menu/mil/knowledgebase.png) no-repeat 0 0;
+    background-size: 100%; }
+  header.header-mil nav .menu-kompetencje:before, header.header-mil nav .menu-kontakt:before {
+    width: 3.625em;
+    height: 2.8125em; }
+  header.header-mil nav .menu-kompetencje:before, header.header-mil nav .menu-kompetencje:hover:before {
+    background: url(../img/menu/mil/catalog.png) no-repeat 0 0;
+    background-size: 100%; }
+  header.header-mil nav .menu-kontakt:before, header.header-mil nav .menu-kontakt:hover:before {
+    background: url(../img/menu/mil/contact.png) no-repeat 0 0;
+    background-size: 100%; }
+  header.header-mil nav .lang-switcher-en:before {
+    background: url(../img/menu/mil/lang_en.png) no-repeat 0 0;
+    background-size: 100%; }
+  header.header-mil nav .lang-switcher-pl:before {
+    background: url(../img/menu/mil/lang_pl.png) no-repeat 0 0;
+    background-size: 100%; }
diff --git a/src/edumed/static/css/mil.scss b/src/edumed/static/css/mil.scss
new file mode 100644 (file)
index 0000000..be3f0aa
--- /dev/null
@@ -0,0 +1,57 @@
+@import "vars";
+
+header.header-mil {
+    
+    background-color: #f47b3b;
+
+    #organizer {
+        color: white;
+        float: none;
+        position: absolute;
+        top: 10px;
+        right:12px;
+    }
+    
+    nav {
+        ul {
+            margin-top: 0;
+            li {
+                vertical-align: text-bottom;
+            }
+        }
+
+        a,a:hover {
+            color: white;
+        }
+
+        a:before {
+            content: " ";
+            display: block;
+            margin-bottom: .8em;
+            width: 88*$px;
+            height: 68*$px;
+            text-align:center;
+            margin: auto;
+            margin-bottom: .8em;
+        }
+
+        .menu-consultations:before { background: url(../img/menu/mil/consultations.png) no-repeat 0 0; background-size: 100%;}
+        .menu-takepart:before { background: url(../img/menu/mil/takepart.png) no-repeat 0 0; background-size: 100%;}
+        .menu-knowledgebase:before { background: url(../img/menu/mil/knowledgebase.png) no-repeat 0 0; background-size: 100%;}
+
+        .menu-kompetencje:before, .menu-kontakt:before {
+            width: 58*$px;
+            height: 45*$px;
+        }
+
+        .menu-kompetencje:before, .menu-kompetencje:hover:before {
+            background: url(../img/menu/mil/catalog.png) no-repeat 0 0; background-size: 100%;
+        }
+        .menu-kontakt:before, .menu-kontakt:hover:before {
+            background: url(../img/menu/mil/contact.png) no-repeat 0 0; background-size: 100%;
+        }
+
+        .lang-switcher-en:before { background: url(../img/menu/mil/lang_en.png) no-repeat 0 0; background-size: 100%;}
+        .lang-switcher-pl:before { background: url(../img/menu/mil/lang_pl.png) no-repeat 0 0; background-size: 100%;}
+    }
+}
\ No newline at end of file
diff --git a/src/edumed/static/css/promobox.css b/src/edumed/static/css/promobox.css
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/src/edumed/static/css/promobox.scss b/src/edumed/static/css/promobox.scss
new file mode 100755 (executable)
index 0000000..f90b03f
--- /dev/null
@@ -0,0 +1,9 @@
+/*TODO: delete cause is not used*/
+
+#main-promobox {
+    h1 {
+        color: white;
+        margin: 0;
+      background: red;
+    }
+}
\ No newline at end of file
diff --git a/src/edumed/static/img/banners/440px_Forum.jpg b/src/edumed/static/img/banners/440px_Forum.jpg
new file mode 100644 (file)
index 0000000..b847807
Binary files /dev/null and b/src/edumed/static/img/banners/440px_Forum.jpg differ
diff --git a/src/edumed/static/img/banners/440px_Salon-1.jpg b/src/edumed/static/img/banners/440px_Salon-1.jpg
new file mode 100644 (file)
index 0000000..47ee486
Binary files /dev/null and b/src/edumed/static/img/banners/440px_Salon-1.jpg differ
diff --git a/src/edumed/static/img/banners/960x150_edukacjaMedialna.jpg b/src/edumed/static/img/banners/960x150_edukacjaMedialna.jpg
new file mode 100644 (file)
index 0000000..c3a9819
Binary files /dev/null and b/src/edumed/static/img/banners/960x150_edukacjaMedialna.jpg differ
diff --git a/src/edumed/static/img/banners/OC_collegium_web_970x250.jpg b/src/edumed/static/img/banners/OC_collegium_web_970x250.jpg
new file mode 100644 (file)
index 0000000..c13cb82
Binary files /dev/null and b/src/edumed/static/img/banners/OC_collegium_web_970x250.jpg differ
diff --git a/src/edumed/static/img/banners/oc-banner.png b/src/edumed/static/img/banners/oc-banner.png
new file mode 100644 (file)
index 0000000..279f1a5
Binary files /dev/null and b/src/edumed/static/img/banners/oc-banner.png differ
diff --git a/src/edumed/static/img/favicon.png b/src/edumed/static/img/favicon.png
new file mode 100644 (file)
index 0000000..61e13ab
Binary files /dev/null and b/src/edumed/static/img/favicon.png differ
diff --git a/src/edumed/static/img/header-bar.png b/src/edumed/static/img/header-bar.png
new file mode 100644 (file)
index 0000000..9bef386
Binary files /dev/null and b/src/edumed/static/img/header-bar.png differ
diff --git a/src/edumed/static/img/icons/activity-kind.png b/src/edumed/static/img/icons/activity-kind.png
new file mode 100644 (file)
index 0000000..d8b7dd7
Binary files /dev/null and b/src/edumed/static/img/icons/activity-kind.png differ
diff --git a/src/edumed/static/img/icons/activity-time.png b/src/edumed/static/img/icons/activity-time.png
new file mode 100644 (file)
index 0000000..1de3451
Binary files /dev/null and b/src/edumed/static/img/icons/activity-time.png differ
diff --git a/src/edumed/static/img/icons/activity-tools.png b/src/edumed/static/img/icons/activity-tools.png
new file mode 100644 (file)
index 0000000..b468872
Binary files /dev/null and b/src/edumed/static/img/icons/activity-tools.png differ
diff --git a/src/edumed/static/img/icons/activity_dark.png b/src/edumed/static/img/icons/activity_dark.png
new file mode 100644 (file)
index 0000000..a2cbaba
Binary files /dev/null and b/src/edumed/static/img/icons/activity_dark.png differ
diff --git a/src/edumed/static/img/icons/activity_orange.png b/src/edumed/static/img/icons/activity_orange.png
new file mode 100644 (file)
index 0000000..2a9f829
Binary files /dev/null and b/src/edumed/static/img/icons/activity_orange.png differ
diff --git a/src/edumed/static/img/icons/activity_white.png b/src/edumed/static/img/icons/activity_white.png
new file mode 100644 (file)
index 0000000..a8550f0
Binary files /dev/null and b/src/edumed/static/img/icons/activity_white.png differ
diff --git a/src/edumed/static/img/icons/announce_dark.png b/src/edumed/static/img/icons/announce_dark.png
new file mode 100644 (file)
index 0000000..485c358
Binary files /dev/null and b/src/edumed/static/img/icons/announce_dark.png differ
diff --git a/src/edumed/static/img/icons/announce_orange.png b/src/edumed/static/img/icons/announce_orange.png
new file mode 100644 (file)
index 0000000..1f1eb01
Binary files /dev/null and b/src/edumed/static/img/icons/announce_orange.png differ
diff --git a/src/edumed/static/img/icons/announce_white.png b/src/edumed/static/img/icons/announce_white.png
new file mode 100644 (file)
index 0000000..0142525
Binary files /dev/null and b/src/edumed/static/img/icons/announce_white.png differ
diff --git a/src/edumed/static/img/icons/internet_black.png b/src/edumed/static/img/icons/internet_black.png
new file mode 100644 (file)
index 0000000..538e60b
Binary files /dev/null and b/src/edumed/static/img/icons/internet_black.png differ
diff --git a/src/edumed/static/img/icons/knowledge_dark.png b/src/edumed/static/img/icons/knowledge_dark.png
new file mode 100644 (file)
index 0000000..3cfdd36
Binary files /dev/null and b/src/edumed/static/img/icons/knowledge_dark.png differ
diff --git a/src/edumed/static/img/icons/knowledge_orange.png b/src/edumed/static/img/icons/knowledge_orange.png
new file mode 100644 (file)
index 0000000..129689f
Binary files /dev/null and b/src/edumed/static/img/icons/knowledge_orange.png differ
diff --git a/src/edumed/static/img/icons/knowledge_white.png b/src/edumed/static/img/icons/knowledge_white.png
new file mode 100644 (file)
index 0000000..62d9b8b
Binary files /dev/null and b/src/edumed/static/img/icons/knowledge_white.png differ
diff --git a/src/edumed/static/img/icons/lesson-plan_dark.png b/src/edumed/static/img/icons/lesson-plan_dark.png
new file mode 100644 (file)
index 0000000..07ce96b
Binary files /dev/null and b/src/edumed/static/img/icons/lesson-plan_dark.png differ
diff --git a/src/edumed/static/img/icons/lesson-plan_orange.png b/src/edumed/static/img/icons/lesson-plan_orange.png
new file mode 100644 (file)
index 0000000..1402d17
Binary files /dev/null and b/src/edumed/static/img/icons/lesson-plan_orange.png differ
diff --git a/src/edumed/static/img/icons/lesson-plan_white.png b/src/edumed/static/img/icons/lesson-plan_white.png
new file mode 100644 (file)
index 0000000..63a516b
Binary files /dev/null and b/src/edumed/static/img/icons/lesson-plan_white.png differ
diff --git a/src/edumed/static/img/icons/nointernet_black.png b/src/edumed/static/img/icons/nointernet_black.png
new file mode 100644 (file)
index 0000000..9977783
Binary files /dev/null and b/src/edumed/static/img/icons/nointernet_black.png differ
diff --git a/src/edumed/static/img/icons/reference_dark.png b/src/edumed/static/img/icons/reference_dark.png
new file mode 100644 (file)
index 0000000..6df814c
Binary files /dev/null and b/src/edumed/static/img/icons/reference_dark.png differ
diff --git a/src/edumed/static/img/icons/reference_orange.png b/src/edumed/static/img/icons/reference_orange.png
new file mode 100644 (file)
index 0000000..f087312
Binary files /dev/null and b/src/edumed/static/img/icons/reference_orange.png differ
diff --git a/src/edumed/static/img/icons/reference_white.png b/src/edumed/static/img/icons/reference_white.png
new file mode 100644 (file)
index 0000000..6487417
Binary files /dev/null and b/src/edumed/static/img/icons/reference_white.png differ
diff --git a/src/edumed/static/img/icons/time_dark.png b/src/edumed/static/img/icons/time_dark.png
new file mode 100644 (file)
index 0000000..157b759
Binary files /dev/null and b/src/edumed/static/img/icons/time_dark.png differ
diff --git a/src/edumed/static/img/icons/time_orange.png b/src/edumed/static/img/icons/time_orange.png
new file mode 100644 (file)
index 0000000..80ee73a
Binary files /dev/null and b/src/edumed/static/img/icons/time_orange.png differ
diff --git a/src/edumed/static/img/icons/time_white.png b/src/edumed/static/img/icons/time_white.png
new file mode 100644 (file)
index 0000000..ab4ec8f
Binary files /dev/null and b/src/edumed/static/img/icons/time_white.png differ
diff --git a/src/edumed/static/img/logo-mil.png b/src/edumed/static/img/logo-mil.png
new file mode 100644 (file)
index 0000000..1f1d780
Binary files /dev/null and b/src/edumed/static/img/logo-mil.png differ
diff --git a/src/edumed/static/img/logo-oc.png b/src/edumed/static/img/logo-oc.png
new file mode 100644 (file)
index 0000000..23f488f
Binary files /dev/null and b/src/edumed/static/img/logo-oc.png differ
diff --git a/src/edumed/static/img/logo.png b/src/edumed/static/img/logo.png
new file mode 100644 (file)
index 0000000..eab7eed
Binary files /dev/null and b/src/edumed/static/img/logo.png differ
diff --git a/src/edumed/static/img/logo_fnp.png b/src/edumed/static/img/logo_fnp.png
new file mode 100644 (file)
index 0000000..768436a
Binary files /dev/null and b/src/edumed/static/img/logo_fnp.png differ
diff --git a/src/edumed/static/img/logo_fnp_white.png b/src/edumed/static/img/logo_fnp_white.png
new file mode 100644 (file)
index 0000000..f189ca7
Binary files /dev/null and b/src/edumed/static/img/logo_fnp_white.png differ
diff --git a/src/edumed/static/img/menu/dla-trenera.png b/src/edumed/static/img/menu/dla-trenera.png
new file mode 100644 (file)
index 0000000..f8923c7
Binary files /dev/null and b/src/edumed/static/img/menu/dla-trenera.png differ
diff --git a/src/edumed/static/img/menu/dla-trenera_active.png b/src/edumed/static/img/menu/dla-trenera_active.png
new file mode 100644 (file)
index 0000000..69647a6
Binary files /dev/null and b/src/edumed/static/img/menu/dla-trenera_active.png differ
diff --git a/src/edumed/static/img/menu/dla-ucznia.png b/src/edumed/static/img/menu/dla-ucznia.png
new file mode 100644 (file)
index 0000000..f0f2bcc
Binary files /dev/null and b/src/edumed/static/img/menu/dla-ucznia.png differ
diff --git a/src/edumed/static/img/menu/dla-ucznia_active.png b/src/edumed/static/img/menu/dla-ucznia_active.png
new file mode 100644 (file)
index 0000000..07c2101
Binary files /dev/null and b/src/edumed/static/img/menu/dla-ucznia_active.png differ
diff --git a/src/edumed/static/img/menu/kompetencje.png b/src/edumed/static/img/menu/kompetencje.png
new file mode 100644 (file)
index 0000000..ffc375e
Binary files /dev/null and b/src/edumed/static/img/menu/kompetencje.png differ
diff --git a/src/edumed/static/img/menu/kompetencje_active.png b/src/edumed/static/img/menu/kompetencje_active.png
new file mode 100644 (file)
index 0000000..95385d8
Binary files /dev/null and b/src/edumed/static/img/menu/kompetencje_active.png differ
diff --git a/src/edumed/static/img/menu/lekcje.png b/src/edumed/static/img/menu/lekcje.png
new file mode 100644 (file)
index 0000000..8635757
Binary files /dev/null and b/src/edumed/static/img/menu/lekcje.png differ
diff --git a/src/edumed/static/img/menu/lekcje_active.png b/src/edumed/static/img/menu/lekcje_active.png
new file mode 100644 (file)
index 0000000..e5f9983
Binary files /dev/null and b/src/edumed/static/img/menu/lekcje_active.png differ
diff --git a/src/edumed/static/img/menu/mil/catalog.png b/src/edumed/static/img/menu/mil/catalog.png
new file mode 100644 (file)
index 0000000..f0cc3c7
Binary files /dev/null and b/src/edumed/static/img/menu/mil/catalog.png differ
diff --git a/src/edumed/static/img/menu/mil/consultations.png b/src/edumed/static/img/menu/mil/consultations.png
new file mode 100644 (file)
index 0000000..e050b98
Binary files /dev/null and b/src/edumed/static/img/menu/mil/consultations.png differ
diff --git a/src/edumed/static/img/menu/mil/contact.png b/src/edumed/static/img/menu/mil/contact.png
new file mode 100644 (file)
index 0000000..7466951
Binary files /dev/null and b/src/edumed/static/img/menu/mil/contact.png differ
diff --git a/src/edumed/static/img/menu/mil/knowledgebase.png b/src/edumed/static/img/menu/mil/knowledgebase.png
new file mode 100644 (file)
index 0000000..6bd0372
Binary files /dev/null and b/src/edumed/static/img/menu/mil/knowledgebase.png differ
diff --git a/src/edumed/static/img/menu/mil/lang_en.png b/src/edumed/static/img/menu/mil/lang_en.png
new file mode 100644 (file)
index 0000000..ed9aa77
Binary files /dev/null and b/src/edumed/static/img/menu/mil/lang_en.png differ
diff --git a/src/edumed/static/img/menu/mil/lang_pl.png b/src/edumed/static/img/menu/mil/lang_pl.png
new file mode 100644 (file)
index 0000000..1c48db6
Binary files /dev/null and b/src/edumed/static/img/menu/mil/lang_pl.png differ
diff --git a/src/edumed/static/img/menu/mil/takepart.png b/src/edumed/static/img/menu/mil/takepart.png
new file mode 100644 (file)
index 0000000..28a6839
Binary files /dev/null and b/src/edumed/static/img/menu/mil/takepart.png differ
diff --git a/src/edumed/static/img/menu/o-nas.png b/src/edumed/static/img/menu/o-nas.png
new file mode 100644 (file)
index 0000000..6815fca
Binary files /dev/null and b/src/edumed/static/img/menu/o-nas.png differ
diff --git a/src/edumed/static/img/menu/o-nas_active.png b/src/edumed/static/img/menu/o-nas_active.png
new file mode 100644 (file)
index 0000000..4e8151b
Binary files /dev/null and b/src/edumed/static/img/menu/o-nas_active.png differ
diff --git a/src/edumed/static/img/menu/old/katalog.png b/src/edumed/static/img/menu/old/katalog.png
new file mode 100644 (file)
index 0000000..106bdae
Binary files /dev/null and b/src/edumed/static/img/menu/old/katalog.png differ
diff --git a/src/edumed/static/img/menu/old/katalog_active.png b/src/edumed/static/img/menu/old/katalog_active.png
new file mode 100644 (file)
index 0000000..5485b5e
Binary files /dev/null and b/src/edumed/static/img/menu/old/katalog_active.png differ
diff --git a/src/edumed/static/img/menu/old/kontakt.png b/src/edumed/static/img/menu/old/kontakt.png
new file mode 100644 (file)
index 0000000..291865d
Binary files /dev/null and b/src/edumed/static/img/menu/old/kontakt.png differ
diff --git a/src/edumed/static/img/menu/old/kontakt_active.png b/src/edumed/static/img/menu/old/kontakt_active.png
new file mode 100644 (file)
index 0000000..892da3c
Binary files /dev/null and b/src/edumed/static/img/menu/old/kontakt_active.png differ
diff --git a/src/edumed/static/img/menu/old/lekcje.png b/src/edumed/static/img/menu/old/lekcje.png
new file mode 100644 (file)
index 0000000..9989280
Binary files /dev/null and b/src/edumed/static/img/menu/old/lekcje.png differ
diff --git a/src/edumed/static/img/menu/old/lekcje_active.png b/src/edumed/static/img/menu/old/lekcje_active.png
new file mode 100644 (file)
index 0000000..47ed591
Binary files /dev/null and b/src/edumed/static/img/menu/old/lekcje_active.png differ
diff --git a/src/edumed/static/img/menu/old/o-nas.png b/src/edumed/static/img/menu/old/o-nas.png
new file mode 100644 (file)
index 0000000..00dab37
Binary files /dev/null and b/src/edumed/static/img/menu/old/o-nas.png differ
diff --git a/src/edumed/static/img/menu/old/o-nas_active.png b/src/edumed/static/img/menu/old/o-nas_active.png
new file mode 100644 (file)
index 0000000..1fc61e9
Binary files /dev/null and b/src/edumed/static/img/menu/old/o-nas_active.png differ
diff --git a/src/edumed/static/img/menu/old/szkolenia.png b/src/edumed/static/img/menu/old/szkolenia.png
new file mode 100644 (file)
index 0000000..97f8362
Binary files /dev/null and b/src/edumed/static/img/menu/old/szkolenia.png differ
diff --git a/src/edumed/static/img/menu/old/szkolenia_active.png b/src/edumed/static/img/menu/old/szkolenia_active.png
new file mode 100644 (file)
index 0000000..271eb8a
Binary files /dev/null and b/src/edumed/static/img/menu/old/szkolenia_active.png differ
diff --git a/src/edumed/static/img/menu/old/wesprzyj.png b/src/edumed/static/img/menu/old/wesprzyj.png
new file mode 100644 (file)
index 0000000..5182a12
Binary files /dev/null and b/src/edumed/static/img/menu/old/wesprzyj.png differ
diff --git a/src/edumed/static/img/menu/old/wesprzyj_active.png b/src/edumed/static/img/menu/old/wesprzyj_active.png
new file mode 100644 (file)
index 0000000..0402b9f
Binary files /dev/null and b/src/edumed/static/img/menu/old/wesprzyj_active.png differ
diff --git a/src/edumed/static/img/menu/old/wspolpraca.png b/src/edumed/static/img/menu/old/wspolpraca.png
new file mode 100644 (file)
index 0000000..af1aa43
Binary files /dev/null and b/src/edumed/static/img/menu/old/wspolpraca.png differ
diff --git a/src/edumed/static/img/menu/old/wspolpraca_active.png b/src/edumed/static/img/menu/old/wspolpraca_active.png
new file mode 100644 (file)
index 0000000..e849d30
Binary files /dev/null and b/src/edumed/static/img/menu/old/wspolpraca_active.png differ
diff --git a/src/edumed/static/img/menu/olimpiada.png b/src/edumed/static/img/menu/olimpiada.png
new file mode 100644 (file)
index 0000000..5194407
Binary files /dev/null and b/src/edumed/static/img/menu/olimpiada.png differ
diff --git a/src/edumed/static/img/menu/olimpiada/harmonogram.png b/src/edumed/static/img/menu/olimpiada/harmonogram.png
new file mode 100644 (file)
index 0000000..06e9c92
Binary files /dev/null and b/src/edumed/static/img/menu/olimpiada/harmonogram.png differ
diff --git a/src/edumed/static/img/menu/olimpiada/harmonogram_active.png b/src/edumed/static/img/menu/olimpiada/harmonogram_active.png
new file mode 100644 (file)
index 0000000..68c9721
Binary files /dev/null and b/src/edumed/static/img/menu/olimpiada/harmonogram_active.png differ
diff --git a/src/edumed/static/img/menu/olimpiada/komitet.png b/src/edumed/static/img/menu/olimpiada/komitet.png
new file mode 100644 (file)
index 0000000..2837890
Binary files /dev/null and b/src/edumed/static/img/menu/olimpiada/komitet.png differ
diff --git a/src/edumed/static/img/menu/olimpiada/komitet_active.png b/src/edumed/static/img/menu/olimpiada/komitet_active.png
new file mode 100644 (file)
index 0000000..b70ad4c
Binary files /dev/null and b/src/edumed/static/img/menu/olimpiada/komitet_active.png differ
diff --git a/src/edumed/static/img/menu/olimpiada/kontakt.png b/src/edumed/static/img/menu/olimpiada/kontakt.png
new file mode 100644 (file)
index 0000000..e94d178
Binary files /dev/null and b/src/edumed/static/img/menu/olimpiada/kontakt.png differ
diff --git a/src/edumed/static/img/menu/olimpiada/kontakt_active.png b/src/edumed/static/img/menu/olimpiada/kontakt_active.png
new file mode 100644 (file)
index 0000000..58e597a
Binary files /dev/null and b/src/edumed/static/img/menu/olimpiada/kontakt_active.png differ
diff --git a/src/edumed/static/img/menu/olimpiada/literatura.png b/src/edumed/static/img/menu/olimpiada/literatura.png
new file mode 100644 (file)
index 0000000..f252351
Binary files /dev/null and b/src/edumed/static/img/menu/olimpiada/literatura.png differ
diff --git a/src/edumed/static/img/menu/olimpiada/literatura_active.png b/src/edumed/static/img/menu/olimpiada/literatura_active.png
new file mode 100644 (file)
index 0000000..98719ac
Binary files /dev/null and b/src/edumed/static/img/menu/olimpiada/literatura_active.png differ
diff --git a/src/edumed/static/img/menu/olimpiada/program.png b/src/edumed/static/img/menu/olimpiada/program.png
new file mode 100644 (file)
index 0000000..56760e1
Binary files /dev/null and b/src/edumed/static/img/menu/olimpiada/program.png differ
diff --git a/src/edumed/static/img/menu/olimpiada/program_active.png b/src/edumed/static/img/menu/olimpiada/program_active.png
new file mode 100644 (file)
index 0000000..9b6ec98
Binary files /dev/null and b/src/edumed/static/img/menu/olimpiada/program_active.png differ
diff --git a/src/edumed/static/img/menu/olimpiada/regulamin.png b/src/edumed/static/img/menu/olimpiada/regulamin.png
new file mode 100644 (file)
index 0000000..449ac1c
Binary files /dev/null and b/src/edumed/static/img/menu/olimpiada/regulamin.png differ
diff --git a/src/edumed/static/img/menu/olimpiada/regulamin_active.png b/src/edumed/static/img/menu/olimpiada/regulamin_active.png
new file mode 100644 (file)
index 0000000..1a1516b
Binary files /dev/null and b/src/edumed/static/img/menu/olimpiada/regulamin_active.png differ
diff --git a/src/edumed/static/img/menu/olimpiada/svg/harmonogram.svg b/src/edumed/static/img/menu/olimpiada/svg/harmonogram.svg
new file mode 100644 (file)
index 0000000..64a3a3e
--- /dev/null
@@ -0,0 +1,145 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   version="1.1"
+   id="Capa_1"
+   x="0px"
+   y="0px"
+   viewBox="0 0 58 58"
+   style="enable-background:new 0 0 58 58;"
+   xml:space="preserve"
+   inkscape:version="0.48.4 r9939"
+   width="100%"
+   height="100%"
+   sodipodi:docname="harmonogram.svg"><metadata
+     id="metadata93"><rdf:RDF><cc:Work
+         rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs
+     id="defs91" /><sodipodi:namedview
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1"
+     objecttolerance="10"
+     gridtolerance="10"
+     guidetolerance="10"
+     inkscape:pageopacity="0"
+     inkscape:pageshadow="2"
+     inkscape:window-width="1366"
+     inkscape:window-height="692"
+     id="namedview89"
+     showgrid="false"
+     inkscape:zoom="5.7543862"
+     inkscape:cx="29"
+     inkscape:cy="29"
+     inkscape:window-x="0"
+     inkscape:window-y="24"
+     inkscape:window-maximized="1"
+     inkscape:current-layer="Capa_1" /><g
+     id="g3889"><path
+       style="fill:#96928b;fill-opacity:1"
+       d="M 42.899,4.5 C 42.434,2.221 40.415,0.5 38,0.5 c -0.553,0 -1,0.447 -1,1 0,0.553 0.447,1 1,1 1.654,0 3,1.346 3,3 0,1.654 -1.346,3 -3,3 -0.553,0 -1,0.447 -1,1 0,0.553 0.447,1 1,1 2.414,0 4.434,-1.721 4.899,-4 H 56 v 9 H 2 v -9 h 14 3 c 0.553,0 1,-0.447 1,-1 0,-0.553 -0.447,-1 -1,-1 h -1.816 c 0.414,-1.162 1.514,-2 2.816,-2 1.654,0 3,1.346 3,3 0,1.654 -1.346,3 -3,3 -0.553,0 -1,0.447 -1,1 0,0.553 0.447,1 1,1 2.757,0 5,-2.243 5,-5 0,-2.757 -2.243,-5 -5,-5 -2.414,0 -4.434,1.721 -4.899,4 H 0 v 13 40 h 58 v -40 -13 H 42.899 z M 56,55.5 H 2 v -38 h 54 v 38 z"
+       id="path5"
+       inkscape:connector-curvature="0" /><path
+       style="fill:#96928b;fill-opacity:1"
+       d="m 26,2.5 c 1.654,0 3,1.346 3,3 0,1.654 -1.346,3 -3,3 -0.553,0 -1,0.447 -1,1 0,0.553 0.447,1 1,1 2.757,0 5,-2.243 5,-5 0,-2.757 -2.243,-5 -5,-5 -0.553,0 -1,0.447 -1,1 0,0.553 0.447,1 1,1 z"
+       id="path7"
+       inkscape:connector-curvature="0" /><path
+       style="fill:#96928b;fill-opacity:1"
+       d="m 32,2.5 c 1.654,0 3,1.346 3,3 0,1.654 -1.346,3 -3,3 -0.553,0 -1,0.447 -1,1 0,0.553 0.447,1 1,1 2.757,0 5,-2.243 5,-5 0,-2.757 -2.243,-5 -5,-5 -0.553,0 -1,0.447 -1,1 0,0.553 0.447,1 1,1 z"
+       id="path9"
+       inkscape:connector-curvature="0" /><path
+       id="circle11"
+       d="m 23,24.5 c 0,0.552285 -0.447715,1 -1,1 -0.552285,0 -1,-0.447715 -1,-1 0,-0.552285 0.447715,-1 1,-1 0.552285,0 1,0.447715 1,1 z"
+       style="fill:#96928b;fill-opacity:1" /><path
+       id="circle13"
+       d="m 30,24.5 c 0,0.552285 -0.447715,1 -1,1 -0.552285,0 -1,-0.447715 -1,-1 0,-0.552285 0.447715,-1 1,-1 0.552285,0 1,0.447715 1,1 z"
+       style="fill:#96928b;fill-opacity:1" /><path
+       id="circle15"
+       d="m 37,24.5 c 0,0.552285 -0.447715,1 -1,1 -0.552285,0 -1,-0.447715 -1,-1 0,-0.552285 0.447715,-1 1,-1 0.552285,0 1,0.447715 1,1 z"
+       style="fill:#96928b;fill-opacity:1" /><path
+       id="circle17"
+       d="m 44,24.5 c 0,0.552285 -0.447715,1 -1,1 -0.552285,0 -1,-0.447715 -1,-1 0,-0.552285 0.447715,-1 1,-1 0.552285,0 1,0.447715 1,1 z"
+       style="fill:#96928b;fill-opacity:1" /><path
+       id="circle19"
+       d="m 51,24.5 c 0,0.552285 -0.447715,1 -1,1 -0.552285,0 -1,-0.447715 -1,-1 0,-0.552285 0.447715,-1 1,-1 0.552285,0 1,0.447715 1,1 z"
+       style="fill:#96928b;fill-opacity:1" /><path
+       id="circle21"
+       d="m 9,32.5 c 0,0.552285 -0.4477153,1 -1,1 -0.5522847,0 -1,-0.447715 -1,-1 0,-0.552285 0.4477153,-1 1,-1 0.5522847,0 1,0.447715 1,1 z"
+       style="fill:#96928b;fill-opacity:1" /><path
+       id="circle23"
+       d="m 16,32.5 c 0,0.552285 -0.447715,1 -1,1 -0.552285,0 -1,-0.447715 -1,-1 0,-0.552285 0.447715,-1 1,-1 0.552285,0 1,0.447715 1,1 z"
+       style="fill:#96928b;fill-opacity:1" /><path
+       id="circle25"
+       d="m 23,32.5 c 0,0.552285 -0.447715,1 -1,1 -0.552285,0 -1,-0.447715 -1,-1 0,-0.552285 0.447715,-1 1,-1 0.552285,0 1,0.447715 1,1 z"
+       style="fill:#96928b;fill-opacity:1" /><path
+       id="circle27"
+       d="m 30,32.5 c 0,0.552285 -0.447715,1 -1,1 -0.552285,0 -1,-0.447715 -1,-1 0,-0.552285 0.447715,-1 1,-1 0.552285,0 1,0.447715 1,1 z"
+       style="fill:#96928b;fill-opacity:1" /><path
+       id="circle29"
+       d="m 37,32.5 c 0,0.552285 -0.447715,1 -1,1 -0.552285,0 -1,-0.447715 -1,-1 0,-0.552285 0.447715,-1 1,-1 0.552285,0 1,0.447715 1,1 z"
+       style="fill:#96928b;fill-opacity:1" /><path
+       id="circle31"
+       d="m 44,32.5 c 0,0.552285 -0.447715,1 -1,1 -0.552285,0 -1,-0.447715 -1,-1 0,-0.552285 0.447715,-1 1,-1 0.552285,0 1,0.447715 1,1 z"
+       style="fill:#96928b;fill-opacity:1" /><path
+       id="circle33"
+       d="m 51,32.5 c 0,0.552285 -0.447715,1 -1,1 -0.552285,0 -1,-0.447715 -1,-1 0,-0.552285 0.447715,-1 1,-1 0.552285,0 1,0.447715 1,1 z"
+       style="fill:#96928b;fill-opacity:1" /><path
+       id="circle35"
+       d="m 9,39.5 c 0,0.552285 -0.4477153,1 -1,1 -0.5522847,0 -1,-0.447715 -1,-1 0,-0.552285 0.4477153,-1 1,-1 0.5522847,0 1,0.447715 1,1 z"
+       style="fill:#96928b;fill-opacity:1" /><path
+       id="circle37"
+       d="m 16,39.5 c 0,0.552285 -0.447715,1 -1,1 -0.552285,0 -1,-0.447715 -1,-1 0,-0.552285 0.447715,-1 1,-1 0.552285,0 1,0.447715 1,1 z"
+       style="fill:#96928b;fill-opacity:1" /><path
+       id="circle39"
+       d="m 23,39.5 c 0,0.552285 -0.447715,1 -1,1 -0.552285,0 -1,-0.447715 -1,-1 0,-0.552285 0.447715,-1 1,-1 0.552285,0 1,0.447715 1,1 z"
+       style="fill:#96928b;fill-opacity:1" /><path
+       id="circle41"
+       d="m 30,39.5 c 0,0.552285 -0.447715,1 -1,1 -0.552285,0 -1,-0.447715 -1,-1 0,-0.552285 0.447715,-1 1,-1 0.552285,0 1,0.447715 1,1 z"
+       style="fill:#96928b;fill-opacity:1" /><path
+       id="circle43"
+       d="m 37,39.5 c 0,0.552285 -0.447715,1 -1,1 -0.552285,0 -1,-0.447715 -1,-1 0,-0.552285 0.447715,-1 1,-1 0.552285,0 1,0.447715 1,1 z"
+       style="fill:#96928b;fill-opacity:1" /><path
+       id="circle45"
+       d="m 44,39.5 c 0,0.552285 -0.447715,1 -1,1 -0.552285,0 -1,-0.447715 -1,-1 0,-0.552285 0.447715,-1 1,-1 0.552285,0 1,0.447715 1,1 z"
+       style="fill:#96928b;fill-opacity:1" /><path
+       id="circle47"
+       d="m 51,39.5 c 0,0.552285 -0.447715,1 -1,1 -0.552285,0 -1,-0.447715 -1,-1 0,-0.552285 0.447715,-1 1,-1 0.552285,0 1,0.447715 1,1 z"
+       style="fill:#96928b;fill-opacity:1" /><path
+       id="circle49"
+       d="m 9,47.5 c 0,0.552285 -0.4477153,1 -1,1 -0.5522847,0 -1,-0.447715 -1,-1 0,-0.552285 0.4477153,-1 1,-1 0.5522847,0 1,0.447715 1,1 z"
+       style="fill:#96928b;fill-opacity:1" /><path
+       id="circle51"
+       d="m 16,47.5 c 0,0.552285 -0.447715,1 -1,1 -0.552285,0 -1,-0.447715 -1,-1 0,-0.552285 0.447715,-1 1,-1 0.552285,0 1,0.447715 1,1 z"
+       style="fill:#96928b;fill-opacity:1" /><path
+       id="circle53"
+       d="m 23,47.5 c 0,0.552285 -0.447715,1 -1,1 -0.552285,0 -1,-0.447715 -1,-1 0,-0.552285 0.447715,-1 1,-1 0.552285,0 1,0.447715 1,1 z"
+       style="fill:#96928b;fill-opacity:1" /><path
+       id="circle55"
+       d="m 30,47.5 c 0,0.552285 -0.447715,1 -1,1 -0.552285,0 -1,-0.447715 -1,-1 0,-0.552285 0.447715,-1 1,-1 0.552285,0 1,0.447715 1,1 z"
+       style="fill:#96928b;fill-opacity:1" /><path
+       id="circle57"
+       d="m 37,47.5 c 0,0.552285 -0.447715,1 -1,1 -0.552285,0 -1,-0.447715 -1,-1 0,-0.552285 0.447715,-1 1,-1 0.552285,0 1,0.447715 1,1 z"
+       style="fill:#96928b;fill-opacity:1" /></g><g
+     id="g59" /><g
+     id="g61" /><g
+     id="g63" /><g
+     id="g65" /><g
+     id="g67" /><g
+     id="g69" /><g
+     id="g71" /><g
+     id="g73" /><g
+     id="g75" /><g
+     id="g77" /><g
+     id="g79" /><g
+     id="g81" /><g
+     id="g83" /><g
+     id="g85" /><g
+     id="g87" /></svg>
\ No newline at end of file
diff --git a/src/edumed/static/img/menu/olimpiada/svg/harmonogram_active.svg b/src/edumed/static/img/menu/olimpiada/svg/harmonogram_active.svg
new file mode 100644 (file)
index 0000000..f690251
--- /dev/null
@@ -0,0 +1,146 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   version="1.1"
+   id="Capa_1"
+   x="0px"
+   y="0px"
+   viewBox="0 0 58 58"
+   style="enable-background:new 0 0 58 58;"
+   xml:space="preserve"
+   inkscape:version="0.48.4 r9939"
+   width="100%"
+   height="100%"
+   sodipodi:docname="harmonogram.svg"><metadata
+     id="metadata93"><rdf:RDF><cc:Work
+         rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
+     id="defs91" /><sodipodi:namedview
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1"
+     objecttolerance="10"
+     gridtolerance="10"
+     guidetolerance="10"
+     inkscape:pageopacity="0"
+     inkscape:pageshadow="2"
+     inkscape:window-width="1366"
+     inkscape:window-height="692"
+     id="namedview89"
+     showgrid="false"
+     inkscape:zoom="5.7543862"
+     inkscape:cx="29"
+     inkscape:cy="29"
+     inkscape:window-x="0"
+     inkscape:window-y="24"
+     inkscape:window-maximized="1"
+     inkscape:current-layer="Capa_1" /><g
+     id="g3889"
+     style="fill:#ed7831;fill-opacity:1"><path
+       style="fill:#ed7831;fill-opacity:1"
+       d="M 42.899,4.5 C 42.434,2.221 40.415,0.5 38,0.5 c -0.553,0 -1,0.447 -1,1 0,0.553 0.447,1 1,1 1.654,0 3,1.346 3,3 0,1.654 -1.346,3 -3,3 -0.553,0 -1,0.447 -1,1 0,0.553 0.447,1 1,1 2.414,0 4.434,-1.721 4.899,-4 H 56 v 9 H 2 v -9 h 14 3 c 0.553,0 1,-0.447 1,-1 0,-0.553 -0.447,-1 -1,-1 h -1.816 c 0.414,-1.162 1.514,-2 2.816,-2 1.654,0 3,1.346 3,3 0,1.654 -1.346,3 -3,3 -0.553,0 -1,0.447 -1,1 0,0.553 0.447,1 1,1 2.757,0 5,-2.243 5,-5 0,-2.757 -2.243,-5 -5,-5 -2.414,0 -4.434,1.721 -4.899,4 H 0 v 13 40 h 58 v -40 -13 H 42.899 z M 56,55.5 H 2 v -38 h 54 v 38 z"
+       id="path5"
+       inkscape:connector-curvature="0" /><path
+       style="fill:#ed7831;fill-opacity:1"
+       d="m 26,2.5 c 1.654,0 3,1.346 3,3 0,1.654 -1.346,3 -3,3 -0.553,0 -1,0.447 -1,1 0,0.553 0.447,1 1,1 2.757,0 5,-2.243 5,-5 0,-2.757 -2.243,-5 -5,-5 -0.553,0 -1,0.447 -1,1 0,0.553 0.447,1 1,1 z"
+       id="path7"
+       inkscape:connector-curvature="0" /><path
+       style="fill:#ed7831;fill-opacity:1"
+       d="m 32,2.5 c 1.654,0 3,1.346 3,3 0,1.654 -1.346,3 -3,3 -0.553,0 -1,0.447 -1,1 0,0.553 0.447,1 1,1 2.757,0 5,-2.243 5,-5 0,-2.757 -2.243,-5 -5,-5 -0.553,0 -1,0.447 -1,1 0,0.553 0.447,1 1,1 z"
+       id="path9"
+       inkscape:connector-curvature="0" /><path
+       id="circle11"
+       d="m 23,24.5 c 0,0.552285 -0.447715,1 -1,1 -0.552285,0 -1,-0.447715 -1,-1 0,-0.552285 0.447715,-1 1,-1 0.552285,0 1,0.447715 1,1 z"
+       style="fill:#ed7831;fill-opacity:1" /><path
+       id="circle13"
+       d="m 30,24.5 c 0,0.552285 -0.447715,1 -1,1 -0.552285,0 -1,-0.447715 -1,-1 0,-0.552285 0.447715,-1 1,-1 0.552285,0 1,0.447715 1,1 z"
+       style="fill:#ed7831;fill-opacity:1" /><path
+       id="circle15"
+       d="m 37,24.5 c 0,0.552285 -0.447715,1 -1,1 -0.552285,0 -1,-0.447715 -1,-1 0,-0.552285 0.447715,-1 1,-1 0.552285,0 1,0.447715 1,1 z"
+       style="fill:#ed7831;fill-opacity:1" /><path
+       id="circle17"
+       d="m 44,24.5 c 0,0.552285 -0.447715,1 -1,1 -0.552285,0 -1,-0.447715 -1,-1 0,-0.552285 0.447715,-1 1,-1 0.552285,0 1,0.447715 1,1 z"
+       style="fill:#ed7831;fill-opacity:1" /><path
+       id="circle19"
+       d="m 51,24.5 c 0,0.552285 -0.447715,1 -1,1 -0.552285,0 -1,-0.447715 -1,-1 0,-0.552285 0.447715,-1 1,-1 0.552285,0 1,0.447715 1,1 z"
+       style="fill:#ed7831;fill-opacity:1" /><path
+       id="circle21"
+       d="m 9,32.5 c 0,0.552285 -0.4477153,1 -1,1 -0.5522847,0 -1,-0.447715 -1,-1 0,-0.552285 0.4477153,-1 1,-1 0.5522847,0 1,0.447715 1,1 z"
+       style="fill:#ed7831;fill-opacity:1" /><path
+       id="circle23"
+       d="m 16,32.5 c 0,0.552285 -0.447715,1 -1,1 -0.552285,0 -1,-0.447715 -1,-1 0,-0.552285 0.447715,-1 1,-1 0.552285,0 1,0.447715 1,1 z"
+       style="fill:#ed7831;fill-opacity:1" /><path
+       id="circle25"
+       d="m 23,32.5 c 0,0.552285 -0.447715,1 -1,1 -0.552285,0 -1,-0.447715 -1,-1 0,-0.552285 0.447715,-1 1,-1 0.552285,0 1,0.447715 1,1 z"
+       style="fill:#ed7831;fill-opacity:1" /><path
+       id="circle27"
+       d="m 30,32.5 c 0,0.552285 -0.447715,1 -1,1 -0.552285,0 -1,-0.447715 -1,-1 0,-0.552285 0.447715,-1 1,-1 0.552285,0 1,0.447715 1,1 z"
+       style="fill:#ed7831;fill-opacity:1" /><path
+       id="circle29"
+       d="m 37,32.5 c 0,0.552285 -0.447715,1 -1,1 -0.552285,0 -1,-0.447715 -1,-1 0,-0.552285 0.447715,-1 1,-1 0.552285,0 1,0.447715 1,1 z"
+       style="fill:#ed7831;fill-opacity:1" /><path
+       id="circle31"
+       d="m 44,32.5 c 0,0.552285 -0.447715,1 -1,1 -0.552285,0 -1,-0.447715 -1,-1 0,-0.552285 0.447715,-1 1,-1 0.552285,0 1,0.447715 1,1 z"
+       style="fill:#ed7831;fill-opacity:1" /><path
+       id="circle33"
+       d="m 51,32.5 c 0,0.552285 -0.447715,1 -1,1 -0.552285,0 -1,-0.447715 -1,-1 0,-0.552285 0.447715,-1 1,-1 0.552285,0 1,0.447715 1,1 z"
+       style="fill:#ed7831;fill-opacity:1" /><path
+       id="circle35"
+       d="m 9,39.5 c 0,0.552285 -0.4477153,1 -1,1 -0.5522847,0 -1,-0.447715 -1,-1 0,-0.552285 0.4477153,-1 1,-1 0.5522847,0 1,0.447715 1,1 z"
+       style="fill:#ed7831;fill-opacity:1" /><path
+       id="circle37"
+       d="m 16,39.5 c 0,0.552285 -0.447715,1 -1,1 -0.552285,0 -1,-0.447715 -1,-1 0,-0.552285 0.447715,-1 1,-1 0.552285,0 1,0.447715 1,1 z"
+       style="fill:#ed7831;fill-opacity:1" /><path
+       id="circle39"
+       d="m 23,39.5 c 0,0.552285 -0.447715,1 -1,1 -0.552285,0 -1,-0.447715 -1,-1 0,-0.552285 0.447715,-1 1,-1 0.552285,0 1,0.447715 1,1 z"
+       style="fill:#ed7831;fill-opacity:1" /><path
+       id="circle41"
+       d="m 30,39.5 c 0,0.552285 -0.447715,1 -1,1 -0.552285,0 -1,-0.447715 -1,-1 0,-0.552285 0.447715,-1 1,-1 0.552285,0 1,0.447715 1,1 z"
+       style="fill:#ed7831;fill-opacity:1" /><path
+       id="circle43"
+       d="m 37,39.5 c 0,0.552285 -0.447715,1 -1,1 -0.552285,0 -1,-0.447715 -1,-1 0,-0.552285 0.447715,-1 1,-1 0.552285,0 1,0.447715 1,1 z"
+       style="fill:#ed7831;fill-opacity:1" /><path
+       id="circle45"
+       d="m 44,39.5 c 0,0.552285 -0.447715,1 -1,1 -0.552285,0 -1,-0.447715 -1,-1 0,-0.552285 0.447715,-1 1,-1 0.552285,0 1,0.447715 1,1 z"
+       style="fill:#ed7831;fill-opacity:1" /><path
+       id="circle47"
+       d="m 51,39.5 c 0,0.552285 -0.447715,1 -1,1 -0.552285,0 -1,-0.447715 -1,-1 0,-0.552285 0.447715,-1 1,-1 0.552285,0 1,0.447715 1,1 z"
+       style="fill:#ed7831;fill-opacity:1" /><path
+       id="circle49"
+       d="m 9,47.5 c 0,0.552285 -0.4477153,1 -1,1 -0.5522847,0 -1,-0.447715 -1,-1 0,-0.552285 0.4477153,-1 1,-1 0.5522847,0 1,0.447715 1,1 z"
+       style="fill:#ed7831;fill-opacity:1" /><path
+       id="circle51"
+       d="m 16,47.5 c 0,0.552285 -0.447715,1 -1,1 -0.552285,0 -1,-0.447715 -1,-1 0,-0.552285 0.447715,-1 1,-1 0.552285,0 1,0.447715 1,1 z"
+       style="fill:#ed7831;fill-opacity:1" /><path
+       id="circle53"
+       d="m 23,47.5 c 0,0.552285 -0.447715,1 -1,1 -0.552285,0 -1,-0.447715 -1,-1 0,-0.552285 0.447715,-1 1,-1 0.552285,0 1,0.447715 1,1 z"
+       style="fill:#ed7831;fill-opacity:1" /><path
+       id="circle55"
+       d="m 30,47.5 c 0,0.552285 -0.447715,1 -1,1 -0.552285,0 -1,-0.447715 -1,-1 0,-0.552285 0.447715,-1 1,-1 0.552285,0 1,0.447715 1,1 z"
+       style="fill:#ed7831;fill-opacity:1" /><path
+       id="circle57"
+       d="m 37,47.5 c 0,0.552285 -0.447715,1 -1,1 -0.552285,0 -1,-0.447715 -1,-1 0,-0.552285 0.447715,-1 1,-1 0.552285,0 1,0.447715 1,1 z"
+       style="fill:#ed7831;fill-opacity:1" /></g><g
+     id="g59" /><g
+     id="g61" /><g
+     id="g63" /><g
+     id="g65" /><g
+     id="g67" /><g
+     id="g69" /><g
+     id="g71" /><g
+     id="g73" /><g
+     id="g75" /><g
+     id="g77" /><g
+     id="g79" /><g
+     id="g81" /><g
+     id="g83" /><g
+     id="g85" /><g
+     id="g87" /></svg>
\ No newline at end of file
diff --git a/src/edumed/static/img/menu/olimpiada/svg/komitet.svg b/src/edumed/static/img/menu/olimpiada/svg/komitet.svg
new file mode 100644 (file)
index 0000000..d04c979
--- /dev/null
@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   version="1.1"
+   id="Capa_1"
+   x="0px"
+   y="0px"
+   viewBox="0 0 60 60"
+   style="enable-background:new 0 0 60 60;"
+   xml:space="preserve"
+   inkscape:version="0.48.4 r9939"
+   width="100%"
+   height="100%"
+   sodipodi:docname="komitet.svg"><metadata
+     id="metadata39"><rdf:RDF><cc:Work
+         rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs
+     id="defs37" /><sodipodi:namedview
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1"
+     objecttolerance="10"
+     gridtolerance="10"
+     guidetolerance="10"
+     inkscape:pageopacity="0"
+     inkscape:pageshadow="2"
+     inkscape:window-width="1366"
+     inkscape:window-height="692"
+     id="namedview35"
+     showgrid="false"
+     inkscape:zoom="3.9333333"
+     inkscape:cx="-16.779661"
+     inkscape:cy="30"
+     inkscape:window-x="0"
+     inkscape:window-y="24"
+     inkscape:window-maximized="1"
+     inkscape:current-layer="Capa_1" /><path
+     d="M55.517,46.55l-9.773-4.233c-0.23-0.115-0.485-0.396-0.704-0.771l6.525-0.005c0.114,0.011,2.804,0.257,4.961-0.67  c0.817-0.352,1.425-1.047,1.669-1.907c0.246-0.868,0.09-1.787-0.426-2.523c-1.865-2.654-6.218-9.589-6.354-16.623  c-0.003-0.121-0.397-12.083-12.21-12.18c-1.739,0.014-3.347,0.309-4.81,0.853c-0.319-0.813-0.789-1.661-1.488-2.459  C30.854,3.688,27.521,2.5,23,2.5s-7.854,1.188-9.908,3.53c-2.368,2.701-2.148,5.976-2.092,6.525v5.319c-0.64,0.729-1,1.662-1,2.625  v4c0,1.217,0.553,2.352,1.497,3.109c0.916,3.627,2.833,6.36,3.503,7.237v3.309c0,0.968-0.528,1.856-1.377,2.32l-8.921,4.866  C1.801,46.924,0,49.958,0,53.262V57.5h44h2h14v-3.697C60,50.711,58.282,47.933,55.517,46.55z M44,55.5H2v-2.238  c0-2.571,1.402-4.934,3.659-6.164l8.921-4.866C16.073,41.417,17,39.854,17,38.155v-4.019l-0.233-0.278  c-0.024-0.029-2.475-2.994-3.41-7.065l-0.091-0.396l-0.341-0.22C12.346,25.803,12,25.176,12,24.5v-4c0-0.561,0.238-1.084,0.67-1.475  L13,18.728V12.5l-0.009-0.131c-0.003-0.027-0.343-2.799,1.605-5.021C16.253,5.458,19.081,4.5,23,4.5  c3.905,0,6.727,0.951,8.386,2.828c0.825,0.932,1.24,1.973,1.447,2.867c0.016,0.07,0.031,0.139,0.045,0.208  c0.014,0.071,0.029,0.142,0.04,0.21c0.013,0.078,0.024,0.152,0.035,0.226c0.008,0.053,0.016,0.107,0.022,0.158  c0.015,0.124,0.027,0.244,0.035,0.355c0.001,0.009,0.001,0.017,0.001,0.026c0.007,0.108,0.012,0.21,0.015,0.303  c0,0.018,0,0.033,0.001,0.051c0.002,0.083,0.002,0.162,0.001,0.231c0,0.01,0,0.02,0,0.03c-0.004,0.235-0.02,0.375-0.02,0.378  L33,18.728l0.33,0.298C33.762,19.416,34,19.939,34,20.5v4c0,0.873-0.572,1.637-1.422,1.899l-0.498,0.153l-0.16,0.495  c-0.669,2.081-1.622,4.003-2.834,5.713c-0.297,0.421-0.586,0.794-0.837,1.079L28,34.123v4.125c0,0.253,0.025,0.501,0.064,0.745  c0.008,0.052,0.022,0.102,0.032,0.154c0.039,0.201,0.091,0.398,0.155,0.59c0.015,0.045,0.031,0.088,0.048,0.133  c0.078,0.209,0.169,0.411,0.275,0.605c0.012,0.022,0.023,0.045,0.035,0.067c0.145,0.256,0.312,0.499,0.504,0.723l0.228,0.281h0.039  c0.343,0.338,0.737,0.632,1.185,0.856l9.553,4.776C42.513,48.374,44,50.78,44,53.457V55.5z M58,55.5H46v-2.043  c0-3.439-1.911-6.53-4.986-8.068l-6.858-3.43c0.169-0.386,0.191-0.828,0.043-1.254c-0.245-0.705-0.885-1.16-1.63-1.16h-2.217  c-0.046-0.081-0.076-0.17-0.113-0.256c-0.05-0.115-0.109-0.228-0.142-0.349C30.036,38.718,30,38.486,30,38.248v-3.381  c0.229-0.28,0.47-0.599,0.719-0.951c1.239-1.75,2.232-3.698,2.954-5.799C35.084,27.47,36,26.075,36,24.5v-4  c0-0.963-0.36-1.896-1-2.625v-5.319c0.026-0.25,0.082-1.069-0.084-2.139c1.288-0.506,2.731-0.767,4.29-0.78  c9.841,0.081,10.2,9.811,10.21,10.221c0.147,7.583,4.746,14.927,6.717,17.732c0.169,0.24,0.22,0.542,0.139,0.827  c-0.046,0.164-0.178,0.462-0.535,0.615c-1.68,0.723-3.959,0.518-4.076,0.513h-6.883c-0.643,0-1.229,0.327-1.568,0.874  c-0.338,0.545-0.37,1.211-0.086,1.783c0.313,0.631,0.866,1.474,1.775,1.927l9.747,4.222C56.715,49.396,58,51.482,58,53.803V55.5z"
+     id="path3"
+     style="fill:#96928b;fill-opacity:1" /><g
+     id="g5" /><g
+     id="g7" /><g
+     id="g9" /><g
+     id="g11" /><g
+     id="g13" /><g
+     id="g15" /><g
+     id="g17" /><g
+     id="g19" /><g
+     id="g21" /><g
+     id="g23" /><g
+     id="g25" /><g
+     id="g27" /><g
+     id="g29" /><g
+     id="g31" /><g
+     id="g33" /></svg>
\ No newline at end of file
diff --git a/src/edumed/static/img/menu/olimpiada/svg/komitet_active.svg b/src/edumed/static/img/menu/olimpiada/svg/komitet_active.svg
new file mode 100644 (file)
index 0000000..9202ac9
--- /dev/null
@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   version="1.1"
+   id="Capa_1"
+   x="0px"
+   y="0px"
+   viewBox="0 0 60 60"
+   style="enable-background:new 0 0 60 60;"
+   xml:space="preserve"
+   inkscape:version="0.48.4 r9939"
+   width="100%"
+   height="100%"
+   sodipodi:docname="komitet.svg"><metadata
+     id="metadata39"><rdf:RDF><cc:Work
+         rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
+     id="defs37" /><sodipodi:namedview
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1"
+     objecttolerance="10"
+     gridtolerance="10"
+     guidetolerance="10"
+     inkscape:pageopacity="0"
+     inkscape:pageshadow="2"
+     inkscape:window-width="1366"
+     inkscape:window-height="692"
+     id="namedview35"
+     showgrid="false"
+     inkscape:zoom="3.9333333"
+     inkscape:cx="-16.779661"
+     inkscape:cy="30"
+     inkscape:window-x="0"
+     inkscape:window-y="24"
+     inkscape:window-maximized="1"
+     inkscape:current-layer="Capa_1" /><path
+     d="M55.517,46.55l-9.773-4.233c-0.23-0.115-0.485-0.396-0.704-0.771l6.525-0.005c0.114,0.011,2.804,0.257,4.961-0.67  c0.817-0.352,1.425-1.047,1.669-1.907c0.246-0.868,0.09-1.787-0.426-2.523c-1.865-2.654-6.218-9.589-6.354-16.623  c-0.003-0.121-0.397-12.083-12.21-12.18c-1.739,0.014-3.347,0.309-4.81,0.853c-0.319-0.813-0.789-1.661-1.488-2.459  C30.854,3.688,27.521,2.5,23,2.5s-7.854,1.188-9.908,3.53c-2.368,2.701-2.148,5.976-2.092,6.525v5.319c-0.64,0.729-1,1.662-1,2.625  v4c0,1.217,0.553,2.352,1.497,3.109c0.916,3.627,2.833,6.36,3.503,7.237v3.309c0,0.968-0.528,1.856-1.377,2.32l-8.921,4.866  C1.801,46.924,0,49.958,0,53.262V57.5h44h2h14v-3.697C60,50.711,58.282,47.933,55.517,46.55z M44,55.5H2v-2.238  c0-2.571,1.402-4.934,3.659-6.164l8.921-4.866C16.073,41.417,17,39.854,17,38.155v-4.019l-0.233-0.278  c-0.024-0.029-2.475-2.994-3.41-7.065l-0.091-0.396l-0.341-0.22C12.346,25.803,12,25.176,12,24.5v-4c0-0.561,0.238-1.084,0.67-1.475  L13,18.728V12.5l-0.009-0.131c-0.003-0.027-0.343-2.799,1.605-5.021C16.253,5.458,19.081,4.5,23,4.5  c3.905,0,6.727,0.951,8.386,2.828c0.825,0.932,1.24,1.973,1.447,2.867c0.016,0.07,0.031,0.139,0.045,0.208  c0.014,0.071,0.029,0.142,0.04,0.21c0.013,0.078,0.024,0.152,0.035,0.226c0.008,0.053,0.016,0.107,0.022,0.158  c0.015,0.124,0.027,0.244,0.035,0.355c0.001,0.009,0.001,0.017,0.001,0.026c0.007,0.108,0.012,0.21,0.015,0.303  c0,0.018,0,0.033,0.001,0.051c0.002,0.083,0.002,0.162,0.001,0.231c0,0.01,0,0.02,0,0.03c-0.004,0.235-0.02,0.375-0.02,0.378  L33,18.728l0.33,0.298C33.762,19.416,34,19.939,34,20.5v4c0,0.873-0.572,1.637-1.422,1.899l-0.498,0.153l-0.16,0.495  c-0.669,2.081-1.622,4.003-2.834,5.713c-0.297,0.421-0.586,0.794-0.837,1.079L28,34.123v4.125c0,0.253,0.025,0.501,0.064,0.745  c0.008,0.052,0.022,0.102,0.032,0.154c0.039,0.201,0.091,0.398,0.155,0.59c0.015,0.045,0.031,0.088,0.048,0.133  c0.078,0.209,0.169,0.411,0.275,0.605c0.012,0.022,0.023,0.045,0.035,0.067c0.145,0.256,0.312,0.499,0.504,0.723l0.228,0.281h0.039  c0.343,0.338,0.737,0.632,1.185,0.856l9.553,4.776C42.513,48.374,44,50.78,44,53.457V55.5z M58,55.5H46v-2.043  c0-3.439-1.911-6.53-4.986-8.068l-6.858-3.43c0.169-0.386,0.191-0.828,0.043-1.254c-0.245-0.705-0.885-1.16-1.63-1.16h-2.217  c-0.046-0.081-0.076-0.17-0.113-0.256c-0.05-0.115-0.109-0.228-0.142-0.349C30.036,38.718,30,38.486,30,38.248v-3.381  c0.229-0.28,0.47-0.599,0.719-0.951c1.239-1.75,2.232-3.698,2.954-5.799C35.084,27.47,36,26.075,36,24.5v-4  c0-0.963-0.36-1.896-1-2.625v-5.319c0.026-0.25,0.082-1.069-0.084-2.139c1.288-0.506,2.731-0.767,4.29-0.78  c9.841,0.081,10.2,9.811,10.21,10.221c0.147,7.583,4.746,14.927,6.717,17.732c0.169,0.24,0.22,0.542,0.139,0.827  c-0.046,0.164-0.178,0.462-0.535,0.615c-1.68,0.723-3.959,0.518-4.076,0.513h-6.883c-0.643,0-1.229,0.327-1.568,0.874  c-0.338,0.545-0.37,1.211-0.086,1.783c0.313,0.631,0.866,1.474,1.775,1.927l9.747,4.222C56.715,49.396,58,51.482,58,53.803V55.5z"
+     id="path3"
+     style="fill:#ed7831;fill-opacity:1;" /><g
+     id="g5" /><g
+     id="g7" /><g
+     id="g9" /><g
+     id="g11" /><g
+     id="g13" /><g
+     id="g15" /><g
+     id="g17" /><g
+     id="g19" /><g
+     id="g21" /><g
+     id="g23" /><g
+     id="g25" /><g
+     id="g27" /><g
+     id="g29" /><g
+     id="g31" /><g
+     id="g33" /></svg>
\ No newline at end of file
diff --git a/src/edumed/static/img/menu/olimpiada/svg/kontakt.svg b/src/edumed/static/img/menu/olimpiada/svg/kontakt.svg
new file mode 100644 (file)
index 0000000..1e9339f
--- /dev/null
@@ -0,0 +1,74 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   version="1.1"
+   id="Capa_1"
+   x="0px"
+   y="0px"
+   viewBox="0 0 59.999 59.999"
+   style="enable-background:new 0 0 59.999 59.999;"
+   xml:space="preserve"
+   inkscape:version="0.48.4 r9939"
+   width="100%"
+   height="100%"
+   sodipodi:docname="kontakt.svg"><metadata
+     id="metadata47"><rdf:RDF><cc:Work
+         rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs
+     id="defs45" /><sodipodi:namedview
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1"
+     objecttolerance="10"
+     gridtolerance="10"
+     guidetolerance="10"
+     inkscape:pageopacity="0"
+     inkscape:pageshadow="2"
+     inkscape:window-width="769"
+     inkscape:window-height="480"
+     id="namedview43"
+     showgrid="false"
+     inkscape:zoom="3.9333989"
+     inkscape:cx="29.9995"
+     inkscape:cy="29.9995"
+     inkscape:window-x="0"
+     inkscape:window-y="24"
+     inkscape:window-maximized="0"
+     inkscape:current-layer="Capa_1" /><g
+     id="g3"
+     style="fill:#96928b;fill-opacity:1"><path
+       d="M36.176,49.999c-1.93,0-3.5,1.57-3.5,3.5s1.57,3.5,3.5,3.5s3.5-1.57,3.5-3.5S38.105,49.999,36.176,49.999z M36.176,54.999   c-0.827,0-1.5-0.673-1.5-1.5s0.673-1.5,1.5-1.5s1.5,0.673,1.5,1.5S37.003,54.999,36.176,54.999z"
+       id="path5"
+       style="fill:#96928b;fill-opacity:1" /><path
+       d="M40.676,36.999c2.206,0,4-1.794,4-4s-1.794-4-4-4s-4,1.794-4,4S38.469,36.999,40.676,36.999z M40.676,30.999   c1.103,0,2,0.897,2,2s-0.897,2-2,2s-2-0.897-2-2S39.573,30.999,40.676,30.999z"
+       id="path7"
+       style="fill:#96928b;fill-opacity:1" /><path
+       d="M16.676,11.999c0.256,0,0.512-0.098,0.707-0.293l2-2c0.391-0.391,0.391-1.023,0-1.414s-1.023-0.391-1.414,0l-2,2   c-0.391,0.391-0.391,1.023,0,1.414C16.164,11.901,16.42,11.999,16.676,11.999z"
+       id="path9"
+       style="fill:#96928b;fill-opacity:1" /><path
+       d="M52.676,29.747c0-0.88-0.343-1.707-0.965-2.329l-0.557-0.557c0.949-0.84,1.521-2.055,1.521-3.362   c0-2.481-2.019-4.5-4.5-4.5c-0.182,0-0.362,0.018-0.54,0.04c0.022-0.179,0.04-0.357,0.04-0.54c0-2.481-2.019-4.5-4.5-4.5   c-0.182,0-0.362,0.018-0.54,0.04c0.022-0.179,0.04-0.357,0.04-0.54c0-2.481-2.019-4.5-4.5-4.5c-0.182,0-0.362,0.018-0.54,0.04   c0.022-0.179,0.04-0.357,0.04-0.54c0-2.481-2.019-4.5-4.5-4.5c-1.308,0-2.522,0.573-3.362,1.521l-0.794-0.794l-3.763-3.763   c-1.285-1.285-3.375-1.285-4.658,0L8.286,13.275c-1.283,1.285-1.283,3.374,0,4.659l3.763,3.763l4.91,4.91   c-1.356,0.776-2.283,2.221-2.283,3.892c0,1.563,0.803,2.941,2.017,3.748c0.061,0.081,0.132,0.161,0.227,0.242l10.756,10.715v1.796   h-2v13h18h8v-13h-2V43.97c1.913-1.621,3-3.952,3-6.471c0-1.74-0.543-3.43-1.536-4.852l0.571-0.571   C52.333,31.454,52.676,30.627,52.676,29.747z M50.676,23.499c0,0.768-0.354,1.479-0.937,1.947l-3.511-3.511   c0.468-0.583,1.18-0.937,1.947-0.937C49.554,20.999,50.676,22.12,50.676,23.499z M45.676,18.499c0,0.768-0.354,1.479-0.937,1.947   l-3.511-3.511c0.468-0.583,1.18-0.937,1.947-0.937C44.554,15.999,45.676,17.12,45.676,18.499z M40.676,13.499   c0,0.768-0.354,1.479-0.937,1.947l-3.511-3.511c0.468-0.583,1.18-0.937,1.947-0.937C39.554,10.999,40.676,12.12,40.676,13.499z    M33.176,5.999c1.379,0,2.5,1.121,2.5,2.5c0,0.768-0.354,1.479-0.937,1.947l-3.511-3.511C31.696,6.353,32.408,5.999,33.176,5.999z    M9.7,16.521c-0.504-0.505-0.504-1.326,0-1.831L22.012,2.378c0.125-0.125,0.271-0.219,0.426-0.282   c0.07-0.029,0.149-0.028,0.223-0.044c0.178-0.038,0.354-0.038,0.532,0c0.074,0.016,0.153,0.015,0.223,0.044   c0.155,0.063,0.3,0.157,0.426,0.282l2.349,2.349L12.049,18.869L9.7,16.521z M27.605,6.141l1.178,1.178l5,5l0.573,0.573l4.427,4.427   l0.573,0.573l4.427,4.427l0.573,0.573l5,5l0.94,0.94c0.505,0.505,0.505,1.325,0,1.83L49.859,31.1l0,0L37.985,42.975   c-0.503,0.504-1.326,0.506-1.831,0l-7.975-7.976h0.996c2.481,0,4.5-2.019,4.5-4.5s-2.019-4.5-4.5-4.5h-9.997l-5.716-5.716   L27.605,6.141z M18.636,28.061l0.415-0.047c0.041-0.006,0.082-0.015,0.124-0.015h10c1.379,0,2.5,1.121,2.5,2.5s-1.121,2.5-2.5,2.5   h-2.996h-2.828h-4.176c-1.379,0-2.5-1.121-2.5-2.5C16.676,29.306,17.517,28.309,18.636,28.061z M27.676,57.999v-9h8.426   c3.073,0,5.574,2.501,5.574,5.574v3.426H27.676z M49.676,57.999h-6v-3.426c0-2.206-0.954-4.188-2.464-5.574h8.464V57.999z    M49.701,34.087c0.634,1.021,0.975,2.202,0.975,3.412c0,2.055-0.948,3.946-2.602,5.191l-0.398,0.3v4.009H36.101h-6.426v-2.718   l-0.353-0.299c-0.045-0.039-0.093-0.075-0.18-0.14l-8.877-8.844h5.085l9.389,9.39c0.643,0.642,1.486,0.963,2.329,0.963   c0.844,0,1.688-0.321,2.33-0.963L49.701,34.087z"
+       id="path11"
+       style="fill:#96928b;fill-opacity:1" /></g><g
+     id="g13" /><g
+     id="g15" /><g
+     id="g17" /><g
+     id="g19" /><g
+     id="g21" /><g
+     id="g23" /><g
+     id="g25" /><g
+     id="g27" /><g
+     id="g29" /><g
+     id="g31" /><g
+     id="g33" /><g
+     id="g35" /><g
+     id="g37" /><g
+     id="g39" /><g
+     id="g41" /></svg>
\ No newline at end of file
diff --git a/src/edumed/static/img/menu/olimpiada/svg/kontakt_active.svg b/src/edumed/static/img/menu/olimpiada/svg/kontakt_active.svg
new file mode 100644 (file)
index 0000000..940e21e
--- /dev/null
@@ -0,0 +1,74 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   version="1.1"
+   id="Capa_1"
+   x="0px"
+   y="0px"
+   viewBox="0 0 59.999 59.999"
+   style="enable-background:new 0 0 59.999 59.999;"
+   xml:space="preserve"
+   inkscape:version="0.48.4 r9939"
+   width="100%"
+   height="100%"
+   sodipodi:docname="kontakt.svg"><metadata
+     id="metadata47"><rdf:RDF><cc:Work
+         rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
+     id="defs45" /><sodipodi:namedview
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1"
+     objecttolerance="10"
+     gridtolerance="10"
+     guidetolerance="10"
+     inkscape:pageopacity="0"
+     inkscape:pageshadow="2"
+     inkscape:window-width="769"
+     inkscape:window-height="480"
+     id="namedview43"
+     showgrid="false"
+     inkscape:zoom="3.9333989"
+     inkscape:cx="29.9995"
+     inkscape:cy="29.9995"
+     inkscape:window-x="0"
+     inkscape:window-y="24"
+     inkscape:window-maximized="0"
+     inkscape:current-layer="Capa_1" /><g
+     id="g3"
+     style="fill:#ed7831;fill-opacity:1"><path
+       d="M36.176,49.999c-1.93,0-3.5,1.57-3.5,3.5s1.57,3.5,3.5,3.5s3.5-1.57,3.5-3.5S38.105,49.999,36.176,49.999z M36.176,54.999   c-0.827,0-1.5-0.673-1.5-1.5s0.673-1.5,1.5-1.5s1.5,0.673,1.5,1.5S37.003,54.999,36.176,54.999z"
+       id="path5"
+       style="fill:#ed7831;fill-opacity:1" /><path
+       d="M40.676,36.999c2.206,0,4-1.794,4-4s-1.794-4-4-4s-4,1.794-4,4S38.469,36.999,40.676,36.999z M40.676,30.999   c1.103,0,2,0.897,2,2s-0.897,2-2,2s-2-0.897-2-2S39.573,30.999,40.676,30.999z"
+       id="path7"
+       style="fill:#ed7831;fill-opacity:1" /><path
+       d="M16.676,11.999c0.256,0,0.512-0.098,0.707-0.293l2-2c0.391-0.391,0.391-1.023,0-1.414s-1.023-0.391-1.414,0l-2,2   c-0.391,0.391-0.391,1.023,0,1.414C16.164,11.901,16.42,11.999,16.676,11.999z"
+       id="path9"
+       style="fill:#ed7831;fill-opacity:1" /><path
+       d="M52.676,29.747c0-0.88-0.343-1.707-0.965-2.329l-0.557-0.557c0.949-0.84,1.521-2.055,1.521-3.362   c0-2.481-2.019-4.5-4.5-4.5c-0.182,0-0.362,0.018-0.54,0.04c0.022-0.179,0.04-0.357,0.04-0.54c0-2.481-2.019-4.5-4.5-4.5   c-0.182,0-0.362,0.018-0.54,0.04c0.022-0.179,0.04-0.357,0.04-0.54c0-2.481-2.019-4.5-4.5-4.5c-0.182,0-0.362,0.018-0.54,0.04   c0.022-0.179,0.04-0.357,0.04-0.54c0-2.481-2.019-4.5-4.5-4.5c-1.308,0-2.522,0.573-3.362,1.521l-0.794-0.794l-3.763-3.763   c-1.285-1.285-3.375-1.285-4.658,0L8.286,13.275c-1.283,1.285-1.283,3.374,0,4.659l3.763,3.763l4.91,4.91   c-1.356,0.776-2.283,2.221-2.283,3.892c0,1.563,0.803,2.941,2.017,3.748c0.061,0.081,0.132,0.161,0.227,0.242l10.756,10.715v1.796   h-2v13h18h8v-13h-2V43.97c1.913-1.621,3-3.952,3-6.471c0-1.74-0.543-3.43-1.536-4.852l0.571-0.571   C52.333,31.454,52.676,30.627,52.676,29.747z M50.676,23.499c0,0.768-0.354,1.479-0.937,1.947l-3.511-3.511   c0.468-0.583,1.18-0.937,1.947-0.937C49.554,20.999,50.676,22.12,50.676,23.499z M45.676,18.499c0,0.768-0.354,1.479-0.937,1.947   l-3.511-3.511c0.468-0.583,1.18-0.937,1.947-0.937C44.554,15.999,45.676,17.12,45.676,18.499z M40.676,13.499   c0,0.768-0.354,1.479-0.937,1.947l-3.511-3.511c0.468-0.583,1.18-0.937,1.947-0.937C39.554,10.999,40.676,12.12,40.676,13.499z    M33.176,5.999c1.379,0,2.5,1.121,2.5,2.5c0,0.768-0.354,1.479-0.937,1.947l-3.511-3.511C31.696,6.353,32.408,5.999,33.176,5.999z    M9.7,16.521c-0.504-0.505-0.504-1.326,0-1.831L22.012,2.378c0.125-0.125,0.271-0.219,0.426-0.282   c0.07-0.029,0.149-0.028,0.223-0.044c0.178-0.038,0.354-0.038,0.532,0c0.074,0.016,0.153,0.015,0.223,0.044   c0.155,0.063,0.3,0.157,0.426,0.282l2.349,2.349L12.049,18.869L9.7,16.521z M27.605,6.141l1.178,1.178l5,5l0.573,0.573l4.427,4.427   l0.573,0.573l4.427,4.427l0.573,0.573l5,5l0.94,0.94c0.505,0.505,0.505,1.325,0,1.83L49.859,31.1l0,0L37.985,42.975   c-0.503,0.504-1.326,0.506-1.831,0l-7.975-7.976h0.996c2.481,0,4.5-2.019,4.5-4.5s-2.019-4.5-4.5-4.5h-9.997l-5.716-5.716   L27.605,6.141z M18.636,28.061l0.415-0.047c0.041-0.006,0.082-0.015,0.124-0.015h10c1.379,0,2.5,1.121,2.5,2.5s-1.121,2.5-2.5,2.5   h-2.996h-2.828h-4.176c-1.379,0-2.5-1.121-2.5-2.5C16.676,29.306,17.517,28.309,18.636,28.061z M27.676,57.999v-9h8.426   c3.073,0,5.574,2.501,5.574,5.574v3.426H27.676z M49.676,57.999h-6v-3.426c0-2.206-0.954-4.188-2.464-5.574h8.464V57.999z    M49.701,34.087c0.634,1.021,0.975,2.202,0.975,3.412c0,2.055-0.948,3.946-2.602,5.191l-0.398,0.3v4.009H36.101h-6.426v-2.718   l-0.353-0.299c-0.045-0.039-0.093-0.075-0.18-0.14l-8.877-8.844h5.085l9.389,9.39c0.643,0.642,1.486,0.963,2.329,0.963   c0.844,0,1.688-0.321,2.33-0.963L49.701,34.087z"
+       id="path11"
+       style="fill:#ed7831;fill-opacity:1" /></g><g
+     id="g13" /><g
+     id="g15" /><g
+     id="g17" /><g
+     id="g19" /><g
+     id="g21" /><g
+     id="g23" /><g
+     id="g25" /><g
+     id="g27" /><g
+     id="g29" /><g
+     id="g31" /><g
+     id="g33" /><g
+     id="g35" /><g
+     id="g37" /><g
+     id="g39" /><g
+     id="g41" /></svg>
\ No newline at end of file
diff --git a/src/edumed/static/img/menu/olimpiada/svg/literatura.svg b/src/edumed/static/img/menu/olimpiada/svg/literatura.svg
new file mode 100644 (file)
index 0000000..a004d7e
--- /dev/null
@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   version="1.1"
+   id="Capa_1"
+   x="0px"
+   y="0px"
+   viewBox="0 0 60 60"
+   style="enable-background:new 0 0 60 60;"
+   xml:space="preserve"
+   inkscape:version="0.48.4 r9939"
+   width="100%"
+   height="100%"
+   sodipodi:docname="literatura.svg"><metadata
+     id="metadata39"><rdf:RDF><cc:Work
+         rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs
+     id="defs37" /><sodipodi:namedview
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1"
+     objecttolerance="10"
+     gridtolerance="10"
+     guidetolerance="10"
+     inkscape:pageopacity="0"
+     inkscape:pageshadow="2"
+     inkscape:window-width="769"
+     inkscape:window-height="480"
+     id="namedview35"
+     showgrid="false"
+     inkscape:zoom="3.9333333"
+     inkscape:cx="30"
+     inkscape:cy="30"
+     inkscape:window-x="0"
+     inkscape:window-y="24"
+     inkscape:window-maximized="0"
+     inkscape:current-layer="Capa_1" /><path
+     d="M13,0c-1.547,0-3.033,0.662-4.078,1.817C7.895,2.954,7.389,4.476,7.525,6H7.5v48.958C7.5,57.738,9.762,60,12.542,60H52.5V11  V9V0H13z M9.5,54.958V9.998c0.836,0.629,1.875,1.002,3,1.002v46.996C10.842,57.973,9.5,56.621,9.5,54.958z M50.5,58h-36V11h3v25.201  c0,0.682,0.441,1.262,1.099,1.444c0.137,0.037,0.273,0.056,0.408,0.056c0.015,0,0.029-0.005,0.044-0.006  c0.045-0.001,0.088-0.012,0.133-0.017c0.103-0.012,0.202-0.033,0.299-0.066c0.048-0.016,0.093-0.035,0.138-0.056  c0.094-0.043,0.18-0.097,0.263-0.159c0.036-0.027,0.073-0.05,0.106-0.08c0.111-0.099,0.212-0.211,0.292-0.346l4.217-7.028  l4.217,7.029c0.327,0.545,0.939,0.801,1.55,0.687c0.045-0.008,0.089-0.002,0.134-0.014c0.657-0.183,1.099-0.763,1.099-1.444V11h19  V58z M29.64,9.483l-0.003,0.007L29.5,9.764v0.042l-0.1,0.23l0.1,0.152v0.112V34.39l-5-8.333l-5,8.333V10.236L21.118,7h9.764  L29.64,9.483z M32.118,9l2-4H19.882l-2,4h-4.67c-1.894,0-3.516-1.379-3.693-3.14c-0.101-0.998,0.214-1.957,0.887-2.701  C11.071,2.422,12.017,2,13,2h37.5v1h-5c-0.553,0-1,0.447-1,1s0.447,1,1,1h5v1h-4c-0.553,0-1,0.447-1,1s0.447,1,1,1h4v1H32.118z"
+     id="path3"
+     style="stroke:none;stroke-opacity:1;fill:#96928b;fill-opacity:1;" /><g
+     id="g5" /><g
+     id="g7" /><g
+     id="g9" /><g
+     id="g11" /><g
+     id="g13" /><g
+     id="g15" /><g
+     id="g17" /><g
+     id="g19" /><g
+     id="g21" /><g
+     id="g23" /><g
+     id="g25" /><g
+     id="g27" /><g
+     id="g29" /><g
+     id="g31" /><g
+     id="g33" /></svg>
\ No newline at end of file
diff --git a/src/edumed/static/img/menu/olimpiada/svg/literatura_active.svg b/src/edumed/static/img/menu/olimpiada/svg/literatura_active.svg
new file mode 100644 (file)
index 0000000..20395e7
--- /dev/null
@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   version="1.1"
+   id="Capa_1"
+   x="0px"
+   y="0px"
+   viewBox="0 0 60 60"
+   style="enable-background:new 0 0 60 60;"
+   xml:space="preserve"
+   inkscape:version="0.48.4 r9939"
+   width="100%"
+   height="100%"
+   sodipodi:docname="literatura.svg"><metadata
+     id="metadata39"><rdf:RDF><cc:Work
+         rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
+     id="defs37" /><sodipodi:namedview
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1"
+     objecttolerance="10"
+     gridtolerance="10"
+     guidetolerance="10"
+     inkscape:pageopacity="0"
+     inkscape:pageshadow="2"
+     inkscape:window-width="769"
+     inkscape:window-height="480"
+     id="namedview35"
+     showgrid="false"
+     inkscape:zoom="3.9333333"
+     inkscape:cx="30"
+     inkscape:cy="30"
+     inkscape:window-x="0"
+     inkscape:window-y="24"
+     inkscape:window-maximized="0"
+     inkscape:current-layer="Capa_1" /><path
+     d="M13,0c-1.547,0-3.033,0.662-4.078,1.817C7.895,2.954,7.389,4.476,7.525,6H7.5v48.958C7.5,57.738,9.762,60,12.542,60H52.5V11  V9V0H13z M9.5,54.958V9.998c0.836,0.629,1.875,1.002,3,1.002v46.996C10.842,57.973,9.5,56.621,9.5,54.958z M50.5,58h-36V11h3v25.201  c0,0.682,0.441,1.262,1.099,1.444c0.137,0.037,0.273,0.056,0.408,0.056c0.015,0,0.029-0.005,0.044-0.006  c0.045-0.001,0.088-0.012,0.133-0.017c0.103-0.012,0.202-0.033,0.299-0.066c0.048-0.016,0.093-0.035,0.138-0.056  c0.094-0.043,0.18-0.097,0.263-0.159c0.036-0.027,0.073-0.05,0.106-0.08c0.111-0.099,0.212-0.211,0.292-0.346l4.217-7.028  l4.217,7.029c0.327,0.545,0.939,0.801,1.55,0.687c0.045-0.008,0.089-0.002,0.134-0.014c0.657-0.183,1.099-0.763,1.099-1.444V11h19  V58z M29.64,9.483l-0.003,0.007L29.5,9.764v0.042l-0.1,0.23l0.1,0.152v0.112V34.39l-5-8.333l-5,8.333V10.236L21.118,7h9.764  L29.64,9.483z M32.118,9l2-4H19.882l-2,4h-4.67c-1.894,0-3.516-1.379-3.693-3.14c-0.101-0.998,0.214-1.957,0.887-2.701  C11.071,2.422,12.017,2,13,2h37.5v1h-5c-0.553,0-1,0.447-1,1s0.447,1,1,1h5v1h-4c-0.553,0-1,0.447-1,1s0.447,1,1,1h4v1H32.118z"
+     id="path3"
+     style="stroke:none;stroke-opacity:1;fill:#ed7831;fill-opacity:1" /><g
+     id="g5" /><g
+     id="g7" /><g
+     id="g9" /><g
+     id="g11" /><g
+     id="g13" /><g
+     id="g15" /><g
+     id="g17" /><g
+     id="g19" /><g
+     id="g21" /><g
+     id="g23" /><g
+     id="g25" /><g
+     id="g27" /><g
+     id="g29" /><g
+     id="g31" /><g
+     id="g33" /></svg>
\ No newline at end of file
diff --git a/src/edumed/static/img/menu/olimpiada/svg/program.svg b/src/edumed/static/img/menu/olimpiada/svg/program.svg
new file mode 100644 (file)
index 0000000..2418f09
--- /dev/null
@@ -0,0 +1,104 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   version="1.1"
+   id="Capa_1"
+   x="0px"
+   y="0px"
+   viewBox="0 0 54 54"
+   style="enable-background:new 0 0 54 54;"
+   xml:space="preserve"
+   inkscape:version="0.48.4 r9939"
+   width="100%"
+   height="100%"
+   sodipodi:docname="program.svg"><metadata
+     id="metadata57"><rdf:RDF><cc:Work
+         rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs
+     id="defs55" /><sodipodi:namedview
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1"
+     objecttolerance="10"
+     gridtolerance="10"
+     guidetolerance="10"
+     inkscape:pageopacity="0"
+     inkscape:pageshadow="2"
+     inkscape:window-width="769"
+     inkscape:window-height="480"
+     id="namedview53"
+     showgrid="false"
+     inkscape:zoom="4.3703704"
+     inkscape:cx="27"
+     inkscape:cy="27"
+     inkscape:window-x="0"
+     inkscape:window-y="24"
+     inkscape:window-maximized="0"
+     inkscape:current-layer="Capa_1" /><g
+     id="g3"
+     style="fill:#96928b;fill-opacity:1;"><path
+       d="M53.516,1.143c-0.3-0.182-0.674-0.19-0.983-0.027L36,9.869L19.468,1.116c-0.013-0.007-0.028-0.009-0.041-0.015   c-0.048-0.023-0.097-0.04-0.147-0.055c-0.028-0.008-0.055-0.017-0.083-0.023c-0.055-0.011-0.111-0.015-0.168-0.017   c-0.025-0.001-0.05-0.004-0.076-0.003c-0.054,0.003-0.107,0.013-0.16,0.025c-0.03,0.006-0.06,0.01-0.089,0.019   c-0.007,0.002-0.014,0.002-0.02,0.004l-18,6C0.275,7.187,0,7.569,0,8v43c0,0.321,0.154,0.623,0.416,0.812   C0.588,51.935,0.793,52,1,52c0.106,0,0.213-0.017,0.316-0.052l17.646-5.882l16.657,6.859c0.014,0.006,0.03,0.004,0.044,0.009   C35.773,52.973,35.885,53,36,53c0.09,0,0.179-0.015,0.266-0.039c0.028-0.008,0.054-0.021,0.082-0.031   c0.04-0.015,0.082-0.026,0.12-0.046l17-9C53.795,43.711,54,43.37,54,43V2C54,1.649,53.816,1.324,53.516,1.143z M2,8.721l16-5.333   v26.992c-0.43,0.078-0.854,0.166-1.264,0.274c-0.534,0.142-0.852,0.689-0.71,1.223c0.119,0.448,0.523,0.744,0.966,0.744   c0.084,0,0.171-0.011,0.257-0.033c0.24-0.064,0.502-0.096,0.751-0.148v11.84L2,49.612V8.721z M20,32.16   c0.321-0.025,0.632-0.066,0.961-0.073c0.552-0.012,0.99-0.469,0.979-1.021c-0.012-0.545-0.457-0.979-1-0.979   c-0.007,0-0.015,0-0.022,0c-0.31,0.007-0.615,0.024-0.918,0.045V3.661l15,7.941v21.194c-0.714-0.031-1.44-0.115-2.201-0.262   c-0.544-0.107-1.067,0.249-1.172,0.791s0.25,1.067,0.792,1.172c0.886,0.172,1.746,0.256,2.582,0.289v15.721L20,44.33V32.16z    M52,42.397l-15,7.941v-15.66c0.372-0.169,0.62-0.549,0.587-0.98c-0.029-0.374-0.269-0.674-0.587-0.821V11.602l15-7.941V42.397z"
+       id="path5"
+       style="fill:#96928b;fill-opacity:1" /><path
+       d="M11,9c-2.757,0-5,2.243-5,5c0,2.415,1.721,4.434,4,4.899V21c0,0.553,0.448,1,1,1s1-0.447,1-1v-2.101   c2.279-0.465,4-2.484,4-4.899C16,11.243,13.757,9,11,9z M11,17c-1.654,0-3-1.346-3-3s1.346-3,3-3s3,1.346,3,3S12.654,17,11,17z"
+       id="path7"
+       style="fill:#96928b;fill-opacity:1" /><path
+       d="M45.07,27.673c0.12,0.047,0.243,0.068,0.364,0.068c0.4,0,0.777-0.241,0.932-0.636c0.47-1.199,0.847-2.553,1.123-4.024   c0.102-0.542-0.256-1.064-0.799-1.167c-0.546-0.09-1.065,0.257-1.167,0.8c-0.252,1.348-0.595,2.58-1.019,3.663   C44.303,26.89,44.556,27.471,45.07,27.673z"
+       id="path9"
+       style="fill:#96928b;fill-opacity:1" /><path
+       d="M12.805,32.342c-1.207,0.757-2.295,1.705-3.235,2.82c-0.356,0.422-0.302,1.053,0.12,1.409   c0.188,0.158,0.417,0.235,0.644,0.235c0.285,0,0.567-0.121,0.765-0.355c0.806-0.956,1.737-1.769,2.768-2.414   c0.468-0.294,0.609-0.911,0.316-1.379C13.89,32.19,13.272,32.048,12.805,32.342z"
+       id="path11"
+       style="fill:#96928b;fill-opacity:1" /><path
+       d="M8.627,38.276c-0.502-0.23-1.096-0.013-1.327,0.489c-1.026,2.226-1.28,4.023-1.291,4.099   c-0.075,0.547,0.307,1.05,0.854,1.125c0.046,0.007,0.093,0.01,0.138,0.01c0.491,0,0.919-0.362,0.99-0.861   c0.002-0.016,0.231-1.597,1.125-3.534C9.347,39.101,9.128,38.508,8.627,38.276z"
+       id="path13"
+       style="fill:#96928b;fill-opacity:1" /><path
+       d="M40.423,33.729c0.153,0,0.309-0.035,0.454-0.109c1.292-0.661,2.431-1.599,3.384-2.786c0.346-0.431,0.277-1.061-0.154-1.406   c-0.43-0.343-1.06-0.276-1.406,0.154c-0.776,0.967-1.696,1.726-2.735,2.257c-0.492,0.252-0.687,0.854-0.435,1.346   C39.709,33.53,40.06,33.729,40.423,33.729z"
+       id="path15"
+       style="fill:#96928b;fill-opacity:1" /><path
+       d="M29.17,31.432c-0.441-0.185-0.699-0.313-0.716-0.322c-0.065-0.033-0.134-0.06-0.205-0.078   c-1.083-0.278-2.15-0.498-3.173-0.654c-0.545-0.086-1.056,0.291-1.14,0.837c-0.083,0.546,0.292,1.057,0.838,1.14   c0.926,0.142,1.893,0.34,2.877,0.59c0.134,0.064,0.39,0.185,0.748,0.334c0.126,0.053,0.257,0.077,0.385,0.077   c0.391,0,0.763-0.23,0.923-0.614C29.92,32.23,29.68,31.644,29.17,31.432z"
+       id="path17"
+       style="fill:#96928b;fill-opacity:1" /><path
+       d="M46.923,19.931c0.022,0.001,0.043,0.002,0.065,0.002c0.523,0,0.963-0.406,0.997-0.937c0.062-0.961,0.093-1.978,0.093-3.02   c0-0.347-0.003-0.699-0.01-1.058c-0.01-0.553-0.49-0.973-1.018-0.982c-0.552,0.01-0.992,0.466-0.982,1.018   c0.006,0.347,0.01,0.688,0.01,1.022c0,1-0.03,1.973-0.089,2.893C45.954,19.42,46.372,19.895,46.923,19.931z"
+       id="path19"
+       style="fill:#96928b;fill-opacity:1" /><path
+       d="M8.293,28.707C8.488,28.902,8.744,29,9,29s0.512-0.098,0.707-0.293L11,27.414l1.293,1.293C12.488,28.902,12.744,29,13,29   s0.512-0.098,0.707-0.293c0.391-0.391,0.391-1.023,0-1.414L12.414,26l1.293-1.293c0.391-0.391,0.391-1.023,0-1.414   s-1.023-0.391-1.414,0L11,24.586l-1.293-1.293c-0.391-0.391-1.023-0.391-1.414,0s-0.391,1.023,0,1.414L9.586,26l-1.293,1.293   C7.902,27.683,7.902,28.316,8.293,28.707z"
+       id="path21"
+       style="fill:#96928b;fill-opacity:1" /></g><g
+     id="g23"
+     style="fill:#96928b;fill-opacity:1;" /><g
+     id="g25"
+     style="fill:#96928b;fill-opacity:1;" /><g
+     id="g27"
+     style="fill:#96928b;fill-opacity:1;" /><g
+     id="g29"
+     style="fill:#96928b;fill-opacity:1;" /><g
+     id="g31"
+     style="fill:#96928b;fill-opacity:1;" /><g
+     id="g33"
+     style="fill:#96928b;fill-opacity:1;" /><g
+     id="g35"
+     style="fill:#96928b;fill-opacity:1;" /><g
+     id="g37"
+     style="fill:#96928b;fill-opacity:1;" /><g
+     id="g39"
+     style="fill:#96928b;fill-opacity:1;" /><g
+     id="g41"
+     style="fill:#96928b;fill-opacity:1;" /><g
+     id="g43"
+     style="fill:#96928b;fill-opacity:1;" /><g
+     id="g45"
+     style="fill:#96928b;fill-opacity:1;" /><g
+     id="g47"
+     style="fill:#96928b;fill-opacity:1;" /><g
+     id="g49"
+     style="fill:#96928b;fill-opacity:1;" /><g
+     id="g51"
+     style="fill:#96928b;fill-opacity:1;" /></svg>
\ No newline at end of file
diff --git a/src/edumed/static/img/menu/olimpiada/svg/program_active.svg b/src/edumed/static/img/menu/olimpiada/svg/program_active.svg
new file mode 100644 (file)
index 0000000..cf39f15
--- /dev/null
@@ -0,0 +1,104 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   version="1.1"
+   id="Capa_1"
+   x="0px"
+   y="0px"
+   viewBox="0 0 54 54"
+   style="enable-background:new 0 0 54 54;"
+   xml:space="preserve"
+   inkscape:version="0.48.4 r9939"
+   width="100%"
+   height="100%"
+   sodipodi:docname="program.svg"><metadata
+     id="metadata57"><rdf:RDF><cc:Work
+         rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
+     id="defs55" /><sodipodi:namedview
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1"
+     objecttolerance="10"
+     gridtolerance="10"
+     guidetolerance="10"
+     inkscape:pageopacity="0"
+     inkscape:pageshadow="2"
+     inkscape:window-width="769"
+     inkscape:window-height="480"
+     id="namedview53"
+     showgrid="false"
+     inkscape:zoom="4.3703704"
+     inkscape:cx="27"
+     inkscape:cy="27"
+     inkscape:window-x="0"
+     inkscape:window-y="24"
+     inkscape:window-maximized="0"
+     inkscape:current-layer="Capa_1" /><g
+     id="g3"
+     style="fill:#ed7831;fill-opacity:1"><path
+       d="M53.516,1.143c-0.3-0.182-0.674-0.19-0.983-0.027L36,9.869L19.468,1.116c-0.013-0.007-0.028-0.009-0.041-0.015   c-0.048-0.023-0.097-0.04-0.147-0.055c-0.028-0.008-0.055-0.017-0.083-0.023c-0.055-0.011-0.111-0.015-0.168-0.017   c-0.025-0.001-0.05-0.004-0.076-0.003c-0.054,0.003-0.107,0.013-0.16,0.025c-0.03,0.006-0.06,0.01-0.089,0.019   c-0.007,0.002-0.014,0.002-0.02,0.004l-18,6C0.275,7.187,0,7.569,0,8v43c0,0.321,0.154,0.623,0.416,0.812   C0.588,51.935,0.793,52,1,52c0.106,0,0.213-0.017,0.316-0.052l17.646-5.882l16.657,6.859c0.014,0.006,0.03,0.004,0.044,0.009   C35.773,52.973,35.885,53,36,53c0.09,0,0.179-0.015,0.266-0.039c0.028-0.008,0.054-0.021,0.082-0.031   c0.04-0.015,0.082-0.026,0.12-0.046l17-9C53.795,43.711,54,43.37,54,43V2C54,1.649,53.816,1.324,53.516,1.143z M2,8.721l16-5.333   v26.992c-0.43,0.078-0.854,0.166-1.264,0.274c-0.534,0.142-0.852,0.689-0.71,1.223c0.119,0.448,0.523,0.744,0.966,0.744   c0.084,0,0.171-0.011,0.257-0.033c0.24-0.064,0.502-0.096,0.751-0.148v11.84L2,49.612V8.721z M20,32.16   c0.321-0.025,0.632-0.066,0.961-0.073c0.552-0.012,0.99-0.469,0.979-1.021c-0.012-0.545-0.457-0.979-1-0.979   c-0.007,0-0.015,0-0.022,0c-0.31,0.007-0.615,0.024-0.918,0.045V3.661l15,7.941v21.194c-0.714-0.031-1.44-0.115-2.201-0.262   c-0.544-0.107-1.067,0.249-1.172,0.791s0.25,1.067,0.792,1.172c0.886,0.172,1.746,0.256,2.582,0.289v15.721L20,44.33V32.16z    M52,42.397l-15,7.941v-15.66c0.372-0.169,0.62-0.549,0.587-0.98c-0.029-0.374-0.269-0.674-0.587-0.821V11.602l15-7.941V42.397z"
+       id="path5"
+       style="fill:#ed7831;fill-opacity:1" /><path
+       d="M11,9c-2.757,0-5,2.243-5,5c0,2.415,1.721,4.434,4,4.899V21c0,0.553,0.448,1,1,1s1-0.447,1-1v-2.101   c2.279-0.465,4-2.484,4-4.899C16,11.243,13.757,9,11,9z M11,17c-1.654,0-3-1.346-3-3s1.346-3,3-3s3,1.346,3,3S12.654,17,11,17z"
+       id="path7"
+       style="fill:#ed7831;fill-opacity:1" /><path
+       d="M45.07,27.673c0.12,0.047,0.243,0.068,0.364,0.068c0.4,0,0.777-0.241,0.932-0.636c0.47-1.199,0.847-2.553,1.123-4.024   c0.102-0.542-0.256-1.064-0.799-1.167c-0.546-0.09-1.065,0.257-1.167,0.8c-0.252,1.348-0.595,2.58-1.019,3.663   C44.303,26.89,44.556,27.471,45.07,27.673z"
+       id="path9"
+       style="fill:#ed7831;fill-opacity:1" /><path
+       d="M12.805,32.342c-1.207,0.757-2.295,1.705-3.235,2.82c-0.356,0.422-0.302,1.053,0.12,1.409   c0.188,0.158,0.417,0.235,0.644,0.235c0.285,0,0.567-0.121,0.765-0.355c0.806-0.956,1.737-1.769,2.768-2.414   c0.468-0.294,0.609-0.911,0.316-1.379C13.89,32.19,13.272,32.048,12.805,32.342z"
+       id="path11"
+       style="fill:#ed7831;fill-opacity:1" /><path
+       d="M8.627,38.276c-0.502-0.23-1.096-0.013-1.327,0.489c-1.026,2.226-1.28,4.023-1.291,4.099   c-0.075,0.547,0.307,1.05,0.854,1.125c0.046,0.007,0.093,0.01,0.138,0.01c0.491,0,0.919-0.362,0.99-0.861   c0.002-0.016,0.231-1.597,1.125-3.534C9.347,39.101,9.128,38.508,8.627,38.276z"
+       id="path13"
+       style="fill:#ed7831;fill-opacity:1" /><path
+       d="M40.423,33.729c0.153,0,0.309-0.035,0.454-0.109c1.292-0.661,2.431-1.599,3.384-2.786c0.346-0.431,0.277-1.061-0.154-1.406   c-0.43-0.343-1.06-0.276-1.406,0.154c-0.776,0.967-1.696,1.726-2.735,2.257c-0.492,0.252-0.687,0.854-0.435,1.346   C39.709,33.53,40.06,33.729,40.423,33.729z"
+       id="path15"
+       style="fill:#ed7831;fill-opacity:1" /><path
+       d="M29.17,31.432c-0.441-0.185-0.699-0.313-0.716-0.322c-0.065-0.033-0.134-0.06-0.205-0.078   c-1.083-0.278-2.15-0.498-3.173-0.654c-0.545-0.086-1.056,0.291-1.14,0.837c-0.083,0.546,0.292,1.057,0.838,1.14   c0.926,0.142,1.893,0.34,2.877,0.59c0.134,0.064,0.39,0.185,0.748,0.334c0.126,0.053,0.257,0.077,0.385,0.077   c0.391,0,0.763-0.23,0.923-0.614C29.92,32.23,29.68,31.644,29.17,31.432z"
+       id="path17"
+       style="fill:#ed7831;fill-opacity:1" /><path
+       d="M46.923,19.931c0.022,0.001,0.043,0.002,0.065,0.002c0.523,0,0.963-0.406,0.997-0.937c0.062-0.961,0.093-1.978,0.093-3.02   c0-0.347-0.003-0.699-0.01-1.058c-0.01-0.553-0.49-0.973-1.018-0.982c-0.552,0.01-0.992,0.466-0.982,1.018   c0.006,0.347,0.01,0.688,0.01,1.022c0,1-0.03,1.973-0.089,2.893C45.954,19.42,46.372,19.895,46.923,19.931z"
+       id="path19"
+       style="fill:#ed7831;fill-opacity:1" /><path
+       d="M8.293,28.707C8.488,28.902,8.744,29,9,29s0.512-0.098,0.707-0.293L11,27.414l1.293,1.293C12.488,28.902,12.744,29,13,29   s0.512-0.098,0.707-0.293c0.391-0.391,0.391-1.023,0-1.414L12.414,26l1.293-1.293c0.391-0.391,0.391-1.023,0-1.414   s-1.023-0.391-1.414,0L11,24.586l-1.293-1.293c-0.391-0.391-1.023-0.391-1.414,0s-0.391,1.023,0,1.414L9.586,26l-1.293,1.293   C7.902,27.683,7.902,28.316,8.293,28.707z"
+       id="path21"
+       style="fill:#ed7831;fill-opacity:1" /></g><g
+     id="g23"
+     style="fill:#ed7831;fill-opacity:1" /><g
+     id="g25"
+     style="fill:#ed7831;fill-opacity:1" /><g
+     id="g27"
+     style="fill:#ed7831;fill-opacity:1" /><g
+     id="g29"
+     style="fill:#ed7831;fill-opacity:1" /><g
+     id="g31"
+     style="fill:#ed7831;fill-opacity:1" /><g
+     id="g33"
+     style="fill:#ed7831;fill-opacity:1" /><g
+     id="g35"
+     style="fill:#ed7831;fill-opacity:1" /><g
+     id="g37"
+     style="fill:#ed7831;fill-opacity:1" /><g
+     id="g39"
+     style="fill:#ed7831;fill-opacity:1" /><g
+     id="g41"
+     style="fill:#ed7831;fill-opacity:1" /><g
+     id="g43"
+     style="fill:#ed7831;fill-opacity:1" /><g
+     id="g45"
+     style="fill:#ed7831;fill-opacity:1" /><g
+     id="g47"
+     style="fill:#ed7831;fill-opacity:1" /><g
+     id="g49"
+     style="fill:#ed7831;fill-opacity:1" /><g
+     id="g51"
+     style="fill:#ed7831;fill-opacity:1" /></svg>
\ No newline at end of file
diff --git a/src/edumed/static/img/menu/olimpiada/svg/regulamin.svg b/src/edumed/static/img/menu/olimpiada/svg/regulamin.svg
new file mode 100644 (file)
index 0000000..61c274e
--- /dev/null
@@ -0,0 +1,98 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   version="1.1"
+   id="Capa_1"
+   x="0px"
+   y="0px"
+   viewBox="0 0 60 60"
+   style="enable-background:new 0 0 60 60;"
+   xml:space="preserve"
+   inkscape:version="0.48.4 r9939"
+   width="100%"
+   height="100%"
+   sodipodi:docname="regulamin.svg"><metadata
+     id="metadata53"><rdf:RDF><cc:Work
+         rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs
+     id="defs51" /><sodipodi:namedview
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1"
+     objecttolerance="10"
+     gridtolerance="10"
+     guidetolerance="10"
+     inkscape:pageopacity="0"
+     inkscape:pageshadow="2"
+     inkscape:window-width="769"
+     inkscape:window-height="480"
+     id="namedview49"
+     showgrid="false"
+     inkscape:zoom="3.9333333"
+     inkscape:cx="30"
+     inkscape:cy="30"
+     inkscape:window-x="0"
+     inkscape:window-y="24"
+     inkscape:window-maximized="0"
+     inkscape:current-layer="Capa_1" /><g
+     id="g3"
+     style="fill:#96928b;fill-opacity:1"><path
+       d="M38.914,0H6.5v60h47V14.586L38.914,0z M39.5,3.414L50.086,14H39.5V3.414z M8.5,58V2h29v14h14v42H8.5z"
+       id="path5"
+       style="fill:#96928b;fill-opacity:1" /><path
+       d="M42.5,21h-16c-0.552,0-1,0.447-1,1s0.448,1,1,1h16c0.552,0,1-0.447,1-1S43.052,21,42.5,21z"
+       id="path7"
+       style="fill:#96928b;fill-opacity:1" /><path
+       d="M22.875,18.219l-4.301,3.441l-1.367-1.367c-0.391-0.391-1.023-0.391-1.414,0s-0.391,1.023,0,1.414l2,2   C17.987,23.901,18.243,24,18.5,24c0.22,0,0.441-0.072,0.624-0.219l5-4c0.432-0.346,0.501-0.975,0.156-1.406   C23.936,17.943,23.306,17.874,22.875,18.219z"
+       id="path9"
+       style="fill:#96928b;fill-opacity:1" /><path
+       d="M42.5,32h-16c-0.552,0-1,0.447-1,1s0.448,1,1,1h16c0.552,0,1-0.447,1-1S43.052,32,42.5,32z"
+       id="path11"
+       style="fill:#96928b;fill-opacity:1" /><path
+       d="M22.875,29.219l-4.301,3.441l-1.367-1.367c-0.391-0.391-1.023-0.391-1.414,0s-0.391,1.023,0,1.414l2,2   C17.987,34.901,18.243,35,18.5,35c0.22,0,0.441-0.072,0.624-0.219l5-4c0.432-0.346,0.501-0.975,0.156-1.406   C23.936,28.943,23.306,28.874,22.875,29.219z"
+       id="path13"
+       style="fill:#96928b;fill-opacity:1" /><path
+       d="M42.5,43h-16c-0.552,0-1,0.447-1,1s0.448,1,1,1h16c0.552,0,1-0.447,1-1S43.052,43,42.5,43z"
+       id="path15"
+       style="fill:#96928b;fill-opacity:1" /><path
+       d="M22.875,40.219l-4.301,3.441l-1.367-1.367c-0.391-0.391-1.023-0.391-1.414,0s-0.391,1.023,0,1.414l2,2   C17.987,45.901,18.243,46,18.5,46c0.22,0,0.441-0.072,0.624-0.219l5-4c0.432-0.346,0.501-0.975,0.156-1.406   C23.936,39.943,23.306,39.874,22.875,40.219z"
+       id="path17"
+       style="fill:#96928b;fill-opacity:1" /></g><g
+     id="g19"
+     style="fill:#96928b;fill-opacity:1" /><g
+     id="g21"
+     style="fill:#96928b;fill-opacity:1" /><g
+     id="g23"
+     style="fill:#96928b;fill-opacity:1" /><g
+     id="g25"
+     style="fill:#96928b;fill-opacity:1" /><g
+     id="g27"
+     style="fill:#96928b;fill-opacity:1" /><g
+     id="g29"
+     style="fill:#96928b;fill-opacity:1" /><g
+     id="g31"
+     style="fill:#96928b;fill-opacity:1" /><g
+     id="g33"
+     style="fill:#96928b;fill-opacity:1" /><g
+     id="g35"
+     style="fill:#96928b;fill-opacity:1" /><g
+     id="g37"
+     style="fill:#96928b;fill-opacity:1" /><g
+     id="g39"
+     style="fill:#96928b;fill-opacity:1" /><g
+     id="g41"
+     style="fill:#96928b;fill-opacity:1" /><g
+     id="g43"
+     style="fill:#96928b;fill-opacity:1" /><g
+     id="g45"
+     style="fill:#96928b;fill-opacity:1" /><g
+     id="g47"
+     style="fill:#96928b;fill-opacity:1" /></svg>
\ No newline at end of file
diff --git a/src/edumed/static/img/menu/olimpiada/svg/regulamin_active.svg b/src/edumed/static/img/menu/olimpiada/svg/regulamin_active.svg
new file mode 100644 (file)
index 0000000..50f8f6d
--- /dev/null
@@ -0,0 +1,98 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   version="1.1"
+   id="Capa_1"
+   x="0px"
+   y="0px"
+   viewBox="0 0 60 60"
+   style="enable-background:new 0 0 60 60;"
+   xml:space="preserve"
+   inkscape:version="0.48.4 r9939"
+   width="100%"
+   height="100%"
+   sodipodi:docname="regulamin.svg"><metadata
+     id="metadata53"><rdf:RDF><cc:Work
+         rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
+     id="defs51" /><sodipodi:namedview
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1"
+     objecttolerance="10"
+     gridtolerance="10"
+     guidetolerance="10"
+     inkscape:pageopacity="0"
+     inkscape:pageshadow="2"
+     inkscape:window-width="769"
+     inkscape:window-height="480"
+     id="namedview49"
+     showgrid="false"
+     inkscape:zoom="3.9333333"
+     inkscape:cx="30"
+     inkscape:cy="30"
+     inkscape:window-x="0"
+     inkscape:window-y="24"
+     inkscape:window-maximized="0"
+     inkscape:current-layer="Capa_1" /><g
+     id="g3"
+     style="fill:#ed7831;fill-opacity:1"><path
+       d="M38.914,0H6.5v60h47V14.586L38.914,0z M39.5,3.414L50.086,14H39.5V3.414z M8.5,58V2h29v14h14v42H8.5z"
+       id="path5"
+       style="fill:#ed7831;fill-opacity:1" /><path
+       d="M42.5,21h-16c-0.552,0-1,0.447-1,1s0.448,1,1,1h16c0.552,0,1-0.447,1-1S43.052,21,42.5,21z"
+       id="path7"
+       style="fill:#ed7831;fill-opacity:1" /><path
+       d="M22.875,18.219l-4.301,3.441l-1.367-1.367c-0.391-0.391-1.023-0.391-1.414,0s-0.391,1.023,0,1.414l2,2   C17.987,23.901,18.243,24,18.5,24c0.22,0,0.441-0.072,0.624-0.219l5-4c0.432-0.346,0.501-0.975,0.156-1.406   C23.936,17.943,23.306,17.874,22.875,18.219z"
+       id="path9"
+       style="fill:#ed7831;fill-opacity:1" /><path
+       d="M42.5,32h-16c-0.552,0-1,0.447-1,1s0.448,1,1,1h16c0.552,0,1-0.447,1-1S43.052,32,42.5,32z"
+       id="path11"
+       style="fill:#ed7831;fill-opacity:1" /><path
+       d="M22.875,29.219l-4.301,3.441l-1.367-1.367c-0.391-0.391-1.023-0.391-1.414,0s-0.391,1.023,0,1.414l2,2   C17.987,34.901,18.243,35,18.5,35c0.22,0,0.441-0.072,0.624-0.219l5-4c0.432-0.346,0.501-0.975,0.156-1.406   C23.936,28.943,23.306,28.874,22.875,29.219z"
+       id="path13"
+       style="fill:#ed7831;fill-opacity:1" /><path
+       d="M42.5,43h-16c-0.552,0-1,0.447-1,1s0.448,1,1,1h16c0.552,0,1-0.447,1-1S43.052,43,42.5,43z"
+       id="path15"
+       style="fill:#ed7831;fill-opacity:1" /><path
+       d="M22.875,40.219l-4.301,3.441l-1.367-1.367c-0.391-0.391-1.023-0.391-1.414,0s-0.391,1.023,0,1.414l2,2   C17.987,45.901,18.243,46,18.5,46c0.22,0,0.441-0.072,0.624-0.219l5-4c0.432-0.346,0.501-0.975,0.156-1.406   C23.936,39.943,23.306,39.874,22.875,40.219z"
+       id="path17"
+       style="fill:#ed7831;fill-opacity:1" /></g><g
+     id="g19"
+     style="fill:#ed7831;fill-opacity:1" /><g
+     id="g21"
+     style="fill:#ed7831;fill-opacity:1" /><g
+     id="g23"
+     style="fill:#ed7831;fill-opacity:1" /><g
+     id="g25"
+     style="fill:#ed7831;fill-opacity:1" /><g
+     id="g27"
+     style="fill:#ed7831;fill-opacity:1" /><g
+     id="g29"
+     style="fill:#ed7831;fill-opacity:1" /><g
+     id="g31"
+     style="fill:#ed7831;fill-opacity:1" /><g
+     id="g33"
+     style="fill:#ed7831;fill-opacity:1" /><g
+     id="g35"
+     style="fill:#ed7831;fill-opacity:1" /><g
+     id="g37"
+     style="fill:#ed7831;fill-opacity:1" /><g
+     id="g39"
+     style="fill:#ed7831;fill-opacity:1" /><g
+     id="g41"
+     style="fill:#ed7831;fill-opacity:1" /><g
+     id="g43"
+     style="fill:#ed7831;fill-opacity:1" /><g
+     id="g45"
+     style="fill:#ed7831;fill-opacity:1" /><g
+     id="g47"
+     style="fill:#ed7831;fill-opacity:1" /></svg>
\ No newline at end of file
diff --git a/src/edumed/static/img/menu/olimpiada_active.png b/src/edumed/static/img/menu/olimpiada_active.png
new file mode 100644 (file)
index 0000000..8dce21b
Binary files /dev/null and b/src/edumed/static/img/menu/olimpiada_active.png differ
diff --git a/src/edumed/static/img/menu/svg/convert.txt b/src/edumed/static/img/menu/svg/convert.txt
new file mode 100644 (file)
index 0000000..ecf1788
--- /dev/null
@@ -0,0 +1 @@
+for f in *.svg; do convert -background none "$f" -resize 44x34 -gravity center -extent 44x34 png/"`basename \"$f\" .svg`.png"; done
diff --git a/src/edumed/static/img/menu/svg/dla-trenera.svg b/src/edumed/static/img/menu/svg/dla-trenera.svg
new file mode 100644 (file)
index 0000000..0f8622b
--- /dev/null
@@ -0,0 +1,69 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   version="1.1"
+   id="Capa_1"
+   x="0px"
+   y="0px"
+   width="757.671px"
+   height="757.671px"
+   viewBox="0 0 757.671 757.671"
+   style="enable-background:new 0 0 757.671 757.671;"
+   xml:space="preserve"
+   inkscape:version="0.91 r13725"
+   sodipodi:docname="dla trenera.svg"><metadata
+     id="metadata44"><rdf:RDF><cc:Work
+         rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
+     id="defs42" /><sodipodi:namedview
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1"
+     objecttolerance="10"
+     gridtolerance="10"
+     guidetolerance="10"
+     inkscape:pageopacity="0"
+     inkscape:pageshadow="2"
+     inkscape:window-width="711"
+     inkscape:window-height="480"
+     id="namedview40"
+     showgrid="false"
+     inkscape:zoom="0.31148083"
+     inkscape:cx="-117.18217"
+     inkscape:cy="378.83551"
+     inkscape:window-x="0"
+     inkscape:window-y="24"
+     inkscape:window-maximized="0"
+     inkscape:current-layer="Capa_1" /><g
+     id="g3"
+     style="fill:#96928b;fill-opacity:1"><g
+       id="Shape_13"
+       style="fill:#96928b;fill-opacity:1"><g
+         id="g6"
+         style="fill:#96928b;fill-opacity:1"><path
+           d="M583.68,495.079H451.693v-50.213c91.013-32.567,153.67-119.792,153.67-215.774C605.363,102.772,503.086,0,377.378,0     c-102.933,0-189.837,70.104-217.1,165.604c-0.044,0.087-0.131,0.146-0.161,0.233c-0.51,1.151-0.597,2.346-0.787,3.526     c-5.1,19.074-8.058,39.037-8.058,59.729c0,95.822,63.094,183.061,154.719,215.789v50.198h-133.27     c-53.215,0-99.887,45.623-99.887,97.629v150.377c0,8.058,6.528,14.586,14.571,14.586h582.857c8.043,0,14.571-6.528,14.571-14.586     V592.708C684.835,540.702,637.566,495.079,583.68,495.079z M377.378,29.172c78.481,0,146.282,46.06,178.602,112.608     c-0.524,0.117-1.049,0.015-1.559,0.189c-0.933,0.32-95.298,31.693-178.763,50.33c-64.202,14.338-152.257-16.349-184.139-28.851     C218.375,85.418,291.436,29.172,377.378,29.172z M655.693,728.499H101.979V592.708c0-36.473,33.062-68.457,70.744-68.457H320.55     c8.043,0,14.571-6.528,14.571-14.586v-75.319c0-6.412-4.196-12.08-10.316-13.945c-85.024-25.966-144.403-104.637-144.403-191.293     c0-12.736,1.297-25.15,3.555-37.215c29.522,11.467,93.752,33.325,154.545,33.325c14.892,0,29.594-1.326,43.51-4.43     c84.937-18.958,180.671-50.811,181.633-51.131c1.137-0.379,2.011-1.107,2.987-1.705c6.178,19.293,9.603,39.824,9.603,61.171     c0,86.846-58.941,165.503-143.354,191.294c-6.134,1.851-10.331,7.519-10.331,13.931v75.319c0,8.059,6.528,14.586,14.572,14.586     H583.68c37.682,0,72.013,32.626,72.013,68.457V728.499z"
+           id="path8"
+           style="fill:#96928b;fill-opacity:1" /></g></g></g><g
+     id="g10" /><g
+     id="g12" /><g
+     id="g14" /><g
+     id="g16" /><g
+     id="g18" /><g
+     id="g20" /><g
+     id="g22" /><g
+     id="g24" /><g
+     id="g26" /><g
+     id="g28" /><g
+     id="g30" /><g
+     id="g32" /><g
+     id="g34" /><g
+     id="g36" /><g
+     id="g38" /></svg>
\ No newline at end of file
diff --git a/src/edumed/static/img/menu/svg/dla-trenera_active.svg b/src/edumed/static/img/menu/svg/dla-trenera_active.svg
new file mode 100644 (file)
index 0000000..1dd32dc
--- /dev/null
@@ -0,0 +1,69 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   version="1.1"
+   id="Capa_1"
+   x="0px"
+   y="0px"
+   width="757.671px"
+   height="757.671px"
+   viewBox="0 0 757.671 757.671"
+   style="enable-background:new 0 0 757.671 757.671;"
+   xml:space="preserve"
+   inkscape:version="0.91 r13725"
+   sodipodi:docname="dla trenera.svg"><metadata
+     id="metadata44"><rdf:RDF><cc:Work
+         rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
+     id="defs42" /><sodipodi:namedview
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1"
+     objecttolerance="10"
+     gridtolerance="10"
+     guidetolerance="10"
+     inkscape:pageopacity="0"
+     inkscape:pageshadow="2"
+     inkscape:window-width="711"
+     inkscape:window-height="480"
+     id="namedview40"
+     showgrid="false"
+     inkscape:zoom="0.31148083"
+     inkscape:cx="-117.18217"
+     inkscape:cy="378.83551"
+     inkscape:window-x="0"
+     inkscape:window-y="24"
+     inkscape:window-maximized="0"
+     inkscape:current-layer="Capa_1" /><g
+     id="g3"
+     style="fill:#ed7831;fill-opacity:1"><g
+       id="Shape_13"
+       style="fill:#ed7831;fill-opacity:1"><g
+         id="g6"
+         style="fill:#ed7831;fill-opacity:1"><path
+           d="M583.68,495.079H451.693v-50.213c91.013-32.567,153.67-119.792,153.67-215.774C605.363,102.772,503.086,0,377.378,0     c-102.933,0-189.837,70.104-217.1,165.604c-0.044,0.087-0.131,0.146-0.161,0.233c-0.51,1.151-0.597,2.346-0.787,3.526     c-5.1,19.074-8.058,39.037-8.058,59.729c0,95.822,63.094,183.061,154.719,215.789v50.198h-133.27     c-53.215,0-99.887,45.623-99.887,97.629v150.377c0,8.058,6.528,14.586,14.571,14.586h582.857c8.043,0,14.571-6.528,14.571-14.586     V592.708C684.835,540.702,637.566,495.079,583.68,495.079z M377.378,29.172c78.481,0,146.282,46.06,178.602,112.608     c-0.524,0.117-1.049,0.015-1.559,0.189c-0.933,0.32-95.298,31.693-178.763,50.33c-64.202,14.338-152.257-16.349-184.139-28.851     C218.375,85.418,291.436,29.172,377.378,29.172z M655.693,728.499H101.979V592.708c0-36.473,33.062-68.457,70.744-68.457H320.55     c8.043,0,14.571-6.528,14.571-14.586v-75.319c0-6.412-4.196-12.08-10.316-13.945c-85.024-25.966-144.403-104.637-144.403-191.293     c0-12.736,1.297-25.15,3.555-37.215c29.522,11.467,93.752,33.325,154.545,33.325c14.892,0,29.594-1.326,43.51-4.43     c84.937-18.958,180.671-50.811,181.633-51.131c1.137-0.379,2.011-1.107,2.987-1.705c6.178,19.293,9.603,39.824,9.603,61.171     c0,86.846-58.941,165.503-143.354,191.294c-6.134,1.851-10.331,7.519-10.331,13.931v75.319c0,8.059,6.528,14.586,14.572,14.586     H583.68c37.682,0,72.013,32.626,72.013,68.457V728.499z"
+           id="path8"
+           style="fill:#ed7831;fill-opacity:1" /></g></g></g><g
+     id="g10" /><g
+     id="g12" /><g
+     id="g14" /><g
+     id="g16" /><g
+     id="g18" /><g
+     id="g20" /><g
+     id="g22" /><g
+     id="g24" /><g
+     id="g26" /><g
+     id="g28" /><g
+     id="g30" /><g
+     id="g32" /><g
+     id="g34" /><g
+     id="g36" /><g
+     id="g38" /></svg>
\ No newline at end of file
diff --git a/src/edumed/static/img/menu/svg/dla-ucznia.svg b/src/edumed/static/img/menu/svg/dla-ucznia.svg
new file mode 100644 (file)
index 0000000..22162b8
--- /dev/null
@@ -0,0 +1,72 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   version="1.1"
+   id="Capa_1"
+   x="0px"
+   y="0px"
+   viewBox="0 0 470 470"
+   style="enable-background:new 0 0 470 470;"
+   xml:space="preserve"
+   inkscape:version="0.91 r13725"
+   sodipodi:docname="dla ucznia.svg"><metadata
+     id="metadata47"><rdf:RDF><cc:Work
+         rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs
+     id="defs45" /><sodipodi:namedview
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1"
+     objecttolerance="10"
+     gridtolerance="10"
+     guidetolerance="10"
+     inkscape:pageopacity="0"
+     inkscape:pageshadow="2"
+     inkscape:window-width="711"
+     inkscape:window-height="480"
+     id="namedview43"
+     showgrid="false"
+     inkscape:zoom="0.50212766"
+     inkscape:cx="235"
+     inkscape:cy="235"
+     inkscape:window-x="102"
+     inkscape:window-y="144"
+     inkscape:window-maximized="0"
+     inkscape:current-layer="Capa_1" /><g
+     id="g3"
+     style="fill-opacity:1;fill:#96928b"><path
+       d="M107.5,15h60.021v69.559c-2.525,7.419-3.771,14.829-3.771,22.606c0,39.287,31.962,71.25,71.25,71.25   c39.287,0,71.25-31.963,71.25-71.25c0-7.778-1.246-15.188-3.771-22.608V15H340v90.674l-7.675,18.53   c-1.586,3.827,0.231,8.214,4.059,9.799c3.827,1.589,8.214-0.231,9.799-4.059l1.317-3.18l1.317,3.18   c1.196,2.889,3.988,4.632,6.932,4.632c0.956,0,1.929-0.185,2.867-0.573c3.827-1.585,5.645-5.972,4.059-9.799L355,105.674V15h7.5   c4.143,0,7.5-3.357,7.5-7.5S366.643,0,362.5,0h-255c-4.142,0-7.5,3.357-7.5,7.5S103.358,15,107.5,15z M235,163.415   c-31.016,0-56.25-25.233-56.25-56.25c0-5.524,0.8-10.822,2.424-16.11c6.048-2.862,12.801-4.365,19.7-4.365   c10.687,0,21.103,3.77,29.329,10.614c1.39,1.157,3.094,1.735,4.797,1.735c1.704,0,3.407-0.578,4.798-1.735   c8.225-6.845,18.641-10.614,29.328-10.614c6.9,0,13.652,1.503,19.7,4.365c1.624,5.288,2.424,10.585,2.424,16.11   C291.25,138.182,266.017,163.415,235,163.415z M287.479,74.469c-5.879-1.832-12.077-2.779-18.353-2.779   c-12.18,0-24.093,3.688-34.126,10.479c-10.034-6.792-21.947-10.479-34.126-10.479c-6.275,0-12.473,0.947-18.353,2.779V15h104.958   V74.469z"
+       id="path5"
+       style="fill-opacity:1;fill:#96928b" /><path
+       d="M462.5,320.915h-92.712c-2.487-45.183-27.294-84.51-63.555-107.126c-0.456-0.363-0.945-0.661-1.455-0.903   c-20.375-12.353-44.261-19.471-69.778-19.471s-49.403,7.118-69.779,19.471c-0.509,0.242-0.998,0.539-1.453,0.902   c-36.262,22.616-61.07,61.943-63.557,107.127H7.5c-4.142,0-7.5,3.357-7.5,7.5s3.358,7.5,7.5,7.5h23.039l9.482,127.143   c0.293,3.941,3.582,6.942,7.471,6.942c0.187,0,0.376-0.007,0.565-0.021c4.131-0.309,7.229-3.906,6.921-8.037L45.58,335.915h378.84   l-9.399,126.027c-0.308,4.131,2.791,7.729,6.922,8.037c0.189,0.014,0.378,0.021,0.565,0.021c3.889,0,7.178-3.001,7.472-6.942   l9.482-127.143H462.5c4.143,0,7.5-3.357,7.5-7.5S466.643,320.915,462.5,320.915z M235,239.172c-4.142,0-7.5,3.357-7.5,7.5v21.437   l-46.724-46.725c14.19-7.218,29.999-11.691,46.724-12.728v8.016c0,4.143,3.358,7.5,7.5,7.5c4.143,0,7.5-3.357,7.5-7.5v-8.016   c16.725,1.037,32.533,5.509,46.724,12.728L242.5,268.108v-21.437C242.5,242.529,239.143,239.172,235,239.172z M167.459,229.28   l62.238,62.238c0.2,0.194,0.371,0.35,0.55,0.497c0.087,0.071,0.178,0.133,0.267,0.199c0.107,0.08,0.212,0.163,0.323,0.237   c0.105,0.071,0.215,0.131,0.323,0.196c0.102,0.061,0.202,0.125,0.307,0.182c0.11,0.059,0.223,0.108,0.336,0.162   c0.109,0.052,0.217,0.106,0.329,0.152c0.11,0.045,0.222,0.082,0.333,0.122c0.12,0.043,0.238,0.089,0.36,0.126   c0.111,0.033,0.223,0.058,0.335,0.086c0.125,0.032,0.249,0.067,0.377,0.092c0.129,0.025,0.26,0.041,0.39,0.06   c0.112,0.016,0.221,0.037,0.334,0.048c0.246,0.024,0.493,0.037,0.74,0.037c0.247,0,0.494-0.013,0.74-0.037   c0.115-0.011,0.226-0.033,0.339-0.049c0.129-0.019,0.257-0.033,0.385-0.059c0.13-0.026,0.257-0.062,0.385-0.094   c0.109-0.027,0.219-0.051,0.326-0.084c0.125-0.038,0.247-0.084,0.369-0.129c0.108-0.039,0.217-0.074,0.324-0.118   c0.115-0.048,0.226-0.104,0.338-0.157c0.109-0.052,0.22-0.1,0.328-0.157c0.107-0.058,0.208-0.123,0.312-0.185   c0.107-0.064,0.215-0.124,0.319-0.193c0.111-0.074,0.214-0.156,0.321-0.236c0.09-0.067,0.182-0.13,0.27-0.202   c0.162-0.133,0.316-0.275,0.466-0.421c0.027-0.026,0.056-0.048,0.083-0.075l62.238-62.238   c29.708,20.304,49.859,53.598,52.217,91.634H115.241C117.599,282.878,137.751,249.585,167.459,229.28z"
+       id="path7"
+       style="fill-opacity:1;fill:#96928b" /><path
+       d="M159.737,360.916h-30c-4.142,0-7.5,3.357-7.5,7.5c0,22.175-16.638,40.368-38.701,42.32   c-4.086,0.361-7.124,3.938-6.818,8.028l3.303,44.293c0.293,3.941,3.582,6.943,7.471,6.942c0.187,0,0.376-0.007,0.565-0.021   c4.131-0.309,7.229-3.906,6.921-8.037l-2.789-37.394c11.417-2.521,21.831-8.484,29.866-17.214   c8.082-8.778,13.166-19.729,14.694-31.419h22.987c4.142,0,7.5-3.357,7.5-7.5S163.879,360.916,159.737,360.916z"
+       id="path9"
+       style="fill-opacity:1;fill:#96928b" /><path
+       d="M386.465,410.736c-22.064-1.952-38.702-20.146-38.702-42.32c0-4.143-3.357-7.5-7.5-7.5H189.737c-4.142,0-7.5,3.357-7.5,7.5   s3.358,7.5,7.5,7.5H333.25c1.528,11.69,6.612,22.641,14.693,31.42c8.035,8.729,18.449,14.691,29.866,17.213l-2.789,37.394   c-0.308,4.131,2.791,7.729,6.922,8.037c0.189,0.014,0.378,0.021,0.565,0.021c3.889,0,7.178-3.001,7.472-6.942l3.304-44.293   C393.588,414.675,390.551,411.098,386.465,410.736z"
+       id="path11"
+       style="fill-opacity:1;fill:#96928b" /></g><g
+     id="g13" /><g
+     id="g15" /><g
+     id="g17" /><g
+     id="g19" /><g
+     id="g21" /><g
+     id="g23" /><g
+     id="g25" /><g
+     id="g27" /><g
+     id="g29" /><g
+     id="g31" /><g
+     id="g33" /><g
+     id="g35" /><g
+     id="g37" /><g
+     id="g39" /><g
+     id="g41" /></svg>
\ No newline at end of file
diff --git a/src/edumed/static/img/menu/svg/dla-ucznia_active.svg b/src/edumed/static/img/menu/svg/dla-ucznia_active.svg
new file mode 100644 (file)
index 0000000..5a46fe0
--- /dev/null
@@ -0,0 +1,72 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   version="1.1"
+   id="Capa_1"
+   x="0px"
+   y="0px"
+   viewBox="0 0 470 470"
+   style="enable-background:new 0 0 470 470;"
+   xml:space="preserve"
+   inkscape:version="0.91 r13725"
+   sodipodi:docname="dla ucznia.svg"><metadata
+     id="metadata47"><rdf:RDF><cc:Work
+         rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs
+     id="defs45" /><sodipodi:namedview
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1"
+     objecttolerance="10"
+     gridtolerance="10"
+     guidetolerance="10"
+     inkscape:pageopacity="0"
+     inkscape:pageshadow="2"
+     inkscape:window-width="711"
+     inkscape:window-height="480"
+     id="namedview43"
+     showgrid="false"
+     inkscape:zoom="0.50212766"
+     inkscape:cx="235"
+     inkscape:cy="235"
+     inkscape:window-x="102"
+     inkscape:window-y="144"
+     inkscape:window-maximized="0"
+     inkscape:current-layer="Capa_1" /><g
+     id="g3"
+     style="fill-opacity:1;fill:#ed7831"><path
+       d="M107.5,15h60.021v69.559c-2.525,7.419-3.771,14.829-3.771,22.606c0,39.287,31.962,71.25,71.25,71.25   c39.287,0,71.25-31.963,71.25-71.25c0-7.778-1.246-15.188-3.771-22.608V15H340v90.674l-7.675,18.53   c-1.586,3.827,0.231,8.214,4.059,9.799c3.827,1.589,8.214-0.231,9.799-4.059l1.317-3.18l1.317,3.18   c1.196,2.889,3.988,4.632,6.932,4.632c0.956,0,1.929-0.185,2.867-0.573c3.827-1.585,5.645-5.972,4.059-9.799L355,105.674V15h7.5   c4.143,0,7.5-3.357,7.5-7.5S366.643,0,362.5,0h-255c-4.142,0-7.5,3.357-7.5,7.5S103.358,15,107.5,15z M235,163.415   c-31.016,0-56.25-25.233-56.25-56.25c0-5.524,0.8-10.822,2.424-16.11c6.048-2.862,12.801-4.365,19.7-4.365   c10.687,0,21.103,3.77,29.329,10.614c1.39,1.157,3.094,1.735,4.797,1.735c1.704,0,3.407-0.578,4.798-1.735   c8.225-6.845,18.641-10.614,29.328-10.614c6.9,0,13.652,1.503,19.7,4.365c1.624,5.288,2.424,10.585,2.424,16.11   C291.25,138.182,266.017,163.415,235,163.415z M287.479,74.469c-5.879-1.832-12.077-2.779-18.353-2.779   c-12.18,0-24.093,3.688-34.126,10.479c-10.034-6.792-21.947-10.479-34.126-10.479c-6.275,0-12.473,0.947-18.353,2.779V15h104.958   V74.469z"
+       id="path5"
+       style="fill-opacity:1;fill:#ed7831" /><path
+       d="M462.5,320.915h-92.712c-2.487-45.183-27.294-84.51-63.555-107.126c-0.456-0.363-0.945-0.661-1.455-0.903   c-20.375-12.353-44.261-19.471-69.778-19.471s-49.403,7.118-69.779,19.471c-0.509,0.242-0.998,0.539-1.453,0.902   c-36.262,22.616-61.07,61.943-63.557,107.127H7.5c-4.142,0-7.5,3.357-7.5,7.5s3.358,7.5,7.5,7.5h23.039l9.482,127.143   c0.293,3.941,3.582,6.942,7.471,6.942c0.187,0,0.376-0.007,0.565-0.021c4.131-0.309,7.229-3.906,6.921-8.037L45.58,335.915h378.84   l-9.399,126.027c-0.308,4.131,2.791,7.729,6.922,8.037c0.189,0.014,0.378,0.021,0.565,0.021c3.889,0,7.178-3.001,7.472-6.942   l9.482-127.143H462.5c4.143,0,7.5-3.357,7.5-7.5S466.643,320.915,462.5,320.915z M235,239.172c-4.142,0-7.5,3.357-7.5,7.5v21.437   l-46.724-46.725c14.19-7.218,29.999-11.691,46.724-12.728v8.016c0,4.143,3.358,7.5,7.5,7.5c4.143,0,7.5-3.357,7.5-7.5v-8.016   c16.725,1.037,32.533,5.509,46.724,12.728L242.5,268.108v-21.437C242.5,242.529,239.143,239.172,235,239.172z M167.459,229.28   l62.238,62.238c0.2,0.194,0.371,0.35,0.55,0.497c0.087,0.071,0.178,0.133,0.267,0.199c0.107,0.08,0.212,0.163,0.323,0.237   c0.105,0.071,0.215,0.131,0.323,0.196c0.102,0.061,0.202,0.125,0.307,0.182c0.11,0.059,0.223,0.108,0.336,0.162   c0.109,0.052,0.217,0.106,0.329,0.152c0.11,0.045,0.222,0.082,0.333,0.122c0.12,0.043,0.238,0.089,0.36,0.126   c0.111,0.033,0.223,0.058,0.335,0.086c0.125,0.032,0.249,0.067,0.377,0.092c0.129,0.025,0.26,0.041,0.39,0.06   c0.112,0.016,0.221,0.037,0.334,0.048c0.246,0.024,0.493,0.037,0.74,0.037c0.247,0,0.494-0.013,0.74-0.037   c0.115-0.011,0.226-0.033,0.339-0.049c0.129-0.019,0.257-0.033,0.385-0.059c0.13-0.026,0.257-0.062,0.385-0.094   c0.109-0.027,0.219-0.051,0.326-0.084c0.125-0.038,0.247-0.084,0.369-0.129c0.108-0.039,0.217-0.074,0.324-0.118   c0.115-0.048,0.226-0.104,0.338-0.157c0.109-0.052,0.22-0.1,0.328-0.157c0.107-0.058,0.208-0.123,0.312-0.185   c0.107-0.064,0.215-0.124,0.319-0.193c0.111-0.074,0.214-0.156,0.321-0.236c0.09-0.067,0.182-0.13,0.27-0.202   c0.162-0.133,0.316-0.275,0.466-0.421c0.027-0.026,0.056-0.048,0.083-0.075l62.238-62.238   c29.708,20.304,49.859,53.598,52.217,91.634H115.241C117.599,282.878,137.751,249.585,167.459,229.28z"
+       id="path7"
+       style="fill-opacity:1;fill:#ed7831" /><path
+       d="M159.737,360.916h-30c-4.142,0-7.5,3.357-7.5,7.5c0,22.175-16.638,40.368-38.701,42.32   c-4.086,0.361-7.124,3.938-6.818,8.028l3.303,44.293c0.293,3.941,3.582,6.943,7.471,6.942c0.187,0,0.376-0.007,0.565-0.021   c4.131-0.309,7.229-3.906,6.921-8.037l-2.789-37.394c11.417-2.521,21.831-8.484,29.866-17.214   c8.082-8.778,13.166-19.729,14.694-31.419h22.987c4.142,0,7.5-3.357,7.5-7.5S163.879,360.916,159.737,360.916z"
+       id="path9"
+       style="fill-opacity:1;fill:#ed7831" /><path
+       d="M386.465,410.736c-22.064-1.952-38.702-20.146-38.702-42.32c0-4.143-3.357-7.5-7.5-7.5H189.737c-4.142,0-7.5,3.357-7.5,7.5   s3.358,7.5,7.5,7.5H333.25c1.528,11.69,6.612,22.641,14.693,31.42c8.035,8.729,18.449,14.691,29.866,17.213l-2.789,37.394   c-0.308,4.131,2.791,7.729,6.922,8.037c0.189,0.014,0.378,0.021,0.565,0.021c3.889,0,7.178-3.001,7.472-6.942l3.304-44.293   C393.588,414.675,390.551,411.098,386.465,410.736z"
+       id="path11"
+       style="fill-opacity:1;fill:#ed7831" /></g><g
+     id="g13" /><g
+     id="g15" /><g
+     id="g17" /><g
+     id="g19" /><g
+     id="g21" /><g
+     id="g23" /><g
+     id="g25" /><g
+     id="g27" /><g
+     id="g29" /><g
+     id="g31" /><g
+     id="g33" /><g
+     id="g35" /><g
+     id="g37" /><g
+     id="g39" /><g
+     id="g41" /></svg>
\ No newline at end of file
diff --git a/src/edumed/static/img/menu/svg/kompetencje.svg b/src/edumed/static/img/menu/svg/kompetencje.svg
new file mode 100644 (file)
index 0000000..754b6f4
--- /dev/null
@@ -0,0 +1,76 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Generator: Adobe Illustrator 17.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   version="1.1"
+   id="Capa_1"
+   x="0px"
+   y="0px"
+   viewBox="0 0 455 455"
+   style="enable-background:new 0 0 455 455;"
+   xml:space="preserve"
+   inkscape:version="0.91 r13725"
+   sodipodi:docname="kompetencje.svg"><metadata
+     id="metadata43"><rdf:RDF><cc:Work
+         rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs
+     id="defs41"><filter
+       inkscape:collect="always"
+       style="color-interpolation-filters:sRGB"
+       id="filter4183"
+       x="-2.8610229e-09"
+       width="1"
+       y="-2.8610229e-09"
+       height="1"><feGaussianBlur
+         inkscape:collect="always"
+         stdDeviation="5.4240227e-07"
+         id="feGaussianBlur4185" /></filter></defs><sodipodi:namedview
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1"
+     objecttolerance="10"
+     gridtolerance="10"
+     guidetolerance="10"
+     inkscape:pageopacity="0"
+     inkscape:pageshadow="2"
+     inkscape:window-width="711"
+     inkscape:window-height="480"
+     id="namedview39"
+     showgrid="false"
+     inkscape:zoom="0.51868132"
+     inkscape:cx="227.5"
+     inkscape:cy="227.5"
+     inkscape:window-x="0"
+     inkscape:window-y="24"
+     inkscape:window-maximized="0"
+     inkscape:current-layer="Capa_1" /><g
+     id="g3"
+     style="fill:#96928b;fill-opacity:1;filter:url(#filter4183)"><path
+       d="M388.367,66.633C345.397,23.664,288.268,0,227.5,0S109.603,23.664,66.633,66.633C23.664,109.602,0,166.732,0,227.5   s23.664,117.897,66.633,160.867C109.603,431.336,166.732,455,227.5,455s117.897-23.664,160.867-66.633   C431.336,345.397,455,288.268,455,227.5S431.336,109.602,388.367,66.633z M227.5,440C110.327,440,15,344.673,15,227.5   S110.327,15,227.5,15S440,110.327,440,227.5S344.673,440,227.5,440z"
+       id="path5"
+       style="fill:#96928b;fill-opacity:1" /><path
+       d="M408.47,287.517c-18.08-8.265-40.271-15.036-65.283-20.114C344.382,254.329,345,240.979,345,227.5   s-0.618-26.829-1.813-39.904c25.012-5.077,47.203-11.849,65.283-20.114c3.767-1.722,5.425-6.172,3.703-9.939   c-1.723-3.767-6.17-5.425-9.939-3.703c-16.541,7.561-37.264,13.873-60.703,18.693c-3.177-24.893-8.47-48.544-15.617-69.895   c9.22-4.434,18.175-9.499,26.797-15.195c3.456-2.283,4.407-6.936,2.124-10.392s-6.937-4.407-10.392-2.124   c-7.634,5.043-15.545,9.563-23.684,13.548c-6.54-16.612-14.271-31.532-23.066-44.147c-2.368-3.397-7.043-4.233-10.441-1.864   c-3.397,2.369-4.232,7.043-1.863,10.441c8.268,11.861,15.541,25.944,21.696,41.67c-22.829,9.232-47.17,14.423-72.084,15.291V37.5   c0-4.142-3.357-7.5-7.5-7.5s-7.5,3.358-7.5,7.5v72.367c-24.914-0.868-49.255-6.059-72.084-15.291   c6.155-15.726,13.428-29.808,21.696-41.67c2.369-3.398,1.534-8.073-1.863-10.441c-3.399-2.369-8.073-1.534-10.441,1.864   c-8.794,12.615-16.526,27.534-23.066,44.147c-8.139-3.984-16.05-8.504-23.684-13.548c-3.455-2.283-8.108-1.332-10.392,2.124   c-2.283,3.456-1.332,8.109,2.124,10.392c8.622,5.696,17.577,10.762,26.797,15.195c-7.147,21.352-12.44,45.002-15.617,69.895   c-23.439-4.82-44.162-11.132-60.703-18.693c-3.767-1.722-8.218-0.064-9.939,3.703s-0.063,8.217,3.703,9.939   c18.08,8.265,40.271,15.036,65.283,20.114C110.618,200.671,110,214.021,110,227.5s0.618,26.829,1.813,39.904   c-25.012,5.077-47.203,11.849-65.283,20.114c-3.767,1.722-5.425,6.172-3.703,9.939c1.723,3.767,6.172,5.426,9.939,3.703   c16.541-7.561,37.264-13.873,60.703-18.693c3.177,24.893,8.47,48.544,15.617,69.895c-9.22,4.434-18.174,9.499-26.797,15.195   c-3.456,2.283-4.407,6.936-2.124,10.392c2.282,3.456,6.936,4.407,10.392,2.124c7.634-5.043,15.545-9.563,23.684-13.548   c6.54,16.613,14.271,31.532,23.066,44.147c1.458,2.091,3.789,3.211,6.159,3.211c1.479,0,2.976-0.437,4.282-1.348   c3.397-2.369,4.232-7.043,1.863-10.442c-8.268-11.862-15.541-25.944-21.696-41.67c22.829-9.232,47.17-14.423,72.084-15.291V417.5   c0,4.142,3.357,7.5,7.5,7.5s7.5-3.358,7.5-7.5v-72.367c24.914,0.868,49.255,6.059,72.084,15.291   c-6.155,15.726-13.428,29.808-21.696,41.67c-2.369,3.398-1.534,8.073,1.863,10.442c1.307,0.911,2.802,1.348,4.282,1.348   c2.37,0,4.701-1.12,6.159-3.211c8.794-12.615,16.526-27.535,23.066-44.147c8.139,3.984,16.05,8.504,23.684,13.548   c1.272,0.841,2.708,1.243,4.127,1.243c2.435,0,4.822-1.184,6.265-3.367c2.283-3.456,1.332-8.109-2.124-10.392   c-8.623-5.696-17.577-10.761-26.797-15.195c7.147-21.352,12.44-45.002,15.617-69.895c23.439,4.82,44.162,11.132,60.703,18.693   c1.011,0.462,2.07,0.681,3.113,0.681c2.845,0,5.566-1.627,6.826-4.384C413.895,293.689,412.236,289.239,408.47,287.517z M330,227.5   c0,12.557-0.556,24.979-1.62,37.147c-28.573-4.837-60.255-7.576-93.38-7.936V198.29c33.125-0.36,64.807-3.1,93.38-7.936   C329.444,202.521,330,214.943,330,227.5z M312.169,108.701c6.696,20.307,11.653,42.838,14.616,66.603   c-28.137,4.822-59.465,7.607-91.785,7.981v-58.414C261.662,124.004,287.719,118.516,312.169,108.701z M142.831,108.701   c24.45,9.815,50.507,15.302,77.169,16.171v58.414c-32.32-0.374-63.648-3.159-91.785-7.981   C131.179,151.539,136.136,129.008,142.831,108.701z M125,227.5c0-12.557,0.556-24.979,1.62-37.147   c28.573,4.837,60.255,7.576,93.38,7.936v58.421c-33.125,0.36-64.807,3.1-93.38,7.936C125.556,252.479,125,240.057,125,227.5z    M142.832,346.299c-6.696-20.307-11.653-42.838-14.617-66.603c28.137-4.822,59.465-7.607,91.785-7.981v58.414   C193.338,330.996,167.281,336.484,142.832,346.299z M312.168,346.299c-24.449-9.815-50.507-15.302-77.168-16.171v-58.414   c32.32,0.374,63.648,3.159,91.785,7.981C323.821,303.461,318.864,325.992,312.168,346.299z"
+       id="path7"
+       style="fill:#96928b;fill-opacity:1" /></g><g
+     id="g9" /><g
+     id="g11" /><g
+     id="g13" /><g
+     id="g15" /><g
+     id="g17" /><g
+     id="g19" /><g
+     id="g21" /><g
+     id="g23" /><g
+     id="g25" /><g
+     id="g27" /><g
+     id="g29" /><g
+     id="g31" /><g
+     id="g33" /><g
+     id="g35" /><g
+     id="g37" /></svg>
\ No newline at end of file
diff --git a/src/edumed/static/img/menu/svg/kompetencje_active.svg b/src/edumed/static/img/menu/svg/kompetencje_active.svg
new file mode 100644 (file)
index 0000000..fa61ac2
--- /dev/null
@@ -0,0 +1,76 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Generator: Adobe Illustrator 17.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   version="1.1"
+   id="Capa_1"
+   x="0px"
+   y="0px"
+   viewBox="0 0 455 455"
+   style="enable-background:new 0 0 455 455;"
+   xml:space="preserve"
+   inkscape:version="0.91 r13725"
+   sodipodi:docname="kompetencje.svg"><metadata
+     id="metadata43"><rdf:RDF><cc:Work
+         rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs
+     id="defs41"><filter
+       inkscape:collect="always"
+       style="color-interpolation-filters:sRGB"
+       id="filter4183"
+       x="-2.8610229e-09"
+       width="1"
+       y="-2.8610229e-09"
+       height="1"><feGaussianBlur
+         inkscape:collect="always"
+         stdDeviation="5.4240227e-07"
+         id="feGaussianBlur4185" /></filter></defs><sodipodi:namedview
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1"
+     objecttolerance="10"
+     gridtolerance="10"
+     guidetolerance="10"
+     inkscape:pageopacity="0"
+     inkscape:pageshadow="2"
+     inkscape:window-width="711"
+     inkscape:window-height="480"
+     id="namedview39"
+     showgrid="false"
+     inkscape:zoom="0.51868132"
+     inkscape:cx="227.5"
+     inkscape:cy="227.5"
+     inkscape:window-x="0"
+     inkscape:window-y="24"
+     inkscape:window-maximized="0"
+     inkscape:current-layer="Capa_1" /><g
+     id="g3"
+     style="fill:#ed7831;fill-opacity:1;filter:url(#filter4183)"><path
+       d="M388.367,66.633C345.397,23.664,288.268,0,227.5,0S109.603,23.664,66.633,66.633C23.664,109.602,0,166.732,0,227.5   s23.664,117.897,66.633,160.867C109.603,431.336,166.732,455,227.5,455s117.897-23.664,160.867-66.633   C431.336,345.397,455,288.268,455,227.5S431.336,109.602,388.367,66.633z M227.5,440C110.327,440,15,344.673,15,227.5   S110.327,15,227.5,15S440,110.327,440,227.5S344.673,440,227.5,440z"
+       id="path5"
+       style="fill:#ed7831;fill-opacity:1" /><path
+       d="M408.47,287.517c-18.08-8.265-40.271-15.036-65.283-20.114C344.382,254.329,345,240.979,345,227.5   s-0.618-26.829-1.813-39.904c25.012-5.077,47.203-11.849,65.283-20.114c3.767-1.722,5.425-6.172,3.703-9.939   c-1.723-3.767-6.17-5.425-9.939-3.703c-16.541,7.561-37.264,13.873-60.703,18.693c-3.177-24.893-8.47-48.544-15.617-69.895   c9.22-4.434,18.175-9.499,26.797-15.195c3.456-2.283,4.407-6.936,2.124-10.392s-6.937-4.407-10.392-2.124   c-7.634,5.043-15.545,9.563-23.684,13.548c-6.54-16.612-14.271-31.532-23.066-44.147c-2.368-3.397-7.043-4.233-10.441-1.864   c-3.397,2.369-4.232,7.043-1.863,10.441c8.268,11.861,15.541,25.944,21.696,41.67c-22.829,9.232-47.17,14.423-72.084,15.291V37.5   c0-4.142-3.357-7.5-7.5-7.5s-7.5,3.358-7.5,7.5v72.367c-24.914-0.868-49.255-6.059-72.084-15.291   c6.155-15.726,13.428-29.808,21.696-41.67c2.369-3.398,1.534-8.073-1.863-10.441c-3.399-2.369-8.073-1.534-10.441,1.864   c-8.794,12.615-16.526,27.534-23.066,44.147c-8.139-3.984-16.05-8.504-23.684-13.548c-3.455-2.283-8.108-1.332-10.392,2.124   c-2.283,3.456-1.332,8.109,2.124,10.392c8.622,5.696,17.577,10.762,26.797,15.195c-7.147,21.352-12.44,45.002-15.617,69.895   c-23.439-4.82-44.162-11.132-60.703-18.693c-3.767-1.722-8.218-0.064-9.939,3.703s-0.063,8.217,3.703,9.939   c18.08,8.265,40.271,15.036,65.283,20.114C110.618,200.671,110,214.021,110,227.5s0.618,26.829,1.813,39.904   c-25.012,5.077-47.203,11.849-65.283,20.114c-3.767,1.722-5.425,6.172-3.703,9.939c1.723,3.767,6.172,5.426,9.939,3.703   c16.541-7.561,37.264-13.873,60.703-18.693c3.177,24.893,8.47,48.544,15.617,69.895c-9.22,4.434-18.174,9.499-26.797,15.195   c-3.456,2.283-4.407,6.936-2.124,10.392c2.282,3.456,6.936,4.407,10.392,2.124c7.634-5.043,15.545-9.563,23.684-13.548   c6.54,16.613,14.271,31.532,23.066,44.147c1.458,2.091,3.789,3.211,6.159,3.211c1.479,0,2.976-0.437,4.282-1.348   c3.397-2.369,4.232-7.043,1.863-10.442c-8.268-11.862-15.541-25.944-21.696-41.67c22.829-9.232,47.17-14.423,72.084-15.291V417.5   c0,4.142,3.357,7.5,7.5,7.5s7.5-3.358,7.5-7.5v-72.367c24.914,0.868,49.255,6.059,72.084,15.291   c-6.155,15.726-13.428,29.808-21.696,41.67c-2.369,3.398-1.534,8.073,1.863,10.442c1.307,0.911,2.802,1.348,4.282,1.348   c2.37,0,4.701-1.12,6.159-3.211c8.794-12.615,16.526-27.535,23.066-44.147c8.139,3.984,16.05,8.504,23.684,13.548   c1.272,0.841,2.708,1.243,4.127,1.243c2.435,0,4.822-1.184,6.265-3.367c2.283-3.456,1.332-8.109-2.124-10.392   c-8.623-5.696-17.577-10.761-26.797-15.195c7.147-21.352,12.44-45.002,15.617-69.895c23.439,4.82,44.162,11.132,60.703,18.693   c1.011,0.462,2.07,0.681,3.113,0.681c2.845,0,5.566-1.627,6.826-4.384C413.895,293.689,412.236,289.239,408.47,287.517z M330,227.5   c0,12.557-0.556,24.979-1.62,37.147c-28.573-4.837-60.255-7.576-93.38-7.936V198.29c33.125-0.36,64.807-3.1,93.38-7.936   C329.444,202.521,330,214.943,330,227.5z M312.169,108.701c6.696,20.307,11.653,42.838,14.616,66.603   c-28.137,4.822-59.465,7.607-91.785,7.981v-58.414C261.662,124.004,287.719,118.516,312.169,108.701z M142.831,108.701   c24.45,9.815,50.507,15.302,77.169,16.171v58.414c-32.32-0.374-63.648-3.159-91.785-7.981   C131.179,151.539,136.136,129.008,142.831,108.701z M125,227.5c0-12.557,0.556-24.979,1.62-37.147   c28.573,4.837,60.255,7.576,93.38,7.936v58.421c-33.125,0.36-64.807,3.1-93.38,7.936C125.556,252.479,125,240.057,125,227.5z    M142.832,346.299c-6.696-20.307-11.653-42.838-14.617-66.603c28.137-4.822,59.465-7.607,91.785-7.981v58.414   C193.338,330.996,167.281,336.484,142.832,346.299z M312.168,346.299c-24.449-9.815-50.507-15.302-77.168-16.171v-58.414   c32.32,0.374,63.648,3.159,91.785,7.981C323.821,303.461,318.864,325.992,312.168,346.299z"
+       id="path7"
+       style="fill:#ed7831;fill-opacity:1" /></g><g
+     id="g9" /><g
+     id="g11" /><g
+     id="g13" /><g
+     id="g15" /><g
+     id="g17" /><g
+     id="g19" /><g
+     id="g21" /><g
+     id="g23" /><g
+     id="g25" /><g
+     id="g27" /><g
+     id="g29" /><g
+     id="g31" /><g
+     id="g33" /><g
+     id="g35" /><g
+     id="g37" /></svg>
\ No newline at end of file
diff --git a/src/edumed/static/img/menu/svg/lekcje.svg b/src/edumed/static/img/menu/svg/lekcje.svg
new file mode 100644 (file)
index 0000000..2bd7384
--- /dev/null
@@ -0,0 +1,102 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   version="1.1"
+   id="Capa_1"
+   x="0px"
+   y="0px"
+   viewBox="0 0 468.74 468.74"
+   style="enable-background:new 0 0 468.74 468.74;"
+   xml:space="preserve"
+   inkscape:version="0.91 r13725"
+   sodipodi:docname="lekcje.svg"><metadata
+     id="metadata67"><rdf:RDF><cc:Work
+         rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs
+     id="defs65" /><sodipodi:namedview
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1"
+     objecttolerance="10"
+     gridtolerance="10"
+     guidetolerance="10"
+     inkscape:pageopacity="0"
+     inkscape:pageshadow="2"
+     inkscape:window-width="711"
+     inkscape:window-height="480"
+     id="namedview63"
+     showgrid="false"
+     inkscape:zoom="0.50347742"
+     inkscape:cx="234.37"
+     inkscape:cy="234.37"
+     inkscape:window-x="0"
+     inkscape:window-y="24"
+     inkscape:window-maximized="0"
+     inkscape:current-layer="Capa_1" /><g
+     id="g3"
+     style="fill:#96928b;fill-opacity:1"><path
+       d="M461.24,59.245h-21.87v-22.5c0-4.142-3.357-7.5-7.5-7.5H263.104c-10.817,0-21.035,4.134-28.733,11.373   c-7.698-7.238-17.917-11.373-28.732-11.373H36.87c-4.143,0-7.5,3.358-7.5,7.5v22.5H7.5c-4.143,0-7.5,3.358-7.5,7.5v263.346   c0,20.678,16.822,37.5,37.5,37.5h144.37v56.904h-32.5c-4.143,0-7.5,3.358-7.5,7.5s3.357,7.5,7.5,7.5h170c4.143,0,7.5-3.358,7.5-7.5   s-3.357-7.5-7.5-7.5h-32.5v-34.404c0-4.142-3.357-7.5-7.5-7.5s-7.5,3.358-7.5,7.5v34.404h-75v-56.904h234.37   c20.678,0,37.5-16.822,37.5-37.5V66.745C468.74,62.603,465.383,59.245,461.24,59.245z M453.74,74.245v213.14h-14.37V74.245H453.74z    M44.37,44.245h161.268c9.056,0,17.461,4.514,22.486,12.075c1.39,2.092,3.734,3.349,6.246,3.349s4.856-1.257,6.247-3.349   c5.023-7.561,13.43-12.074,22.486-12.074H424.37v243.14h-380V44.245z M29.37,74.245v213.14H15V74.245H29.37z M431.24,352.591H37.5   c-12.406,0-22.5-10.093-22.5-22.5v-27.707h438.74v27.707C453.74,342.498,443.646,352.591,431.24,352.591z"
+       id="path5"
+       style="fill:#96928b;fill-opacity:1" /><path
+       d="M234.37,272.385c4.143,0,7.5-3.358,7.5-7.5V82.168c0-4.142-3.357-7.5-7.5-7.5s-7.5,3.358-7.5,7.5v182.716   C226.87,269.027,230.228,272.385,234.37,272.385z"
+       id="path7"
+       style="fill:#96928b;fill-opacity:1" /><path
+       d="M77.5,84.245h114.965c4.143,0,7.5-3.358,7.5-7.5s-3.357-7.5-7.5-7.5H77.5c-4.143,0-7.5,3.358-7.5,7.5   S73.357,84.245,77.5,84.245z"
+       id="path9"
+       style="fill:#96928b;fill-opacity:1" /><path
+       d="M77.5,119.873h114.965c4.143,0,7.5-3.358,7.5-7.5s-3.357-7.5-7.5-7.5H77.5c-4.143,0-7.5,3.358-7.5,7.5   S73.357,119.873,77.5,119.873z"
+       id="path11"
+       style="fill:#96928b;fill-opacity:1" /><path
+       d="M77.5,155.501h57.482c4.143,0,7.5-3.358,7.5-7.5s-3.357-7.5-7.5-7.5H77.5c-4.143,0-7.5,3.358-7.5,7.5   S73.357,155.501,77.5,155.501z"
+       id="path13"
+       style="fill:#96928b;fill-opacity:1" /><path
+       d="M77.5,191.129h114.965c4.143,0,7.5-3.358,7.5-7.5s-3.357-7.5-7.5-7.5H77.5c-4.143,0-7.5,3.358-7.5,7.5   S73.357,191.129,77.5,191.129z"
+       id="path15"
+       style="fill:#96928b;fill-opacity:1" /><path
+       d="M77.5,226.757h114.965c4.143,0,7.5-3.358,7.5-7.5s-3.357-7.5-7.5-7.5H77.5c-4.143,0-7.5,3.358-7.5,7.5   S73.357,226.757,77.5,226.757z"
+       id="path17"
+       style="fill:#96928b;fill-opacity:1" /><path
+       d="M77.5,262.385h57.482c4.143,0,7.5-3.358,7.5-7.5s-3.357-7.5-7.5-7.5H77.5c-4.143,0-7.5,3.358-7.5,7.5   S73.357,262.385,77.5,262.385z"
+       id="path19"
+       style="fill:#96928b;fill-opacity:1" /><path
+       d="M276.275,84.245h114.964c4.143,0,7.5-3.358,7.5-7.5s-3.357-7.5-7.5-7.5H276.275c-4.143,0-7.5,3.358-7.5,7.5   S272.133,84.245,276.275,84.245z"
+       id="path21"
+       style="fill:#96928b;fill-opacity:1" /><path
+       d="M276.275,119.873h114.964c4.143,0,7.5-3.358,7.5-7.5s-3.357-7.5-7.5-7.5H276.275c-4.143,0-7.5,3.358-7.5,7.5   S272.133,119.873,276.275,119.873z"
+       id="path23"
+       style="fill:#96928b;fill-opacity:1" /><path
+       d="M276.275,155.501h57.481c4.143,0,7.5-3.358,7.5-7.5s-3.357-7.5-7.5-7.5h-57.481c-4.143,0-7.5,3.358-7.5,7.5   S272.133,155.501,276.275,155.501z"
+       id="path25"
+       style="fill:#96928b;fill-opacity:1" /><path
+       d="M276.275,191.129h114.964c4.143,0,7.5-3.358,7.5-7.5s-3.357-7.5-7.5-7.5H276.275c-4.143,0-7.5,3.358-7.5,7.5   S272.133,191.129,276.275,191.129z"
+       id="path27"
+       style="fill:#96928b;fill-opacity:1" /><path
+       d="M276.275,226.757h114.964c4.143,0,7.5-3.358,7.5-7.5s-3.357-7.5-7.5-7.5H276.275c-4.143,0-7.5,3.358-7.5,7.5   S272.133,226.757,276.275,226.757z"
+       id="path29"
+       style="fill:#96928b;fill-opacity:1" /><path
+       d="M276.275,262.385h57.481c4.143,0,7.5-3.358,7.5-7.5s-3.357-7.5-7.5-7.5h-57.481c-4.143,0-7.5,3.358-7.5,7.5   S272.133,262.385,276.275,262.385z"
+       id="path31"
+       style="fill:#96928b;fill-opacity:1" /></g><g
+     id="g33" /><g
+     id="g35" /><g
+     id="g37" /><g
+     id="g39" /><g
+     id="g41" /><g
+     id="g43" /><g
+     id="g45" /><g
+     id="g47" /><g
+     id="g49" /><g
+     id="g51" /><g
+     id="g53" /><g
+     id="g55" /><g
+     id="g57" /><g
+     id="g59" /><g
+     id="g61" /></svg>
\ No newline at end of file
diff --git a/src/edumed/static/img/menu/svg/lekcje_active.svg b/src/edumed/static/img/menu/svg/lekcje_active.svg
new file mode 100644 (file)
index 0000000..bc8b24a
--- /dev/null
@@ -0,0 +1,102 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   version="1.1"
+   id="Capa_1"
+   x="0px"
+   y="0px"
+   viewBox="0 0 468.74 468.74"
+   style="enable-background:new 0 0 468.74 468.74;"
+   xml:space="preserve"
+   inkscape:version="0.91 r13725"
+   sodipodi:docname="lekcje.svg"><metadata
+     id="metadata67"><rdf:RDF><cc:Work
+         rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs
+     id="defs65" /><sodipodi:namedview
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1"
+     objecttolerance="10"
+     gridtolerance="10"
+     guidetolerance="10"
+     inkscape:pageopacity="0"
+     inkscape:pageshadow="2"
+     inkscape:window-width="711"
+     inkscape:window-height="480"
+     id="namedview63"
+     showgrid="false"
+     inkscape:zoom="0.50347742"
+     inkscape:cx="234.37"
+     inkscape:cy="234.37"
+     inkscape:window-x="0"
+     inkscape:window-y="24"
+     inkscape:window-maximized="0"
+     inkscape:current-layer="Capa_1" /><g
+     id="g3"
+     style="fill:#ed7831;fill-opacity:1"><path
+       d="M461.24,59.245h-21.87v-22.5c0-4.142-3.357-7.5-7.5-7.5H263.104c-10.817,0-21.035,4.134-28.733,11.373   c-7.698-7.238-17.917-11.373-28.732-11.373H36.87c-4.143,0-7.5,3.358-7.5,7.5v22.5H7.5c-4.143,0-7.5,3.358-7.5,7.5v263.346   c0,20.678,16.822,37.5,37.5,37.5h144.37v56.904h-32.5c-4.143,0-7.5,3.358-7.5,7.5s3.357,7.5,7.5,7.5h170c4.143,0,7.5-3.358,7.5-7.5   s-3.357-7.5-7.5-7.5h-32.5v-34.404c0-4.142-3.357-7.5-7.5-7.5s-7.5,3.358-7.5,7.5v34.404h-75v-56.904h234.37   c20.678,0,37.5-16.822,37.5-37.5V66.745C468.74,62.603,465.383,59.245,461.24,59.245z M453.74,74.245v213.14h-14.37V74.245H453.74z    M44.37,44.245h161.268c9.056,0,17.461,4.514,22.486,12.075c1.39,2.092,3.734,3.349,6.246,3.349s4.856-1.257,6.247-3.349   c5.023-7.561,13.43-12.074,22.486-12.074H424.37v243.14h-380V44.245z M29.37,74.245v213.14H15V74.245H29.37z M431.24,352.591H37.5   c-12.406,0-22.5-10.093-22.5-22.5v-27.707h438.74v27.707C453.74,342.498,443.646,352.591,431.24,352.591z"
+       id="path5"
+       style="fill:#ed7831;fill-opacity:1" /><path
+       d="M234.37,272.385c4.143,0,7.5-3.358,7.5-7.5V82.168c0-4.142-3.357-7.5-7.5-7.5s-7.5,3.358-7.5,7.5v182.716   C226.87,269.027,230.228,272.385,234.37,272.385z"
+       id="path7"
+       style="fill:#ed7831;fill-opacity:1" /><path
+       d="M77.5,84.245h114.965c4.143,0,7.5-3.358,7.5-7.5s-3.357-7.5-7.5-7.5H77.5c-4.143,0-7.5,3.358-7.5,7.5   S73.357,84.245,77.5,84.245z"
+       id="path9"
+       style="fill:#ed7831;fill-opacity:1" /><path
+       d="M77.5,119.873h114.965c4.143,0,7.5-3.358,7.5-7.5s-3.357-7.5-7.5-7.5H77.5c-4.143,0-7.5,3.358-7.5,7.5   S73.357,119.873,77.5,119.873z"
+       id="path11"
+       style="fill:#ed7831;fill-opacity:1" /><path
+       d="M77.5,155.501h57.482c4.143,0,7.5-3.358,7.5-7.5s-3.357-7.5-7.5-7.5H77.5c-4.143,0-7.5,3.358-7.5,7.5   S73.357,155.501,77.5,155.501z"
+       id="path13"
+       style="fill:#ed7831;fill-opacity:1" /><path
+       d="M77.5,191.129h114.965c4.143,0,7.5-3.358,7.5-7.5s-3.357-7.5-7.5-7.5H77.5c-4.143,0-7.5,3.358-7.5,7.5   S73.357,191.129,77.5,191.129z"
+       id="path15"
+       style="fill:#ed7831;fill-opacity:1" /><path
+       d="M77.5,226.757h114.965c4.143,0,7.5-3.358,7.5-7.5s-3.357-7.5-7.5-7.5H77.5c-4.143,0-7.5,3.358-7.5,7.5   S73.357,226.757,77.5,226.757z"
+       id="path17"
+       style="fill:#ed7831;fill-opacity:1" /><path
+       d="M77.5,262.385h57.482c4.143,0,7.5-3.358,7.5-7.5s-3.357-7.5-7.5-7.5H77.5c-4.143,0-7.5,3.358-7.5,7.5   S73.357,262.385,77.5,262.385z"
+       id="path19"
+       style="fill:#ed7831;fill-opacity:1" /><path
+       d="M276.275,84.245h114.964c4.143,0,7.5-3.358,7.5-7.5s-3.357-7.5-7.5-7.5H276.275c-4.143,0-7.5,3.358-7.5,7.5   S272.133,84.245,276.275,84.245z"
+       id="path21"
+       style="fill:#ed7831;fill-opacity:1" /><path
+       d="M276.275,119.873h114.964c4.143,0,7.5-3.358,7.5-7.5s-3.357-7.5-7.5-7.5H276.275c-4.143,0-7.5,3.358-7.5,7.5   S272.133,119.873,276.275,119.873z"
+       id="path23"
+       style="fill:#ed7831;fill-opacity:1" /><path
+       d="M276.275,155.501h57.481c4.143,0,7.5-3.358,7.5-7.5s-3.357-7.5-7.5-7.5h-57.481c-4.143,0-7.5,3.358-7.5,7.5   S272.133,155.501,276.275,155.501z"
+       id="path25"
+       style="fill:#ed7831;fill-opacity:1" /><path
+       d="M276.275,191.129h114.964c4.143,0,7.5-3.358,7.5-7.5s-3.357-7.5-7.5-7.5H276.275c-4.143,0-7.5,3.358-7.5,7.5   S272.133,191.129,276.275,191.129z"
+       id="path27"
+       style="fill:#ed7831;fill-opacity:1" /><path
+       d="M276.275,226.757h114.964c4.143,0,7.5-3.358,7.5-7.5s-3.357-7.5-7.5-7.5H276.275c-4.143,0-7.5,3.358-7.5,7.5   S272.133,226.757,276.275,226.757z"
+       id="path29"
+       style="fill:#ed7831;fill-opacity:1" /><path
+       d="M276.275,262.385h57.481c4.143,0,7.5-3.358,7.5-7.5s-3.357-7.5-7.5-7.5h-57.481c-4.143,0-7.5,3.358-7.5,7.5   S272.133,262.385,276.275,262.385z"
+       id="path31"
+       style="fill:#ed7831;fill-opacity:1" /></g><g
+     id="g33" /><g
+     id="g35" /><g
+     id="g37" /><g
+     id="g39" /><g
+     id="g41" /><g
+     id="g43" /><g
+     id="g45" /><g
+     id="g47" /><g
+     id="g49" /><g
+     id="g51" /><g
+     id="g53" /><g
+     id="g55" /><g
+     id="g57" /><g
+     id="g59" /><g
+     id="g61" /></svg>
\ No newline at end of file
diff --git a/src/edumed/static/img/menu/svg/o-nas.svg b/src/edumed/static/img/menu/svg/o-nas.svg
new file mode 100644 (file)
index 0000000..540d2c5
--- /dev/null
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   version="1.1"
+   viewBox="0 0 470 470"
+   enable-background="new 0 0 470 470"
+   id="svg2"
+   inkscape:version="0.91 r13725"
+   sodipodi:docname="o nas.svg">
+  <metadata
+     id="metadata10">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <defs
+     id="defs8" />
+  <sodipodi:namedview
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1"
+     objecttolerance="10"
+     gridtolerance="10"
+     guidetolerance="10"
+     inkscape:pageopacity="0"
+     inkscape:pageshadow="2"
+     inkscape:window-width="711"
+     inkscape:window-height="480"
+     id="namedview6"
+     showgrid="false"
+     inkscape:zoom="0.50212766"
+     inkscape:cx="235"
+     inkscape:cy="235"
+     inkscape:window-x="0"
+     inkscape:window-y="24"
+     inkscape:window-maximized="0"
+     inkscape:current-layer="svg2" />
+  <path
+     d="m469.19,46.536c-1.467-2.894-4.636-4.521-7.832-4.021l-40.045,6.173 6.173-40.045c0.494-3.205-1.128-6.365-4.021-7.832-2.894-1.467-6.402-0.908-8.695,1.386l-46.484,46.484c-1.127,1.128-1.866,2.585-2.108,4.161l-7.358,47.733-26.609,26.609c-36.654-34.03-84.102-52.694-134.454-52.694-52.864,0-102.536,20.559-139.866,57.889-37.332,37.331-57.891,87.003-57.891,139.867s20.559,102.535 57.889,139.866c37.331,37.33 87.003,57.888 139.866,57.888s102.536-20.559 139.866-57.889c37.33-37.331 57.889-87.003 57.889-139.866 0-42.051-12.996-82.189-37.583-116.076-2.433-3.354-7.125-4.1-10.475-1.666-3.353,2.433-4.099,7.122-1.666,10.475 22.717,31.31 34.724,68.402 34.724,107.268 0,100.771-81.984,182.754-182.755,182.754-100.771,0-182.755-81.983-182.755-182.754s81.984-182.755 182.755-182.755c46.345,1.42109e-14 90.026,17.105 123.84,48.308l-34.284,34.284c-24.653-22.076-56.23-34.173-89.557-34.173-74.074,0-134.337,60.264-134.337,134.337s60.263,134.337 134.337,134.337 134.336-60.264 134.336-134.337c0-24.723-6.76-48.882-19.548-69.866-2.156-3.537-6.771-4.658-10.308-2.501-3.537,2.155-4.656,6.771-2.501,10.308 11.354,18.632 17.356,40.092 17.356,62.06 0,65.803-53.534,119.337-119.336,119.337-65.803,0-119.337-53.534-119.337-119.337s53.534-119.337 119.337-119.337c29.327,0 57.131,10.538 78.937,29.793l-34.365,34.365c-12.575-10.193-28.141-15.74-44.572-15.74-39.104,0-70.918,31.814-70.918,70.919s31.814,70.918 70.918,70.918c39.105,0 70.918-31.813 70.918-70.918 0-6.967-1.008-13.853-2.995-20.468-1.192-3.967-5.374-6.219-9.341-5.024-3.967,1.191-6.217,5.373-5.024,9.341 1.566,5.214 2.36,10.647 2.36,16.151 0,30.833-25.085,55.918-55.918,55.918s-55.918-25.085-55.918-55.918c0-30.834 25.085-55.919 55.918-55.919 12.416,0 24.2,4.021 33.886,11.426l-39.19,39.19c-2.929,2.93-2.929,7.678 0,10.607 1.464,1.464 3.384,2.196 5.303,2.196 1.919,0 3.839-0.732 5.303-2.196l134.539-134.539c0.046-0.046 31.828-31.828 31.828-31.828l47.733-7.359c1.576-0.242 3.033-0.981 4.161-2.108l46.484-46.484c2.297-2.297 2.856-5.805 1.39-8.698zm-88.563,11.017l28.542-28.541-3.866,25.079-28.542,28.542 3.866-25.08zm31.82,31.821l-25.078,3.866 28.542-28.542 25.077-3.866-28.541,28.542z"
+     id="path4"
+     style="fill-opacity:1;fill:#96928b" />
+</svg>
diff --git a/src/edumed/static/img/menu/svg/o-nas_active.svg b/src/edumed/static/img/menu/svg/o-nas_active.svg
new file mode 100644 (file)
index 0000000..9878327
--- /dev/null
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   version="1.1"
+   viewBox="0 0 470 470"
+   enable-background="new 0 0 470 470"
+   id="svg2"
+   inkscape:version="0.91 r13725"
+   sodipodi:docname="o nas.svg">
+  <metadata
+     id="metadata10">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <defs
+     id="defs8" />
+  <sodipodi:namedview
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1"
+     objecttolerance="10"
+     gridtolerance="10"
+     guidetolerance="10"
+     inkscape:pageopacity="0"
+     inkscape:pageshadow="2"
+     inkscape:window-width="711"
+     inkscape:window-height="480"
+     id="namedview6"
+     showgrid="false"
+     inkscape:zoom="0.50212766"
+     inkscape:cx="235"
+     inkscape:cy="235"
+     inkscape:window-x="0"
+     inkscape:window-y="24"
+     inkscape:window-maximized="0"
+     inkscape:current-layer="svg2" />
+  <path
+     d="m469.19,46.536c-1.467-2.894-4.636-4.521-7.832-4.021l-40.045,6.173 6.173-40.045c0.494-3.205-1.128-6.365-4.021-7.832-2.894-1.467-6.402-0.908-8.695,1.386l-46.484,46.484c-1.127,1.128-1.866,2.585-2.108,4.161l-7.358,47.733-26.609,26.609c-36.654-34.03-84.102-52.694-134.454-52.694-52.864,0-102.536,20.559-139.866,57.889-37.332,37.331-57.891,87.003-57.891,139.867s20.559,102.535 57.889,139.866c37.331,37.33 87.003,57.888 139.866,57.888s102.536-20.559 139.866-57.889c37.33-37.331 57.889-87.003 57.889-139.866 0-42.051-12.996-82.189-37.583-116.076-2.433-3.354-7.125-4.1-10.475-1.666-3.353,2.433-4.099,7.122-1.666,10.475 22.717,31.31 34.724,68.402 34.724,107.268 0,100.771-81.984,182.754-182.755,182.754-100.771,0-182.755-81.983-182.755-182.754s81.984-182.755 182.755-182.755c46.345,1.42109e-14 90.026,17.105 123.84,48.308l-34.284,34.284c-24.653-22.076-56.23-34.173-89.557-34.173-74.074,0-134.337,60.264-134.337,134.337s60.263,134.337 134.337,134.337 134.336-60.264 134.336-134.337c0-24.723-6.76-48.882-19.548-69.866-2.156-3.537-6.771-4.658-10.308-2.501-3.537,2.155-4.656,6.771-2.501,10.308 11.354,18.632 17.356,40.092 17.356,62.06 0,65.803-53.534,119.337-119.336,119.337-65.803,0-119.337-53.534-119.337-119.337s53.534-119.337 119.337-119.337c29.327,0 57.131,10.538 78.937,29.793l-34.365,34.365c-12.575-10.193-28.141-15.74-44.572-15.74-39.104,0-70.918,31.814-70.918,70.919s31.814,70.918 70.918,70.918c39.105,0 70.918-31.813 70.918-70.918 0-6.967-1.008-13.853-2.995-20.468-1.192-3.967-5.374-6.219-9.341-5.024-3.967,1.191-6.217,5.373-5.024,9.341 1.566,5.214 2.36,10.647 2.36,16.151 0,30.833-25.085,55.918-55.918,55.918s-55.918-25.085-55.918-55.918c0-30.834 25.085-55.919 55.918-55.919 12.416,0 24.2,4.021 33.886,11.426l-39.19,39.19c-2.929,2.93-2.929,7.678 0,10.607 1.464,1.464 3.384,2.196 5.303,2.196 1.919,0 3.839-0.732 5.303-2.196l134.539-134.539c0.046-0.046 31.828-31.828 31.828-31.828l47.733-7.359c1.576-0.242 3.033-0.981 4.161-2.108l46.484-46.484c2.297-2.297 2.856-5.805 1.39-8.698zm-88.563,11.017l28.542-28.541-3.866,25.079-28.542,28.542 3.866-25.08zm31.82,31.821l-25.078,3.866 28.542-28.542 25.077-3.866-28.541,28.542z"
+     id="path4"
+     style="fill-opacity:1;fill:#ed7831" />
+</svg>
diff --git a/src/edumed/static/img/menu/svg/olimpiada.svg b/src/edumed/static/img/menu/svg/olimpiada.svg
new file mode 100644 (file)
index 0000000..5d0b8eb
--- /dev/null
@@ -0,0 +1,109 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   version="1.1"
+   viewBox="0 0 455.881 455.881"
+   enable-background="new 0 0 455.881 455.881"
+   id="svg2"
+   inkscape:version="0.91 r13725"
+   sodipodi:docname="olimpiada.svg">
+  <metadata
+     id="metadata38">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <defs
+     id="defs36" />
+  <sodipodi:namedview
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1"
+     objecttolerance="10"
+     gridtolerance="10"
+     guidetolerance="10"
+     inkscape:pageopacity="0"
+     inkscape:pageshadow="2"
+     inkscape:window-width="711"
+     inkscape:window-height="480"
+     id="namedview34"
+     showgrid="false"
+     inkscape:zoom="0.51767894"
+     inkscape:cx="227.94051"
+     inkscape:cy="227.94051"
+     inkscape:window-x="0"
+     inkscape:window-y="24"
+     inkscape:window-maximized="0"
+     inkscape:current-layer="svg2" />
+  <g
+     id="g4"
+     style="fill:#96928b;fill-opacity:1">
+    <path
+       d="m321.218,257.555c15.516-20.46 23.717-44.881 23.717-70.624 0-31.563-12.379-61.151-34.857-83.314-22.474-22.158-52.261-34.124-83.828-33.668-30.591,0.433-59.412,12.708-81.154,34.564-21.741,21.855-33.867,50.741-34.145,81.335-0.238,26.228 8.011,51.088 23.855,71.894 25.721,33.776 39.887,75.149 39.887,116.498v45.244c0,20.069 16.327,36.396 36.396,36.396h33.854c20.069,0 36.396-16.328 36.396-36.396v-45.241c0.001-41.806 13.691-82.157 39.879-116.688zm-174.478-8.9c-13.808-18.132-20.997-39.803-20.79-62.67 0.499-54.935 45.588-100.26 100.512-101.037 27.553-0.37 53.493,10.035 73.084,29.352 19.597,19.321 30.389,45.116 30.389,72.632 0,22.442-7.147,43.729-20.669,61.56-27.593,36.385-42.45,78.833-43.058,122.93h-76.536c-0.627-43.669-15.817-87.161-42.932-122.767zm42.953,165.746v-6.072l76.647,8.781v2.374c0,1.25-0.13,2.468-0.336,3.659l-76.311-8.742zm0-21.17v-6.809h76.647v15.59l-76.647-8.781zm21.396,47.65c-8.057,0-15.082-4.48-18.731-11.077l64.567,7.397c-3.421,2.321-7.545,3.679-11.981,3.679h-33.855z"
+       id="path6"
+       style="fill:#96928b;fill-opacity:1" />
+    <path
+       d="m153.776,198.213c-0.585-3.925-0.864-7.957-0.827-11.983 0.038-4.142-3.289-7.53-7.431-7.568-4.114-0.036-7.53,3.289-7.568,7.431-0.044,4.81 0.289,9.632 0.99,14.333 0.555,3.722 3.755,6.395 7.409,6.395 0.368,0 0.741-0.027 1.116-0.083 4.096-0.612 6.922-4.428 6.311-8.525z"
+       id="path8"
+       style="fill:#96928b;fill-opacity:1" />
+    <path
+       d="m197.913,312.135c0.776,0 1.566-0.122 2.344-0.377 3.935-1.294 6.076-5.533 4.782-9.467-8.312-25.277-20.7-48.827-36.82-69.994-2.664-3.499-5.025-7.226-7.016-11.079-1.902-3.68-6.427-5.12-10.107-3.218-3.679,1.902-5.12,6.427-3.218,10.107 2.39,4.622 5.218,9.089 8.408,13.278 15.106,19.836 26.715,41.904 34.504,65.591 1.038,3.157 3.971,5.159 7.123,5.159z"
+       id="path10"
+       style="fill:#96928b;fill-opacity:1" />
+    <path
+       d="m306.746,212.613c-3.804-1.639-8.217,0.117-9.855,3.921-2.376,5.518-5.451,10.781-9.139,15.643-2.503,3.3-1.856,8.005 1.444,10.508 1.355,1.028 2.947,1.524 4.526,1.524 2.267,0 4.507-1.023 5.982-2.969 4.419-5.827 8.107-12.143 10.963-18.772 1.639-3.804-0.116-8.217-3.921-9.855z"
+       id="path12"
+       style="fill:#96928b;fill-opacity:1" />
+    <path
+       d="m227.941,111.938c41.352,0 74.994,33.643 74.994,74.995 0,2.351-0.108,4.72-0.321,7.041-0.378,4.125 2.658,7.775 6.783,8.154 0.233,0.021 0.464,0.032 0.694,0.032 3.833,0 7.103-2.923 7.46-6.815 0.254-2.775 0.384-5.605 0.384-8.412 0-49.623-40.371-89.995-89.994-89.995-4.142,0-7.5,3.358-7.5,7.5s3.358,7.5 7.5,7.5z"
+       id="path14"
+       style="fill:#96928b;fill-opacity:1" />
+    <path
+       d="m227.941,57c4.142,0 7.5-3.358 7.5-7.5v-42c0-4.142-3.358-7.5-7.5-7.5s-7.5,3.358-7.5,7.5v42c0,4.142 3.358,7.5 7.5,7.5z"
+       id="path16"
+       style="fill:#96928b;fill-opacity:1" />
+    <path
+       d="m152.065,71.82c1.39,2.407 3.91,3.752 6.502,3.752 1.272,0 2.562-0.324 3.743-1.006 3.587-2.071 4.817-6.658 2.746-10.245l-20.99-36.36c-2.072-3.588-6.658-4.817-10.245-2.746-3.587,2.071-4.817,6.658-2.746,10.245l20.99,36.36z"
+       id="path18"
+       style="fill:#96928b;fill-opacity:1" />
+    <path
+       d="m388.22,272.115l-36.36-20.99c-3.588-2.072-8.175-0.842-10.245,2.746-2.071,3.587-0.842,8.174 2.746,10.245l36.36,20.99c1.181,0.682 2.47,1.006 3.743,1.006 2.592,0 5.113-1.346 6.502-3.752 2.071-3.587 0.841-8.174-2.746-10.245z"
+       id="path20"
+       style="fill:#96928b;fill-opacity:1" />
+    <path
+       d="m67.661,104.366l36.36,20.99c1.181,0.682 2.47,1.006 3.743,1.006 2.592,0 5.113-1.346 6.502-3.752 2.071-3.587 0.842-8.174-2.746-10.245l-36.36-20.99c-3.587-2.072-8.174-0.842-10.245,2.746-2.071,3.587-0.842,8.173 2.746,10.245z"
+       id="path22"
+       style="fill:#96928b;fill-opacity:1" />
+    <path
+       d="m408.68,180.74h-42c-4.142,0-7.5,3.358-7.5,7.5s3.358,7.5 7.5,7.5h42c4.142,0 7.5-3.358 7.5-7.5s-3.357-7.5-7.5-7.5z"
+       id="path24"
+       style="fill:#96928b;fill-opacity:1" />
+    <path
+       d="m96.7,188.24c0-4.142-3.358-7.5-7.5-7.5h-42c-4.142,0-7.5,3.358-7.5,7.5s3.358,7.5 7.5,7.5h42c4.143,0 7.5-3.358 7.5-7.5z"
+       id="path26"
+       style="fill:#96928b;fill-opacity:1" />
+    <path
+       d="m348.117,126.362c1.272,0 2.562-0.324 3.743-1.006l36.36-20.99c3.587-2.071 4.817-6.658 2.746-10.245-2.071-3.587-6.659-4.817-10.245-2.746l-36.36,20.99c-3.587,2.071-4.817,6.658-2.746,10.245 1.389,2.406 3.911,3.752 6.502,3.752z"
+       id="path28"
+       style="fill:#96928b;fill-opacity:1" />
+    <path
+       d="m104.021,251.125l-36.36,20.99c-3.587,2.071-4.817,6.658-2.746,10.245 1.389,2.406 3.91,3.752 6.502,3.752 1.272,0 2.562-0.324 3.743-1.006l36.36-20.99c3.587-2.071 4.817-6.658 2.746-10.245-2.07-3.588-6.66-4.817-10.245-2.746z"
+       id="path30"
+       style="fill:#96928b;fill-opacity:1" />
+    <path
+       d="m293.571,74.566c1.181,0.682 2.47,1.006 3.743,1.006 2.592,0 5.113-1.346 6.502-3.752l20.99-36.36c2.071-3.587 0.841-8.174-2.746-10.245-3.586-2.071-8.174-0.842-10.245,2.746l-20.99,36.36c-2.071,3.587-0.841,8.174 2.746,10.245z"
+       id="path32"
+       style="fill:#96928b;fill-opacity:1" />
+  </g>
+</svg>
diff --git a/src/edumed/static/img/menu/svg/olimpiada_active.svg b/src/edumed/static/img/menu/svg/olimpiada_active.svg
new file mode 100644 (file)
index 0000000..c5b390f
--- /dev/null
@@ -0,0 +1,109 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   version="1.1"
+   viewBox="0 0 455.881 455.881"
+   enable-background="new 0 0 455.881 455.881"
+   id="svg2"
+   inkscape:version="0.91 r13725"
+   sodipodi:docname="olimpiada.svg">
+  <metadata
+     id="metadata38">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <defs
+     id="defs36" />
+  <sodipodi:namedview
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1"
+     objecttolerance="10"
+     gridtolerance="10"
+     guidetolerance="10"
+     inkscape:pageopacity="0"
+     inkscape:pageshadow="2"
+     inkscape:window-width="711"
+     inkscape:window-height="480"
+     id="namedview34"
+     showgrid="false"
+     inkscape:zoom="0.51767894"
+     inkscape:cx="227.94051"
+     inkscape:cy="227.94051"
+     inkscape:window-x="0"
+     inkscape:window-y="24"
+     inkscape:window-maximized="0"
+     inkscape:current-layer="svg2" />
+  <g
+     id="g4"
+     style="fill:#ed7831;fill-opacity:1">
+    <path
+       d="m321.218,257.555c15.516-20.46 23.717-44.881 23.717-70.624 0-31.563-12.379-61.151-34.857-83.314-22.474-22.158-52.261-34.124-83.828-33.668-30.591,0.433-59.412,12.708-81.154,34.564-21.741,21.855-33.867,50.741-34.145,81.335-0.238,26.228 8.011,51.088 23.855,71.894 25.721,33.776 39.887,75.149 39.887,116.498v45.244c0,20.069 16.327,36.396 36.396,36.396h33.854c20.069,0 36.396-16.328 36.396-36.396v-45.241c0.001-41.806 13.691-82.157 39.879-116.688zm-174.478-8.9c-13.808-18.132-20.997-39.803-20.79-62.67 0.499-54.935 45.588-100.26 100.512-101.037 27.553-0.37 53.493,10.035 73.084,29.352 19.597,19.321 30.389,45.116 30.389,72.632 0,22.442-7.147,43.729-20.669,61.56-27.593,36.385-42.45,78.833-43.058,122.93h-76.536c-0.627-43.669-15.817-87.161-42.932-122.767zm42.953,165.746v-6.072l76.647,8.781v2.374c0,1.25-0.13,2.468-0.336,3.659l-76.311-8.742zm0-21.17v-6.809h76.647v15.59l-76.647-8.781zm21.396,47.65c-8.057,0-15.082-4.48-18.731-11.077l64.567,7.397c-3.421,2.321-7.545,3.679-11.981,3.679h-33.855z"
+       id="path6"
+       style="fill:#ed7831;fill-opacity:1" />
+    <path
+       d="m153.776,198.213c-0.585-3.925-0.864-7.957-0.827-11.983 0.038-4.142-3.289-7.53-7.431-7.568-4.114-0.036-7.53,3.289-7.568,7.431-0.044,4.81 0.289,9.632 0.99,14.333 0.555,3.722 3.755,6.395 7.409,6.395 0.368,0 0.741-0.027 1.116-0.083 4.096-0.612 6.922-4.428 6.311-8.525z"
+       id="path8"
+       style="fill:#ed7831;fill-opacity:1" />
+    <path
+       d="m197.913,312.135c0.776,0 1.566-0.122 2.344-0.377 3.935-1.294 6.076-5.533 4.782-9.467-8.312-25.277-20.7-48.827-36.82-69.994-2.664-3.499-5.025-7.226-7.016-11.079-1.902-3.68-6.427-5.12-10.107-3.218-3.679,1.902-5.12,6.427-3.218,10.107 2.39,4.622 5.218,9.089 8.408,13.278 15.106,19.836 26.715,41.904 34.504,65.591 1.038,3.157 3.971,5.159 7.123,5.159z"
+       id="path10"
+       style="fill:#ed7831;fill-opacity:1" />
+    <path
+       d="m306.746,212.613c-3.804-1.639-8.217,0.117-9.855,3.921-2.376,5.518-5.451,10.781-9.139,15.643-2.503,3.3-1.856,8.005 1.444,10.508 1.355,1.028 2.947,1.524 4.526,1.524 2.267,0 4.507-1.023 5.982-2.969 4.419-5.827 8.107-12.143 10.963-18.772 1.639-3.804-0.116-8.217-3.921-9.855z"
+       id="path12"
+       style="fill:#ed7831;fill-opacity:1" />
+    <path
+       d="m227.941,111.938c41.352,0 74.994,33.643 74.994,74.995 0,2.351-0.108,4.72-0.321,7.041-0.378,4.125 2.658,7.775 6.783,8.154 0.233,0.021 0.464,0.032 0.694,0.032 3.833,0 7.103-2.923 7.46-6.815 0.254-2.775 0.384-5.605 0.384-8.412 0-49.623-40.371-89.995-89.994-89.995-4.142,0-7.5,3.358-7.5,7.5s3.358,7.5 7.5,7.5z"
+       id="path14"
+       style="fill:#ed7831;fill-opacity:1" />
+    <path
+       d="m227.941,57c4.142,0 7.5-3.358 7.5-7.5v-42c0-4.142-3.358-7.5-7.5-7.5s-7.5,3.358-7.5,7.5v42c0,4.142 3.358,7.5 7.5,7.5z"
+       id="path16"
+       style="fill:#ed7831;fill-opacity:1" />
+    <path
+       d="m152.065,71.82c1.39,2.407 3.91,3.752 6.502,3.752 1.272,0 2.562-0.324 3.743-1.006 3.587-2.071 4.817-6.658 2.746-10.245l-20.99-36.36c-2.072-3.588-6.658-4.817-10.245-2.746-3.587,2.071-4.817,6.658-2.746,10.245l20.99,36.36z"
+       id="path18"
+       style="fill:#ed7831;fill-opacity:1" />
+    <path
+       d="m388.22,272.115l-36.36-20.99c-3.588-2.072-8.175-0.842-10.245,2.746-2.071,3.587-0.842,8.174 2.746,10.245l36.36,20.99c1.181,0.682 2.47,1.006 3.743,1.006 2.592,0 5.113-1.346 6.502-3.752 2.071-3.587 0.841-8.174-2.746-10.245z"
+       id="path20"
+       style="fill:#ed7831;fill-opacity:1" />
+    <path
+       d="m67.661,104.366l36.36,20.99c1.181,0.682 2.47,1.006 3.743,1.006 2.592,0 5.113-1.346 6.502-3.752 2.071-3.587 0.842-8.174-2.746-10.245l-36.36-20.99c-3.587-2.072-8.174-0.842-10.245,2.746-2.071,3.587-0.842,8.173 2.746,10.245z"
+       id="path22"
+       style="fill:#ed7831;fill-opacity:1" />
+    <path
+       d="m408.68,180.74h-42c-4.142,0-7.5,3.358-7.5,7.5s3.358,7.5 7.5,7.5h42c4.142,0 7.5-3.358 7.5-7.5s-3.357-7.5-7.5-7.5z"
+       id="path24"
+       style="fill:#ed7831;fill-opacity:1" />
+    <path
+       d="m96.7,188.24c0-4.142-3.358-7.5-7.5-7.5h-42c-4.142,0-7.5,3.358-7.5,7.5s3.358,7.5 7.5,7.5h42c4.143,0 7.5-3.358 7.5-7.5z"
+       id="path26"
+       style="fill:#ed7831;fill-opacity:1" />
+    <path
+       d="m348.117,126.362c1.272,0 2.562-0.324 3.743-1.006l36.36-20.99c3.587-2.071 4.817-6.658 2.746-10.245-2.071-3.587-6.659-4.817-10.245-2.746l-36.36,20.99c-3.587,2.071-4.817,6.658-2.746,10.245 1.389,2.406 3.911,3.752 6.502,3.752z"
+       id="path28"
+       style="fill:#ed7831;fill-opacity:1" />
+    <path
+       d="m104.021,251.125l-36.36,20.99c-3.587,2.071-4.817,6.658-2.746,10.245 1.389,2.406 3.91,3.752 6.502,3.752 1.272,0 2.562-0.324 3.743-1.006l36.36-20.99c3.587-2.071 4.817-6.658 2.746-10.245-2.07-3.588-6.66-4.817-10.245-2.746z"
+       id="path30"
+       style="fill:#ed7831;fill-opacity:1" />
+    <path
+       d="m293.571,74.566c1.181,0.682 2.47,1.006 3.743,1.006 2.592,0 5.113-1.346 6.502-3.752l20.99-36.36c2.071-3.587 0.841-8.174-2.746-10.245-3.586-2.071-8.174-0.842-10.245,2.746l-20.99,36.36c-2.071,3.587-0.841,8.174 2.746,10.245z"
+       id="path32"
+       style="fill:#ed7831;fill-opacity:1" />
+  </g>
+</svg>
diff --git a/src/edumed/static/img/nina-white.png b/src/edumed/static/img/nina-white.png
new file mode 100644 (file)
index 0000000..3d2afe7
Binary files /dev/null and b/src/edumed/static/img/nina-white.png differ
diff --git a/src/edumed/static/img/nina.jpg b/src/edumed/static/img/nina.jpg
new file mode 100644 (file)
index 0000000..a056df0
Binary files /dev/null and b/src/edumed/static/img/nina.jpg differ
diff --git a/src/edumed/static/img/ornaments/draggable.png b/src/edumed/static/img/ornaments/draggable.png
new file mode 100644 (file)
index 0000000..75af63e
Binary files /dev/null and b/src/edumed/static/img/ornaments/draggable.png differ
diff --git a/src/edumed/static/img/sciezki-kopernika/cc.jpg b/src/edumed/static/img/sciezki-kopernika/cc.jpg
new file mode 100644 (file)
index 0000000..0ff7abc
Binary files /dev/null and b/src/edumed/static/img/sciezki-kopernika/cc.jpg differ
diff --git a/src/edumed/static/img/sciezki-kopernika/fe.jpg b/src/edumed/static/img/sciezki-kopernika/fe.jpg
new file mode 100644 (file)
index 0000000..f353aa7
Binary files /dev/null and b/src/edumed/static/img/sciezki-kopernika/fe.jpg differ
diff --git a/src/edumed/static/img/sciezki-kopernika/fnp.png b/src/edumed/static/img/sciezki-kopernika/fnp.png
new file mode 100644 (file)
index 0000000..d6bb0c7
Binary files /dev/null and b/src/edumed/static/img/sciezki-kopernika/fnp.png differ
diff --git a/src/edumed/static/img/sciezki-kopernika/ue.jpg b/src/edumed/static/img/sciezki-kopernika/ue.jpg
new file mode 100644 (file)
index 0000000..30ae44f
Binary files /dev/null and b/src/edumed/static/img/sciezki-kopernika/ue.jpg differ
diff --git a/src/edumed/static/jquery/colorbox/colorbox.css b/src/edumed/static/jquery/colorbox/colorbox.css
new file mode 100644 (file)
index 0000000..b75b0ce
--- /dev/null
@@ -0,0 +1,93 @@
+/*
+    ColorBox Core Style:
+    The following CSS is consistent between example themes and should not be altered.
+*/
+#colorbox, #cboxOverlay, #cboxWrapper{position:absolute; top:0; left:0; z-index:9999; overflow:hidden;}
+#cboxOverlay{position:fixed; width:100%; height:100%;}
+#cboxMiddleLeft, #cboxBottomLeft{clear:left;}
+#cboxContent{position:relative;}
+#cboxLoadedContent{overflow:auto; -webkit-overflow-scrolling: touch;}
+#cboxTitle{margin:0;}
+#cboxLoadingOverlay, #cboxLoadingGraphic{position:absolute; top:0; left:0; width:100%; height:100%;}
+#cboxPrevious, #cboxNext, #cboxClose, #cboxSlideshow{cursor:pointer;}
+.cboxPhoto{float:left; margin:auto; border:0; display:block; max-width:none;}
+.cboxIframe{width:100%; height:100%; display:block; border:0;}
+#colorbox, #cboxContent, #cboxLoadedContent{box-sizing:content-box; -moz-box-sizing:content-box; -webkit-box-sizing:content-box;}
+
+/* 
+    User Style:
+    Change the following styles to modify the appearance of ColorBox.  They are
+    ordered & tabbed in a way that represents the nesting of the generated HTML.
+*/
+#cboxOverlay{background:url(images/overlay.png) repeat 0 0;}
+#colorbox{outline:0;}
+    #cboxTopLeft{width:21px; height:21px; background:url(images/controls.png) no-repeat -101px 0;}
+    #cboxTopRight{width:21px; height:21px; background:url(images/controls.png) no-repeat -130px 0;}
+    #cboxBottomLeft{width:21px; height:21px; background:url(images/controls.png) no-repeat -101px -29px;}
+    #cboxBottomRight{width:21px; height:21px; background:url(images/controls.png) no-repeat -130px -29px;}
+    #cboxMiddleLeft{width:21px; background:url(images/controls.png) left top repeat-y;}
+    #cboxMiddleRight{width:21px; background:url(images/controls.png) right top repeat-y;}
+    #cboxTopCenter{height:21px; background:url(images/border.png) 0 0 repeat-x;}
+    #cboxBottomCenter{height:21px; background:url(images/border.png) 0 -29px repeat-x;}
+    #cboxContent{background:#fff; overflow:hidden;}
+        .cboxIframe{background:#fff;}
+        #cboxError{padding:50px; border:1px solid #ccc;}
+        #cboxLoadedContent{margin-bottom:28px;}
+        #cboxTitle{position:absolute; bottom:4px; left:0; text-align:center; width:100%; color:#949494;}
+        #cboxCurrent{position:absolute; bottom:4px; left:58px; color:#949494;}
+        #cboxLoadingOverlay{background:url(images/loading_background.png) no-repeat center center;}
+        #cboxLoadingGraphic{background:url(images/loading.gif) no-repeat center center;}
+
+        /* these elements are buttons, and may need to have additional styles reset to avoid unwanted base styles */
+        #cboxPrevious, #cboxNext, #cboxSlideshow, #cboxClose {border:0; padding:0; margin:0; overflow:visible; width:auto; background:none; }
+        
+        /* avoid outlines on :active (mouseclick), but preserve outlines on :focus (tabbed navigating) */
+        #cboxPrevious:active, #cboxNext:active, #cboxSlideshow:active, #cboxClose:active {outline:0;}
+
+        #cboxSlideshow{position:absolute; bottom:4px; right:30px; color:#0092ef;}
+        #cboxPrevious{position:absolute; bottom:0; left:0; background:url(images/controls.png) no-repeat -75px 0; width:25px; height:25px; text-indent:-9999px;}
+        #cboxPrevious:hover{background-position:-75px -25px;}
+        #cboxNext{position:absolute; bottom:0; left:27px; background:url(images/controls.png) no-repeat -50px 0; width:25px; height:25px; text-indent:-9999px;}
+        #cboxNext:hover{background-position:-50px -25px;}
+        #cboxClose{position:absolute; bottom:0; right:0; background:url(images/controls.png) no-repeat -25px 0; width:25px; height:25px; text-indent:-9999px;}
+        #cboxClose:hover{background-position:-25px -25px;}
+
+/*
+  The following fixes a problem where IE7 and IE8 replace a PNG's alpha transparency with a black fill
+  when an alpha filter (opacity change) is set on the element or ancestor element.  This style is not applied to or needed in IE9.
+  See: http://jacklmoore.com/notes/ie-transparency-problems/
+*/
+.cboxIE #cboxTopLeft,
+.cboxIE #cboxTopCenter,
+.cboxIE #cboxTopRight,
+.cboxIE #cboxBottomLeft,
+.cboxIE #cboxBottomCenter,
+.cboxIE #cboxBottomRight,
+.cboxIE #cboxMiddleLeft,
+.cboxIE #cboxMiddleRight {
+    filter: progid:DXImageTransform.Microsoft.gradient(startColorstr=#00FFFFFF,endColorstr=#00FFFFFF);
+}
+
+/*
+  The following provides PNG transparency support for IE6
+  Feel free to remove this and the /ie6/ directory if you have dropped IE6 support.
+*/
+.cboxIE6 #cboxTopLeft{background:url(images/ie6/borderTopLeft.png);}
+.cboxIE6 #cboxTopCenter{background:url(images/ie6/borderTopCenter.png);}
+.cboxIE6 #cboxTopRight{background:url(images/ie6/borderTopRight.png);}
+.cboxIE6 #cboxBottomLeft{background:url(images/ie6/borderBottomLeft.png);}
+.cboxIE6 #cboxBottomCenter{background:url(images/ie6/borderBottomCenter.png);}
+.cboxIE6 #cboxBottomRight{background:url(images/ie6/borderBottomRight.png);}
+.cboxIE6 #cboxMiddleLeft{background:url(images/ie6/borderMiddleLeft.png);}
+.cboxIE6 #cboxMiddleRight{background:url(images/ie6/borderMiddleRight.png);}
+
+.cboxIE6 #cboxTopLeft,
+.cboxIE6 #cboxTopCenter,
+.cboxIE6 #cboxTopRight,
+.cboxIE6 #cboxBottomLeft,
+.cboxIE6 #cboxBottomCenter,
+.cboxIE6 #cboxBottomRight,
+.cboxIE6 #cboxMiddleLeft,
+.cboxIE6 #cboxMiddleRight {
+    _behavior: expression(this.src = this.src ? this.src : this.currentStyle.backgroundImage.split('"')[1], this.style.background = "none", this.style.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src=" + this.src + ", sizingMethod='scale')");
+}
diff --git a/src/edumed/static/jquery/colorbox/images/border.png b/src/edumed/static/jquery/colorbox/images/border.png
new file mode 100644 (file)
index 0000000..f463a10
Binary files /dev/null and b/src/edumed/static/jquery/colorbox/images/border.png differ
diff --git a/src/edumed/static/jquery/colorbox/images/controls.png b/src/edumed/static/jquery/colorbox/images/controls.png
new file mode 100644 (file)
index 0000000..dcfd6fb
Binary files /dev/null and b/src/edumed/static/jquery/colorbox/images/controls.png differ
diff --git a/src/edumed/static/jquery/colorbox/images/ie6/borderBottomCenter.png b/src/edumed/static/jquery/colorbox/images/ie6/borderBottomCenter.png
new file mode 100644 (file)
index 0000000..0d4475e
Binary files /dev/null and b/src/edumed/static/jquery/colorbox/images/ie6/borderBottomCenter.png differ
diff --git a/src/edumed/static/jquery/colorbox/images/ie6/borderBottomLeft.png b/src/edumed/static/jquery/colorbox/images/ie6/borderBottomLeft.png
new file mode 100644 (file)
index 0000000..2775eba
Binary files /dev/null and b/src/edumed/static/jquery/colorbox/images/ie6/borderBottomLeft.png differ
diff --git a/src/edumed/static/jquery/colorbox/images/ie6/borderBottomRight.png b/src/edumed/static/jquery/colorbox/images/ie6/borderBottomRight.png
new file mode 100644 (file)
index 0000000..f7f5137
Binary files /dev/null and b/src/edumed/static/jquery/colorbox/images/ie6/borderBottomRight.png differ
diff --git a/src/edumed/static/jquery/colorbox/images/ie6/borderMiddleLeft.png b/src/edumed/static/jquery/colorbox/images/ie6/borderMiddleLeft.png
new file mode 100644 (file)
index 0000000..a2d63d1
Binary files /dev/null and b/src/edumed/static/jquery/colorbox/images/ie6/borderMiddleLeft.png differ
diff --git a/src/edumed/static/jquery/colorbox/images/ie6/borderMiddleRight.png b/src/edumed/static/jquery/colorbox/images/ie6/borderMiddleRight.png
new file mode 100644 (file)
index 0000000..fd7c3e8
Binary files /dev/null and b/src/edumed/static/jquery/colorbox/images/ie6/borderMiddleRight.png differ
diff --git a/src/edumed/static/jquery/colorbox/images/ie6/borderTopCenter.png b/src/edumed/static/jquery/colorbox/images/ie6/borderTopCenter.png
new file mode 100644 (file)
index 0000000..2937a9c
Binary files /dev/null and b/src/edumed/static/jquery/colorbox/images/ie6/borderTopCenter.png differ
diff --git a/src/edumed/static/jquery/colorbox/images/ie6/borderTopLeft.png b/src/edumed/static/jquery/colorbox/images/ie6/borderTopLeft.png
new file mode 100644 (file)
index 0000000..f9d458b
Binary files /dev/null and b/src/edumed/static/jquery/colorbox/images/ie6/borderTopLeft.png differ
diff --git a/src/edumed/static/jquery/colorbox/images/ie6/borderTopRight.png b/src/edumed/static/jquery/colorbox/images/ie6/borderTopRight.png
new file mode 100644 (file)
index 0000000..74b8583
Binary files /dev/null and b/src/edumed/static/jquery/colorbox/images/ie6/borderTopRight.png differ
diff --git a/src/edumed/static/jquery/colorbox/images/loading.gif b/src/edumed/static/jquery/colorbox/images/loading.gif
new file mode 100644 (file)
index 0000000..b4695d8
Binary files /dev/null and b/src/edumed/static/jquery/colorbox/images/loading.gif differ
diff --git a/src/edumed/static/jquery/colorbox/images/loading_background.png b/src/edumed/static/jquery/colorbox/images/loading_background.png
new file mode 100644 (file)
index 0000000..6ae83e6
Binary files /dev/null and b/src/edumed/static/jquery/colorbox/images/loading_background.png differ
diff --git a/src/edumed/static/jquery/colorbox/images/overlay.png b/src/edumed/static/jquery/colorbox/images/overlay.png
new file mode 100644 (file)
index 0000000..53ea98f
Binary files /dev/null and b/src/edumed/static/jquery/colorbox/images/overlay.png differ
diff --git a/src/edumed/static/jquery/colorbox/jquery.colorbox-min.js b/src/edumed/static/jquery/colorbox/jquery.colorbox-min.js
new file mode 100644 (file)
index 0000000..45295d2
--- /dev/null
@@ -0,0 +1,6 @@
+/*!
+       jQuery ColorBox v1.4.1 - 2013-02-14
+       (c) 2013 Jack Moore - jacklmoore.com/colorbox
+       license: http://www.opensource.org/licenses/mit-license.php
+*/
+(function(e,t,i){function o(i,o,n){var r=t.createElement(i);return o&&(r.id=Y+o),n&&(r.style.cssText=n),e(r)}function n(e){var t=T.length,i=(A+e)%t;return 0>i?t+i:i}function r(e,t){return Math.round((/%/.test(e)?("x"===t?k.width():k.height())/100:1)*parseInt(e,10))}function h(e){return K.photo||K.photoRegex.test(e)}function l(e){return K.retinaUrl&&i.devicePixelRatio>1?e.replace(K.photoRegex,K.retinaSuffix):e}function s(t){e.contains(w[0],t.target)||w[0]===t.target||(t.stopPropagation(),w.focus())}function a(){var t,i=e.data(N,V);null==i?(K=e.extend({},J),console&&console.log&&console.log("Error: cboxElement missing settings object")):K=e.extend({},i);for(t in K)e.isFunction(K[t])&&"on"!==t.slice(0,2)&&(K[t]=K[t].call(N));K.rel=K.rel||N.rel||e(N).data("rel")||"nofollow",K.href=K.href||e(N).attr("href"),K.title=K.title||N.title,"string"==typeof K.href&&(K.href=e.trim(K.href))}function d(i,o){e(t).trigger(i),at.trigger(i),e.isFunction(o)&&o.call(N)}function c(){var e,t,i,o,n,r=Y+"Slideshow_",h="click."+Y;K.slideshow&&T[1]?(t=function(){clearTimeout(e)},i=function(){(K.loop||T[A+1])&&(e=setTimeout(G.next,K.slideshowSpeed))},o=function(){M.html(K.slideshowStop).unbind(h).one(h,n),at.bind(it,i).bind(tt,t).bind(ot,n),w.removeClass(r+"off").addClass(r+"on")},n=function(){t(),at.unbind(it,i).unbind(tt,t).unbind(ot,n),M.html(K.slideshowStart).unbind(h).one(h,function(){G.next(),o()}),w.removeClass(r+"on").addClass(r+"off")},K.slideshowAuto?o():n()):w.removeClass(r+"off "+r+"on")}function u(i){U||(N=i,a(),T=e(N),A=0,"nofollow"!==K.rel&&(T=e("."+Z).filter(function(){var t,i=e.data(this,V);return i&&(t=e(this).data("rel")||i.rel||this.rel),t===K.rel}),A=T.index(N),-1===A&&(T=T.add(N),A=T.length-1)),m.css({opacity:parseFloat(K.opacity),cursor:K.overlayClose?"pointer":"auto",visibility:"visible"}).show(),j||(j=q=!0,w.css({visibility:"hidden",display:"block"}),E=o(dt,"LoadedContent","width:0; height:0; overflow:hidden").appendTo(v),_=x.height()+C.height()+v.outerHeight(!0)-v.height(),z=y.width()+b.width()+v.outerWidth(!0)-v.width(),D=E.outerHeight(!0),B=E.outerWidth(!0),K.w=r(K.initialWidth,"x"),K.h=r(K.initialHeight,"y"),G.position(),lt&&k.bind("resize."+st+" scroll."+st,function(){m.css({width:k.width(),height:k.height(),top:k.scrollTop(),left:k.scrollLeft()})}).trigger("resize."+st),c(),d(et,K.onOpen),P.add(W).hide(),R.html(K.close).show(),w.focus(),t.addEventListener&&(t.addEventListener("focus",s,!0),at.one(nt,function(){t.removeEventListener("focus",s,!0)})),K.returnFocus&&at.one(nt,function(){e(N).focus()})),G.load(!0))}function f(){!w&&t.body&&(X=!1,k=e(i),w=o(dt).attr({id:V,"class":ht?Y+(lt?"IE6":"IE"):"",role:"dialog",tabindex:"-1"}).hide(),m=o(dt,"Overlay",lt?"position:absolute":"").hide(),L=o(dt,"LoadingOverlay").add(o(dt,"LoadingGraphic")),g=o(dt,"Wrapper"),v=o(dt,"Content").append(W=o(dt,"Title"),H=o(dt,"Current"),F=o("button","Previous"),S=o("button","Next"),M=o("button","Slideshow"),L,R=o("button","Close")),g.append(o(dt).append(o(dt,"TopLeft"),x=o(dt,"TopCenter"),o(dt,"TopRight")),o(dt,!1,"clear:left").append(y=o(dt,"MiddleLeft"),v,b=o(dt,"MiddleRight")),o(dt,!1,"clear:left").append(o(dt,"BottomLeft"),C=o(dt,"BottomCenter"),o(dt,"BottomRight"))).find("div div").css({"float":"left"}),I=o(dt,!1,"position:absolute; width:9999px; visibility:hidden; display:none"),P=S.add(F).add(H).add(M),e(t.body).append(m,w.append(g,I)))}function p(){function i(e){e.which>1||e.shiftKey||e.altKey||e.metaKey||(e.preventDefault(),u(this))}return w?(X||(X=!0,S.click(function(){G.next()}),F.click(function(){G.prev()}),R.click(function(){G.close()}),m.click(function(){K.overlayClose&&G.close()}),e(t).bind("keydown."+Y,function(e){var t=e.keyCode;j&&K.escKey&&27===t&&(e.preventDefault(),G.close()),j&&K.arrowKey&&T[1]&&!e.altKey&&(37===t?(e.preventDefault(),F.click()):39===t&&(e.preventDefault(),S.click()))}),e.isFunction(e.fn.on)?e(t).on("click."+Y,"."+Z,i):e("."+Z).live("click."+Y,i)),!0):!1}var m,w,g,v,x,y,b,C,T,k,E,I,L,W,H,M,S,F,R,P,K,_,z,D,B,N,A,O,j,q,U,$,G,Q,X,J={transition:"elastic",speed:300,width:!1,initialWidth:"600",innerWidth:!1,maxWidth:!1,height:!1,initialHeight:"450",innerHeight:!1,maxHeight:!1,scalePhotos:!0,scrolling:!0,inline:!1,html:!1,iframe:!1,fastIframe:!0,photo:!1,href:!1,title:!1,rel:!1,opacity:.9,preloading:!0,className:!1,retinaImage:!1,retinaUrl:!1,retinaSuffix:"@2x.$1",current:"image {current} of {total}",previous:"previous",next:"next",close:"close",xhrError:"This content failed to load.",imgError:"This image failed to load.",open:!1,returnFocus:!0,reposition:!0,loop:!0,slideshow:!1,slideshowAuto:!0,slideshowSpeed:2500,slideshowStart:"start slideshow",slideshowStop:"stop slideshow",photoRegex:/\.(gif|png|jp(e|g|eg)|bmp|ico)((#|\?).*)?$/i,onOpen:!1,onLoad:!1,onComplete:!1,onCleanup:!1,onClosed:!1,overlayClose:!0,escKey:!0,arrowKey:!0,top:!1,bottom:!1,left:!1,right:!1,fixed:!1,data:void 0},V="colorbox",Y="cbox",Z=Y+"Element",et=Y+"_open",tt=Y+"_load",it=Y+"_complete",ot=Y+"_cleanup",nt=Y+"_closed",rt=Y+"_purge",ht=!e.support.leadingWhitespace,lt=ht&&!i.XMLHttpRequest,st=Y+"_IE6",at=e({}),dt="div";e.colorbox||(e(f),G=e.fn[V]=e[V]=function(t,i){var o=this;if(t=t||{},f(),p()){if(e.isFunction(o))o=e("<a/>"),t.open=!0;else if(!o[0])return o;i&&(t.onComplete=i),o.each(function(){e.data(this,V,e.extend({},e.data(this,V)||J,t))}).addClass(Z),(e.isFunction(t.open)&&t.open.call(o)||t.open)&&u(o[0])}return o},G.position=function(e,t){function i(e){x[0].style.width=C[0].style.width=v[0].style.width=parseInt(e.style.width,10)-z+"px",v[0].style.height=y[0].style.height=b[0].style.height=parseInt(e.style.height,10)-_+"px"}var o,n,h,l=0,s=0,a=w.offset();k.unbind("resize."+Y),w.css({top:-9e4,left:-9e4}),n=k.scrollTop(),h=k.scrollLeft(),K.fixed&&!lt?(a.top-=n,a.left-=h,w.css({position:"fixed"})):(l=n,s=h,w.css({position:"absolute"})),s+=K.right!==!1?Math.max(k.width()-K.w-B-z-r(K.right,"x"),0):K.left!==!1?r(K.left,"x"):Math.round(Math.max(k.width()-K.w-B-z,0)/2),l+=K.bottom!==!1?Math.max(k.height()-K.h-D-_-r(K.bottom,"y"),0):K.top!==!1?r(K.top,"y"):Math.round(Math.max(k.height()-K.h-D-_,0)/2),w.css({top:a.top,left:a.left,visibility:"visible"}),e=w.width()===K.w+B&&w.height()===K.h+D?0:e||0,g[0].style.width=g[0].style.height="9999px",o={width:K.w+B+z,height:K.h+D+_,top:l,left:s},0===e&&w.css(o),w.dequeue().animate(o,{duration:e,complete:function(){i(this),q=!1,g[0].style.width=K.w+B+z+"px",g[0].style.height=K.h+D+_+"px",K.reposition&&setTimeout(function(){k.bind("resize."+Y,G.position)},1),t&&t()},step:function(){i(this)}})},G.resize=function(e){j&&(e=e||{},e.width&&(K.w=r(e.width,"x")-B-z),e.innerWidth&&(K.w=r(e.innerWidth,"x")),E.css({width:K.w}),e.height&&(K.h=r(e.height,"y")-D-_),e.innerHeight&&(K.h=r(e.innerHeight,"y")),e.innerHeight||e.height||(E.css({height:"auto"}),K.h=E.height()),E.css({height:K.h}),G.position("none"===K.transition?0:K.speed))},G.prep=function(t){function i(){return K.w=K.w||E.width(),K.w=K.mw&&K.mw<K.w?K.mw:K.w,K.w}function r(){return K.h=K.h||E.height(),K.h=K.mh&&K.mh<K.h?K.mh:K.h,K.h}if(j){var l,s="none"===K.transition?0:K.speed;E.empty().remove(),E=o(dt,"LoadedContent").append(t),E.hide().appendTo(I.show()).css({width:i(),overflow:K.scrolling?"auto":"hidden"}).css({height:r()}).prependTo(v),I.hide(),e(O).css({"float":"none"}),l=function(){function t(){ht&&w[0].style.removeAttribute("filter")}var i,r,l=T.length,a="frameBorder",c="allowTransparency";j&&(r=function(){clearTimeout($),L.hide(),d(it,K.onComplete)},ht&&O&&E.fadeIn(100),W.html(K.title).add(E).show(),l>1?("string"==typeof K.current&&H.html(K.current.replace("{current}",A+1).replace("{total}",l)).show(),S[K.loop||l-1>A?"show":"hide"]().html(K.next),F[K.loop||A?"show":"hide"]().html(K.previous),K.slideshow&&M.show(),K.preloading&&e.each([n(-1),n(1)],function(){var t,i,o=T[this],n=e.data(o,V);n&&n.href?(t=n.href,e.isFunction(t)&&(t=t.call(o))):t=e(o).attr("href"),t&&(h(t)||n.photo)&&(i=new Image,i.src=t)})):P.hide(),K.iframe?(i=o("iframe")[0],a in i&&(i[a]=0),c in i&&(i[c]="true"),K.scrolling||(i.scrolling="no"),e(i).attr({src:K.href,name:(new Date).getTime(),"class":Y+"Iframe",allowFullScreen:!0,webkitAllowFullScreen:!0,mozallowfullscreen:!0}).one("load",r).appendTo(E),at.one(rt,function(){i.src="//about:blank"}),K.fastIframe&&e(i).trigger("load")):r(),"fade"===K.transition?w.fadeTo(s,1,t):t())},"fade"===K.transition?w.fadeTo(s,0,function(){G.position(0,l)}):G.position(s,l)}},G.load=function(t){var n,s,c,u=G.prep;q=!0,O=!1,N=T[A],t||a(),Q&&w.add(m).removeClass(Q),K.className&&w.add(m).addClass(K.className),Q=K.className,d(rt),d(tt,K.onLoad),K.h=K.height?r(K.height,"y")-D-_:K.innerHeight&&r(K.innerHeight,"y"),K.w=K.width?r(K.width,"x")-B-z:K.innerWidth&&r(K.innerWidth,"x"),K.mw=K.w,K.mh=K.h,K.maxWidth&&(K.mw=r(K.maxWidth,"x")-B-z,K.mw=K.w&&K.w<K.mw?K.w:K.mw),K.maxHeight&&(K.mh=r(K.maxHeight,"y")-D-_,K.mh=K.h&&K.h<K.mh?K.h:K.mh),n=K.href,$=setTimeout(function(){L.show()},100),K.inline?(c=o(dt).hide().insertBefore(e(n)[0]),at.one(rt,function(){c.replaceWith(E.children())}),u(e(n))):K.iframe?u(" "):K.html?u(K.html):h(n)?(n=l(n),e(O=new Image).addClass(Y+"Photo").bind("error",function(){K.title=!1,u(o(dt,"Error").html(K.imgError))}).one("load",function(){var e;K.retinaImage&&i.devicePixelRatio>1&&(O.height=O.height/i.devicePixelRatio,O.width=O.width/i.devicePixelRatio),K.scalePhotos&&(s=function(){O.height-=O.height*e,O.width-=O.width*e},K.mw&&O.width>K.mw&&(e=(O.width-K.mw)/O.width,s()),K.mh&&O.height>K.mh&&(e=(O.height-K.mh)/O.height,s())),K.h&&(O.style.marginTop=Math.max(K.mh-O.height,0)/2+"px"),T[1]&&(K.loop||T[A+1])&&(O.style.cursor="pointer",O.onclick=function(){G.next()}),ht&&(O.style.msInterpolationMode="bicubic"),setTimeout(function(){u(O)},1)}),setTimeout(function(){O.src=n},1)):n&&I.load(n,K.data,function(t,i){u("error"===i?o(dt,"Error").html(K.xhrError):e(this).contents())})},G.next=function(){!q&&T[1]&&(K.loop||T[A+1])&&(A=n(1),G.load())},G.prev=function(){!q&&T[1]&&(K.loop||A)&&(A=n(-1),G.load())},G.close=function(){j&&!U&&(U=!0,j=!1,d(ot,K.onCleanup),k.unbind("."+Y+" ."+st),m.fadeTo(200,0),w.stop().fadeTo(300,0,function(){w.add(m).css({opacity:1,cursor:"auto"}).hide(),d(rt),E.empty().remove(),setTimeout(function(){U=!1,d(nt,K.onClosed)},1)}))},G.remove=function(){e([]).add(w).add(m).remove(),w=null,e("."+Z).removeData(V).removeClass(Z),e(t).unbind("click."+Y)},G.element=function(){return e(N)},G.settings=J)})(jQuery,document,window);
\ No newline at end of file
diff --git a/src/edumed/static/jquery/colorbox/jquery.colorbox-pl.js b/src/edumed/static/jquery/colorbox/jquery.colorbox-pl.js
new file mode 100644 (file)
index 0000000..370cdca
--- /dev/null
@@ -0,0 +1,16 @@
+/*\r
+       jQuery ColorBox language configuration\r
+       language: Polski (pl)\r
+       translated by: Tomasz Wasiński\r
+       site: 2bevisible.pl\r
+*/\r
+jQuery.extend(jQuery.colorbox.settings, {\r
+       current: "{current}. obrazek z {total}",\r
+       previous: "Poprzedni",\r
+       next: "Następny",\r
+       close: "Zamknij",\r
+       xhrError: "Nie udało się załadować treści.",\r
+       imgError: "Nie udało się załadować obrazka.",\r
+       slideshowStart: "rozpocznij pokaz slajdów",\r
+       slideshowStop: "zatrzymaj pokaz slajdów"\r
+});
\ No newline at end of file
diff --git a/src/edumed/static/js/formset.js b/src/edumed/static/js/formset.js
new file mode 100755 (executable)
index 0000000..7a4657f
--- /dev/null
@@ -0,0 +1,30 @@
+(function($) {
+    $(function() {
+
+
+function cloneMore(selector, type) {
+    var newElement = $(selector).clone(true);
+    var total = $('#id_' + type + '-TOTAL_FORMS').val();
+    newElement.find(':input').each(function() {
+        var name = $(this).attr('name').replace('__prefix__', total);
+        var id = 'id_' + name;
+        $(this).attr({'name': name, 'id': id});
+    });
+    newElement.find('label').each(function() {
+        var newFor = $(this).attr('for').replace('__prefix__', total);
+        $(this).attr('for', newFor);
+    });
+    newElement.attr({'style': '', 'id': ''});
+    total++;
+    $('#id_' + type + '-TOTAL_FORMS').val(total);
+    $(selector).before(newElement);
+}
+
+
+
+            $('.add_more').click(function() {
+                cloneMore($(this).data('selector'), $(this).data('prefix'));
+            });
+
+    });
+})(jQuery);
diff --git a/src/edumed/templates/404.html b/src/edumed/templates/404.html
new file mode 100644 (file)
index 0000000..74ee437
--- /dev/null
@@ -0,0 +1,14 @@
+{% extends "base.html" %}
+{% load i18n %}
+
+{% block title %}{% trans "Page not found" %}{% endblock %}
+
+{% block body %}
+
+<h1>{% trans "Page not found" %}</h1>
+
+<p class="notice">
+    {% trans "The page you were looking for doesn't exist." %}
+</p>
+
+{% endblock %}
diff --git a/src/edumed/templates/404_mil.html b/src/edumed/templates/404_mil.html
new file mode 100644 (file)
index 0000000..bdc4f15
--- /dev/null
@@ -0,0 +1,14 @@
+{% extends "base_mil.html" %}
+{% load i18n %}
+
+{% block title %}{% trans "Page not found" %}{% endblock %}
+
+{% block body %}
+
+<h1>{% trans "Page not found" %}</h1>
+
+<p class="notice">
+    {% trans "The page you were looking for doesn't exist." %}
+</p>
+
+{% endblock %}
diff --git a/src/edumed/templates/500.html b/src/edumed/templates/500.html
new file mode 100644 (file)
index 0000000..be751c1
--- /dev/null
@@ -0,0 +1,5 @@
+<h1>Wystąpił błąd serwera.</h1>
+
+<p>Coś poszło nie tak. Administratorzy zostali już powiadomieni.</p>
+
+<p>Przepraszamy!</p>
diff --git a/src/edumed/templates/annoy.html b/src/edumed/templates/annoy.html
new file mode 100755 (executable)
index 0000000..d48e669
--- /dev/null
@@ -0,0 +1,18 @@
+{% load static %}
+<a id='annoy-on' href="http://nowoczesnapolska.org.pl/pomoz-nam/wesprzyj-nas/">1%</a>
+<div id='annoy'>
+    <a href="http://nowoczesnapolska.org.pl/pomoz-nam/wesprzyj-nas/">
+        <img src='http://static.wolnelektury.pl/img/procent.png' alt="Logo akcji 1%" style="float:left;margin: 0 2em" /></a>
+    <p>Droga użytkowniczko, drogi użytkowniku!</p>
+    <p>Czy wiesz, że Edukacja Medialna to jeden z&nbsp;projektów
+    <strong>fundacji Nowoczesna Polska</strong> –
+    organizacji pożytku publicznego działającej na rzecz wolności korzystania
+    z&nbsp;dóbr kultury? Wesprzyj nasze działania, przeznaczając na nie 1% swojego podatku.
+    Możesz to zrobić, wpisując w&nbsp;zeznaniu podatkowym numer
+    <strong>KRS 0000070056</strong>.</p>
+
+    <p><a href="http://nowoczesnapolska.org.pl/pomoz-nam/wesprzyj-nas/">Dowiedz się więcej</a></p>
+    
+    <a id='annoy-off'>x</a>
+    <div style="clear:both;"></div>
+</div>
diff --git a/src/edumed/templates/base.html b/src/edumed/templates/base.html
new file mode 100644 (file)
index 0000000..6f1341d
--- /dev/null
@@ -0,0 +1,27 @@
+{% extends "base_super.html" %}
+{% load sponsor_tags %}
+{% load compressed %}
+
+
+{% block tagline %}Scenariusze zajęć, ćwiczenia, materiały{% endblock %}
+
+{% block top_navigation %}
+    <li><a class="menu-lekcje" href="{% url "catalogue_lessons" %}">Lekcje</a></li>
+    <li><a class="menu-kompetencje" href="{% url "curriculum" %}">Kompetencje</a></li>
+    <li><a class="menu-olimpiada" href="https://olimpiadacyfrowa.pl">Olimpiada</a></li>
+    <li><a class="menu-trener" href="{% url "info" "dlatrenera/" %}">Dla trenera</a></li>
+    <li><a class="menu-kurs" href="http://kurs.edukacjamedialna.edu.pl">Dla ucznia</a></li>
+    <li><a class="menu-o-nas" href="{% url "info" "o-nas/" %}">O projekcie</a></li>
+{% endblock %}
+
+{% block sponsors %}
+    {% sponsor_page "footer" %}
+{% endblock %}
+
+{% block extra_script %}
+    {% compressed_js 'base' %}
+{% endblock %}
+
+{% block copyrights %}
+    <p>Ikonki w menu: <a href="http://www.flaticon.com/authors/freepik">Designed by Freepik and distributed by Flaticon</a></p>
+{% endblock %}
\ No newline at end of file
diff --git a/src/edumed/templates/base_forum.html b/src/edumed/templates/base_forum.html
new file mode 100755 (executable)
index 0000000..587a1e8
--- /dev/null
@@ -0,0 +1,10 @@
+{% extends "base.html" %}
+{% load i18n %}
+
+{% block body %}
+<div class="forum-body">
+    {% block breadcrumb %}{% endblock %}
+    <a href="{% url 'forum_search' %}" style="position: absolute; top: 0; right: 5px;">{% trans 'Forum search' %}</a>
+    {% block content %}{% endblock %}
+</div>
+{% endblock %}
diff --git a/src/edumed/templates/base_mil.html b/src/edumed/templates/base_mil.html
new file mode 100644 (file)
index 0000000..7a88f45
--- /dev/null
@@ -0,0 +1,38 @@
+{% extends "base_super.html" %}
+{% load subdomainurls %}
+{% load fnp_lang %}
+{% load sponsor_tags %}
+{% load static %}
+
+{% load i18n %}
+
+{% block header_class %}header-mil{% endblock %}
+
+{% block logo %}
+<img src="{% static "img/logo-mil.png" %}" alt="Edukacja medialna"/>
+{% endblock %}
+
+{% block top_navigation %}
+    <li><a class="menu-consultations" href="{% url "mil_home" "katalog" %}">{% trans 'About Catalogue' %}</a></li>
+    <li><a class="menu-kompetencje" href="{% url "curriculum" %}">{% trans 'Competencies' %}</a></li>
+    {% comment %}<li><a class="menu-takepart" href="{% url "comment_document_index" %}">{% trans 'Take Part' %}</a></li>{% endcomment %}
+        {% if request.LANGUAGE_CODE == 'pl' %}
+            <li><a class="menu-knowledgebase" href="{% url 'knowledge_base' 'katalog' url='' %}">Baza wiedzy</a></li>
+        {% endif %}
+        <li><a class="menu-kontakt" href="{% url 'mil_contact' 'katalog' %}">{% trans 'Contact' %}</a></li>
+        <li>{% lang_switcher %}</li>
+{% endblock %}
+
+{% block sponsors %}
+    {% sponsor_page "footer_mil" %}
+{% endblock %}
+
+{% block organizer %}
+    Projekt prowadzi:<br/>
+    <a href="http://nowoczesnapolska.org.pl">
+        <img src="{% static "img/logo_fnp_white.png" %}" alt="Fundacja Nowoczesna Polska" />
+    </a><br/>
+    <a href="http://http://www.nina.gov.pl/">
+        <img src="{% static "img/nina-white.png" %}" alt="Narodowy Instytut Audiowizualny" />
+    </a>
+{% endblock %}
\ No newline at end of file
diff --git a/src/edumed/templates/base_super.html b/src/edumed/templates/base_super.html
new file mode 100644 (file)
index 0000000..fc82730
--- /dev/null
@@ -0,0 +1,114 @@
+<!DOCTYPE html>
+{% load i18n static %}
+{% load fnp_common fnp_share fnp_lang macros %}
+{% load compressed static %}
+{% load subdomainurls %}
+{% load piwik_tags %}
+
+{% macro title %}{% block title %}{% endblock %}{% endmacro %}
+{% macro site_name %}Edukacja medialna{% endmacro %}
+
+<html prefix="og: http://ogp.me/ns#">
+    <head>
+       <title>{% block full_title %}{% usemacro title %} :: {% usemacro site_name %}{% endblock %}</title>
+       <link rel="shortcut icon" type="image/png" href="{% static "img/favicon.png" %}" />
+        {% compressed_css 'base' %}
+
+        <meta charset="UTF-8" />
+        <meta property='og:url' content='{% block ogurl %}{{ "/"|build_absolute_uri:request }}{% endblock %}' />
+        <meta property='og:title' content='{% block og_title %}{% usemacro title %}{% endblock %}' />
+        <meta property='og:site_name' content='{% block og_site_name %}{% usemacro site_name %}{% endblock %}' />
+        <meta property='og:description' content='{% block og_description %}{% endblock %}' />
+        <meta property='og:type' content='{% block og_type %}website{% endblock %}' />
+        <meta property='og:image' content='{% block og_image %}http://edukacjamedialna.edu.pl/static/img/logo.png{% endblock %}' />
+        <meta property='og:locale' content='pl_PL' />
+        <!--[if lt IE 9]><script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script></script><![endif]-->
+    </head>
+    <body id="{% block body-id %}body{% endblock %}">
+        {% load fnp_annoy %}{% annoy %}
+        {% comment %}
+        <div id="banners">
+            <a href="https://nowoczesnapolska.org.pl/pomoz-nam/wesprzyj-nas/">
+                <img src="{% static 'img/banners/960x150_edukacjaMedialna.jpg' %}"
+                     alt="Wesprzyj działalność Nowoczesnej Polski"/>
+            </a>
+        </div>
+        {% endcomment %}
+        <div id="header-wrapper">
+        <header class="main {% block header_class %}{% endblock %}" style="position:relative;">
+            <!--img
+                src="{% static "tlo.png" %}"
+                style="position:absolute; opacity: 0.5; top:0; left: -83px; z-index:1000"
+                -->
+            {% if request.user.is_authenticated %}
+                <a href="{% url 'logout' subdomain=None %}" style="position: absolute; top:5px; right: 10px; font-size: 12px;">Wyloguj</a>
+            {% endif %}
+            <div id="header-top">
+            <a id="logo" href="/">{% block logo %}<img src="{% static "img/logo.png" %}" alt="Edukacja medialna"/>{% endblock %}</a>
+            <div id="organizer">
+                {% block organizer %}
+                Projekt prowadzi:<br/>
+                <a href="http://nowoczesnapolska.org.pl">
+                    <img src="{% static "img/logo_fnp.png" %}" alt="Fundacja Nowoczesna Polska" />
+                </a>
+                {% endblock %}
+            </div>
+            <nav><ul>
+                {% block top_navigation %}
+                {% endblock %}
+            </ul></nav>
+            </div>
+
+            <div id="tagline">{% block tagline %}{% endblock %}</div>
+            {% block searchbox %}
+              <div id="search">
+                  <form action="{% url 'haystack_search' None %}">
+                      <input name="q" placeholder="szukaj" /><button><span>&rarr;</span></button>
+                  </form>
+              </div>
+            {% endblock %}
+            <div class="clr"></div>
+        </header>
+        </div>
+
+        <div id="content">{% block body %}{% endblock %}</div>
+
+        <footer class="main">
+            {# chunks? #}
+            {% block footer_contact %}
+                <div class="footer-item">
+                    <p>
+                    fundacja Nowoczesna Polska<br/>
+                    <br/>
+                    ul. Marszałkowska 84/92 lok. 125<br/>
+                    00-514 Warszawa<br/>
+                    tel: +48 22 621 30 17<br/>
+                    e-mail: fundacja@nowoczesnapolska.org.pl
+                    <br/><br/>
+                    KRS: 0000070056<br/>
+                    REGON: 017423865<br/>
+                    Nr konta: 59 1030 0019 0109 8530 0040 5685
+                    </p>
+                </div>
+            {% endblock %}
+            <div class="footer-item" style="margin-right:0;">
+                <p>
+                Webdesign Ortografika<br/>
+                <br/>
+                Jeśli nie oznaczono inaczej, wszystkie materiały na stronie są objęte wolną licencją
+                <a href="http://creativecommons.org/licenses/by-sa/3.0/deed.pl">Creative Commons Uznanie autorstwa
+                – Na tych samych warunkach 3.0</a>.
+                {% block copyrights %}{% endblock %}
+                </p>
+            </div>
+            {% block sponsors %}
+            {% endblock %}
+            <div class="clr"></div>
+            <div class="footer-extra">{% block footer_extra %}{% endblock %}</div>
+        </footer>
+
+    <script src="//ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
+    {% block extra_script %}{% endblock %}
+    {% tracking_code %}
+    </body>
+</html>
diff --git a/src/edumed/templates/contact/collegium-mlodych-test/form.html b/src/edumed/templates/contact/collegium-mlodych-test/form.html
new file mode 100644 (file)
index 0000000..5235b54
--- /dev/null
@@ -0,0 +1,35 @@
+{% extends "contact/form.html" %}
+
+{% block body %}
+    {% include 'sciezki_logos.html' %}
+    {{ block.super }}
+{% endblock %}
+
+{% block form %}
+    {{ form.as_p }}
+    <p>
+      Test powstał w ramach projektu „Collegium Młodych – media i technologie” realizowanego w ramach
+      III Osi priorytetowej: Szkolnictwo wyższe dla gospodarki i rozwoju, Działanie 3.1 Kompetencje
+      w szkolnictwie wyższym Programu Operacyjnego Wiedza Edukacja Rozwój, współfinansowanego przez
+      Unię Europejską w ramach Europejskiego Funduszu Społecznego. Nr umowy POWR.03.01.00-00-C078/16-00.
+    </p>
+    <p>
+      Użytkowników, którzy wypełnili test kompetencji, zachęcamy do wypełnienia
+      <a href="/media/chunks/attachment/ZAKRES_DANYCH_OSOBOWYCH_DO_PRZETWARZANIA.pdf">FORMULARZU DANYCH OSOBOWYCH</a>
+      i przesłania go na adres fundacji. Pozwoli nam to na zaraportowanie naszych działań do
+      Narodowego Centrum Badań i Rozwoju.
+    </p>
+    <p>
+      Administratorem danych osobowych jest Fundacja Nowoczesna Polska (ul. Marszałkowska 84/92 lok. 125,
+      00-514 Warszawa). Podanie danych osobowych jest dobrowolne. Dane są przetwarzane w zakresie niezbędnym
+      do udziału w projekcie „Collegium Młodych - media i technologie”. Osobom, których dane są zbierane,
+      przysługuje prawo dostępu do treści swoich danych oraz ich poprawiania. Więcej informacji w
+      <a href="https://nowoczesnapolska.org.pl/prywatnosc/">polityce prywatności</a>.
+    </p>
+    <p>
+      Projekt „Collegium Młodych – media i technologie” jest finansowany ze środków
+      Narodowego Centrum Badań i Rozwoju. Dane zawarte w formularzu mogą być przekazane NCBiR
+      w ramach sprawozdawczości i kontroli realizacji projektu.
+    </p>
+    <p><button>{{ form.submit_label }}</button></p>
+{% endblock %}
diff --git a/src/edumed/templates/contact/collegium-mlodych-test/mail_subject.txt b/src/edumed/templates/contact/collegium-mlodych-test/mail_subject.txt
new file mode 100644 (file)
index 0000000..f315550
--- /dev/null
@@ -0,0 +1 @@
+Wyniki testu
\ No newline at end of file
diff --git a/src/edumed/templates/contact/collegium-mlodych-test/results.html b/src/edumed/templates/contact/collegium-mlodych-test/results.html
new file mode 100644 (file)
index 0000000..49d2682
--- /dev/null
@@ -0,0 +1,61 @@
+{% extends base_template|default:"base.html" %}
+{% load i18n %}
+{% load contact_tags %}
+
+{% block title %}Wyniki{% endblock %}
+
+{% block body %}
+    {% include 'sciezki_logos.html' %}
+    <h1>Wyniki</h1>
+
+    <p>Suma uzyskanych punktów: {{ results.points|floatformat }} na {{ results.total }} możliwych.</p>
+
+    {% if 'collegium-mlodych'|is_enabled %}
+        <p class="box-button" style="max-width: 20em;"><a href="{% url 'contact_form' 'collegium-mlodych' %}" class="nice-button">Zgłoś się na warsztaty</a></p>
+    {% endif %}
+
+    {% for question in results.questions %}
+        <strong>{{ question.label }}</strong>
+        <ol class="alpha">
+            {% for answer, chosen, correct in question.answers %}
+                <li style="{% if chosen %}font-weight: bold;{% endif %}{% if correct %}color: #00cc44;{% endif %}">{{ answer }}</li>
+            {% endfor %}
+        </ol>
+        <p><strong>Komentarze do odpowiedzi:</strong></p>
+        {% for answer in question.answer_data %}
+            <p><strong>{{ answer.letter }}</strong>:</p>
+            {{ answer.comment }}
+        {% endfor %}
+    {% endfor %}
+    {% if 'collegium-mlodych'|is_enabled %}
+        <p class="box-button" style="max-width: 20em;"><a href="{% url 'contact_form' 'collegium-mlodych' %}" class="nice-button">Zgłoś się na warsztaty</a></p>
+    {% endif %}
+    {% comment %}
+    <p>Pytania stworzyli: Grzegorz Stunża, Marcin Wilkowski.</p>
+    <p>Komentarzami opatrzyła: Justyna Bakalarska.</p>
+    {% endcomment %}
+    <p>
+      Test powstał w ramach projektu „Collegium Młodych – media i technologie” realizowanego w ramach
+      III Osi priorytetowej: Szkolnictwo wyższe dla gospodarki i rozwoju, Działanie 3.1 Kompetencje
+      w szkolnictwie wyższym Programu Operacyjnego Wiedza Edukacja Rozwój, współfinansowanego przez
+      Unię Europejską w ramach Europejskiego Funduszu Społecznego. Nr umowy POWR.03.01.00-00-C078/16-00.
+    </p>
+    <p>
+      Użytkowników, którzy wypełnili test kompetencji, zachęcamy do wypełnienia
+      <a href="/media/chunks/attachment/ZAKRES_DANYCH_OSOBOWYCH_DO_PRZETWARZANIA.pdf">FORMULARZU DANYCH OSOBOWYCH</a>
+      i przesłania go na adres fundacji. Pozwoli nam to na zaraportowanie naszych działań do
+      Narodowego Centrum Badań i Rozwoju.
+    </p>
+    <p>
+      Administratorem danych osobowych jest Fundacja Nowoczesna Polska (ul. Marszałkowska 84/92 lok. 125,
+      00-514 Warszawa). Podanie danych osobowych jest dobrowolne. Dane są przetwarzane w zakresie niezbędnym
+      do udziału w projekcie „Collegium Młodych - media i technologie”. Osobom, których dane są zbierane,
+      przysługuje prawo dostępu do treści swoich danych oraz ich poprawiania. Więcej informacji w
+      <a href="https://nowoczesnapolska.org.pl/prywatnosc/">polityce prywatności</a>.
+    </p>
+    <p>
+      Projekt „Collegium Młodych – media i technologie” jest finansowany ze środków
+      Narodowego Centrum Badań i Rozwoju. Dane zawarte w formularzu mogą być przekazane NCBiR
+      w ramach sprawozdawczości i kontroli realizacji projektu.
+    </p>
+{% endblock %}
\ No newline at end of file
diff --git a/src/edumed/templates/contact/collegium-mlodych-test/results_email.txt b/src/edumed/templates/contact/collegium-mlodych-test/results_email.txt
new file mode 100644 (file)
index 0000000..3b015ac
--- /dev/null
@@ -0,0 +1,17 @@
+{% load contact_tags %}Witaj,
+
+Oto wyniki testu:
+
+Suma uzyskanych punktów: {{ results.points|floatformat }} na {{ results.total }} możliwych.
+
+Pod poniższym adresem możesz obejrzeć swoje odpowiedzi z komentarzami:
+https://edukacjamedialna.edu.pl{% url 'contact_results' contact.id contact.digest %}
+{% if 'collegium-mlodych'|is_enabled %}
+Zgłoś się na warsztaty:
+https://edukacjamedialna.edu.pl{% url 'contact_form' 'collegium-mlodych' %}
+{% endif %}
+Z pozdrowieniami,
+fundacja Nowoczesna Polska
+
+--
+Wiadomość wysłana automatycznie. Prosimy na nią nie odpowiadać.
\ No newline at end of file
diff --git a/src/edumed/templates/contact/collegium-mlodych/form.html b/src/edumed/templates/contact/collegium-mlodych/form.html
new file mode 100644 (file)
index 0000000..d1ddbf8
--- /dev/null
@@ -0,0 +1,31 @@
+{% extends "contact/form.html" %}
+
+{% block body %}
+    {% include 'sciezki_logos.html' %}
+    {{ block.super }}
+{% endblock %}
+
+{% block form_extra %}
+    <tr>
+      <td colspan="2">
+        <p>
+          Warsztaty realizowane są w ramach projektu „Collegium Młodych – media i technologie” realizowanego w ramach
+          III Osi priorytetowej: Szkolnictwo wyższe dla gospodarki i rozwoju, Działanie 3.1 Kompetencje
+          w szkolnictwie wyższym Programu Operacyjnego Wiedza Edukacja Rozwój, współfinansowanego przez
+          Unię Europejską w ramach Europejskiego Funduszu Społecznego. Nr umowy POWR.03.01.00-00-C078/16-00.
+        </p>
+        <p>
+          Administratorem danych osobowych jest Fundacja Nowoczesna Polska (ul. Marszałkowska 84/92 lok. 125,
+          00-514 Warszawa). Podanie danych osobowych jest dobrowolne. Dane są przetwarzane w zakresie niezbędnym
+          do udziału w projekcie „Collegium Młodych - media i technologie”. Osobom, których dane są zbierane,
+          przysługuje prawo dostępu do treści swoich danych oraz ich poprawiania. Więcej informacji w
+          <a href="https://nowoczesnapolska.org.pl/prywatnosc/">polityce prywatności</a>.
+        </p>
+        <p>
+          Projekt „Collegium Młodych – media i technologie” jest finansowany ze środków
+          Narodowego Centrum Badań i Rozwoju. Dane zawarte w formularzu mogą być przekazane NCBiR
+          w ramach sprawozdawczości i kontroli realizacji projektu.
+        </p>
+      </td>
+    </tr>
+{% endblock %}
\ No newline at end of file
diff --git a/src/edumed/templates/contact/collegium-mlodych/mail_body.txt b/src/edumed/templates/contact/collegium-mlodych/mail_body.txt
new file mode 100644 (file)
index 0000000..71ca78f
--- /dev/null
@@ -0,0 +1,20 @@
+Witaj,
+
+Dziękujemy za przesłanie zgłoszenia do udziału w warsztatach z zakresu edukacji medialnej i cyfrowej prowadzonych przez Collegium Civitas i Fundację Nowoczesna Polska w ramach projektu „Collegium Młodych – media i technologie”.
+
+Pamiętaj, że aby zaakceptować Twoje zgłoszenie, musimy otrzymać komplet dokumentów rekrutacyjnych w formie papierowej, opatrzonych wymaganymi podpisami, oraz potwierdzić dane w nich zawarte. O ostatecznej decyzji powiadomimy Ciebie i Twojego rodzica / opiekuna prawnego w późniejszym terminie.
+
+Wzory dokumentów rekrutacyjnych znajdziesz pod adresem
+http://edukacjamedialna.edu.pl/media/chunks/attachment/dokumenty_rekrutacyjne_v2.zip.
+
+Po wypełnieniu i podpisaniu odeślij je na adres:
+
+Fundacja Nowoczesna Polska
+ul. Marszałkowska 84/92 lok. 125
+00-514 Warszawa
+z dopiskiem: Warsztaty – Ścieżki Kopernika
+
+Jeśli masz jakieś pytania, napisz do nas: warsztaty@nowoczesnapolska.org.pl lub zadzwoń: (22) 465-15-35.
+
+Pozdrawiamy,
+fundacja Nowoczesna Polska
\ No newline at end of file
diff --git a/src/edumed/templates/contact/collegium-mlodych/mail_subject.txt b/src/edumed/templates/contact/collegium-mlodych/mail_subject.txt
new file mode 100644 (file)
index 0000000..28ae8f2
--- /dev/null
@@ -0,0 +1 @@
+Potwierdzenie otrzymania zgłoszenia
\ No newline at end of file
diff --git a/src/edumed/templates/contact/collegium-mlodych/on_hold.html b/src/edumed/templates/contact/collegium-mlodych/on_hold.html
new file mode 100644 (file)
index 0000000..f8e645d
--- /dev/null
@@ -0,0 +1,13 @@
+{% extends "base.html" %}
+
+{% block title %}{{ title }}{% endblock %}
+
+{% block body %}
+
+    <h1>{{ title }}</h1>
+
+    {% block contact_form_description %}
+        <p class="notice">W związku z dużym zainteresowaniem warsztatami rekrutacja została wstrzymana na czas weryfikacji zgłoszeń uczestników.</p>
+    {% endblock %}
+
+{% endblock %}
diff --git a/src/edumed/templates/contact/collegium-mlodych/thanks.html b/src/edumed/templates/contact/collegium-mlodych/thanks.html
new file mode 100644 (file)
index 0000000..4d470bc
--- /dev/null
@@ -0,0 +1,27 @@
+{% extends "contact/thanks.html" %}
+
+{% block body %}
+    {% include "sciezki_logos.html" %}
+    {{ block.super }}
+{% endblock %}
+
+{% block contact_form_description %}
+    <p>Dziękujemy za przesłanie zgłoszenia do udziału w warsztatach z zakresu edukacji medialnej i cyfrowej prowadzonych przez Collegium Civitas i Fundację Nowoczesna Polska w ramach projektu „Collegium Młodych – media i technologie”.</p>
+
+    <p>Pamiętaj, że aby zaakceptować Twoje zgłoszenie, musimy otrzymać komplet dokumentów rekrutacyjnych w formie papierowej, opatrzonych wymaganymi podpisami, oraz potwierdzić dane w nich zawarte. O ostatecznej decyzji powiadomimy Ciebie i Twojego rodzica / opiekuna prawnego w późniejszym terminie.</p>
+
+    <p class="box-button"><a href="/media/chunks/attachment/dokumenty_rekrutacyjne_v2.zip" class="dl-button">Pobierz wzory dokumentów rekrutacyjnych</a></p>
+
+    <p>Po wypełnieniu i podpisaniu dokumentów, odeślij je na adres:</p>
+
+    <p>Fundacja Nowoczesna Polska<br>
+    ul. Marszałkowska 84/92 lok. 125<br>
+    00-514 Warszawa<br>
+    z dopiskiem: Warsztaty – Ścieżki Kopernika</p>
+
+    <p>Jeśli masz jakieś pytania, napisz do nas:
+    <a href="mailto:warsztaty@nowoczesnapolska.org.pl">warsztaty@nowoczesnapolska.org.pl</a> lub zadzwoń: (22) 465-15-35.</p>
+
+    <p>Pozdrawiamy,<br>
+    fundacja Nowoczesna Polska</p>
+{% endblock %}
diff --git a/src/edumed/templates/contact/konkurs/mail_body.txt b/src/edumed/templates/contact/konkurs/mail_body.txt
new file mode 100644 (file)
index 0000000..6e4ba7c
--- /dev/null
@@ -0,0 +1,15 @@
+Dziękujemy za rejestrację udziału w konkursie MediaLog.
+
+Przypominamy, że prace można nadsyłać do 6 maja 2013 na adres 
+edukacjamedialna@nowoczesnapolska.org.pl. W mailu należy podać dane 
+kontaktowe Autora/ów pracy, Opiekuna (osoby, która zarejestrowała udział 
+danej instytucji w konkursie i prowadziła zajęcia z edukacji medialnej) 
+oraz nazwę instytucji (szkoły, biblioteki, domu kultury itp.). 
+W przypadku prac opublikowanych już wcześniej wystarczy w mailu podać
+link do odpowiedniej strony.
+
+W razie jakichkolwiek wątpliwości prosimy o kontakt:
+http://edukacjamedialna.edu.pl/info/kontakt/
+
+-- 
+Wiadomość wysłana automatycznie. Prosimy na nią nie odpowiadać.
diff --git a/src/edumed/templates/contact/konkurs/mail_subject.txt b/src/edumed/templates/contact/konkurs/mail_subject.txt
new file mode 100644 (file)
index 0000000..386c1e6
--- /dev/null
@@ -0,0 +1 @@
+Zgłoszenie na konkurs MediaLog zostało zarejestrowane.
diff --git a/src/edumed/templates/contact/konkurs/thanks.html b/src/edumed/templates/contact/konkurs/thanks.html
new file mode 100644 (file)
index 0000000..6c4a518
--- /dev/null
@@ -0,0 +1,13 @@
+{% extends "contact/thanks.html" %}
+
+{% block contact_form_description %}
+<p>Dziękujemy za rejestrację udziału w konkursie MediaLog.</p>
+
+<p>Przypominamy, że prace można nadsyłać do 6 maja 2013 na adres 
+edukacjamedialna@nowoczesnapolska.org.pl. W mailu należy podać dane 
+kontaktowe Autora/ów pracy, Opiekuna (osoby, która zarejestrowała udział 
+danej instytucji w konkursie i prowadziła zajęcia z edukacji medialnej) 
+oraz nazwę instytucji (szkoły, biblioteki, domu kultury itp.). 
+W przypadku prac opublikowanych już wcześniej wystarczy w mailu podać
+link do odpowiedniej strony.</p>
+{% endblock %}
diff --git a/src/edumed/templates/contact/misja-cybernautow/mail_body.txt b/src/edumed/templates/contact/misja-cybernautow/mail_body.txt
new file mode 100644 (file)
index 0000000..ddbcc44
--- /dev/null
@@ -0,0 +1,9 @@
+Treść maila potwierdzającego rejestrację zespołu.
+
+Link do formularza edycji: https://{{ site_domain }}{{ contact.update_url }}
+
+W razie jakichkolwiek wątpliwości prosimy o kontakt:
+http://edukacjamedialna.edu.pl/info/kontakt/
+
+--
+Wiadomość wysłana automatycznie. Prosimy na nią nie odpowiadać.
diff --git a/src/edumed/templates/contact/olimpiada/form.html b/src/edumed/templates/contact/olimpiada/form.html
new file mode 100755 (executable)
index 0000000..c28925a
--- /dev/null
@@ -0,0 +1,93 @@
+{% extends "base.html" %}
+{% load chunks %}
+{% load honeypot %}
+
+{% block title %}{{ form.form_title }}{% endblock %}
+
+{% block body %}
+
+
+
+
+
+
+    <h1>{% block contact_form_title %}{{ form.form_title }}{% endblock %}</h1>
+
+    <div class="form-info">
+    {% block contact_form_description %}
+        {% chunk "contact_form__"|add:form.form_tag %}
+    {% endblock %}
+    </div>
+
+    <form method="POST" action="." enctype="multipart/form-data" class="submit-form">
+    {% csrf_token %}
+    {% render_honeypot_field %}
+    <h3>Dane Przewodniczącego i szkoły zgłaszającej Uczestników:</h3>
+    <table>
+        {{ form.as_table }}
+    </table>
+
+    {% with formsets.commission as formset %}
+
+        <h3>Dane członków Komisji Szkolnej:</h3>
+
+        {{ formset.management_form }}
+
+        <ul class="errorlist">
+        {% for err in formset.non_form_errors %}
+            <li>{{ err }}</li>
+        {% endfor %}
+        </ul>
+
+        {% for form in formset.forms %}
+            <table>
+                {{ form.as_table }}
+            </table>
+        {% endfor %}
+
+        <div id="formstub-{{ formset.prefix }}" style="display:none">
+            <table>
+                {{ formset.empty_form.as_table }}
+            </table>
+        </div>
+
+        <input type="button" value="+ Dodaj kolejną osobę" class="add_more" data-selector="#formstub-{{formset.prefix}}" data-prefix="{{formset.prefix}}">
+    {% endwith %}
+
+
+    {% with formsets.student as formset %}
+        <h3>Dane Uczestników:</h3>
+
+        {{ formset.management_form }}
+
+        <ul class="errorlist">
+        {% for err in formset.non_form_errors %}
+            <li>{{ err }}</li>
+        {% endfor %}
+        </ul>
+
+        {% for form in formset.forms %}
+            <h4>Uczestnik/Uczestniczka:</h4>
+
+            <table>
+                {{ form.as_table }}
+            </table>
+        {% endfor %}
+
+        <div id="formstub-{{ formset.prefix }}" style="display:none">
+            <h4>Uczestnik/Uczestniczka:</h4>
+            <table>
+                {{ formset.empty_form.as_table }}
+            </table>
+        </div>
+
+        <input type="button" value="+ Dodaj kolejną osobę" class="add_more" data-selector="#formstub-{{formset.prefix}}" data-prefix="{{formset.prefix}}">
+    {% endwith %}
+
+    <p>
+    <button style="font-size:1.5em;">{% block contact_form_submit %}{{ form.submit_label }}{% endblock %}</button>
+    </p>
+    </form>
+
+
+{% endblock %}
diff --git a/src/edumed/templates/contact/olimpiada/mail_body.txt b/src/edumed/templates/contact/olimpiada/mail_body.txt
new file mode 100755 (executable)
index 0000000..0a63f92
--- /dev/null
@@ -0,0 +1,19 @@
+Dziękujemy za rejestrację w Olimpiadzie Cyfrowej.
+Do udziału zostały zgłoszone następujące osoby:
+{% for student in contact.body.student %}* {{ student.first_name }} {{ student.last_name }}{% endfor %}
+
+Każdy zgłoszony uczeń powinien otrzymać wiadomość z potwierdzeniem
+rejestracji. Prosimy upewnić się, czy potwierdzenie dotarło do każdego
+ze zgłoszonych uczniów. W ten sposób zweryfikujemy, czy podane adresy
+są prawidłowe.
+
+Pierwszy etap Olimpiady (test on-line) odbędzie się
+15 listopada 2016 r. o godz. 10:00 i potrwa 90 minut.
+
+Wszystkie ogłoszenia związane z Turniejem będą publikowane na stronie https://olimpiadacyfrowa.pl.
+W razie pytań lub wątpliwości można kontaktować się z nami, pisząc na adres: olimpiada@nowoczesnapolska.org.pl.
+
+Z pozdrowieniami,
+
+Zespół Olimpiady Cyfrowej
+Fundacja Nowoczesna Polska
\ No newline at end of file
diff --git a/src/edumed/templates/contact/olimpiada/mail_subject.txt b/src/edumed/templates/contact/olimpiada/mail_subject.txt
new file mode 100755 (executable)
index 0000000..b40c079
--- /dev/null
@@ -0,0 +1 @@
+Potwierdzenie zgłoszenia uczniów do Olimpiady Cyfrowej
\ No newline at end of file
diff --git a/src/edumed/templates/contact/olimpiada/student_mail_body.html b/src/edumed/templates/contact/olimpiada/student_mail_body.html
new file mode 100644 (file)
index 0000000..eb3df3e
--- /dev/null
@@ -0,0 +1,17 @@
+Witaj,
+
+Przewodniczący Komisji Szkolnej właśnie zgłosił Cię do Olimpiady Cyfrowej.
+Cieszymy się, że chcesz wziąć w niej udział.
+
+Pierwszy etap Olimpiady (test on-line) odbędzie się 15 listopada 2016 r.
+o godz. 10:00 i potrwa 90 minut.
+
+Szczegółowe informacje na temat pierwszego etapu Olimpiady oraz wszystkie
+ogłoszenia z nią związane będą publikowane na stronie https://olimpiadacyfrowa.pl.
+W razie pytań lub wątpliwości możesz kontaktować się z nami, pisząc na adres
+olimpiada@nowoczesnapolska.org.pl.
+
+Z pozdrowieniami,
+
+Zespół Olimpiady Cyfrowej
+Fundacja Nowoczesna Polska
diff --git a/src/edumed/templates/contact/olimpiada/student_mail_subject.html b/src/edumed/templates/contact/olimpiada/student_mail_subject.html
new file mode 100644 (file)
index 0000000..4910d3f
--- /dev/null
@@ -0,0 +1 @@
+Potwierdzenie zgłoszenia do Olimpiady Cyfrowej
\ No newline at end of file
diff --git a/src/edumed/templates/contact/olimpiada/thanks.html b/src/edumed/templates/contact/olimpiada/thanks.html
new file mode 100755 (executable)
index 0000000..f05dd36
--- /dev/null
@@ -0,0 +1,17 @@
+{% extends "contact/thanks.html" %}
+
+{% block contact_form_description %}
+<p>Dziękujemy za rejestrację w Olimpiadzie Cyfrowej.</p>
+
+<p>Na adres e-mail Przewodniczącego/Przewodniczącej została wysłana wiadomość potwierdzająca
+rejestrację.</p>
+
+<p>Każdy zgłoszony uczeń powinien otrzymać wiadomość z potwierdzeniem
+rejestracji.
+Prosimy upewnić się, że potwierdzenie dotarło do każdego ze
+zgłoszonych uczniów.
+W ten sposób zweryfikujemy, czy podane adresy są prawidłowe. </p>
+
+<p>Zespół Olimpiady Cyfrowej<br>
+fundacja Nowoczesna Polska</p>
+{% endblock %}
diff --git a/src/edumed/templates/contact/sciezki-kopernika-test/form.html b/src/edumed/templates/contact/sciezki-kopernika-test/form.html
new file mode 100644 (file)
index 0000000..59433a2
--- /dev/null
@@ -0,0 +1,11 @@
+{% extends "contact/form.html" %}
+
+{% block body %}
+    {% include 'sciezki_logos.html' %}
+    {{ block.super }}
+{% endblock %}
+
+{% block form %}
+    {{ form.as_p }}
+    <p><button>{{ form.submit_label }}</button></p>
+{% endblock %}
diff --git a/src/edumed/templates/contact/sciezki-kopernika-test/mail_subject.txt b/src/edumed/templates/contact/sciezki-kopernika-test/mail_subject.txt
new file mode 100644 (file)
index 0000000..f315550
--- /dev/null
@@ -0,0 +1 @@
+Wyniki testu
\ No newline at end of file
diff --git a/src/edumed/templates/contact/sciezki-kopernika-test/results.html b/src/edumed/templates/contact/sciezki-kopernika-test/results.html
new file mode 100644 (file)
index 0000000..46f51ad
--- /dev/null
@@ -0,0 +1,33 @@
+{% extends base_template|default:"base.html" %}
+{% load i18n %}
+
+{% block title %}Wyniki{% endblock %}
+
+{% block body %}
+    {% include 'sciezki_logos.html' %}
+    <h1>Wyniki</h1>
+
+    <p>Suma uzyskanych punktów: {{ results.points|floatformat }} na {{ results.total }} możliwych.</p>
+
+    {#<p class="box-button" style="max-width: 20em;"><a href="{% url 'contact_form' 'sciezki-kopernika' %}" class="nice-button">Zgłoś się na warsztaty</a></p>#}
+
+    {% for question in results.questions %}
+        <strong>{{ question.label }}</strong>
+        <ol class="alpha">
+            {% for answer, chosen, correct in question.answers %}
+                <li style="{% if chosen %}font-weight: bold;{% endif %}{% if correct %}color: #00cc44;{% endif %}">{{ answer }}</li>
+            {% endfor %}
+        </ol>
+        {% if question.chosen == question.correct %}
+            <p>Wybrana poprawna odpowiedź {{ question.chosen }}.</p>
+        {% else %}
+            <p>Wybrana odpowiedź {{ question.chosen }}, poprawna odpowiedź {{ question.correct }}.</p>
+        {% endif %}
+        <p><strong>Komentarz do odpowiedzi:</strong></p>
+        {{ question.comment }}
+    {% endfor %}
+    {#<p class="box-button" style="max-width: 20em;"><a href="{% url 'contact_form' 'sciezki-kopernika' %}" class="nice-button">Zgłoś się na warsztaty</a></p>#}
+    <p>Pytania stworzyli: Grzegorz Stunża, Marcin Wilkowski.</p>
+    <p>Komentarzami opatrzyli: Paulina Piasecka, Paweł Maranowski.</p>
+
+{% endblock %}
\ No newline at end of file
diff --git a/src/edumed/templates/contact/sciezki-kopernika-test/results_email.txt b/src/edumed/templates/contact/sciezki-kopernika-test/results_email.txt
new file mode 100644 (file)
index 0000000..7b68c48
--- /dev/null
@@ -0,0 +1,19 @@
+Witaj,
+
+Oto wyniki testu:
+
+Suma uzyskanych punktów: {{ results.points|floatformat }} na {{ results.total }} możliwych.
+
+Pod poniższym adresem możesz obejrzeć swoje odpowiedzi z komentarzami:
+https://edukacjamedialna.edu.pl{% url 'contact_results' contact.id contact.digest %}
+
+{% comment %}
+Zgłoś się na warsztaty:
+https://edukacjamedialna.edu.pl{% url 'contact_form' 'sciezki-kopernika' %}
+{% endcomment %}
+
+Z pozdrowieniami,
+fundacja Nowoczesna Polska
+
+--
+Wiadomość wysłana automatycznie. Prosimy na nią nie odpowiadać.
\ No newline at end of file
diff --git a/src/edumed/templates/contact/sciezki-kopernika/form.html b/src/edumed/templates/contact/sciezki-kopernika/form.html
new file mode 100644 (file)
index 0000000..31f6534
--- /dev/null
@@ -0,0 +1,6 @@
+{% extends "contact/form.html" %}
+
+{% block body %}
+    {% include 'sciezki_logos.html' %}
+    {{ block.super }}
+{% endblock %}
\ No newline at end of file
diff --git a/src/edumed/templates/contact/sciezki-kopernika/mail_body.txt b/src/edumed/templates/contact/sciezki-kopernika/mail_body.txt
new file mode 100644 (file)
index 0000000..0760553
--- /dev/null
@@ -0,0 +1,20 @@
+Witaj,
+
+Dziękujemy za przesłanie zgłoszenia do udziału w warsztatach z zakresu edukacji medialnej i cyfrowej prowadzonych przez Collegium Civitas i Fundację Nowoczesna Polska w ramach projektu „Collegium Młodych – media i technologie”.
+
+Pamiętaj, że aby zaakceptować Twoje zgłoszenie, musimy otrzymać komplet dokumentów rekrutacyjnych w formie papierowej, opatrzonych wymaganymi podpisami, oraz potwierdzić dane w nich zawarte. O ostatecznej decyzji powiadomimy Ciebie i Twojego rodzica / opiekuna prawnego w późniejszym terminie.
+
+Wzory dokumentów rekrutacyjnych znajdziesz pod adresem
+http://edukacjamedialna.edu.pl/media/chunks/attachment/dokumenty_rekrutacyjne.zip.
+
+Po wypełnieniu i podpisaniu odeślij je na adres:
+
+Fundacja Nowoczesna Polska
+ul. Marszałkowska 84/92 lok. 125
+00-514 Warszawa
+z dopiskiem: Warsztaty – Ścieżki Kopernika
+
+Jeśli masz jakieś pytania, napisz do nas: warsztaty@nowoczesnapolska.org.pl lub zadzwoń: (22) 465-15-35.
+
+Pozdrawiamy,
+fundacja Nowoczesna Polska
\ No newline at end of file
diff --git a/src/edumed/templates/contact/sciezki-kopernika/mail_subject.txt b/src/edumed/templates/contact/sciezki-kopernika/mail_subject.txt
new file mode 100644 (file)
index 0000000..28ae8f2
--- /dev/null
@@ -0,0 +1 @@
+Potwierdzenie otrzymania zgłoszenia
\ No newline at end of file
diff --git a/src/edumed/templates/contact/sciezki-kopernika/thanks.html b/src/edumed/templates/contact/sciezki-kopernika/thanks.html
new file mode 100644 (file)
index 0000000..b55caa3
--- /dev/null
@@ -0,0 +1,27 @@
+{% extends "contact/thanks.html" %}
+
+{% block body %}
+    {% include "sciezki_logos.html" %}
+    {{ block.super }}
+{% endblock %}
+
+{% block contact_form_description %}
+    <p>Dziękujemy za przesłanie zgłoszenia do udziału w warsztatach z zakresu edukacji medialnej i cyfrowej prowadzonych przez Collegium Civitas i Fundację Nowoczesna Polska w ramach projektu „Collegium Młodych – media i technologie”.</p>
+
+    <p>Pamiętaj, że aby zaakceptować Twoje zgłoszenie, musimy otrzymać komplet dokumentów rekrutacyjnych w formie papierowej, opatrzonych wymaganymi podpisami, oraz potwierdzić dane w nich zawarte. O ostatecznej decyzji powiadomimy Ciebie i Twojego rodzica / opiekuna prawnego w późniejszym terminie.</p>
+
+    <p class="box-button"><a href="/media/chunks/attachment/dokumenty_rekrutacyjne.zip" class="dl-button">Pobierz wzory dokumentów rekrutacyjnych</a></p>
+
+    <p>Po wypełnieniu i podpisaniu dokumentów, odeślij je na adres:</p>
+
+    <p>Fundacja Nowoczesna Polska<br>
+    ul. Marszałkowska 84/92 lok. 125<br>
+    00-514 Warszawa<br>
+    z dopiskiem: Warsztaty – Ścieżki Kopernika</p>
+
+    <p>Jeśli masz jakieś pytania, napisz do nas:
+    <a href="mailto:warsztaty@nowoczesnapolska.org.pl">warsztaty@nowoczesnapolska.org.pl</a> lub zadzwoń: (22) 465-15-35.</p>
+
+    <p>Pozdrawiamy,<br>
+    fundacja Nowoczesna Polska</p>
+{% endblock %}
diff --git a/src/edumed/templates/contact/sugestie/mail_body.txt b/src/edumed/templates/contact/sugestie/mail_body.txt
new file mode 100644 (file)
index 0000000..ad38005
--- /dev/null
@@ -0,0 +1,10 @@
+Dziękujemy,
+
+Zgłoszenie na stronie {{ site_name }}
+zostało przekazane koordynatorce projektu.
+
+W razie jakichkolwiek dodatkowych wątpliwości prosimy o kontakt:
+http://edukacjamedialna.edu.pl/info/kontakt/
+
+-- 
+Wiadomość wysłana automatycznie. Prosimy na nią nie odpowiadać.
diff --git a/src/edumed/templates/contact/sugestie/mail_subject.txt b/src/edumed/templates/contact/sugestie/mail_subject.txt
new file mode 100644 (file)
index 0000000..19fcbfa
--- /dev/null
@@ -0,0 +1 @@
+Zgłoszenie na stronie {{ site_name }} zostało zarejestrowane.
diff --git a/src/edumed/templates/contact/sugestie/thanks.html b/src/edumed/templates/contact/sugestie/thanks.html
new file mode 100644 (file)
index 0000000..5c89bba
--- /dev/null
@@ -0,0 +1,5 @@
+{% extends "contact/thanks.html" %}
+
+{% block contact_form_description %}
+<p>Dziękujemy, zgłoszenie zostało zarejestrowane.</p>
+{% endblock %}
diff --git a/src/edumed/templates/contact/tem/mail_body.txt b/src/edumed/templates/contact/tem/mail_body.txt
new file mode 100755 (executable)
index 0000000..bb22ccb
--- /dev/null
@@ -0,0 +1,8 @@
+Dziękujemy za przesłanie zgłoszenia.
+
+O wynikach rekrutacji poinformujemy uczestników do 30 kwietnia. 
+
+Z pozdrowieniami
+
+Zespół Edukacji Medialnej
+fundacja Nowoczesna Polska
diff --git a/src/edumed/templates/contact/tem/mail_subject.txt b/src/edumed/templates/contact/tem/mail_subject.txt
new file mode 100755 (executable)
index 0000000..edd517f
--- /dev/null
@@ -0,0 +1 @@
+TEM - szkolenie dla trenerów edukacji medialnej
diff --git a/src/edumed/templates/contact/tem/thanks.html b/src/edumed/templates/contact/tem/thanks.html
new file mode 100755 (executable)
index 0000000..0f0c893
--- /dev/null
@@ -0,0 +1,7 @@
+{% extends "contact/thanks.html" %}
+
+{% block contact_form_description %}
+<p>Dziękujemy za przesłanie zgłoszenia.</p>
+
+<p>O wynikach rekrutacji poinformujemy uczestników do 30 kwietnia.</p>
+{% endblock %}
diff --git a/src/edumed/templates/contact/trenerzy-cybernauci/mail_body.txt b/src/edumed/templates/contact/trenerzy-cybernauci/mail_body.txt
new file mode 100644 (file)
index 0000000..948a6d8
--- /dev/null
@@ -0,0 +1,15 @@
+Dziękujemy za przesłanie zgłoszenia do udziału w Szkoleniu Trenerskim i wdrażaniu Programu Szkoleniowego w ramach projektu „Cybernauci”.
+
+Zakończenie naboru dokumentów nastąpi 7 maja. Następnie dokumenty zostaną poddane weryfikacji formalnej i merytorycznej, w wyniku której zostaną wyłonione osoby do drugiego etapu rekrutacji – rozmów telefonicznych.
+
+O stanie rekrutacji będziemy informować mailowo.
+
+Z pozdrowieniami,
+zespół projektu „Cybernauci”
+
+---
+
+„Cybernauci - kompleksowy projekt kształtowania bezpiecznych zachowań w sieci” jest finansowany ze środków Ministra Edukacji Narodowej.
+
+Parter projektu: Collegium Civitas
+Patronat honorowy: Ministerstwo Cyfryzacji, Rzecznik Praw Dziecka Marek Michalak, Ośrodek Rozwoju Edukacji
diff --git a/src/edumed/templates/contact/trenerzy-cybernauci/mail_subject.txt b/src/edumed/templates/contact/trenerzy-cybernauci/mail_subject.txt
new file mode 100644 (file)
index 0000000..15eaebc
--- /dev/null
@@ -0,0 +1 @@
+Dziękujemy za przesłanie formularza zgłoszeniowego
\ No newline at end of file
diff --git a/src/edumed/templates/contact/trenerzy-cybernauci2017 b/src/edumed/templates/contact/trenerzy-cybernauci2017
new file mode 120000 (symlink)
index 0000000..66a5718
--- /dev/null
@@ -0,0 +1 @@
+trenerzy-cybernauci
\ No newline at end of file
diff --git a/src/edumed/templates/contact/wspolpraca/mail_body.txt b/src/edumed/templates/contact/wspolpraca/mail_body.txt
new file mode 100644 (file)
index 0000000..1e68866
--- /dev/null
@@ -0,0 +1,9 @@
+Dziękujemy,
+
+Zgłoszenie na stronie {{ site_name }} zostało zarejestrowane.
+
+W razie jakichkolwiek dodatkowych wątpliwości prosimy o kontakt:
+http://edukacjamedialna.edu.pl/info/kontakt/
+
+-- 
+Wiadomość wysłana automatycznie. Prosimy na nią nie odpowiadać.
diff --git a/src/edumed/templates/contact/wspolpraca/mail_subject.txt b/src/edumed/templates/contact/wspolpraca/mail_subject.txt
new file mode 100644 (file)
index 0000000..19fcbfa
--- /dev/null
@@ -0,0 +1 @@
+Zgłoszenie na stronie {{ site_name }} zostało zarejestrowane.
diff --git a/src/edumed/templates/contact/wspolpraca/thanks.html b/src/edumed/templates/contact/wspolpraca/thanks.html
new file mode 100644 (file)
index 0000000..5c89bba
--- /dev/null
@@ -0,0 +1,5 @@
+{% extends "contact/thanks.html" %}
+
+{% block contact_form_description %}
+<p>Dziękujemy, zgłoszenie zostało zarejestrowane.</p>
+{% endblock %}
diff --git a/src/edumed/templates/contact/wtem/form.html b/src/edumed/templates/contact/wtem/form.html
new file mode 100755 (executable)
index 0000000..e340633
--- /dev/null
@@ -0,0 +1,71 @@
+{% extends "base.html" %}
+{% load chunks %}
+
+{% block title %}{{ form.form_title }}{% endblock %}
+
+{% block body %}
+
+
+
+
+
+
+    <h1>{% block contact_form_title %}{{ form.form_title }}{% endblock %}</h1>
+
+    <div class="form-info">
+    {% block contact_form_description %}
+        {% chunk "contact_form__"|add:form.form_tag %}
+    {% endblock %}
+    </div>
+
+    <form method="POST" action="." enctype="multipart/form-data" class="submit-form">
+    {% csrf_token %}
+    <h3>Dane Opiekuna/Opiekunki i instytucji zgłaszającej Uczestnika:</h3>
+    <table>
+        {{ form.as_table }}
+    </table>
+
+    {% for formset in formsets %}
+
+        <h3>Dane Uczestników i Uczestniczek:</h3>
+       <p>Można zgłosić 3 do 5 osób.</p>
+
+        {{ formset.management_form }}
+
+        <ul class="errorlist">
+        {% for err in formset.non_form_errors %}
+            <li>{{ err }}</li>
+        {% endfor %}
+        </ul>
+
+        {% for form in formset.forms %}
+            <h4>Uczestnik lub Uczestniczka nr {{ forloop.counter }}:</h4>
+
+            <table>
+                {{ form.as_table }}
+            </table>
+        {% endfor %}
+
+{% comment %}
+        <div id="formstub-{{ formset.prefix }}" style="display:none">
+            <h3>Dane Uczestnika/Uczestniczki:</h3>
+            <table>
+                {{ formset.empty_form.as_table }}
+            </table>
+        </div>
+
+        <input type="button" value="+ Dodaj kolejną osobę" class="add_more" data-selector="#formstub-{{formset.prefix}}" data-prefix="{{formset.prefix}}">
+{% endcomment %}
+        <script>
+
+        </script>
+
+    {% endfor %}
+
+    <p>
+    <button style="font-size:1.5em;">{% block contact_form_submit %}{{ form.submit_label }}{% endblock %}</button>
+    </p>
+    </form>
+
+
+{% endblock %}
diff --git a/src/edumed/templates/contact/wtem/mail_body.txt b/src/edumed/templates/contact/wtem/mail_body.txt
new file mode 100755 (executable)
index 0000000..0a63f92
--- /dev/null
@@ -0,0 +1,19 @@
+Dziękujemy za rejestrację w Olimpiadzie Cyfrowej.
+Do udziału zostały zgłoszone następujące osoby:
+{% for student in contact.body.student %}* {{ student.first_name }} {{ student.last_name }}{% endfor %}
+
+Każdy zgłoszony uczeń powinien otrzymać wiadomość z potwierdzeniem
+rejestracji. Prosimy upewnić się, czy potwierdzenie dotarło do każdego
+ze zgłoszonych uczniów. W ten sposób zweryfikujemy, czy podane adresy
+są prawidłowe.
+
+Pierwszy etap Olimpiady (test on-line) odbędzie się
+15 listopada 2016 r. o godz. 10:00 i potrwa 90 minut.
+
+Wszystkie ogłoszenia związane z Turniejem będą publikowane na stronie https://olimpiadacyfrowa.pl.
+W razie pytań lub wątpliwości można kontaktować się z nami, pisząc na adres: olimpiada@nowoczesnapolska.org.pl.
+
+Z pozdrowieniami,
+
+Zespół Olimpiady Cyfrowej
+Fundacja Nowoczesna Polska
\ No newline at end of file
diff --git a/src/edumed/templates/contact/wtem/mail_subject.txt b/src/edumed/templates/contact/wtem/mail_subject.txt
new file mode 100755 (executable)
index 0000000..b40c079
--- /dev/null
@@ -0,0 +1 @@
+Potwierdzenie zgłoszenia uczniów do Olimpiady Cyfrowej
\ No newline at end of file
diff --git a/src/edumed/templates/contact/wtem/student_mail_body.html b/src/edumed/templates/contact/wtem/student_mail_body.html
new file mode 100644 (file)
index 0000000..eb3df3e
--- /dev/null
@@ -0,0 +1,17 @@
+Witaj,
+
+Przewodniczący Komisji Szkolnej właśnie zgłosił Cię do Olimpiady Cyfrowej.
+Cieszymy się, że chcesz wziąć w niej udział.
+
+Pierwszy etap Olimpiady (test on-line) odbędzie się 15 listopada 2016 r.
+o godz. 10:00 i potrwa 90 minut.
+
+Szczegółowe informacje na temat pierwszego etapu Olimpiady oraz wszystkie
+ogłoszenia z nią związane będą publikowane na stronie https://olimpiadacyfrowa.pl.
+W razie pytań lub wątpliwości możesz kontaktować się z nami, pisząc na adres
+olimpiada@nowoczesnapolska.org.pl.
+
+Z pozdrowieniami,
+
+Zespół Olimpiady Cyfrowej
+Fundacja Nowoczesna Polska
diff --git a/src/edumed/templates/contact/wtem/student_mail_subject.html b/src/edumed/templates/contact/wtem/student_mail_subject.html
new file mode 100644 (file)
index 0000000..4910d3f
--- /dev/null
@@ -0,0 +1 @@
+Potwierdzenie zgłoszenia do Olimpiady Cyfrowej
\ No newline at end of file
diff --git a/src/edumed/templates/contact/wtem/thanks.html b/src/edumed/templates/contact/wtem/thanks.html
new file mode 100755 (executable)
index 0000000..0185bcc
--- /dev/null
@@ -0,0 +1,15 @@
+{% extends "contact/thanks.html" %}
+
+{% block contact_form_description %}
+<p>Dziękujemy za rejestrację w Wielkim Turnieju Edukacji Medialnej.</p>
+
+<p>Na adres adres e-mail Opiekuna została wysłana wiadomość potwierdzająca
+rejestrację.</p>
+
+<p>Każdy zgłoszony uczeń powinien otrzymać wiadomość z potwierdzeniem rejestracji.
+Prosimy upewnić się, czy potwierdzenie dotarło do każdego ze zgłoszonych uczniów.
+W ten sposób zweryfikujemy, czy podane adresy są prawidłowe. </p>
+
+<p>Zespół Edukacji Medialnej<br>
+fundacja Nowoczesna Polska</p>
+{% endblock %}
diff --git a/src/edumed/templates/flatpages/default.html b/src/edumed/templates/flatpages/default.html
new file mode 100755 (executable)
index 0000000..1ab012c
--- /dev/null
@@ -0,0 +1,10 @@
+{% extends "base.html" %}
+{% load textile_pl from fnp_markup %}
+
+{% block title %}{{ flatpage.title }}{% endblock %}
+
+{% block body %}
+<div id="main-bar" class="flatpage">
+{{ flatpage.content|textile_pl }}
+</div>
+{% endblock %}
diff --git a/src/edumed/templates/flatpages/mil.html b/src/edumed/templates/flatpages/mil.html
new file mode 100644 (file)
index 0000000..5ac86a6
--- /dev/null
@@ -0,0 +1,10 @@
+{% extends "base_mil.html" %}
+{% load textile_pl from fnp_markup %}
+
+{% block title %}{{ flatpage.title }}{% endblock %}
+
+{% block body %}
+<div id="main-bar" class="flatpage">
+{{ flatpage.content|textile_pl }}
+</div>
+{% endblock %}
diff --git a/src/edumed/templates/flatpages/sciezki.html b/src/edumed/templates/flatpages/sciezki.html
new file mode 100644 (file)
index 0000000..9b0c392
--- /dev/null
@@ -0,0 +1,11 @@
+{% extends "base.html" %}
+{% load textile_pl from fnp_markup %}
+
+{% block title %}{{ flatpage.title }}{% endblock %}
+
+{% block body %}
+    {% include "sciezki_logos.html" %}
+    <div id="main-bar" class="flatpage">
+        {{ flatpage.content|textile_pl }}
+    </div>
+{% endblock %}
diff --git a/src/edumed/templates/home.html b/src/edumed/templates/home.html
new file mode 100755 (executable)
index 0000000..2ea96c6
--- /dev/null
@@ -0,0 +1,68 @@
+{% extends "base.html" %}
+{% load catalogue_tags %}
+{% load course_boxes_toc from curriculum_tags %}
+{% load chunk from chunks %}
+{% load static %}
+
+{% block full_title %}Edukacja medialna{% endblock %}
+
+{% block body %}
+
+{% catalogue_carousel %}
+
+<section id="main-promobox">
+  {% chunk "promobox" %}
+</section>
+
+<section id="main-sections">
+  <h1>Lekcje:</h1>
+  {% catalogue_levels_main %}
+</section>
+
+<section id="main-howto">
+  <h1>Nasze lekcje to:</h1>
+  <ul class="link-list">
+    <li><a class="knowledge" href="/info/jak-korzystac/#wiedza-w-pigulce">wiedza w pigułce</a></li>
+    <li><a class="activity" href="/info/jak-korzystac/#zadania">zadania</a></li>
+    <li><a class="lesson-plan" href="/info/jak-korzystac/#scenariusze">scenariusze</a></li>
+    <li><a class="reference" href="/info/jak-korzystac/#slowniczek">słowniczek</a></li>
+  </ul>
+  <p>Zobacz, <a href="{% url 'info' 'dobre-praktyki' %}">jak przeprowadzili je inni.</a></p>
+
+  <iframe width="220" height="124" src="//www.youtube.com/embed/XJ2q_ZCPIA8?controls=2&amp;rel=0&amp;showinfo=0&amp;theme=light" frameborder="0" allowfullscreen></iframe>
+</section>
+
+<section id="main-chosen">
+<h1>Według podstawy programowej:</h1>
+{% course_boxes_toc %}
+</section>
+
+
+<section id="main-tools">
+
+<section class="main-tools-box">
+<h1>Aktualności na stronie Fundacji</h1>
+{% latest_blog_posts "http://nowoczesnapolska.org.pl/feed" 5 %}
+</section>
+
+<section class="main-tools-box">
+<h1>Narzędzia</h1>
+<ul class="link-list">
+    <li><a href="{% url 'contact_form' 'sugestie' %}">Zgłoś błąd lub sugestię</a></li>
+    <li><a href="{% url 'info' 'jak-korzystac/' %}">Jak korzystać?</a></li>
+    <li><a href="{% url 'catalogue_lesson' 'slowniczek' %}">Słowniczek</a></li>
+    <li><a href="{% url 'catalogue_lesson' 'metody' %}">Metody edukacyjne</a></li>
+    {% if request.user.is_authenticated %}<li><a href="{% url 'pybb:index' %}">Forum</a></li>{% endif %}
+    <li><a href="{% url 'info' 'infografiki' %}">Infografiki</a></li>
+    <li><a href="{% url 'info' 'aplikacje-mobilne' %}">Aplikacje mobilne</a></li>
+    <li><a href="/media/chunks/attachment/poradnik-bezpieczenstwa-mobilnego.pdf">Poradnik bezpieczeństwa mobilnego (PDF)</a></li>
+    <li><a href="http://nowoczesnapolska.org.pl/prywatnosc/">Polityka prywatności i ciasteczka</a></li>
+</ul>
+</section>
+
+<div style="clear:both"></div>
+</section>
+
+
+{% endblock %}
+
diff --git a/src/edumed/templates/home_mil.html b/src/edumed/templates/home_mil.html
new file mode 100644 (file)
index 0000000..5811963
--- /dev/null
@@ -0,0 +1,5 @@
+{% extends "base_mil.html" %}
+
+{% block body %}
+mil
+{% endblock %}
diff --git a/src/edumed/templates/olimpiada_teaser.html b/src/edumed/templates/olimpiada_teaser.html
new file mode 100644 (file)
index 0000000..f5266d8
--- /dev/null
@@ -0,0 +1,45 @@
+{% extends "base_super.html" %}
+{% load textile_pl from fnp_markup %}
+{% load sponsor_tags %}
+{% load compressed %}
+{% load static %}
+
+{% block full_title %}Olimpiada cyfrowa{% endblock %}
+
+{% block og_site_name %}Olimpiada cyfrowa{% endblock %}
+
+{% block ogurl %}https://olimpiadacyfrowa.pl{% endblock %}
+
+{% block og_image %}http://olimpiadacyfrowa.pl/media/chunks/attachment/olimpiada_cyfrowa_logo.png{% endblock %}
+
+{% block logo %}<img src="{% static "img/logo-oc.png" %}" height="73" alt="Olimpiada cyfrowa"/>{% endblock %}
+
+{% block searchbox %}{% endblock %}
+
+{% block top_navigation %}
+  <li><a class="menu-oc-regulamin" href="/regulamin/">Regulamin</a></li>
+  <li><a class="menu-oc-program" href="/program/">Program</a></li>
+  <li><a class="menu-oc-literatura" href="/literatura/">Literatura</a></li>
+  <li><a class="menu-oc-harmonogram" href="/harmonogram/">Harmonogram</a></li>
+  <li><a class="menu-oc-komitet" href="/sklad/">Rada i komitet</a></li>
+  <li><a class="menu-oc-kontakt" href="/kontakt/">Kontakt</a></li>
+{% endblock %}
+
+{% block body %}
+  <div id="main-bar" class="flatpage">
+    {{ flatpage.content|textile_pl }}
+  </div>
+{% endblock %}
+
+{% block copyrights %}
+  <br/>Ikonki w menu:
+  <a href="http://www.flaticon.com/authors/freepik">Designed by Freepik and distributed by Flaticon</a>
+{% endblock %}
+
+{% block sponsors %}
+    {% sponsor_page "footer_olimpiada" %}
+{% endblock %}
+
+{% block extra_script %}
+    {% compressed_js 'base' %}
+{% endblock %}
\ No newline at end of file
diff --git a/src/edumed/templates/pybb/_need_to_login_message.html b/src/edumed/templates/pybb/_need_to_login_message.html
new file mode 100755 (executable)
index 0000000..bcc8550
--- /dev/null
@@ -0,0 +1,2 @@
+{% load i18n %}
+<a href="{% url 'login' %}">{% trans "Login" %} / {% trans "register" %}</a> {% trans "to create to post a reply" %}.
diff --git a/src/edumed/templates/pybb/avatar.html b/src/edumed/templates/pybb/avatar.html
new file mode 100755 (executable)
index 0000000..0358753
--- /dev/null
@@ -0,0 +1,8 @@
+{% load pybb_tags %}
+{% load libravatar_tags %}
+<div class="avatar">
+    {% pybb_get_profile user=user as user_profile %}
+    <a href="{{ user_profile.get_absolute_url }}">
+        <img src="{% libravatar user.email PYBB_AVATAR_WIDTH %}" alt="{{ user }} libravatar" width="{{ PYBB_AVATAR_WIDTH }}" height="{{ PYBB_AVATAR_HEIGHT }}" />
+    </a>
+</div>
diff --git a/src/edumed/templates/pybb/breadcrumb.html b/src/edumed/templates/pybb/breadcrumb.html
new file mode 100755 (executable)
index 0000000..a537281
--- /dev/null
@@ -0,0 +1,20 @@
+{% load i18n pybb_tags %}
+<ul class='breadcrumb'>
+    {% include "pybb/breadcrumb_top_extra_crumb.html" %}
+    <li><a href="{% url 'pybb:index' %}">Forum</a> <span class="divider">/</span></li>
+    {% if object %}
+        {% if object.get_parents %}
+            {% for obj in object.get_parents %}
+                <li>{% pybb_link obj %} <span class="divider">/</span></li>
+            {% endfor %}
+        {% endif %}
+        {% if extra_crumb %}
+            <li>{% pybb_link object %} <span class="divider">/</span></li>
+        {% else %}
+            <li>{{ object }}</li>
+        {% endif %}
+    {% endif %}
+    {% if extra_crumb %}
+        <li>{% trans extra_crumb %}</li>
+    {% endif %}
+</ul>
diff --git a/src/edumed/templates/pybb/breadcrumb_top_extra_crumb.html b/src/edumed/templates/pybb/breadcrumb_top_extra_crumb.html
new file mode 100755 (executable)
index 0000000..dd09f97
--- /dev/null
@@ -0,0 +1 @@
+<li><a href="{% url 'home' %}">Strona główna</a> <span class="divider">/</span></li>
diff --git a/src/edumed/templates/sciezki_logos.html b/src/edumed/templates/sciezki_logos.html
new file mode 100644 (file)
index 0000000..84cc45d
--- /dev/null
@@ -0,0 +1,5 @@
+{% load static %}
+<img src="{% static 'img/sciezki-kopernika/fe.jpg' %}" height="60" style="margin-right: 20px;">
+<img src="{% static 'img/sciezki-kopernika/cc.jpg' %}" height="60" style="margin-right: 20px;">
+<img src="{% static 'img/sciezki-kopernika/fnp.png' %}" height="60" style="margin-right: 20px;">
+<img src="{% static 'img/sciezki-kopernika/ue.jpg' %}" height="60">
\ No newline at end of file
diff --git a/src/edumed/templates/search/search.html b/src/edumed/templates/search/search.html
new file mode 100755 (executable)
index 0000000..4216ab9
--- /dev/null
@@ -0,0 +1,25 @@
+{% extends "base.html" %}
+
+{% block body %}
+    <h1>Wyszukiwanie</h1>
+
+    {% if query %}
+        {% for result in page.object_list %}
+            <p>
+                <a href="{{ result.object.get_absolute_url }}">{{ result.object.title }}</a>
+            </p>
+        {% empty %}
+            <p>Brak wyników.</p>
+        {% endfor %}
+
+        {% if page.has_previous or page.has_next %}
+            <div>
+                {% if page.has_previous %}<a href="?q={{ query }}&amp;page={{ page.previous_page_number }}">{% endif %}&laquo; Poprzednie{% if page.has_previous %}</a>{% endif %}
+                |
+                {% if page.has_next %}<a href="?q={{ query }}&amp;page={{ page.next_page_number }}">{% endif %}Następne &raquo;{% if page.has_next %}</a>{% endif %}
+            </div>
+        {% endif %}
+    {% else %}
+        <p>Brak wyników.</p>
+    {% endif %}
+{% endblock %}
diff --git a/src/edumed/templatetags/__init__.py b/src/edumed/templatetags/__init__.py
new file mode 100644 (file)
index 0000000..d384124
--- /dev/null
@@ -0,0 +1,4 @@
+# -*- coding: utf-8 -*-
+# This file is part of Wolnelektury, licensed under GNU Affero GPLv3 or later.
+# Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
+#
diff --git a/src/edumed/templatetags/inline_stylesheet.py b/src/edumed/templatetags/inline_stylesheet.py
new file mode 100644 (file)
index 0000000..76f0faf
--- /dev/null
@@ -0,0 +1,39 @@
+# -*- coding: utf-8 -*-
+# https://github.com/jazzband/django-pipeline/issues/295#issuecomment-152095865
+# adjusted for older pipeline
+from __future__ import unicode_literals
+import codecs
+
+from django.contrib.staticfiles.storage import staticfiles_storage
+from django.utils.safestring import mark_safe
+from django import template
+from pipeline.templatetags import compressed
+
+register = template.Library()
+
+
+class StylesheetNode(compressed.CompressedCSSNode):
+    def render_css(self, package, path):
+        return self.render_individual_css(package, [path])
+
+    def render_individual_css(self, package, paths, **kwargs):
+        html = []
+        for path in paths:
+            with codecs.open(staticfiles_storage.path(path), 'r', 'utf-8') as f:
+                html.append(f.read())
+        html = '<style type="text/css">' + '\n'.join(html) + '</style>'
+        return mark_safe(html)
+
+
+@register.tag
+def inline_stylesheet(parser, token):
+    """ Template tag that mimics pipeline's stylesheet tag, but embeds
+    the resulting CSS directly in the page.
+    """
+    try:
+        tag_name, name = token.split_contents()
+    except ValueError:
+        raise template.TemplateSyntaxError(
+            '%r requires exactly one argument: the name of a group in the PIPELINE_CSS setting'
+            % token.split_contents()[0])
+    return StylesheetNode(name)
diff --git a/src/edumed/urls.py b/src/edumed/urls.py
new file mode 100644 (file)
index 0000000..262c433
--- /dev/null
@@ -0,0 +1,74 @@
+# -*- coding: utf-8 -*-
+from django.conf.urls import patterns, include, url
+from django.conf import settings
+from django.contrib.flatpages.views import flatpage
+from django.shortcuts import redirect
+
+from .views import HomeView, AvatarlessProfileEditView, flatpage_with_template
+
+urlpatterns = patterns(
+    '',
+    url(r'^$', HomeView.as_view(), name="home"),
+    url(r'^lekcje/', include('catalogue.urls')),
+    url(r'^info/turniej/(?P<url>.*)$', lambda request, url: redirect('olimpiada', url)),
+    url(r'^info/(?P<url>.*)$', flatpage, name="info"),
+    url(r'^olimpiada/$', lambda request: flatpage(request, 'turniej/'), name='olimpiada'),
+    url(r'^olimpiada/(?P<url>.*)$', lambda request, url: flatpage(request, 'turniej/' + url), name='olimpiada'),
+    url(r'^olimpiada-teaser/(?P<url>.*)$',
+        lambda request, url: flatpage_with_template(request, 'turniej/' + url, 'olimpiada_teaser.html'),
+        name='olimpiada_teaser'),
+    url(r'^szukaj/', include('haystack.urls')),
+    url(r'^zglos/', include('contact.urls')),
+    url(r'^forum/profile/edit/$', AvatarlessProfileEditView.as_view(), name='edit_profile'),
+    url(r'^forum/', include('forum.urls')),
+    url(r'^forum/', include('pybb.urls', namespace='pybb')),
+    url(r'^kompetencje/', include('curriculum.urls')),
+    url(r'^wlem/', include('wtem.urls')),
+    url(r'^api/', include('api.urls')),
+)
+
+
+# Admin stuff, if necessary.
+if 'django.contrib.admin' in settings.INSTALLED_APPS:
+    from django.contrib import admin
+    admin.autodiscover()
+
+    if 'django_cas' in settings.INSTALLED_APPS:
+        urlpatterns += patterns(
+            '',
+            (r'^admin/logout/$', 'django_cas.views.logout'),
+        )
+    urlpatterns += patterns(
+        '',
+        url(r'^admin/doc/', include('django.contrib.admindocs.urls')),
+        url(r'^admin/', include(admin.site.urls)),
+    )
+
+# Auth stuff, if necessary
+if 'django_cas' in settings.INSTALLED_APPS:
+    urlpatterns += patterns(
+        '',
+        url(r'^accounts/login/$', 'django_cas.views.login', name='login'),
+        url(r'^accounts/logout/$', 'django_cas.views.logout', name='logout'),
+    )
+
+
+if settings.DEBUG:
+    from fnpdjango.utils.urls import i18n_patterns
+    from .views import mil_home_view, mil_contact_view, mil_knowledge_base_view
+    urlpatterns += i18n_patterns(
+        '',
+        url(r'^katalog/$', mil_home_view, name="mil_home"),
+        url(r'^wez-udzial/', include('comment.urls')),
+        url(r'^kontakt/$', mil_contact_view, name='mil_contact'),
+        url(r'^bazawiedzy/(?P<url>.*)$', mil_knowledge_base_view, name="knowledge_base"),
+    )
+
+
+if settings.DEBUG:
+    urlpatterns += patterns(
+        '',
+        url(r'^media/(?P<path>.*)$', 'django.views.static.serve', {
+            'document_root': settings.MEDIA_ROOT,
+        }),
+    )
diff --git a/src/edumed/utils.py b/src/edumed/utils.py
new file mode 100644 (file)
index 0000000..2dce875
--- /dev/null
@@ -0,0 +1,44 @@
+# -*- coding: utf-8 -*-
+import codecs
+import csv
+import cStringIO
+
+from settings.apps import INSTALLED_APPS
+
+
+# source: https://docs.python.org/2/library/csv.html#examples
+class UnicodeCSVWriter(object):
+    """
+    A CSV writer which will write rows to CSV file "f",
+    which is encoded in the given encoding.
+    """
+
+    def __init__(self, f, dialect=csv.excel, encoding="utf-8", **kwds):
+        # Redirect output to a queue
+        self.queue = cStringIO.StringIO()
+        self.writer = csv.writer(self.queue, dialect=dialect, **kwds)
+        self.stream = f
+        self.encoder = codecs.getincrementalencoder(encoding)()
+
+    def writerow(self, row):
+        self.writer.writerow([s.encode("utf-8") for s in row])
+        # Fetch UTF-8 output from the queue ...
+        data = self.queue.getvalue()
+        data = data.decode("utf-8")
+        # ... and reencode it into the target encoding
+        data = self.encoder.encode(data)
+        # write to the target stream
+        self.stream.write(data)
+        # empty queue
+        self.queue.truncate(0)
+
+    def writerows(self, rows):
+        for row in rows:
+            self.writerow(row)
+
+
+def process_app_deps(list_with_deps):
+    return tuple(
+        (x[0] if type(x) == tuple else x)
+        for x in list_with_deps
+        if type(x) != tuple or x[1] in INSTALLED_APPS)
\ No newline at end of file
diff --git a/src/edumed/views.py b/src/edumed/views.py
new file mode 100644 (file)
index 0000000..af9bad5
--- /dev/null
@@ -0,0 +1,64 @@
+# -*- coding: utf-8 -*-
+from django.contrib.flatpages.views import flatpage
+from django.views.defaults import page_not_found
+from django.views.generic import TemplateView
+from pybb.views import ProfileEditView
+
+from .forms import AvatarlessEditProfileForm
+
+
+class HomeView(TemplateView):
+    template_name = "home.html"
+
+
+def mil_home_view(request):
+    return flatpage(request, url='/' if request.LANGUAGE_CODE == 'pl' else '/en/')
+
+
+def mil_404_view(request):
+    return page_not_found(request, '404_mil.html')
+
+
+def mil_contact_view(request):
+    return flatpage(request, url='/kontakt_mil/' if request.LANGUAGE_CODE == 'pl' else '/contact_mil/')
+
+
+def mil_knowledge_base_view(request, url):
+    return flatpage(request, url='bazawiedzy/' + url)
+
+
+class AvatarlessProfileEditView(ProfileEditView):
+    form_class = AvatarlessEditProfileForm
+
+
+def flatpage_with_template(request, url, template_name):
+    """
+    Public interface to the flat page view.
+
+    Models: `flatpages.flatpages`
+    Templates: Uses the template defined by the ``template_name`` field,
+        or :template:`flatpages/default.html` if template_name is not defined.
+    Context:
+        flatpage
+            `flatpages.flatpages` object
+    """
+    from django.conf import settings
+    from django.contrib.flatpages.models import FlatPage
+    from django.contrib.flatpages.views import render_flatpage
+    from django.contrib.sites.models import get_current_site
+    from django.http.response import Http404, HttpResponsePermanentRedirect
+    from django.shortcuts import get_object_or_404
+    if not url.startswith('/'):
+        url = '/' + url
+    site_id = get_current_site(request).id
+    try:
+        f = get_object_or_404(FlatPage, url__exact=url, sites__id__exact=site_id)
+    except Http404:
+        if not url.endswith('/') and settings.APPEND_SLASH:
+            url += '/'
+            get_object_or_404(FlatPage, url__exact=url, sites__id__exact=site_id)
+            return HttpResponsePermanentRedirect('%s/' % request.path)
+        else:
+            raise
+    f.template_name = template_name
+    return render_flatpage(request, f)
diff --git a/src/edumed/wsgi.py b/src/edumed/wsgi.py
new file mode 100644 (file)
index 0000000..840d8e5
--- /dev/null
@@ -0,0 +1,36 @@
+"""
+WSGI config for edumed project.
+
+This module contains the WSGI application used by Django's development server
+and any production WSGI deployments. It should expose a module-level variable
+named ``application``. Django's ``runserver`` and ``runfcgi`` commands discover
+this application via the ``WSGI_APPLICATION`` setting.
+
+Usually you will have the standard Django WSGI application here, but it also
+might make sense to replace the whole Django WSGI application with a custom one
+that later delegates to the Django one. For example, you could introduce WSGI
+middleware here, or combine a Django application with an application of another
+framework.
+
+"""
+import os
+import sys
+
+ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
+
+# Add apps and lib directories to PYTHONPATH
+sys.path = [
+    os.path.join(ROOT, 'lib/librarian'),
+] + sys.path
+
+os.environ.setdefault("DJANGO_SETTINGS_MODULE", "edumed.settings")
+
+# This application object is used by any WSGI server configured to use this
+# file. This includes Django's development server, if the WSGI_APPLICATION
+# setting points here.
+from django.core.wsgi import get_wsgi_application
+application = get_wsgi_application()
+
+# Apply WSGI middleware here.
+# from helloworld.wsgi import HelloWorldApplication
+# application = HelloWorldApplication(application)
diff --git a/src/forum/__init__.py b/src/forum/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/src/forum/forms.py b/src/forum/forms.py
new file mode 100644 (file)
index 0000000..37c9b35
--- /dev/null
@@ -0,0 +1,41 @@
+# -*- coding: utf-8 -*-
+from django import forms
+from django.forms.models import ModelChoiceIterator
+from django.utils.translation import ugettext as _
+import pybb.forms
+
+from catalogue.models import Lesson
+
+
+class GroupedModelChoiceIterator(ModelChoiceIterator):
+    def __init__(self, field):
+        super(GroupedModelChoiceIterator, self).__init__(field)
+        self.queryset = self.field.grouping_model.objects
+        self.items_queryset = self.field.queryset
+    
+    def choice(self, obj):
+        items_query = self.items_queryset.filter(**{self.field.grouping_fk_field: obj})
+        items = [super(GroupedModelChoiceIterator, self).choice(item) for item in items_query.all()]
+        return unicode(obj), items
+
+
+class GroupedModelChoiceField(forms.ModelChoiceField):
+    
+    def __init__(self, queryset, grouping_fk_field, **kwargs):
+        self.grouping_fk_field = grouping_fk_field
+        self.grouping_model = queryset.model._meta.get_field(grouping_fk_field).rel.to
+        super(GroupedModelChoiceField, self).__init__(queryset, **kwargs)
+
+    def _get_choices(self):
+        toret = super(GroupedModelChoiceField, self)._get_choices()
+        if isinstance(toret, ModelChoiceIterator):
+            toret = GroupedModelChoiceIterator(self)
+        return toret
+
+    choices = property(_get_choices, forms.ModelChoiceField.choices.fset)
+
+
+class PostForm(pybb.forms.PostForm):
+    lesson = GroupedModelChoiceField(
+        label=_('Related lesson'), queryset=Lesson.objects.all(),
+        grouping_fk_field='section', required=False)
diff --git a/src/forum/locale/pl/LC_MESSAGES/django.mo b/src/forum/locale/pl/LC_MESSAGES/django.mo
new file mode 100644 (file)
index 0000000..219ea2a
Binary files /dev/null and b/src/forum/locale/pl/LC_MESSAGES/django.mo differ
diff --git a/src/forum/locale/pl/LC_MESSAGES/django.po b/src/forum/locale/pl/LC_MESSAGES/django.po
new file mode 100644 (file)
index 0000000..bc13e50
--- /dev/null
@@ -0,0 +1,60 @@
+# 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.
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: PACKAGE VERSION\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2013-08-29 10:00+0200\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: FULL NAME <EMAIL@ADDRESS>\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:9 templates/forum/related_lesson_info.html:2
+msgid "Related lesson"
+msgstr "Powiązana lekcja"
+
+#: templates/pybb/topic.html:27 templates/pybb/topic.html.py:47
+msgid "Posts"
+msgstr ""
+
+#: templates/pybb/topic.html:55
+msgid "Unstick topic"
+msgstr ""
+
+#: templates/pybb/topic.html:57
+msgid "Stick topic"
+msgstr ""
+
+#: templates/pybb/topic.html:61
+msgid "Open topic"
+msgstr ""
+
+#: templates/pybb/topic.html:63
+msgid "Close topic"
+msgstr ""
+
+#: templates/pybb/topic.html:66
+msgid "Admin"
+msgstr ""
+
+#: templates/pybb/topic.html:75
+msgid "Unsubscribe"
+msgstr ""
+
+#: templates/pybb/topic.html:77
+msgid "Subscribe"
+msgstr ""
+
+#: templates/pybb/topic.html:96
+msgid "Subscribers"
+msgstr ""
diff --git a/src/forum/middleware.py b/src/forum/middleware.py
new file mode 100644 (file)
index 0000000..1b6e26b
--- /dev/null
@@ -0,0 +1,16 @@
+# -*- coding: utf-8 -*-
+from urllib import urlencode
+
+from django.contrib.auth import REDIRECT_FIELD_NAME
+from django.http import HttpResponseRedirect
+from django.core.urlresolvers import reverse
+from django_cas.views import login as cas_login
+
+
+class ForumMiddleware(object):
+    @staticmethod
+    def process_request(request):
+        if request.path.startswith(reverse('pybb:index')) \
+                and (not hasattr(request, 'user') or not request.user.is_authenticated()):
+            params = urlencode({REDIRECT_FIELD_NAME: request.get_full_path()})
+            return HttpResponseRedirect(reverse(cas_login) + '?' + params)
diff --git a/src/forum/migrations/0001_initial.py b/src/forum/migrations/0001_initial.py
new file mode 100644 (file)
index 0000000..3a80106
--- /dev/null
@@ -0,0 +1,164 @@
+# -*- coding: utf-8 -*-
+import datetime
+from south.db import db
+from south.v2 import SchemaMigration
+from django.db import models
+
+
+class Migration(SchemaMigration):
+
+    def forwards(self, orm):
+        # Adding model 'Topic'
+        db.create_table(u'forum_topic', (
+            ('pybb_topic', self.gf('django.db.models.fields.related.OneToOneField')(to=orm['pybb.Topic'], unique=True, primary_key=True)),
+            ('lesson', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['catalogue.Lesson'], null=True, blank=True)),
+        ))
+        db.send_create_signal(u'forum', ['Topic'])
+
+
+    def backwards(self, orm):
+        # Deleting model 'Topic'
+        db.delete_table(u'forum_topic')
+
+
+    models = {
+        u'auth.group': {
+            'Meta': {'object_name': 'Group'},
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
+            'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
+        },
+        u'auth.permission': {
+            'Meta': {'ordering': "(u'content_type__app_label', u'content_type__model', u'codename')", 'unique_together': "((u'content_type', u'codename'),)", 'object_name': 'Permission'},
+            'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+            'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['contenttypes.ContentType']"}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
+        },
+        u'auth.user': {
+            'Meta': {'object_name': 'User'},
+            'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
+            'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
+            'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
+            'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
+            'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+            'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+            'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
+            'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
+            'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
+            'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
+            'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
+        },
+        u'catalogue.lesson': {
+            'Meta': {'ordering': "['section', 'level', 'order']", 'object_name': 'Lesson'},
+            'curriculum_courses': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['curriculum.CurriculumCourse']", 'symmetrical': 'False', 'blank': 'True'}),
+            'dc': ('jsonfield.fields.JSONField', [], {'default': "'{}'"}),
+            'html_file': ('django.db.models.fields.files.FileField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'level': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['curriculum.Level']"}),
+            'order': ('django.db.models.fields.IntegerField', [], {'db_index': 'True'}),
+            'package': ('django.db.models.fields.files.FileField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
+            'pdf': ('django.db.models.fields.files.FileField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
+            'section': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['catalogue.Section']", 'null': 'True', 'blank': 'True'}),
+            'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '255'}),
+            'student_package': ('django.db.models.fields.files.FileField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
+            'student_pdf': ('django.db.models.fields.files.FileField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
+            'title': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+            'type': ('django.db.models.fields.CharField', [], {'max_length': '15', 'db_index': 'True'}),
+            'xml_file': ('django.db.models.fields.files.FileField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'})
+        },
+        u'catalogue.section': {
+            'Meta': {'ordering': "['order']", 'object_name': 'Section'},
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'image': ('django.db.models.fields.files.ImageField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
+            'order': ('django.db.models.fields.IntegerField', [], {}),
+            'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '255'}),
+            'title': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'}),
+            'xml_file': ('django.db.models.fields.files.FileField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'})
+        },
+        u'contenttypes.contenttype': {
+            'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
+            'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+            'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
+        },
+        u'curriculum.curriculumcourse': {
+            'Meta': {'ordering': "['slug']", 'object_name': 'CurriculumCourse'},
+            'accusative': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'slug': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}),
+            'title': ('django.db.models.fields.CharField', [], {'max_length': '255'})
+        },
+        u'curriculum.level': {
+            'Meta': {'ordering': "['order']", 'object_name': 'Level'},
+            'group': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+            'order': ('django.db.models.fields.IntegerField', [], {}),
+            'slug': ('django.db.models.fields.CharField', [], {'max_length': '255'})
+        },
+        u'forum.topic': {
+            'Meta': {'object_name': 'Topic'},
+            'lesson': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['catalogue.Lesson']", 'null': 'True', 'blank': 'True'}),
+            'pybb_topic': ('django.db.models.fields.related.OneToOneField', [], {'to': u"orm['pybb.Topic']", 'unique': 'True', 'primary_key': 'True'})
+        },
+        u'pybb.category': {
+            'Meta': {'ordering': "['position']", 'object_name': 'Category'},
+            'hidden': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'name': ('django.db.models.fields.CharField', [], {'max_length': '80'}),
+            'position': ('django.db.models.fields.IntegerField', [], {'default': '0', 'blank': 'True'})
+        },
+        u'pybb.forum': {
+            'Meta': {'ordering': "['position']", 'object_name': 'Forum'},
+            'category': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'forums'", 'to': u"orm['pybb.Category']"}),
+            'description': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
+            'headline': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
+            'hidden': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'moderators': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'to': u"orm['auth.User']", 'null': 'True', 'blank': 'True'}),
+            'name': ('django.db.models.fields.CharField', [], {'max_length': '80'}),
+            'position': ('django.db.models.fields.IntegerField', [], {'default': '0', 'blank': 'True'}),
+            'post_count': ('django.db.models.fields.IntegerField', [], {'default': '0', 'blank': 'True'}),
+            'readed_by': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'readed_forums'", 'symmetrical': 'False', 'through': u"orm['pybb.ForumReadTracker']", 'to': u"orm['auth.User']"}),
+            'topic_count': ('django.db.models.fields.IntegerField', [], {'default': '0', 'blank': 'True'}),
+            'updated': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'})
+        },
+        u'pybb.forumreadtracker': {
+            'Meta': {'unique_together': "(('user', 'forum'),)", 'object_name': 'ForumReadTracker'},
+            'forum': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['pybb.Forum']", 'null': 'True', 'blank': 'True'}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'time_stamp': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}),
+            'user': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['auth.User']"})
+        },
+        u'pybb.topic': {
+            'Meta': {'ordering': "['-created']", 'object_name': 'Topic'},
+            'closed': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+            'created': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}),
+            'forum': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'topics'", 'to': u"orm['pybb.Forum']"}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+            'on_moderation': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+            'poll_question': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
+            'poll_type': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
+            'post_count': ('django.db.models.fields.IntegerField', [], {'default': '0', 'blank': 'True'}),
+            'readed_by': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'readed_topics'", 'symmetrical': 'False', 'through': u"orm['pybb.TopicReadTracker']", 'to': u"orm['auth.User']"}),
+            'sticky': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+            'subscribers': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'subscriptions'", 'blank': 'True', 'to': u"orm['auth.User']"}),
+            'updated': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}),
+            'user': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['auth.User']"}),
+            'views': ('django.db.models.fields.IntegerField', [], {'default': '0', 'blank': 'True'})
+        },
+        u'pybb.topicreadtracker': {
+            'Meta': {'unique_together': "(('user', 'topic'),)", 'object_name': 'TopicReadTracker'},
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'time_stamp': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}),
+            'topic': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['pybb.Topic']", 'null': 'True', 'blank': 'True'}),
+            'user': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['auth.User']"})
+        }
+    }
+
+    complete_apps = ['forum']
\ No newline at end of file
diff --git a/src/forum/migrations/__init__.py b/src/forum/migrations/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/src/forum/models.py b/src/forum/models.py
new file mode 100644 (file)
index 0000000..5ec506b
--- /dev/null
@@ -0,0 +1,11 @@
+# -*- coding: utf-8 -*-
+from django.db import models
+
+import pybb.models
+
+from catalogue.models import Lesson
+
+
+class Topic(models.Model):
+    pybb_topic = models.OneToOneField(pybb.models.Topic, primary_key=True, related_name='edumed_topic')
+    lesson = models.ForeignKey(Lesson, null=True, blank=True, related_name='forum_topics')
diff --git a/src/forum/search_indexes.py b/src/forum/search_indexes.py
new file mode 100644 (file)
index 0000000..0a3f413
--- /dev/null
@@ -0,0 +1,10 @@
+# -*- coding: utf-8 -*-
+from haystack import indexes
+from pybb.models import Post
+
+
+class PostIndex(indexes.SearchIndex, indexes.Indexable):
+    text = indexes.CharField(document=True, use_template=True)
+
+    def get_model(self):
+        return Post
diff --git a/src/forum/templates/forum/related_lesson_info.html b/src/forum/templates/forum/related_lesson_info.html
new file mode 100644 (file)
index 0000000..1f807f6
--- /dev/null
@@ -0,0 +1,4 @@
+{% load i18n %}
+{% if lesson %}
+<h5 style="margin-top: -20px;">{% trans 'Related lesson' %}: <a href="{{lesson.get_absolute_url}}">{{lesson.title}}</a></h5>
+{% endif %}
\ No newline at end of file
diff --git a/src/forum/templates/forum/search_results.html b/src/forum/templates/forum/search_results.html
new file mode 100644 (file)
index 0000000..b656a40
--- /dev/null
@@ -0,0 +1,41 @@
+{% extends 'pybb/base.html' %}
+{% load i18n %}
+
+
+{% block content %}
+    
+        <h1>{% trans 'Search' %}</h1>
+        <form method="get">
+            {{form.q}}
+            <tr>
+                <td>&nbsp;</td>
+                <td>
+                    <input type="submit" value="{% trans 'Search' %}">
+                </td>
+            </tr>
+        </form>
+
+    {% if query %}
+        <hr/>
+        {% for result in page.object_list %}
+            <p class="search-result">
+                <strong>Temat:</strong> <a href="{{ result.object.get_absolute_url }}">{{ result.object.topic.name }}</a><br/>
+                {% autoescape off %}
+                {% for snippet in result.highlighted.text %}
+                    {{snippet}}{% if not forloop.last %} <strong>...</strong> {% endif %}
+                {% endfor %}
+                {% endautoescape %}
+            </p>
+        {% empty %}
+            <p>Brak wyników.</p>
+        {% endfor %}
+
+        {% if page.has_previous or page.has_next %}
+            <div>
+                {% if page.has_previous %}<a href="?q={{ query }}&amp;page={{ page.previous_page_number }}">{% endif %}&laquo; Poprzednie{% if page.has_previous %}</a>{% endif %}
+                |
+                {% if page.has_next %}<a href="?q={{ query }}&amp;page={{ page.next_page_number }}">{% endif %}Następne &raquo;{% if page.has_next %}</a>{% endif %}
+            </div>
+        {% endif %}
+    {% endif %}
+{% endblock %}
\ No newline at end of file
diff --git a/src/forum/templates/pybb/category.html b/src/forum/templates/pybb/category.html
new file mode 100644 (file)
index 0000000..53c3c50
--- /dev/null
@@ -0,0 +1,47 @@
+{% load url from future %}
+{% load i18n pybb_tags %}
+
+{% if category.forums_accessed|pybb_forum_unread:user|length > 0 %}
+<div class='category'>
+    <table class="table category-table">
+        <thead>
+            <tr class="forum-row head-row">
+                <th class="forum-name">
+                    {% trans "Forum" %}
+                </th>
+                <th class="forum-topic-count">
+                    {% trans "Topics" %}
+                </th>
+                <th class="forum-post-count">
+                    {% trans "Posts" %}
+                </th>
+                <th class="forum-last-post">
+                    {% trans "Last posts" %}
+                </th>
+            </tr>
+        </thead>
+        <tbody>
+        {% for forum in category.forums_accessed|pybb_forum_unread:user %}
+            <tr class="forum-row">
+                <td class="forum-name {% if forum.unread %} forum-unread{% endif %}">
+                    <div class="state-indicator"></div>
+                    <a href="{{ forum.get_absolute_url }}">{{ forum.name }}</a> {% if forum.hidden %}[{% trans "Hidden" %}]{% endif %}
+                    <div class="forum-description">
+                        {{ forum.description|safe }}
+                    </div>
+                </td>
+                <td class="forum-topic-count">
+                    {{ forum.topic_count }}
+                </td>
+                <td class="forum-post-count">
+                    {{ forum.post_count }}
+                </td>
+                <td class="forum-last-post">
+                    {% include "pybb/forum_last_update_info.html" %}
+                </td>
+            </tr>
+        {% endfor %}
+        </tbody>
+    </table>
+</div>
+{% endif %}
\ No newline at end of file
diff --git a/src/forum/templates/pybb/forum_last_update_info.html b/src/forum/templates/pybb/forum_last_update_info.html
new file mode 100644 (file)
index 0000000..c3256a9
--- /dev/null
@@ -0,0 +1,5 @@
+{% load humanize %}
+{% if forum.updated %}
+    {{ forum.last_post.user }}
+    {{ forum.updated|naturaltime }}
+{% endif %}
\ No newline at end of file
diff --git a/src/forum/templates/pybb/post_form.html b/src/forum/templates/pybb/post_form.html
new file mode 100644 (file)
index 0000000..5db31a4
--- /dev/null
@@ -0,0 +1,36 @@
+{% load url from future %}
+{% load i18n pybb_tags %}
+<form class="post-form" action="
+    {% if forum %}
+        {% url 'pybb:add_topic' forum.pk %}
+    {% else %}
+        {% if topic %}
+            {% url 'pybb:add_post' topic.pk %}
+        {% else %}
+            {% url 'pybb:edit_post' pk=object.pk %}
+        {% endif %}
+    {% endif %}" method="post" enctype="multipart/form-data">
+  {% csrf_token %}
+  <fieldset>
+    {% include "pybb/form_errors.html" %}
+    {% if form.name %} {% include "pybb/form_field.html" with field=form.name %} {% endif %}
+
+    {% if lesson_editable %}
+        {% include "pybb/form_field.html" with field=form.lesson %}
+    {% endif %}
+
+    {% if form.login %} {% include "pybb/form_field.html" with field=form.login %}  {% endif %}
+    {% if form.body %} {% include "pybb/form_field.html" with field=form.body %}  {% endif %}
+    <div id='emoticons'>
+      {% for smile, url in form.available_smiles.items %}
+        <a href='#' title='{{ smile|safe }}'><img src='{{ STATIC_URL }}{{ form.smiles_prefix }}{{ url }}'></a>
+      {% endfor %}
+    </div>
+
+    {% if form.poll_type and request.user.is_superuser %}
+      {% include "pybb/poll_edit_form.html" %}
+    {% endif %}
+    {% include "pybb/attachments_formset.html" %}
+    <p class="submit">{% include "pybb/_button_submit.html" %}</p>
+  </fieldset>
+</form>
diff --git a/src/forum/templates/pybb/topic.html b/src/forum/templates/pybb/topic.html
new file mode 100644 (file)
index 0000000..f11f2cb
--- /dev/null
@@ -0,0 +1,102 @@
+{% extends 'pybb/base.html' %}
+
+{% load url from future %}
+
+{% load pybb_tags i18n %}
+
+{% block title %}{{ topic }}{% endblock %}
+
+{% block extra_script %}
+    {{ block.super }}
+    {% include "pybb/_markitup.html" %}
+    <script type="text/javascript" src="{{ STATIC_URL }}pybb/js/jquery.formset.min.js"></script>
+{% endblock %}
+
+{% block breadcrumb %}
+    {% with object=topic %}
+        {% include "pybb/breadcrumb.html" %}
+    {% endwith %}
+{% endblock %}
+
+{% block content %}
+    <div class="topic">
+        <h1>{{ topic.name }}</h1>
+        
+        {% include 'forum/related_lesson_info.html' with lesson=topic.edumed_topic.lesson %}
+        
+        {% with _('Posts') as label %}
+            {% include "pybb/pagination.html" %}
+        {% endwith %}
+
+        {% if topic.poll_type %}
+            {% include 'pybb/poll.html' %}
+        {% endif %}
+
+        <div class="posts">
+            {% if first_post %}{% ifnotequal first_post post_list.0 %}
+                {% with first_post as post %}
+                    <li class="first_post">{% include "pybb/post_template.html" %}</li>
+                {% endwith %}
+            {% endifnotequal %}{% endif %}
+            {% for post in post_list %}
+                {% cycle 'odd' 'even' as rowcolors silent %}
+                {% include "pybb/post_template.html" %}
+            {% endfor %}
+        </div>
+        <div>&nbsp;</div>
+        {% with _('Posts') as label %}
+            {% include "pybb/pagination.html" %}
+        {% endwith %}
+
+        {% if user.is_authenticated %}
+            <div class="controls">
+                {% if user.is_moderator %}
+                    {% if topic.sticky %}
+                        <a href="{% url 'pybb:unstick_topic' topic.id %}">{% trans "Unstick topic" %}</a> /
+                    {% else %}
+                        <a href="{% url 'pybb:stick_topic' topic.id %}">{% trans "Stick topic" %}</a> /
+                    {% endif %}
+
+                    {% if topic.closed %}
+                        <a href="{% url 'pybb:open_topic' topic.id %}">{% trans "Open topic" %}</a> /
+                    {% else %}
+                        <a href="{% url 'pybb:close_topic' topic.id %}">{% trans "Close topic" %}</a> /
+                    {% endif %}
+                    {% if perms.pybb.change_topic and user.is_staff %}
+                        <a href="{% url 'admin:pybb_topic_change' topic.id %}">{% trans 'Admin' %}</a> /
+                    {% endif %}
+                    {% comment %}
+            <a href="{% url 'pybb:merge_topics' %}?topic={{ topic.id }}">{% trans 'Merge topics' %}</a> /
+            {% endcomment %}
+                {% endif %}
+
+                {% if user.is_subscribed %}
+                    <a href="{% url 'pybb:delete_subscription' topic.id %}?from_topic">{% trans "Unsubscribe" %}</a>
+                {% else %}
+                    <a href="{% url 'pybb:add_subscription' topic.id %}">{% trans "Subscribe" %}</a>
+                {% endif %}
+            </div>
+        {% endif %}
+
+        {% if user.is_authenticated or PYBB_ENABLE_ANONYMOUS_POST %}
+            {% pybb_get_profile user=user as user_profile %}
+
+            {% if not user_profile.is_banned %}
+                {% if not topic.closed %}
+                    {% include "pybb/post_form.html" %}
+                {% endif %}
+            {% endif %}
+        {% else %}
+            {% include 'pybb/_need_to_login_message.html' %}
+        {% endif %}
+
+        {% if user.is_staff %}
+            <div class="subscriber-list">
+                {% trans "Subscribers" %}:
+                {% for subscriber in topic.subscribers.all %}
+                    <a href="{% url 'pybb:user' subscriber.username %}">{{ subscriber.username }}</a>,
+                {% endfor %}
+            </div>
+        {% endif %}
+    </div>
+{% endblock %}
diff --git a/src/forum/templates/pybb/topic_last_message_info.html b/src/forum/templates/pybb/topic_last_message_info.html
new file mode 100644 (file)
index 0000000..ff49ffa
--- /dev/null
@@ -0,0 +1,6 @@
+{% load humanize %}
+{% if topic.updated %}
+    {{ topic.last_post.user }}
+    {{ topic.updated|naturaltime }}
+    
+{% endif %}
\ No newline at end of file
diff --git a/src/forum/templates/search/indexes/pybb/post_text.txt b/src/forum/templates/search/indexes/pybb/post_text.txt
new file mode 100644 (file)
index 0000000..c51be26
--- /dev/null
@@ -0,0 +1 @@
+{{object.body_text}}
\ No newline at end of file
diff --git a/src/forum/urls.py b/src/forum/urls.py
new file mode 100644 (file)
index 0000000..c669808
--- /dev/null
@@ -0,0 +1,26 @@
+# -*- coding: utf-8 -*-
+from django.conf.urls import patterns, url
+from haystack.query import SearchQuerySet
+from haystack.views import SearchView, search_view_factory
+from haystack.forms import SearchForm
+from pybb.models import Post
+
+from .views import AddPostView, EditPostView
+
+
+urlpatterns = patterns(
+    '',
+    url(r'^forum/(?P<forum_id>\d+)/topic/add/$', AddPostView.as_view()),
+    url(r'^post/(?P<pk>\d+)/edit/$', EditPostView.as_view()),
+)
+
+PostsSearchQuerySet = SearchQuerySet().models(Post).highlight()
+
+urlpatterns += patterns(
+    'haystack.views',
+    url(r'^szukaj/$', search_view_factory(
+        view_class=SearchView,
+        template='forum/search_results.html',
+        searchqueryset=PostsSearchQuerySet,
+        form_class=SearchForm
+    ), name='forum_search'))
diff --git a/src/forum/views.py b/src/forum/views.py
new file mode 100644 (file)
index 0000000..6750d99
--- /dev/null
@@ -0,0 +1,58 @@
+# -*- coding: utf-8 -*-
+from django.core.exceptions import ObjectDoesNotExist
+import pybb.views
+import pybb.forms
+
+from .forms import PostForm
+from .models import Topic
+
+
+class PostEditMixin(pybb.views.PostEditMixin):
+
+    def get_form_class(self):
+        toret = super(PostEditMixin, self).get_form_class()
+        if issubclass(toret, pybb.forms.PostForm):
+            toret = PostForm
+        return toret
+
+    def form_valid(self, form):
+        toret = super(PostEditMixin, self).form_valid(form)
+
+        pybb_post = self.object
+        pybb_topic = pybb_post.topic
+        topic, topic_created = Topic.objects.get_or_create(pybb_topic=pybb_topic)
+
+        if pybb_post == pybb_topic.head:
+            topic.lesson = form.cleaned_data['lesson']
+            topic.save()
+
+        return toret
+
+
+class AddPostView(PostEditMixin, pybb.views.AddPostView):
+    def get_context_data(self, **kwargs):
+        ctx = super(AddPostView, self).get_context_data(**kwargs)
+        ctx['lesson_editable'] = self._creates_new_topic()
+        return ctx
+
+    def _creates_new_topic(self):
+        return self.forum is not None
+
+
+class EditPostView(PostEditMixin, pybb.views.EditPostView):
+    def get_context_data(self, **kwargs):
+        ctx = super(EditPostView, self).get_context_data(**kwargs)
+        ctx['lesson_editable'] = self._edits_topics_head()
+        return ctx
+
+    def _edits_topics_head(self):
+        return self.object == self.object.topic.head
+
+    def get_form_kwargs(self):
+        kwargs = super(EditPostView, self).get_form_kwargs()
+        try:
+            lesson = self.object.topic.edumed_topic.lesson
+        except ObjectDoesNotExist:
+            lesson = None
+        kwargs['initial']['lesson'] = lesson
+        return kwargs
diff --git a/src/lib/librarian b/src/lib/librarian
new file mode 160000 (submodule)
index 0000000..978c34b
--- /dev/null
@@ -0,0 +1 @@
+Subproject commit 978c34b8de4031e3759225138b2c30d2cc28035d
diff --git a/src/manage.py b/src/manage.py
new file mode 100755 (executable)
index 0000000..28228a0
--- /dev/null
@@ -0,0 +1,15 @@
+#!/usr/bin/env python
+import os
+import sys
+
+ROOT = os.path.dirname(os.path.abspath(__file__))
+sys.path = [
+    os.path.join(ROOT, 'lib/librarian'),
+] + sys.path
+
+if __name__ == "__main__":
+    os.environ.setdefault("DJANGO_SETTINGS_MODULE", "edumed.settings")
+
+    from django.core.management import execute_from_command_line
+
+    execute_from_command_line(sys.argv)
diff --git a/src/publishers/__init__.py b/src/publishers/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/src/publishers/admin.py b/src/publishers/admin.py
new file mode 100644 (file)
index 0000000..95bd7ab
--- /dev/null
@@ -0,0 +1,5 @@
+# -*- coding: utf-8 -*-
+from django.contrib import admin
+from .models import Publisher
+
+admin.site.register(Publisher)
diff --git a/src/publishers/migrations/0001_initial.py b/src/publishers/migrations/0001_initial.py
new file mode 100644 (file)
index 0000000..1a77507
--- /dev/null
@@ -0,0 +1,34 @@
+# -*- coding: utf-8 -*-
+import datetime
+from south.db import db
+from south.v2 import SchemaMigration
+from django.db import models
+
+
+class Migration(SchemaMigration):
+
+    def forwards(self, orm):
+        # Adding model 'Publisher'
+        db.create_table(u'publishers_publisher', (
+            (u'id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
+            ('name', self.gf('django.db.models.fields.CharField')(max_length=255)),
+            ('logo', self.gf('django.db.models.fields.files.ImageField')(max_length=100)),
+        ))
+        db.send_create_signal(u'publishers', ['Publisher'])
+
+
+    def backwards(self, orm):
+        # Deleting model 'Publisher'
+        db.delete_table(u'publishers_publisher')
+
+
+    models = {
+        u'publishers.publisher': {
+            'Meta': {'object_name': 'Publisher'},
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'logo': ('django.db.models.fields.files.ImageField', [], {'max_length': '100'}),
+            'name': ('django.db.models.fields.CharField', [], {'max_length': '255'})
+        }
+    }
+
+    complete_apps = ['publishers']
\ No newline at end of file
diff --git a/src/publishers/migrations/__init__.py b/src/publishers/migrations/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/src/publishers/models.py b/src/publishers/models.py
new file mode 100644 (file)
index 0000000..14ed63a
--- /dev/null
@@ -0,0 +1,10 @@
+# -*- coding: utf-8 -*-
+from django.db import models
+
+
+class Publisher(models.Model):
+    name = models.CharField(max_length=255)
+    logo = models.ImageField(upload_to='publishers/logo')
+
+    def __unicode__(self):
+        return self.name
diff --git a/src/wtem/__init__.py b/src/wtem/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/src/wtem/admin.py b/src/wtem/admin.py
new file mode 100644 (file)
index 0000000..03c4446
--- /dev/null
@@ -0,0 +1,239 @@
+# -*- coding: utf-8 -*-
+import json
+
+from django import forms
+from django.conf.urls import url, patterns
+from django.contrib import admin
+from django.contrib.auth.models import User
+from django.core.urlresolvers import reverse
+from django.http import HttpResponse
+from django.template.loader import render_to_string
+from django.utils.safestring import mark_safe
+
+from .middleware import get_current_request
+from .models import Submission, Assignment, Attachment, exercises
+
+
+def get_user_exercises(user):
+    try:
+        assignment = Assignment.objects.get(user=user)
+        return [e for e in exercises if e['id'] in assignment.exercises]
+    except Assignment.DoesNotExist:
+        return []
+
+
+readonly_fields = ('submitted_by', 'first_name', 'last_name', 'email', 'key', 'key_sent')
+
+
+class AttachmentWidget(forms.Widget):
+    def render(self, name, value, *args, **kwargs):
+        if value:
+            a_tag = '<a href="%s">%s</a>' % (value, value)
+        else:
+            a_tag = 'brak'
+        return mark_safe(('<input type="hidden" name="%s" value="%s"/>' % (name, value)) + a_tag)
+
+
+class TextareaWithLinks(forms.Textarea):
+    def render(self, name, value, *args, **kwargs):
+        t, links = value
+        self.links = links
+        output = super(TextareaWithLinks, self).render(name, t, *args, **kwargs)
+        moreoutput = "<div style='margin-left: 106px'>"
+        for k, n, v in links:
+            moreoutput += u"<br>%s: %s" % (k, AttachmentWidget().render(n, v))
+        output += mark_safe(moreoutput + "</div>")
+        return output
+
+
+class SubmissionFormBase(forms.ModelForm):
+    class Meta:
+        model = Submission
+        exclude = ('answers', 'marks', 'contact', 'end_time') + readonly_fields
+
+
+def get_open_answer(answers, exercise):
+    def get_option(options, id):
+        for option in options:
+            if str(option['id']) == id:
+                return option
+
+    exercise_id = str(exercise['id'])
+    answer = answers[exercise_id]
+    if exercise['type'] == 'open':
+        if isinstance(answer, list):
+            toret = ''
+            for part in answer:
+                field = get_option(exercise['fields'], part['id'])
+                toret += '- %s:\n\n%s\n\n' % (field['caption'], part['text'])
+        else:
+            toret = answer
+    if exercise['type'] == 'edumed_wybor':
+        ok = set(map(str, exercise['answer'])) == set(map(str, answer['closed_part']))
+        toret = u'Czesc testowa [%s]:\n' % ('poprawna' if ok else 'niepoprawna')
+        if len(answer['closed_part']):
+            for selected in answer['closed_part']:
+                option = get_option(exercise['options'], selected)
+                toret += '%s: %s\n' % (selected, option['text'])
+        else:
+            toret += u'<nie wybrano odpowiedzi>\n'
+        toret += u'\nCzesc otwarta (%s):\n\n' % ' '.join(exercise['open_part'])
+        toret += answer['open_part']
+
+    return toret
+
+
+def get_form(request, submission):
+    fields = dict()
+    if submission and submission.answers:
+        answers = json.loads(submission.answers)
+        user_exercises = get_user_exercises(request.user)
+        for exercise in exercises:
+            if exercise not in user_exercises:
+                continue
+            
+            answer_field_name = 'exercise_%s' % exercise['id']
+            mark_field_name = 'markof_%s_by_%s' % (exercise['id'], request.user.id)
+            if exercise['type'] in ('open', 'file_upload') or exercise.get('open_part', None):
+                if exercise['type'] == 'file_upload':
+                    try:
+                        attachment = Attachment.objects.get(submission=submission, exercise_id=exercise['id'])
+                    except Attachment.DoesNotExist:
+                        attachment = None
+                    widget = AttachmentWidget
+                    initial = attachment.file.url if attachment else None
+                else:
+                    # widget = forms.Textarea(attrs={'readonly':True})
+                    widget = TextareaWithLinks(attrs={'readonly': True})
+                    links = []
+                    qfiles = []
+                    for qfield in exercise.get('fields', []):
+                        if qfield.get('type') == 'file':
+                            qfiles.append((qfield['id'], qfield['caption']))
+                    if qfiles:
+                        eid = int(exercise['id'])
+                        by_tag = {}
+                        for att in Attachment.objects.filter(submission=submission, exercise_id=eid).order_by('tag'):
+                            by_tag[att.tag] = att.file.url
+                        for tag, caption in qfiles:
+                            v = by_tag.get(tag)
+                            if v:
+                                links.append((caption, "file_%s__%s" % (eid, tag), v))
+                    initial = get_open_answer(answers, exercise), links
+
+                fields[answer_field_name] = forms.CharField(
+                    widget=widget,
+                    initial=initial,
+                    label=u'Rozwiązanie zadania %s' % exercise['id'],
+                    required=False
+                )
+
+                choices = [(None, '-')]  # + [(i,i) for i in range(exercise['max_points']+1)],
+                i = 0
+                while i <= exercise['max_points']:
+                    choices.append((i, i))
+                    i += .5
+                fields[mark_field_name] = forms.ChoiceField(
+                    choices=choices,
+                    initial=submission.get_mark(user_id=request.user.id, exercise_id=exercise['id']),
+                    label=u'Twoja ocena zadania %s' % exercise['id']
+                )
+
+    if not request.user.is_superuser:
+        class Meta(SubmissionFormBase.Meta):
+            pass
+        Meta.exclude += ('examiners',)
+        fields['Meta'] = Meta
+
+    return type('SubmissionForm', (SubmissionFormBase,), fields)
+
+
+class SubmissionAdmin(admin.ModelAdmin):
+    list_display = ('__unicode__', 'todo', 'examiners_repr')
+    readonly_fields = readonly_fields
+
+    def get_form(self, request, obj=None, **kwargs):
+        return get_form(request, obj)
+
+    def submitted_by(self, instance):
+        if instance.contact:
+            return '<a href="%s">%s</a>' % (
+                reverse('admin:contact_contact_change', args=[instance.contact.id]),
+                instance.contact.contact
+            )
+        return '-'
+    submitted_by.allow_tags = True
+    submitted_by.short_description = "Zgłoszony/a przez"
+
+    def todo(self, submission):
+        user = get_current_request().user
+        user_exercises = get_user_exercises(user)
+        user_marks = submission.marks.get(str(user.id), {})
+        return ','.join([str(e['id']) for e in user_exercises if str(e['id']) not in user_marks.keys()])
+    todo.short_description = 'Twoje nieocenione zadania'
+
+    def examiners_repr(self, submission):
+        return ', '.join([u.username for u in submission.examiners.all()])
+    examiners_repr.short_description = 'Przypisani do zgłoszenia'
+
+    def save_model(self, request, submission, form, change):
+        for name, value in form.cleaned_data.items():
+            if name.startswith('markof_'):
+                parts = name.split('_')
+                exercise_id = parts[1]
+                user_id = parts[3]
+                submission.set_mark(user_id=user_id, exercise_id=exercise_id, mark=value)
+        submission.save()
+
+    def changelist_view(self, request, extra_context=None):
+        context = dict(examiners=[])
+        assignments = Assignment.objects.all()
+        if not request.user.is_superuser:
+            assignments = assignments.filter(user=request.user)
+        for assignment in assignments:
+            examiner = dict(name=assignment.user.username, todo=0)
+            for submission in Submission.objects.filter(examiners=assignment.user):
+                for exercise_id in assignment.exercises:
+                    if submission.get_mark(user_id=assignment.user.id, exercise_id=exercise_id) is None:
+                        examiner['todo'] += 1
+            context['examiners'].append(examiner)
+        return super(SubmissionAdmin, self).changelist_view(request, extra_context=context)
+
+    def queryset(self, request):
+        qs = super(SubmissionAdmin, self).queryset(request)
+        if not request.user.is_superuser:
+            qs = qs.filter(examiners=request.user)
+        return qs
+
+    def get_urls(self):
+        urls = super(SubmissionAdmin, self).get_urls()
+        return patterns(
+            '',
+            url(r'^report/$', self.admin_site.admin_view(report_view), name='wtem_admin_report')
+        ) + super(SubmissionAdmin, self).get_urls()
+
+
+class SubmissionsSet:
+    def __init__(self, submissions):
+        self.submissions = submissions
+        self.examiners_by_exercise = {}
+        for submission in submissions:
+            for user_id, marks in submission.marks.items():
+                user = User.objects.get(pk=user_id)
+                for exercise_id in marks.keys():
+                    examiners = self.examiners_by_exercise.setdefault(exercise_id, [])
+                    if user not in examiners:
+                        examiners.append(user)
+
+
+def report_view(request):
+    submissions = sorted(Submission.objects.all(), key=lambda s: -s.final_result)
+    toret = render_to_string('wtem/admin_report.csv', {
+        'submissionsSet': SubmissionsSet(submissions),
+        'exercise_ids': [str(e['id']) for e in exercises]})
+    response = HttpResponse(toret, content_type='text/csv')
+    response['Content-Disposition'] = 'attachment; filename="wyniki.csv"'
+    return response
+
+admin.site.register(Submission, SubmissionAdmin)
+admin.site.register(Assignment)
diff --git a/src/wtem/fixtures/exercises-2013.json b/src/wtem/fixtures/exercises-2013.json
new file mode 100644 (file)
index 0000000..8fc52f7
--- /dev/null
@@ -0,0 +1,418 @@
+[
+
+{
+    "id": 1,
+    "type": "edumed_uporzadkuj",
+    "description": ["Ułóż propozycje haseł internetowych w kolejności od najmniej do najbardziej bezpiecznego."],
+    "items": [
+        {"id": "1", "text": "Gdzi3.j3$t.N3m0"},
+        {"id": "2", "text": "abc123"},
+        {"id": "3", "text": "mojazor17"},
+        {"id": "4", "text": "czarnyKotbialyKot"},
+        {"id": "5", "text": "qwerty456"}
+    ],
+    "answer": [2, 5, 3, 4, 1],
+    "points": 1
+},
+
+{
+    "id": 2,
+    "type": "edumed_przyporzadkuj",
+    "hide_default_instruction": 1,
+    "description": ["Rozpoznaj i nazwij typy reklam"],
+    "buckets":  [
+        {"id": 1, "title": "lokowanie produktu"},
+        {"id": 2, "title": "baner"},
+        {"id": 3, "title": "infomercial"},
+        {"id": 4, "title": "power content"},
+        {"id": 5, "title": "sponsoring"},
+        {"id": 6, "title": "AdWords"}
+    ],
+    "buckets_name": "typy",
+    "items": [
+        {"id": 1, "text": "1", "img": "1_small.png", "href": "1.png"},
+        {"id": 2, "text": "2", "img": "2_small.png", "href": "2.png"},
+        {"id": 3, "text": "3", "img": "3_small.png", "href": "3.png"}
+    ],
+    "items_name": "reklamy",
+    "items_inline": 1,
+    "items_instruction": "Przeciągnij numery zdjęć do odpowiednich szarych pól powyżej; kliknij w obrazek, aby powiększyć",
+    "answer": {
+        "1": [2],
+        "4": [3],
+        "6": [1]
+    },
+    "points_per_hit": 1
+},
+
+{
+    "id": 3,
+    "type": "edumed_wybor",
+    "description": ["Wykonałeś/wykonałaś remiks cudzych utworów. W jakich sytuacjach możesz rozpowszechnić swój utwór?"],
+    "options": [
+        {"id": 1, "text": "Mam zgodę autora/autorki oryginalnego utworu."},
+        {"id": 2, "text": "Materiały do remiksu zostały ściągnięte z serwisu do przechowywania plików."},
+        {"id": 3, "text": "Wykorzystane piosenki przesłała mi na Facebooku koleżanka."},
+        {"id": 4, "text": "Zezwala na to licencja, na której są opublikowane wykorzystane utwory."},
+        {"id": 5, "text": "Wykorzystane w remiksie utwory są dostępne w domenie publicznej (minęło 70 lat od śmierci autora)."},
+        {"id": 6, "text": "Utwory użyte w remiksie były udostępnione do odsłuchania na stronach twórców w formie plików mp3."}
+    ],
+    "answer": [1, 4, 5],
+    "points_per_hit": 1
+},
+
+{
+    "id": 4,
+    "type": "edumed_wybor",
+    "description": ["Jedziesz na wakacje do Turcji. Ustal, jaki termin ważnosci musi mieć Twój paszport."],
+    "options": [
+        {"id": 1, "text": "3 miesiące od daty wyjazdu z Polski"},
+        {"id": 2, "text": "12 miesięcy od daty powrotu do Polski"},
+        {"id": 3, "text": "6 miesięcy od daty wyjazdu z Polski"},
+        {"id": 4, "text": "nie muszę mieć paszportu, by wyjechać do Turcji"}
+    ],
+    "answer": [3],
+    "points": 1
+},
+
+{
+    "id": 5,
+    "type": "edumed_przyporzadkuj",
+    "description": ["Który z poniższych tekstów jest informacją, opinią, perswazją?"],
+    "buckets": [
+        {"id": 1, "title": "informacja"},
+        {"id": 2, "title": "opinia"},
+        {"id": 3, "title": "perswazja"}
+    ],
+    "buckets_name": "kategorie",
+    "items": [
+        {"id": 1, "text": "1", "desc": "Serdecznie zapraszamy do udziału w V Festiwalu Poezji Lokalnej im. Zbigniewa Herberta. Przyjdź i zaprezentuj swoją twórczość literacką biorąc udział w tradycyjnym już Turnieju Jednego Wiersza! Dla najlepszych poetów – atrakcyjne nagrody!"},
+        {"id": 2, "text": "2", "desc": "22 grudnia w Domu Kultury Miejskiej przy ul. Wielebskiego 3 uczestniczyliśmy w kolejnym V Festiwalu Poezji Lokalnej im. Zbigniewa Herberta. Swoje wiersze zaprezentowało blisko 30 poetów, zarówno z naszego miasta jak i przybyłych gości. Tradycyjny już Turniej Jednego Wiersza wygrał Jan Kowalski z Krętowa."},
+        {"id": 3, "text": "3", "desc": "Atmosfera V Festiwalu Poezji Lokalnej była bardzo podniosła. Nie wiedziałem, że mamy tak wielu dobrych poetów w naszym mieście i regionie. Uważam, że to jeden z najlepszych tego typu przeglądów i turniejów literackich w Polsce. Profesjonalnie przygotowany, o wysokim poziomie artystycznym. Warto było przyjechać."}
+    ],
+    "items_name": "źródła",
+    "answer": {
+        "1": [2],
+        "2": [3],
+        "3": [1]
+    },
+    "points_per_hit": 1
+},
+
+{
+    "id": 6,
+    "type": "edumed_wybor",
+    "description": ["W jaki sposób zwiększysz niezależność wyników wyszukiwania od wcześniej wprowadzanych do wyszukiwarki fraz i przeglądanych stron internetowych?"],
+    "options": [
+        {"id": 1, "text": "ustawię tryb prywatny w przeglądarce (incognito)"},
+        {"id": 2, "text": "wyloguję się z serwisu społecznościowego"},
+        {"id": 3, "text": "skorzystam z innej niż zazwyczaj wyszukiwarki"},
+        {"id": 4, "text": "skorzystam z innej niż zazwyczaj przeglądarki"},
+        {"id": 5, "text": "zamknę zakładkę z portalem społecznościowym"},
+        {"id": 6, "text": "usunę historię wyszukiwania i ciasteczka"},
+        {"id": 7, "text": "zrestartuję przeglądarkę"}
+    ],
+    "answer": [1,4,6],
+    "points_per_hit": 1
+},
+
+{
+    "id": 7,
+    "type": "edumed_wybor",
+    "description": ["Jesteś w Olsztynie na przystanku Plac Roosevelta. Którym autobusem nie dojedziesz bezpośrednio na przystanek Szpital Wojewódzki?"],
+    "options": [
+        {"id": 1, "text": "13"},
+        {"id": 2, "text": "6"},
+        {"id": 3, "text": "22"},
+        {"id": 4, "text": "3"}
+    ],
+    "open_part": ["W jaki sposób dotarłeś/aś do tej informacji? Wklej adres strony, z której skorzystałeś/aś."],
+    "open_part_rows": 1,
+    "answer": [4],
+    "max_points": 2
+},
+
+{
+    "id": 8,
+    "type": "edumed_wybor",
+    "description": ["Kupiłeś płytę CD z nowym albumem ulubionego zespołu. Co możesz z nim zrobić?"],
+    "options": [
+        {"id": 1, "text": "umieścić pliki w sieci, tak by inni mogli ściągnąć album"},
+        {"id": 2, "text": "zgrać pliki na swoje urządzenia (laptop, smartfon, odtwarzacz mp3 itp.)"},
+        {"id": 3, "text": "skopiować płytę najbliższym znajomym i rodzinie"},
+        {"id": 4, "text": "skopiować płytę nauczycielce/nauczycielowi, która lubi podobną muzykę"},
+        {"id": 5, "text": "nagrać kopie albumu na płyty CD i odsprzedać je w szkole zainteresowanym osobom"},
+        {"id": 6, "text": "odsprzedać płytę z albumem w serwisie aukcyjnym"}
+    ],
+    "answer": [2,3,6],
+    "points_per_hit": 1
+
+},
+
+{
+    "id": 9,
+    "type": "edumed_przyporzadkuj",
+    "description": ["Przyporządkuj poniższe pojęcia ich definicjom."],
+    "buckets": [
+        {"id": 1, "title": "infotainment"},
+        {"id": 2, "title": "cyfrowe narracje"},
+        {"id": 3, "title": "gatunek"},
+        {"id": 4, "title": "konwencja"},
+        {"id": 5, "title": "remiks"}
+
+    ],
+    "buckets_name": "pojęcia",
+    "items": [
+        {"id": 1, "text": "1", "desc": "zbiór cech utworów (artystycznych, dziennikarskich itp.) wielokrotnie powtarzany i wykorzystywany. Może być typowy dla jednego twórcy, grupy czy okresu. Składać się na niego mogą różne elementy utworu – zarówno te związane formą, jak i treścią."},
+        {"id": 2, "text": "2", "desc": "utwór, w którym wykorzystano i połączono elementy różnych innych dzieł. Dzięki nowemu kontekstowi zmieniają one swoje znaczenie. Pierwotnie termin ten odnosił się tylko do utworów muzycznych i oznaczał zmianę aranżacji piosenki, połączenie jej pierwotnej wersji z innymi elementami dźwiękowymi."},
+        {"id": 3, "text": "3", "desc": "zjawisko zacierania różnic pomiędzy przekazami informacyjnymi i rozrywkowymi. Obserwujemy je we współczesnych mediach."},
+        {"id": 4, "text": "4", "desc": "opowieść w formie multimedialnej. Jej autor przekazuje treść za pomocą połączenia różnych form przekazu, np. tekstu, animacji, dźwięku, obrazu, wideo. Może przybierać formę hipertekstu, prezentacji, filmu."},
+        {"id": 5, "text": "5", "desc": "typ, odmiana czegoś. W odniesieniu do tekstów kultury: określony sposób organizacji przekazu, zależny od jego celu. Utwory tego samego gatunku mają zwykle podobą formę, wykorzystują te same konwencje."}
+    ],
+    "items_name": "definicje",
+    "answer": {
+        "1": [3],
+        "2": [4],
+        "3": [5],
+        "4": [1],
+        "5": [2]
+    },
+    "points_per_hit": 0.5
+},
+
+{
+    "id": 10,
+    "type": "edumed_wybor",
+    "description": ["<div>Widzisz, że na ekranie Twojego kolegi strona <a href=\"http://www.krrit.gov.pl/\">http://www.krrit.gov.pl/</a> wyświetla się w ten sposób:</div> <img src=\"/static/wtem/img/krrit_zrzut_ekranu.png\"/ style=\"margin-bottom:10px; margin-top:10px;\"> Dlaczego?"],
+    "options": [
+        {"id": 1, "text": "Kolega ma starą wersję przeglądarki, która nie obsługuje zaawansowanej grafiki strony."},
+        {"id": 2, "text": "Został użyty przycisk “wersja kontrastowa”, który pomaga osobom słabowidzącym zapoznać się z treścią strony."},
+        {"id": 3, "text": "Komputer został zaatakowany wirusem typu Trojan."},
+        {"id": 4, "text": "Kolega wyświetla stronę przygotowaną do wydruku."}
+    ],
+    "answer": [2],
+    "points": 1
+},
+
+{
+    "id": 11,
+    "type": "edumed_wybor",
+    "description": ["Wskaż bezpośrednie zagrożenia, które wiążą się z posiadaniem profilu na portalu społecznościowym."],
+    "options": [
+        {"id": 1, "text": "możliwość niekontrolowanego wycieku prywatnych informacji (niedoskonała ochrona danych osobowych)"},
+        {"id": 2, "text": "stalking"},
+        {"id": 3, "text": "zablokowanie komputera"},
+        {"id": 4, "text": "kradzież tożsamości (profilu)"},
+        {"id": 5, "text": "kradzież pieniędzy z konta bankowego"},
+        {"id": 6, "text": "phishing"},
+        {"id": 7, "text": "cenzurowanie publikowanych i otrzymywanych treści"},
+        {"id": 8, "text": "fałszerstwo dokumentu tożsamości"},
+        {"id": 9, "text": "śledzenie aktywności użytkownika w internecie"}
+    ],
+    "answer": [1,2,4,6,7,9],
+    "points_per_hit": 0.5
+},
+
+{
+    "id": 12,
+    "type": "edumed_przyporzadkuj",
+    "description": ["Do jakiej instytucji zwrócisz się w konkretnej sprawie?"],
+    "buckets": [
+        {"id": 1, "title": "GIODO"},
+        {"id": 2, "title": "UOKiK"},
+        {"id": 3, "title": "RPD"},
+        {"id": 4, "title": "KRRiT"},
+        {"id": 5, "title": "UKE"}
+
+    ],
+    "buckets_name": "instytucje",
+    "items": [
+        {"id": 1, "text": "1", "desc": "sklep internetowy nie chce oddać Ci pieniędzy za towar zwrócony w ciągu 10 dni od daty zakupu"},
+        {"id": 2, "text": "2", "desc": "wiesz, że kolega z młodszej klasy jest prześladowany w internecie, a lokalne instytucje nie reagują na problem"},
+        {"id": 3, "text": "3", "desc": "w audycji radiowej prowadzący obrażał cudzoziemców mieszkających w Polsce"}
+    ],
+    "items_name": "sprawy",
+    "answer": {
+        "2": [1],
+        "3": [2],
+        "4": [3]
+    },
+    "points_per_hit": 1
+},
+
+{
+    "id": 13,
+    "type": "edumed_wybor",
+    "description": ["Chcesz dowiedzieć się, co sklep internetowy robi z Twoimi danymi osobowymi. Gdzie szukasz tej informacji?"],
+    "options": [
+        {"id": 1, "text": "w zakładce “O nas”"},
+        {"id": 2, "text": "w zakładce “Twój profil”"},
+        {"id": 3, "text": "w “Polityce prywatności”"},
+        {"id": 4, "text": "w “Regulaminie zakupów”"}
+    ],
+    "answer": [3],
+    "points": 1
+},
+
+{
+    "id": 14,
+    "type": "edumed_wybor",
+    "description": ["Jak należy oznaczyć zdjęcie ściągnięte z Wikipedii, które chcesz opublikować na swoim blogu?"],
+    "options": [
+        {"id": 1, "text": "Należy podać informację, że zdjęcie pochodzi z internetu (źródło: internet)."},
+        {"id": 2, "text": "Należy podać nazwisko/pseudonim autorki lub autora."},
+        {"id": 3, "text": "Należy podać informacje o licencji, na której opublikowane jest zdjęcie."},
+        {"id": 4, "text": "Należy podać link do strony, z której ściągnięto zdjęcie."}
+    ],
+    "answer": [2,3,4],
+    "answer_mode": "all_or_nothing",
+    "points": 1
+},
+
+{
+    "id": 15,
+    "type": "edumed_wybor",
+    "description": ["Na ostatniej imprezie karaoke zrobiłaś/eś świetne zdjęcie swojej koleżanki śpiewającej przeboje Abby. Wiesz, że pewnie nie będzie się jej podobać, ale chcesz, żeby jak najwięcej osób zapamiętało ten wieczór. Co robisz?"],
+    "options": [
+        {"id": 1, "text": "wysyłasz zdjęcie do wszystkich uczestników imprezy mailem"},
+        {"id": 2, "text": "wrzucasz zdjęcie na swój publiczny profil w portalu społecznościowym, a potem informujesz o tym koleżankę"},
+        {"id": 3, "text": "pytasz koleżankę, czy zgadza się na publikację zdjęcia, a potem udostępniasz je tylko osobom, które były na imprezie"},
+        {"id": 4, "text": "wrzucasz zdjęcie na swojego bloga, ale zamazujesz twarz koleżanki"}
+    ],
+    "answer": [3],
+    "points": 1
+},
+
+{
+    "id": 16,
+    "type": "edumed_wybor",
+    "description": ["Twój starszy brat chce podczas imprezy urodzinowej w Sopocie puszczać ze znajomymi tzw. chińskie lampiony. Jakie zezwolenie jest mu potrzebne?"],
+    "options": [
+        {"id": 1, "text": "zezwolenie Państwowej Straży Pożarnej"},
+        {"id": 2, "text": "zezwolenie Polskiej Agencji Żeglugi Powietrznej"},
+        {"id": 3, "text": "zezwolenie Urzędu Miasta"},
+        {"id": 4, "text": "zezwolenie Sanepidu"}
+    ],
+    "answer": [2],
+    "open_part": ["Co wpisałeś/aś w okno wyszukiwarki, żeby znaleźć tę informację?"],
+    "max_points": 2
+},
+
+{
+    "id": 17,
+    "type": "edumed_wybor",
+    "description": ["Na pulpicie Twojego komputera wyświetla się taki komunikat. Komputer faktycznie zostaje zablokowany. Co robisz?",
+        "<img src=\"/static/wtem/img/komunikat_policyjny.png\"/>"
+    ],
+    "options": [
+        {"id": 1, "text": "pokazujesz komunikat rodzicom/opiekunom"},
+        {"id": 2, "text": "sprawdzasz prawdziwość zawartych w komunikacie informacji, np. wymienionych artykułów prawnych"},
+        {"id": 3, "text": "dokonujesz zalecanej płatności"},
+        {"id": 4, "text": "sprawdzasz w wyszukiwarce internetowej (z telefonu komórkowego lub innego komputera) co należy zrobić w takiej sytuacji"},
+        {"id": 5, "text": "restartujesz komputer"},
+        {"id": 6, "text": "podejrzewasz, że może to być wirus komputerowy i zgłaszasz to osobie kompetentnej, np. informatykowi"}
+    ],
+    "answer": [1,2,4,6],
+    "points_per_hit": 0.5
+},
+
+{
+    "id": 18,
+    "type": "edumed_przyporzadkuj",
+    "hide_default_instruction": 1,
+    "description": ["Wyobraź sobie, że poniższe zdjęcia przedstawiają Twój wizerunek. Jak i gdzie można je wykorzystać? Połącz w pary zdjęcia i miejsca ich publikacji."],
+    "buckets": [
+        {"id": 1, "title": "dostępny dla wszystkich album ze zdjęciami na towarzyskim portalu społecznościowym"},
+        {"id": 2, "title": "dostępny tylko dla najbliższych znajomych album ze zdjęciami na towarzyskim portalu społecznościowym"},
+        {"id": 3, "title": "avatar na forum dotyczącym pracy w bankowości"},
+        {"id": 4, "title": "formularz rekrutacyjny na wakacyjną wymianę młodzieży"},
+        {"id": 5, "title": "nie publikuję tego zdjęcia w sieci"}
+
+    ],
+    "buckets_name": "miejsca",
+    "items": [
+        {"id": 1, "text": "1", "href_absolute": 1, "href": "http://www.flickr.com/photos/kk/5443214980/sizes/s/in/photostream/", "img": "przyp/1.jpg"},
+        {"id": 2, "text": "2", "href_absolute": 1, "href": "http://www.flickr.com/photos/keithusc/2799394010/sizes/s/in/photostream/","img": "przyp/2.jpg"},
+        {"id": 3, "text": "3", "href_absolute": 1, "href": "http://www.flickr.com/photos/mike-burns/7459087/sizes/s/in/photostream/","img": "przyp/3.jpg"},
+        {"id": 4, "text": "4", "href_absolute": 1, "href": "http://www.flickr.com/photos/76029035@N02/6829334723/sizes/s/in/photostream/","img": "przyp/4.jpg"},
+        {"id": 5, "text": "5", "href_absolute": 1, "href": "http://www.flickr.com/photos/84502900@N00/3502014745", "img": "przyp/5.jpg"}
+    ],
+    "items_name": "zdjęcia",
+    "items_instruction": "Przeciągnij numery zdjęć do odpowiednich szarych poł powyżej",
+    "items_inline": 1,
+    "description_after": ["<span class=\"wtem-disclaimer\">(Wszystkie użyte zdjęcia dostępne na CC-BY-SA - źródła/autorzy dostępni po kliknięciu w obrazek)</span>"],
+    "points_per_hit": 0.5,
+    "answer_mode": "possible_buckets_for_item",
+    "answer": {
+        "1": [1,2,3,4],
+        "2": [5],
+        "3": [2,5],
+        "4": [1,2,3,4],
+        "5": [1,2]
+    }
+},
+
+{
+    "id": 19,
+    "type": "edumed_wybor",
+    "description": ["Jaki jest symbol klasyfikacji bibliotecznej najnowszego wydania książki “Ekonomia w jednej lekcji” autorstwa Henry’ego Hazlitta w zbiorach Biblioteki Uniwersyteckiej w Warszawie?"],
+    "options": [
+        {"id": 1, "text": "HG229 .H39165 2007"},
+        {"id": 2, "text": "1151471"},
+        {"id": 3, "text": "PS3515.A96 T56165 2011"},
+        {"id": 4, "text": "HB171 .H445165 2012"}
+    ],
+    "answer": [4],
+    "points": 1
+},
+
+{
+    "id": 20,
+    "type": "edumed_prawdafalsz",
+    "description": ["Oznacz poniższe zdania jako prawdziwe lub fałszywe."],
+    "statements": [
+        ["Telewizja TVN finansowana jest ze środków pochodzących z abonamentu radiowo - telewizyjnego.", false],
+        ["Polskie Radio nie może nadawać żadnych reklam.", false],
+        ["TVP Historia należy do mediów publicznych.", true],
+        ["TVP Kultura nie jest nastawiona na zysk.", true],
+        ["Radiowa Czwórka jest stacją komercyjną.", false],
+        ["Działalność mediów publicznych ma charakter misyjny.", true]
+    ],
+    "points_per_hit": 0.5
+},
+
+{
+    "id": 21,
+    "type": "open",
+    "description": ["Przygotuj komunikat na podstawie podanych niżej wiadomości w formie:"],
+    "fields": [
+        {"caption": "1. oficjalnego zaproszenia wysyłanego mailem", "id": 1},
+        {"caption": "2. sms-a do znajomych, maksymalnie 140 znaków", "id": 2, "max_length": 140, "rows": 2, "input_id": "wtem_sms"},
+        {"caption": "3. informacji prasowej do lokalnej gazety", "id": 3}
+    ],
+    "description_after": [
+        "Twój przyjaciel – Krzysztof Gawroński, znany w środowisku jako Gawron – jest gitarzystą i wokalistą w zespole rockowo-metalowym „The Urban Jungle”. 22 stycznia br. o 19. odbędzie się koncert zespołu w Domu Kultury Miejskiej przy ul. Wielebskiego 3 w Krętowie. Zespół zagra m.in. covery Metallicy, Black Sabbath, ale też własne utwory. Bilety mają być w cenie 15 zł. Oprócz Krzysztofa w zespole grają także Michał Kordowski na gitarze basowej i Tomasz Bielewski na perkusji. Ostatnio miałeś okazję się z nimi spotkać i porozmawiać o ich twórczości. Planują występ w programie „Must be the music”, a wcześniej małą trasę koncertową po powiecie bełżeckim, odwiedzając – oprócz Krętowa – Bełżec, Wielkie Głazy i Niechorzów. Gawron zwierzył Ci się, że napisał 2 nowe utwory, które po raz pierwszy zostaną zaprezentowane na koncercie 22 stycznia. Jeśli uda im się zebrać pieniądze (ok. 15 tys. zł) chcą zacząć nagrywanie swojej pierwsze płyty."
+    ],
+    "max_points": 9
+},
+
+{
+    "id": 22,
+    "type": "file_upload",
+    "description": [
+        "Na podstawie poniższego fragmentu tekstu przygotuj 1 slajd prezentacji przeznaczonej dla uczniów 2 klasy szkoły podstawowej. Wykorzystaj też zdjęcie dostępne w interencie, które jest udostępnione na licencji umożliwiającej jego dalsze przetwarzanie i rozpowszechnianie.",
+        "Zapisz przygotowany slajd na dysku swojego komputera, a następnie, korzystając z poniższego przycisku załącz go do zadania"
+    ],
+    "description_after": [
+        "<cite>Puszcza Białowieska – kompleks leśny położony na terenie Polski i Białorusi, odznaczający się dużymi walorami przyrodniczymi i historycznymi. W Puszczy Białowieskiej zachowały się ostatnie fragmenty lasu o charakterze pierwotnym. Tutaj mieszka największa populacja wolnego żubra na świecie.</cite>",
+        "<cite>Puszcza Białowieska leży w strefie klimatu umiarkowanego przejściowego, stosunkowo chłodnego i z dominacją wpływów kontynentalnych w związku z czym w pewnych klasyfikacjach bywa on określany jako klimat leśny subkontynentalny strefy umiarkowanie chłodnej.</cite>",
+        "<cite>Według danych z Białowieskiego Parku Narodowego średnia roczna temperatura powietrza w latach 1955-2001 wynosiła 6,8 °C. Odnotowane temperatury mieściły się w zakresie od +34,5 °C do –38,7 °C (rekord zimna w 1950 r.).</cite>",
+        "<cite>Średnia ilość opadów wynosi 633 mm na rok, z czego większość w sezonie wegetacyjnym który względem Polski zachodniej jest krótszy o miesiąc i trwa 205 dni. Zima natomiast jest długa, z pokrywą śnieżną utrzymującą się średnio ponad 92 dni.</cite>",
+        "<cite>Na terenie Puszczy białowieskiej żyje 58 gatunków ssaków co stanowi ponad 70 procent fauny niżowej Polski w obrębie tej grupy. Z pośród występujących tu gatunków 33 podlegają w Polsce ochronie prawnej, a 12 figuruje w Polskiej Czerwonej Księdze Zwierząt.</cite>",
+        "Żródło: Puszcza Białowieska, <a href=\"http://pl.wikipedia.org/w/index.php?title=Puszcza_Bia%C5%82owieska&oldid=37917751\">http//pl.wikipedia.org/w/index.php?title=Puszcza_Bia%C5%82owieska&oldid=37917751</a> (dostęp 18.11.2013), CC BY-SA"
+    ],
+    "max_points": 9,
+    "max_file_size_string": "5 megabajtów"
+}
+
+]
\ No newline at end of file
diff --git a/src/wtem/fixtures/exercises-2014.json b/src/wtem/fixtures/exercises-2014.json
new file mode 100644 (file)
index 0000000..0793ce5
--- /dev/null
@@ -0,0 +1,266 @@
+[
+
+{
+    "id": 1,
+    "type": "edumed_wybor",
+    "description": ["Z jaką licencją Creative Commons jest zgodna OGL (Open Government License) i w jakim kraju się ją stosuje?"],
+    "options": [
+        {"id": 1, "text": "CC BY-SA, w Nowej Zelandii,"},
+        {"id": 2, "text": "CC BY-ND, w Kanadzie,"},
+        {"id": 3, "text": "CC BY-SA, w Wlk. Brytanii,"},
+        {"id": 4, "text": "CC BY, w Wlk. Brytanii."}
+    ],
+    "answer": [4],
+    "points": 1
+},
+
+{
+    "id": 2,
+    "type": "edumed_przyporzadkuj",
+    "description": ["Dopasuj definicje do pojęć:"],
+    "buckets":  [
+        {"id": 1, "title": "plonk"},
+        {"id": 2, "title": "OZZ"},
+        {"id": 3, "title": "DRM"},
+        {"id": 4, "title": "booksprint"},
+        {"id": 5, "title": "protokół HTTPS"}
+    ],
+    "buckets_name": "Pojęcia",
+    "items": [
+        {"id": 1, "text": "1", "desc": "Oprogramowanie i sprzęt mające uniemożliwić działania niezgodne z prawem autorskim lub warunkami serwisu/wolą producenta. Stosuje się w muzyce, filmach, grach i innych mediach. Opiera się na mechanizmach kryptograficznych, zabezpieczając np. przed nieautoryzowanym odczytem lub skopiowaniem."},
+        {"id": 2, "text": "2", "desc": "Forma współpracy, polegająca na bardzo szybkim (od kilku godzin do kilku dni) stworzeniu książki przez zespół autorów. Zwykle zespół ten zbiera się przez internet, a książka wydawana jest w formie elektronicznej."},
+        {"id": 3, "text": "4", "desc": "Jeden z protokołów umożliwiający przesyłanie w sieci zaszyfrowanych informacji, dzięki czemu dostęp do treści mają jedynie nadawca oraz odbiorca komunikatu."},
+        {"id": 4, "text": "5", "desc": "Dodanie osoby, której postów nie chcemy czytać, do mechanizmu automatycznego usuwania wiadomości."},
+        {"id": 5, "text": "6", "desc": "Podmiot zarządzający majątkowymi prawami autorskimi, głównie poprzez wydawanie licencji na korzystanie z utworów."}
+    ],
+    "items_name": "Definicje",
+    "answer": {
+        "1": [4],
+        "2": [5],
+        "3": [1],
+        "4": [2],
+        "5": [3]
+    },
+    "points_per_hit": 1
+},
+
+{
+    "id": 3,
+    "type": "open",
+    "description": ["Co Myszka Miki ma wspólnego z wydłużeniem okresu obowiązywania majątkowych praw autorskich? O ile został wydłużony okres obowiązywania praw majątkowych w stosunku do wcześniejszych przepisów?"],
+    "open_part": ["W jaki sposób dotarłeś/aś do tej informacji? Wklej adres strony, z której skorzystałeś/aś."],
+    "open_part_rows": 1,
+    "max_points": 2
+},
+
+{
+    "id": 4,
+    "type": "edumed_wybor",
+    "description": ["W którym z tych miast dojedziesz trolejbusem nr 150 z dworca PKP do al. Racławickich?"],
+    "options": [
+        {"id": 1, "text": "w Lublinie"},
+        {"id": 2, "text": "w Tychach"},
+        {"id": 3, "text": "w Gdyni"}
+    ],
+    "answer": [1],
+    "points": 1,
+    "open_part": ["W jaki sposób dotarłeś/aś do tej informacji? Wklej adres strony, z której skorzystałeś/aś."],
+    "open_part_rows": 1,
+    "max_points": 1.5
+},
+
+{
+    "id": 5,
+    "type": "edumed_wybor",
+    "description": ["Którą frazę należy dodać do zapytania w wyszukiwarce internetowej Google.com, aby wyszukać tylko prezentacje w formacie OpenDocument?"],
+    "options": [
+        {"id": 1, "text": "tylko prezentacje"},
+        {"id": 2, "text": "OpenDocument"},
+        {"id": 3, "text": "filetype:ppt"},
+        {"id": 4, "text": "filetype:odp"}
+    ],
+    "answer": [4],
+    "points": 1
+},
+
+{
+    "id": 6,
+    "type": "edumed_wybor",
+    "description": ["Do jakiej organizacji powinieneś/-nnaś się zwrócić, jeśli zapłaciłeś/-aś za zamówiony przez internet  towar i go nie otrzymałeś/-aś, a ze sprzedawcą nie ma kontaktu?"],
+    "options": [
+        {"id": 1, "text": "UOKiK"},
+        {"id": 2, "text": "UKE"},
+        {"id": 3, "text": "RZP"},
+        {"id": 4, "text": "KNF"}
+    ],
+    "answer": [1],
+    "points": 1
+},
+
+{
+    "id": 7,
+    "type": "open",
+    "description": ["Ile czasu, zgodnie z polskim prawem, klient ma na zwrot towaru/usługi zakupionych przez internet? Czy można to zrobić bez podawania przyczyny? Podaj, jaki akt prawny to reguluje."],
+    "max_points": 3
+},
+
+{
+    "id": 8,
+    "type": "open",
+    "description": ["Jakie poziomy widoczności swoich postów możesz ustawić na Facebooku? Wskaż co najmniej dwa."],
+    "max_points": 2
+},
+
+{
+    "id": 9,
+    "type": "open",
+    "description": ["Podaj przykład inicjatywy sfinansowanej metodą crowdfundingu. Czy w Polsce można finansować tą metodą różne przedsięwzięcia? Jeśli tak, to na jakiej podstawie prawnej?"],
+    "max_points": 2
+},
+
+{
+    "id": 10,
+    "type": "edumed_prawdafalsz",
+    "description": ["Oznacz poniższe zdania jako prawdziwe lub fałszywe."],
+    "statements": [
+        ["Akcyza to jeden z elementów polityki antymonopolowej.", false],
+        ["Większość (98%) treści w serwisie ninateka.pl jest dostępna za darmo bez konieczności logowania.", true],
+        ["GIODO to instytucja uprawniona do kontroli zgodności przetwarzanych danych z przepisami o ochronie danych osobowych.", true],
+        ["Polska telewizja publiczna utrzymuje się jedynie z wpływów finansowych z abonamentu radiowo-telewizyjnego.", false],
+        ["Grupa ITI jest właścicielem TV TVN oraz serwisu sympatia.pl.", true]
+    ],
+    "points_per_hit": 0.5
+},
+
+{
+    "id": 11,
+    "type": "open",
+    "description": ["Znajdź w sieci krótki przykład (tekstowy lub filmowy) każdego z podanych poniżej gatunków. W przypadku tekstu - wklej go i podaj jego źródło. Jeśli prezentujesz film - wklej link do strony, na której się znajduje."],
+    "fields": [
+        {"caption": "reportaż", "id": 1},
+        {"caption": "felieton", "id": 2},
+        {"caption": "wywiad", "id": 3}
+    ],
+    "max_points": 3
+},
+
+{
+    "id": 12,
+    "type": "open",
+    "description": ["Na podstawie poniższego tekstu przygotuj:"],
+    "fields": [
+        {"caption": "a. komunikat zawierający Twoją  opinię nt. proponowanych w rozporządzeniu zmian. Staraj się uargumentować swoje stanowisko.", "id": 1},
+        {"caption": "b. komunikat perswazyjny będący częścią kampanii informacyjno-promocyjnej nowych przepisów.", "id": 2}
+    ],
+    "description_after": [
+        "Opakowania,  pojemniki lub komory ładunkowe w środkach transportu powinny być  oznakowane w sposób trwały i czytelny, umożliwiać identyfikację rodzaju  transportowanych odpadów oraz posiadać widoczne odporne na warunki  atmosferyczne oznakowanie identyfikujące zawierające:<br/>1) kod odpadów w nich transportowanych zgodnie z katalogiem odpadów;<br/>2) imię i nazwisko oraz adres zamieszkania lub nazwę i adres siedziby wytwórcy odpadów. (...)"
+    ],
+    "max_points": 4
+},
+
+{
+    "id": 13,
+    "type": "edumed_wybor",
+    "description": ["Czy możesz opublikować niekomercyjnie remiks wierszy dostępnych w bibliotece internetowej Wolne Lektury? Dlaczego?"],
+    "options": [
+        {"id": 1, "text": "Nie mogę."},
+        {"id": 2, "text": "Mogę, ale dopiero kiedy uzyskam zgodę autorów/autorek lub ich spadkobierców."},
+        {"id": 3, "text": "Mogę. Uiściłem/-am opłaty na rzecz Funduszu Promocji Twórczości."},
+        {"id": 4, "text": "Mogę, wiersze z biblioteki Wolne Lektury znajdują się w domenie publicznej albo publikowane są na licencji CC BY-SA 3.0, która umożliwia taką publikację."}
+    ],
+    "answer": [4],
+    "points": 1
+},
+
+{
+    "id": 14,
+    "type": "open",
+    "description": ["Na czym polega tzw. otwarty dostęp? Podaj dwa przykłady inicjatyw realizowanych zgodnie z tym hasłem.  Podaj adres(y) stron(y), na której/ych znalazłeś(-aś) te informacje."],
+    "max_points": 3
+},
+
+{
+    "id": 15,
+    "type": "edumed_wybor",
+    "description": ["Wskaż wszystkie prawidłowe odpowiedzi dotyczące Urzędu Komisji Nadzoru Finansowego:"],
+    "options": [
+        {"id": 1, "text": "wydaje zezwolenia na prowadzenie działalności na rynku finansowym"},
+        {"id": 2, "text": "realizuje postanowienia KNF"},
+        {"id": 3, "text": "pracownicy Urzędu należą do korpusu służby cywilnej"},
+        {"id": 4, "text": "w skład urzędu wchodzi Departament Nadzoru Inwestycji Emerytalnych"}
+    ],
+    "answer": [2, 4],
+    "points_per_hit": 1
+},
+
+{
+    "id": 16,
+    "type": "edumed_wybor",
+    "description": ["Administrator strony zgodnej z <em>Wytycznymi dla dostępności treści internetowych</em> na najwyższym poziomie zgodności (AAA) może:"],
+    "options": [
+        {"id": 1, "text": "umieszczać na niej skany dokumentów bez OCR"},
+        {"id": 2, "text": "zamieszczać najważniejsze informacje w postaci audio lub wideo, dołączając alternatywną wersję tekstową"},
+        {"id": 3, "text": "wymagać od użytkownika wpisania słowa odczytanego z obrazka"},
+        {"id": 4, "text": "pisać, stosując żargon naukowy i nie wyjaśniając znaczenia trudniejszych pojęć"}
+    ],
+    "answer": [2],
+    "points": 1
+},
+
+{
+    "id": 17,
+    "type": "open",
+    "description": ["W  pobliskim domu kultury odbywa się koncert Twojej ulubionej grupy. Zaproś swojego nauczyciela języka polskiego (napisz e-mail). Poinformuj o tym wydarzeniu swoich znajomych na Facebooku. Pamiętaj, aby każdy z komunikatów był sformułowany zgodnie z zasadami medialnego savoire vivre'u."],
+    "fields": [
+        {"caption": "e-mail do nauczyciela", "id": 1},
+        {"caption": "wiadomość do znajomych", "id": 2}
+    ],
+    "max_points": 4
+},
+
+{
+    "id": 18,
+    "type": "edumed_wybor",
+    "description": [" Kolega prosi Cię w komentarzu na Facebooku o podanie numeru telefonu wspólnego znajomego. Co robisz?"],
+    "options": [
+        {"id": 1, "text": "telefonujesz do znajomego i pytasz go, czy możesz przekażać nr telefonu koledze"},
+        {"id": 2, "text": "przekazujesz nr znajomego smsem lub w prywatnej wiadomości"},
+        {"id": 3, "text": "podajesz nr telefonu w kolejnym komentarzu"}
+    ],
+    "answer": [1, 2],
+    "answer_mode": "all_or_nothing",
+    "points": 1
+},
+
+{
+    "id": 19,
+    "type": "file_upload",
+    "description": [
+        "Poszukujesz materiałów z blogów lub innych serwisów internetowych dotyczących księcia Józefa Poniatowskiego. Zależy Ci jednak, aby materiały te można było swobodnie wykorzystywać, udostępniać i modyfikować, także w celach komercyjnych. Stwórz odpowiednie zapytanie w wyszukiwarce; zrób zrzut ekranu przedstawiający zapytanie."
+    ],
+    "max_points": 2,
+    "max_file_size_string": "5 megabajtów"
+},
+
+{
+    "id": 20,
+    "type": "edumed_wybor",
+    "description": ["W przypadku logowania się w ramach sieci TOR dostawca internetu użytkownika zna:"],
+    "options": [
+        {"id": 1, "text": "numer IP użytkownika"},
+        {"id": 2, "text": "loginy i hasła użytkownika"},
+        {"id": 3, "text": "dane, które użytkownik przesyła i odbiera"},
+        {"id": 4, "text": "adresy stron, które użytkownik odwiedza"}
+    ],
+    "answer": [1],
+    "points": 1
+},
+
+{
+    "id": 21,
+    "type": "open",
+    "description": ["Podaj trzy przykłady wolnego oprogramowania."],
+    "max_points": 3
+}
+
+]
diff --git a/src/wtem/fixtures/exercises-2015.json b/src/wtem/fixtures/exercises-2015.json
new file mode 100644 (file)
index 0000000..aa98785
--- /dev/null
@@ -0,0 +1,327 @@
+[
+{
+    "id": 1,
+    "type": "edumed_przyporzadkuj",
+    "hide_default_instruction": 1,
+    "description": ["Które z fotografii umieścił(a)byś jako zdjęcie profilowe na portalu Facebook, które na LinkedIn, a które z nich na żadnej z tych stron?"],
+    "buckets": [
+        {"id": 1, "title": "Facebook"},
+        {"id": 2, "title": "Facebook"},
+        {"id": 3, "title": "Facebook"},
+        {"id": 4, "title": "Facebook"},
+        {"id": 5, "title": "LinkedIn"},
+        {"id": 6, "title": "LinkedIn"},
+        {"id": 7, "title": "LinkedIn"},
+        {"id": 8, "title": "LinkedIn"},
+        {"id": 9, "title": "nigdzie"},
+        {"id": 10, "title": "nigdzie"},
+        {"id": 11, "title": "nigdzie"},
+        {"id": 12, "title": "nigdzie"}
+    ],
+    "buckets_name": "strony",
+    "items": [
+        {"id": 1, "text": "1", "href_absolute": 1, "href": "https://www.flickr.com/photos/seeminglee/3942177783/", "img": "przyp2/1.jpg"},
+        {"id": 2, "text": "2", "href_absolute": 1, "href": "https://www.flickr.com/photos/davebloggs007/14573899083/","img": "przyp2/2.jpg"},
+        {"id": 3, "text": "3", "href_absolute": 1, "href": "https://www.flickr.com/photos/125303894@N06/14365668676/","img": "przyp2/3.jpg"},
+        {"id": 4, "text": "4", "href_absolute": 1, "href": "https://www.flickr.com/photos/gagilas/4224108472/","img": "przyp2/4.jpg"},
+        {"id": 5, "text": "5", "href_absolute": 1, "href": "https://www.flickr.com/photos/conejoazul/1455987854/", "img": "przyp2/5.jpg"}
+    ],
+    "items_name": "zdjęcia",
+    "items_instruction": "Przeciągnij numery zdjęć do odpowiednich szarych pól powyżej. W każdym szarym polu można umieścić tylko jeden numer.",
+    "items_inline": 1,
+    "description_after": ["<span class=\"wtem-disclaimer\">(Wszystkie użyte zdjęcia dostępne na CC BY lub CC BY-SA – źródła/autorzy dostępni po kliknięciu w obrazek)</span>"],
+    "points_per_hit": 0.5,
+    "answer_mode": "possible_buckets_for_item",
+    "answer": {
+        "1": [1,2,3,4],
+        "2": [1,2,3,4],
+        "3": [1,2,3,4,5,6,7,8],
+        "4": [9,10,11,12],
+        "5": [9,10,11,12]
+    }
+},
+
+{
+    "id": 2,
+    "type": "open",
+    "description": ["Twoja koleżanka wygrała ogólnopolski konkurs muzyczny, na którym zyskała uznanie jury i publiczności. Pogratuluj sukcesu w określonej poniżej formie:"],
+    "fields": [
+        {"id": 1, "caption": "1. tweet"},
+        {"id": 2, "caption": "2. wpis na tablicy na Facebooku"},
+        {"id": 3, "caption": "3. krótki mail do jej rodziców"}
+    ],
+    "max_points": 6
+},
+
+{
+    "id": 3,
+    "type": "open",
+    "description": ["Twoja mama jest początkującą użytkowniczką internetu. Prosi cię o rady, jak bezpiecznie korzystać z sieci. Przekaż jej co najmniej pięć wskazówek, które będzie mogła wykorzystać podczas codziennej pracy przy komputerze."],
+    "max_points": 5
+},
+
+{
+    "id": 4,
+    "type": "edumed_przyporzadkuj",
+    "description": ["Dopasuj nazwę wtyczki do jej działania:"],
+    "buckets": [
+        {"id": 1, "title": "AdBlock"},
+        {"id": 2, "title": "CookieMonster"},
+        {"id": 3, "title": "NoScript"},
+        {"id": 4, "title": "FlashBlock"}
+    ],
+    "buckets_name": "wtyczki",
+    "items": [
+        {"id": 1, "text": "1", "desc": "rozszerzenie do przeglądarek internetowych, automatycznie blokuje skrypty uruchamiane i zewnętrzne zasoby pobierane przez strony internetowe w przeglądarce."},
+        {"id": 2, "text": "2", "desc": "rozszerzenie do przeglądarek internetowych domyślnie blokujące wszystkie filmiki typu flash na stronach internetowych, pozwalające je uruchomić jednym kliknięciem myszki."},
+        {"id": 3, "text": "3", "desc": "rozszerzenie do przeglądarek internetowych, automatycznie blokuje i usuwa reklamy ze stron internetowych. Zwiększa wygodę i bezpieczeństwo korzystania z sieci. Ogranicza przepływ informacji o historii przeglądania."},
+        {"id": 4, "text": "4", "desc": "rozszerzenie do przeglądarek internetowych, pozwala bardzo dokładnie kontrolować ciasteczka i to, jakie strony (i na jak długo) mogą je ustawiać."}
+    ],
+    "items_name": "działania",
+    "answer": {
+        "1": [3],
+        "2": [4],
+        "3": [1],
+        "4": [2]
+    },
+    "points_per_hit": 0.5
+},
+
+{
+    "id": 5,
+    "type": "open",
+    "description": ["Podaj po jednym przykładzie serwisu (konkretne nazwy), który umożliwia podane niżej akcje."],
+    "instruction": "Każda strona może byc podana tylko jeden raz.",
+    "fields": [
+        {"id": 1, "caption": "budowanie i podtrzymywanie relacji", "rows": 1},
+        {"id": 2, "caption": "komunikację, dyskusję", "rows": 1},
+        {"id": 3, "caption": "bieżące informowanie i odnoszenie się do aktualności", "rows": 1},
+        {"id": 4, "caption": "prezentacja opinii i poglądów", "rows": 1},
+        {"id": 5, "caption": "współdzielenie plików", "rows": 1},
+        {"id": 6, "caption": "współtworzenie dokumentów", "rows": 1}
+    ],
+    "max_points": 3
+},
+
+{
+    "id": 6,
+    "type": "open",
+    "description": ["Wraz ze znajomymi 5 marca 2016 r. chcecie wybrać się w podróż z Zakopanego do Gdańska. Żadne z was nie posiada prawa jazdy i samochodu, nie chcecie korzystać z pomocy rodziców. Zależy wam, aby podróż trwała jak najkrócej i była jak najtańsza. Zaplanuj waszą podróż środkami transportu publicznego. Podaj godzinę rozpoczęcia i zakończenia podróży, szczegóły trasy i usług komunikacyjnych, z których skorzystacie.", "Podaj adres(y) stron(y), z których skorzystałeś/-aś."],
+    "max_points": 6
+},
+
+{
+    "id": 7,
+    "type": "open",
+    "description": ["Podaj cztery aspekty (obszary) prywatności człowieka."],
+    "max_points": 2
+},
+
+{
+    "id": 8,
+    "type": "open",
+    "description": ["Wyjaśnij krótko, na czym polega hakowanie w pozytywnym aspekcie tego zjawiska."],
+    "max_points": 5
+},
+
+{
+    "id": 9,
+    "type": "open",
+    "description": ["Wymień trzy przykłady projektów, które powstają i rozwijają się dzięki crowdsourcingowi."],
+    "max_points": 1.5
+},
+
+{
+    "id": 10,
+    "type": "edumed_przyporzadkuj",
+    "description": ["Dopasuj pojęcie do definicji:"],
+    "buckets": [
+        {"id": 1, "title": "dyskryminacja"},
+        {"id": 2, "title": "kryptoreklama"},
+        {"id": 3, "title": "cyberprzemoc"},
+        {"id": 4, "title": "koncesja"}
+    ],
+    "buckets_name": "pojęcia",
+    "items": [
+        {"id": 1, "text": "1", "desc": "stosowanie przemocy poprzez: prześladowanie, zastraszanie, nękanie,wyśmiewanie innych osób przy pomocy narzędzi typu elektronicznego,np. SMS, e-mail, witryny internetowe, fora dyskusyjne."},
+        {"id": 2, "text": "2", "desc": "traktowanie pewnych osób lub grup społecznych w inny sposób, zwykle mniej sprawiedliwy, niż innych osób i grup."},
+        {"id": 3, "text": "3", "desc": "zezwolenie,upoważnienie do prowadzenia jakiejś działalności."},
+        {"id": 4, "text": "4", "desc": "przekaz handlowy polegający na przedstawieniu lub nawiązywaniu do towaru, usługi lub ich znaku towarowego w taki sposób, że stanowią one element samej audycji."}
+    ],
+    "items_name": "definicje",
+    "answer": {
+        "1": [2],
+        "2": [4],
+        "3": [1],
+        "4": [3]
+    },
+    "points_per_hit": 0.5
+},
+
+{
+    "id": 11,
+    "type": "open",
+    "description": ["Istnieje dwanaście wytycznych dotyczących dostępności treści internetowych (WCAG). Każdą wytyczną przyporządkuj do jednej z czterech zasad."],
+    "instruction": "Wpisz litery do odpowiednich pól tekstowych.",
+    "fields": [
+        {"id": 1, "caption": "zrozumiałość", "rows": 1},
+        {"id": 2, "caption": "brak przeszkód w obsłudze", "rows": 1},
+        {"id": 3, "caption": "postrzegalność zmysłowa", "rows": 1},
+        {"id": 4, "caption": "solidne wykonanie", "rows": 1}
+    ],
+    "description_after": [
+        "a) teksty są czytelne i łatwe w odbiorze",
+        "b) treść ma swój odpowiednik: obrazom i filmom towarzyszą opisy tekstowe, głosowe,napisy, tłumaczenia na język migowy",
+        "c) treść jest eksponowana za pomocą najnowszych technologii uwzględniających wytyczne dotyczące dostępności",
+        "d) prezentacja treści (kształt graficzny, styl) nie wpływa na odbiór",
+        "e) strona jest możliwa w obsłudze przy użyciu klawiatury",
+        "f) do treści można dotrzeć różnymi drogami (urządzenia, oprogramowanie)",
+        "g) interfejs jest intuicyjny i logicznie zbudowany",
+        "h) trudno popełnić błąd w obsłudze interfejsu",
+        "i) nie ma limitów czasowych w korzystaniu z serwisu",
+        "j) informacje pierwszoplanowe nie zlewają się z tłem",
+        "k) sekcje na stronie mają jednoznaczne tytuły i są logicznie podzielone",
+        "l) można pominąć szkodliwe dla wzroku i słuchu komunikaty"
+    ],
+    "max_points": 6
+},
+
+{
+    "id": 12,
+    "type": "edumed_wybor",
+    "description": ["Na co NIE pozwala ci dozwolony użytek?"],
+    "options": [
+        {"id": 1, "text": "na sprzedawanie kopii płyt z muzyką twojego ulubionego zespołu"},
+        {"id": 2, "text": "na oglądanie filmu pobranego z internetu"},
+        {"id": 3, "text": "na nagranie serialu na płytę i obejrzenie go z rodziną"},
+        {"id": 4, "text": "żadna z powyższych odpowiedzi nie jest prawidłowa"}
+    ],
+    "answer": [1],
+    "points": 1
+},
+
+{
+    "id": 13,
+    "type": "edumed_wybor",
+    "description": ["Chcesz opublikować swoje opowiadanie na wolnej licencji. Zezwalasz na jego kopiowanie, zmienianie, remiksowanie, rozprowadzanie i wykonanie, ale pod warunkiem, że ewentualne utwory zależne -- np. tłumaczenia -- będą przez ich autorów udostępnione na takiej samej licencji. Którą z licencji wybierzesz?"],
+    "options": [
+        {"id": 1, "text": "CC BY-SA"},
+        {"id": 2, "text": "CC BY-NC"},
+        {"id": 3, "text": "CC BY"},
+        {"id": 4, "text": "żadną z wymienionych"}
+    ],
+    "answer": [1],
+    "points": 1
+},
+
+{
+    "id": 14,
+    "type": "edumed_wybor",
+    "description": ["Do nawyków higieny informacyjnej należą:"],
+    "options": [
+        {"id": 1, "text": "tworzenie kopii zapasowych informacji, na których nam zależy"},
+        {"id": 2, "text": "odczytywanie informacji na specjalnym czytniku"},
+        {"id": 3, "text": "robienie przerw co 20 minut, aby uporządkować informacje"},
+        {"id": 4, "text": "ograniczenie korzystania z „usług w chmurze”"},
+        {"id": 5, "text": "szyfrowanie danych na dysku twardym"},
+        {"id": 6, "text": "korzystanie z technologii anonimizujących"},
+        {"id": 7, "text": "mycie rąk po skorzystaniu z komputera"}
+    ],
+    "answer": [1,4,5,6],
+    "answer_mode": "all_or_nothing",
+    "points": 2
+},
+
+{
+    "id": 15,
+    "type": "edumed_przyporzadkuj",
+    "description": ["Dopasuj rodzaj formatu do jego cech charakterystycznych."],
+    "buckets": [
+        {"id": 1, "title": "JPG"},
+        {"id": 2, "title": "PDF"},
+        {"id": 3, "title": "OpenDocument"},
+        {"id": 4, "title": "PNG"},
+        {"id": 5, "title": "EPUB"}
+    ],
+    "buckets_name": "formaty",
+    "items": [
+        {"id": 1, "text": "1", "desc": "format plików służący do prezentacji, przenoszenia i drukowania treści tekstowo-graficznych. Jego zastosowanie zapewnia to, że po otwarciu w innym programie nie zmieni się to, jak wyglądają poszczególne strony."},
+        {"id": 2, "text": "2", "desc": "format obrazów rastrowych (bitmap), najlepiej sprawdzający się przy zapisie fotografii oraz obrazów naturalnych (pejzaży, portretów itp.), w których barwy płynnie przechodzą i w których nie ma wiele ostrych krawędzi czy drobnych detali. Przy zapisie w tym formacie dokonywana jest stratna kompresja, co sprawia, że część informacji zostaje bezpowrotnie utracona."},
+        {"id": 3, "text": "3", "desc": "otwarty standard,oparty na języku XML, służący do publikowania elektronicznych książek. Tworzone w nim książki nie mają podziału na strony,choć istnieje możliwość wyświetlania na marginesie numeru strony pochodzącego z książki drukowanej."},
+        {"id": 4, "text": "4", "desc": "format plików pakietów biurowych, będący otwartym standardem ISO (Międzynarodowej Organizacji Normalizacyjnej), podstawowy dla wolnych programów do edycji tekstu."},
+        {"id": 5, "text": "5", "desc": "rastrowy format plików graficznych, korzystający z kompresji bezstratnej."}
+    ],
+    "items_name": "definicje",
+    "answer": {
+        "1": [2],
+        "2": [1],
+        "3": [4],
+        "4": [5],
+        "5": [3]
+    },
+    "points_per_hit": 0.5
+},
+
+{
+    "id": 16,
+    "type": "open",
+    "description": ["Podaj min. 3 objawy obecności wirusa na twoim komputerze."],
+    "max_points": 3
+},
+
+{
+    "id": 17,
+    "type": "open",
+    "description": ["Wyszukaj w odpowiednim katalogu Biblioteki Narodowej artykuły z polskich czasopism opublikowane w 2010 roku, które dotyczyły edukacji medialnej. Podaj liczbę tekstów oraz 3 tytuły czasopism, w których je opublikowano."],
+    "max_points": 6
+},
+
+{
+    "id": 18,
+    "type": "open",
+    "description": ["Podaj co najmniej 3 działania, które możesz podjąć, aby wyjść z bańki filtrującej."],
+    "max_points": 3
+},
+
+{
+    "id": 19,
+    "type": "open",
+    "description": ["Zauważyłeś/-aś, że twój kolega coraz rzadziej wychodzi z domu i ma coraz gorsze wyniki w nauce, za to ciągle siedzi przed komputerem. Domyślasz się, że jest uzależniony od internetu. Udziel mu co najmniej trzech rad, jak uwolnić się od tego nałogu."],
+    "max_points": 3
+},
+
+{
+    "id": 20,
+    "type": "edumed_wybor",
+    "description": ["Z poniższej listy wybierz czynności i rzeczy, na podstawie których stosowane jest profilowanie w sieci."],
+    "options": [
+        {"id": 1, "text": "przeglądane strony internetowe"},
+        {"id": 2, "text": "słowa wpisywane w wyszukiwarce internetowej"},
+        {"id": 3, "text": "informacje o sobie publikowane w sieci (np. wiek, płeć, zainteresowania)"},
+        {"id": 4, "text": "odpowiedzi na internetowe ankiety"},
+        {"id": 5, "text": "„polubienia” w serwisie społecznościowym"},
+        {"id": 6, "text": "informacje o geolokalizacji"},
+        {"id": 7, "text": "przedmioty oglądane w sklepach internetowych"},
+        {"id": 8, "text": "przedmioty kupione w sklepach internetowych"}
+    ],
+    "answer": [1,2,3,4,5,6,7,8],
+    "answer_mode": "all_or_nothing",
+    "points": 2
+},
+
+{
+    "id": 21,
+    "type": "open",
+    "description": ["Chcesz usunąć profil na Facebooku, ale nie chciał(a)byś utracić danych i treści, które udostępniałeś. Jak je zdobyć? Jakie dane ocaleją (wymień 3 rodzaje)?"],
+    "max_points": 2.5
+},
+
+{
+    "id": 22,
+    "type": "open",
+    "description": ["Znajdź informacje o 2 organizacjach pozarządowych, które działają w Twojej okolicy. Komu pomagają?",
+        "W jaki sposób dotarłeś/aś do tej informacji? Wklej adres strony, z której skorzystałeś/aś."],
+    "max_points": 3
+}
+
+]
\ No newline at end of file
diff --git a/src/wtem/fixtures/exercises-tem.json b/src/wtem/fixtures/exercises-tem.json
new file mode 100644 (file)
index 0000000..6ad8716
--- /dev/null
@@ -0,0 +1,173 @@
+[
+
+{
+    "id": 1,
+    "type": "open",
+    "description": ["Zbieranie literatury, aby przygotować własne wystąpienie to trudne zadanie, ale dzięki zasobom internetu może obecnie odbywać się w dużej części on-line. Przygotuj wystąpienie, które może być częścią szkolenia z edukcji medialnej. Wymyśl temat, do którego należy zebrać literaturę . Opisz w 3-5 zdaniach, czego dotyczyć będzie referat i wskaż do jakiej grupy docelowej będzie skierowany. Zaproponuj 2 źródła informacji w Internecie, które mogą się okazać użyteczne (uzasadnij dokonany wybór dla każdego ze źródeł). Dla każdego ze źródeł informacji wskaż, jak będzie wyglądać instrukcja wyszukiwawcza (używane terminy, odpowiednie operatory logiczne, ew. maskowanie końcówek, itd.)."],
+    "fields": [
+        {"caption": "Temat", "rows": 3, "id": "temat"},
+        {"caption": "Krótki opis wystąpienia", "id": "opis"},
+        {"caption": "Grupa docelowa", "id": "grupa"},
+        {"caption": "Źródło 1 (link, uzasadnienie, instrukcja wyszukiwawcza)", "id": "zrodlo1"},
+        {"caption": "Źródło 2 (link, uzasadnienie, instrukcja wyszukiwawcza)", "id": "zrodlo2"}
+    ],
+    "max_points": 12
+},
+
+{
+    "id": 2,
+    "type": "open",
+    "description": [
+        "Wykorzystaj znalezione w zadaniu 1 materiały i zawarte w nich informacje, aby przygotować graficzną ilustrację treści przedstawianych w wystąpieniu (infografika lub prezentacja multimedilana - maks. długośc prezentacji 12 slajdów). Zwróć uwagę na logiczne i klarowne przedstawienie informacji - toku rozumowania. Zadbaj o kwestie właściwego wskazania źródeł prezentownych informacji. Postaraj się rozwiązaniami graficznymi estetycznie wzmocnić przekaz wystąpienia."
+    ],
+    "fields": [
+        {"caption": "Plik z prezentacją", "type": "file", "id": "plik"},
+        {"caption": "Ew. link do prezentacji", "rows": 1, "id": "link"}
+    ],
+    "max_points": 8
+},
+
+{
+    "id": 3,
+    "type": "open",
+    "description": [
+        "Uczestnik Twoich warsztatów zwrócił się do Ciebie z prośbą o poradę w stworzeniu strony internetowej. Od kilku lat interesuje się modą, myśli o założeniu własnego bloga. Zależy mu na tym, żeby już teraz, mimo młodego wieku, świadomie budować w sieci swój wizerunek eksperta. Prosi Cię o polecenie trzech blogów, którymi według Ciebie mógłby się inspirować.",
+        "Podaj trzy strony oraz uzasadnij jakimi kryteriami się kierowałaś/eś, wybierając każdą z nich. Stwórz również mini katalog zasad, którymi wg Ciebie powinien się kierować przy prowadzeniu własnego bloga (min. 5 zasad)."
+    ],
+    "fields": [
+        {"caption": "Link + uzasadnienie (1)", "id": "link1"},
+        {"caption": "Link + uzasadnienie (2)", "id": "link2"},
+        {"caption": "Link + uzasadnienie (3)", "id": "link3"},
+        {"caption": "Katalog zasad", "id": "zasady"}
+    ],
+    "max_points": 11
+},
+
+{
+    "id": 4,
+    "type": "open",
+    "description": [
+        "Na nasz wizerunek w internecie wpływa między innymi język, jakim się posługujemy oraz umiejętność dyskutowania. Młodzież często ma problemy z określeniem granicy pomiędzy wolnością słowa a hejtowaniem czy mową nienawiści. „Konstytucja przecież gwarantuje nam wolnośćwypowiedzi, więc…!” - często słyszysz to zdanie, pracując ze swoją grupą. Postanawiasz więc przygotować warsztaty dotyczące powyższego zagadnienia.",
+        "Znajdź w internecie po jednym przykładzie obrazującym: mowę nienawiści, hejt, wolność słowa. Uzasadnij swój wybór. Przykłady przedstaw w postaci zrzutów ekranu (pamiętaj o ich odpowiednim przygotowaniu: np. wymazaniu danych osobowych i/lub zdjęcia profilowego)."
+    ],
+    "fields": [
+        {"caption": "Zrzut ekranu (1)", "type": "file", "id": "zrzut1"},
+        {"caption": "Uzasadnienie (1)", "id": "uzasadnienie1"},
+        {"caption": "Zrzut ekranu (2)", "type": "file", "id": "zrzut2"},
+        {"caption": "Uzasadnienie (2)", "id": "uzasadnienie2"},
+        {"caption": "Zrzut ekranu (3)", "type": "file", "id": "zrzut3"},
+        {"caption": "Uzasadnienie (3)", "id": "uzasadnienie3"}
+    ],
+    "max_points": 9
+},
+
+{
+    "id": 5,
+    "type": "open",
+    "description": [
+        "Przeczytaj polecenie poniżej. Wykonanie proponowanego zadania w tej formie niesie ze sobą pewne ryzyka. Jakich informacji w nim brakuje? Na co powinieneś/powinnaś zwrócić uwagę uczestniczek i uczestników?",
+        "Zadanie: Zdjęcia w sieci. Poproś uczniów o przygotowanie na lekcję dwóch zdjęć: jednego które wykonają sami, na którym będzie widnieć ktoś spośród innych uczniów z ich szkoły oraz drugiego zdjęcia, które mogą wykonać sami lub znaleźć w sieci, na którym widnieje znana osoba np. aktor lub pisarz. Następnie na lekcji poproś aby wybrali najlepszy technicznie serwis, w którym umieszczą te zdjęcia i opublikowali je, wybierając dla nich jedną z licencji Creative Commons."
+    ],
+    "max_points": 10
+},  
+
+{
+    "id": 6,
+    "type": "open",
+    "description": [
+        "W sieci dostępnych jest wiele utworów, do których prawa autorskie już wygasły (znajdują się w domenie publicznej) i można z nich swobodnie korzystać. Niestety wiele z nich nie jest wcale jasno opisanych i często nie wiemy, jakie mamy do nich prawa.",
+        "Przygotowujesz zajęcia na temat domeny publicznej. Utwory, które chcesz pokazać uczniom, o których wiesz, że prawa do nich wygałsy, w sieci często są opisane znaczkiem „copyright” lub podobnymi infomacjami. Chcesz przygotować zajęcia tak, aby omówić ten problem i pomóc uczestnikom uniknąć pomyłki w przyszłości.",
+        "a) Znajdź w sieci przykład utworu np. obrazu lub fotografii, który znajduje się w domenie publicznej, ale nie we wszystkich, nawet oficjalnych źródłach, jest tak opisany. Podaj linki do dwóch różnych miejsc w sieci, gdzie ten sam utwór jest oznaczony jako domena publiczna i drugiego, gdzie brakuje takiego opisu lub utwór jest oznaczony jako chroniony."
+    ],
+    "fields": [
+        {"caption": "Utwór", "rows": 1, "id": "a-utwor"},
+        {"caption": "Link (1)", "rows": 1, "id": "a-link-1"},
+        {"caption": "Link (2)", "rows": 1, "id": "a-link-2"},
+        {"caption": "b) Podaj dwa przykłady tego, jak można oznaczyć utwór znajdujący się w domenie publicznej, które będziesz mógł/mogła zasugerować uczniom, aby łatwiej było im rozpoznać takie utwory.", "id": "b"},
+        {"caption": "c) Podaj co najmniej trzy przykłady serwisów w sieci, które możesz polecić uczniom, w których nie będą oni mieli problemów z rozpoznaniem praw do danego utworu.<br><br>Link(1)", "rows": 1, "id": "c-1"},
+        {"caption": "Link (2)", "rows": 1, "id": "c-link-2"},
+        {"caption": "Link (3)", "rows": 1, "id": "c-link-3"}
+    ],  
+    "max_points": 10
+},  
+
+{
+    "id": 7,
+    "type": "open",
+    "description": [
+        "Znajdź w Internecie zdjęcie lub krótki film, które odwoływać się będą do zjawiska cyberprzemocy. Na ich podstawie zbuduj dwa zadania dla uczniów i uczennic gimnazjum, z których:",
+        "a. Pierwsze będzie analizą tekstu kultury (np.karta pracy, ankieta).",
+        "b. Drugie będzie omawiać zjawisko (w powiązaniu z tekstem kultury)."
+    ],
+    "fields": [
+        {"caption": "Link do znalezionego materiału", "rows": 1, "id": "link"},
+        {"caption": "Plik (1)", "type": "file", "id": "plik1"},
+        {"caption": "Plik (2)", "type": "file", "id": "plik2"}
+    ],
+    "max_points": 12
+},
+
+{
+    "id": 8,
+    "type": "file_upload",
+    "description": [
+        "Zaproponuj ćwiczenie, które będzie doskonaliło umiejętność pracy w chmurze na poziomie liceum. Młodzież na wykonanie zadania ma 45 minut. W sali są komputery (przy komputerze siedzą dwie osoby), wszyscy mają dostęp do internetu w telefonach komórkowych."
+    ],
+    "max_points": 8
+},
+
+{
+    "id": "9a",
+    "id_show": 9,
+    "type": "edumed_wybor",
+    "description": [
+        "Przygotowujesz się do przeprowadzenia zajęć poświęconych cyfrowym narracjom i publikowaniu własnych materiałów multimedialnych w sieci.",
+        "a) Wybierz prawidłową definicję terminu „narracja cyfrowa”:"],
+    "options": [
+        {"id": 1, "text": "Narracja cyfrowa to zaszyfrowana opowieść tekstowa zapisana w formie kodu binarnego."},
+        {"id": 2, "text": "Narracja cyfrowa to opowieść (filmowa, złożona z kolekcji zdjęć lub nagrania radiowego) nadawana na żywo w internecie."},
+        {"id": 3, "text": "Narracja cyfrowa to nagrany za pomocą cyfrowej kamery wideo film, opublikowany następnie w serwisie YouTube lub Vimeo."},
+        {"id": 4, "text": "Narracja cyfrowa to opowieść przygotowana w formie filmu lub podcastu, składająca się - w zależności od ostatecznej formy ze zdjęć, wideo, nagranego głosu lub dźwięków otoczenia."}
+    ],
+    "answer": [4],
+    "points": 2,
+    "max_points": 11
+},
+
+{
+    "id": "9b",
+    "continuation": true,
+    "type": "open",
+    "description": ["b) Znajdź w internecie trzy przykłady cyfrowych narracji."],
+    "fields": [
+        {"caption": "Link (1)", "rows": 1, "id": "link-1"},
+        {"caption": "Link (2)", "rows": 1, "id": "link-2"},
+        {"caption": "Link (3)", "rows": 1, "id": "link-3"}
+    ],
+    "max_points": 3
+},
+
+{
+    "id": "9c",
+    "continuation": true,
+    "type": "open",
+    "description": ["c) Wskaż trzy źródła treści, które można legalnie wykorzystać do tworzenia własnych materiałów multimedialnych (np. własnego vloga, prezentacji multimedialnej, podcastu, wpisu blogowego). Przy każdym wskazanym źródle wyjaśnij w jednym zdaniu, dlaczego można z niego skorzystać."
+    ],
+    "fields": [
+        {"caption": "Źródło zdjęć i grafik (link + uzasadnienie)", "id": "link-1"},
+        {"caption": "Źródło materiałów dźwiękowych (link + uzasadnienie)", "id": "link-2"},
+        {"caption": "Źródło materiałów wideo (link + uzasadnienie)", "id": "link-3"}
+    ],
+    "max_points": 6
+},
+
+{
+    "id": 10,
+    "type": "file_upload",
+    "description": [
+        "Zaplanuj przygotowania do realizacji wspólnej narracji cyfrowej przez całą klasę na wybranym przez Ciebie etapie edukacyjnym. Wyznacz i uzasadnij kolejne kroki realizacji w formie harmonogramu.  Zaproponuj, jak podzielisz klasę na grupy i przydzielisz im konkretne zadania. Opisz, jaki będzie efekt końcowy i jakie należy Twoim zdaniem spełnić warunki, żeby współpraca pomiędzy grupami była możliwa i przyczyniła się do wysokiej jakości realizacji narracji cyfrowej. Wskaż i uzasadnij, jakich narzędzi użyłbyś/użyłabyś na kolejnych etapach realizacji projektu."
+    ],
+    "max_points": 9
+}
+
+]
diff --git a/src/wtem/fixtures/exercises-wlem.json b/src/wtem/fixtures/exercises-wlem.json
new file mode 100644 (file)
index 0000000..fac4005
--- /dev/null
@@ -0,0 +1,152 @@
+[
+
+{
+    "id": 1,
+    "type": "open",
+    "description": [
+        "W sieci nieustannie pojawiają się nowe zagrożenia, która bardzo często celują w naszą nieuwagę i słabą higienę pracy z komputerem. Są to m.in. phishing, a ostatnio ransomware. Chcesz przygotować uczestników zajęć na to, by potrafili rozpoznawać je i unikać ryzykowanych sytuacji. Twoim zadaniem jest przygotowanie zajęć, które wyczulą uczestników na sygnały, które mogą świadczyć o zbliżającym się zagrożeniu.",
+        ""
+    ],
+    "fields": [
+        {"caption": "a) Wypisz 2 oznaki tego, że mail, strona WWW lub sms mogą być atakiem phishingowym.", "id": "1a"},
+        {"caption": "b) Wypisz 2 porady jak możesz zabezpieczyć się przed konsekwencjami działania ransomware.", "id": "1b"},
+        {"caption": "c) Wymyśl i opisz krótko propozycję ćwiczenia, które w praktyczny sposób nauczy jak odróżniać groźne wiadomości mailowe, strony WWW czy sms-y, które mogą być atakami. Wybierz jeden z tych sposobów ataku, znajdź w sieci jeden przykład historii ataku w Polsce, który będzie mógł posłużyć Ci za przykład w ćwiczeniu. Przygotuj krótką instrukcje dla uczestników zajęć – co mają zrobić w ramach ćwiczenia? Uwaga! Nie podpowiadaj uczestnikom za bardzo, spróbuj pobudzić ich czujność i samodzielność.", "id": "1c"}
+    ],
+    "max_points": 10
+},
+
+{
+    "id": 2,
+    "type": "open",
+    "description": [
+        "Twoja instytucja/organizacja posiada współczesnego patrona (np. Jana Nowaka-Jeziorańskiego). Chcesz zorganizować publiczną wystawę na jego temat oraz wspomnień o nim jego bliskich, rodziny i przyjaciół. Będziecie potrzebować do tego zdjęć Nowaka-Jeziorańskiego oraz zdjęć jego bliskich. Zdjęcia do wystawy mają pozyskać uczestnicy Twoich zajęć."
+    ],
+    "fields": [
+        {"caption": "a) Na co powinnaś zwrócić im uwagę: podaj jakie obszary prawa mogą być ważne w tym zadaniu?", "id": "2a"},
+        {"caption": "b) Co zawrzesz w instrukcji dot. Pozyskiwania praw do zdjęć? Podaj 3 przykładowe porady z dwóch różnych obszarów prawa.", "id": "2b"}
+    ],
+    "max_points": 11
+},
+
+{
+    "id": 3,
+    "type": "open",
+    "description": [
+        "Czy wiesz, kiedy autorzy i prawo wymagają, by podczas wykorzystania cudzego utworu podpisać odpowiednio utwór? Co możesz zrobić z utworem który cytujesz, a co z takim dostępnym na jednej z licencji CC?"
+    ],
+    "fields": [
+        {"caption": "a) Znajdź w sieci przykład utworu literackiego chronionego przez prawo autorskie, który mogłabyś użyć w krytycznym opracowaniu na temat jego autora/ki. Opisz ten cytat tak jakbyś zrobiła to w.w. publikacji.", "id": "3a"},
+        {"caption": "b) Napisz krótkie uzasadnienie, co pozwala Ci zacytować ten utwór w powyższej sytuacji.", "id": "3b"},
+        {"caption": "c) Znajdź w sieci przykłady utworów (po jednym do każdej sytuacji). Podaj linki do nich razem z opisem licencji/praw.<br><br>na licencji Creative Commons Uznanie autorstwa – Użycie niekomercyjne,", "id": "cc-by-nc"},
+        {"caption": "na licencji Creative Commons Uznanie autorstwa – bez utworów zależnych,", "id": "cc-by-nd"},
+        {"caption": "utworu z domeny publicznej.", "id": "pd"},
+        {"caption": "d) Uszereguj wszystkie utwory z pkt. a) i c) wg swobody wykorzystania (od tych z najszerszą swobodą)", "id": "3d"}
+    ],
+    "max_points": 12
+},
+
+{
+    "id": 4,
+    "type": "open",
+    "description": [
+        "Doceniając potencjał mediów społecznościowych i wykorzystując ich różne formy, przygotuj trasę wycieczki: „Najpiękniejsze murale w Polsce”."
+    ],
+    "fields": [
+        {"caption": "a) Opisz w maksymalnie 7 punktach przebieg wycieczki.", "id": "4a"},
+        {"caption": "b) Wskaż minimum 3 źródła informacji, z których skorzystałaś, uzasadniając ich użyteczność i kryteria wyboru, którymi się kierowałaś. Weź pod uwagę różnorodność mediów społecznościowych i ich różne funkcje.", "id": "4b"}
+    ],
+    "max_points": 8
+},
+
+{
+    "id": 5,
+    "type": "open",
+    "description": [
+        "Wyjaśnij, jakie są różnice między telenowelą dokumentalną a mockumentem. Podaj 2 wiarygodne źródła, gdzie można znaleźć informacje na ten temat."
+    ],
+    "fields": [
+        {"caption": "a) Różnice", "id": "5a"},
+        {"caption": "b) Źródła informacji.", "id": "5b"}
+    ],
+    "max_points": 3
+},  
+
+{
+    "id": 6,
+    "type": "open",
+    "description": [
+        "Zostałaś poproszona przez swojego pracodawcę o przygotowanie warsztatu z zakresu edukacji medialnej na temat: „Informacja a opinia. Jak je rozróżnić?”. Wyszukaj w internecie po 3 zestawy tekstów, z których przygotujesz karty pracy dla uczestników. W każdym zestawie uczestnik warsztatów będzie musiał wskazać, który tekst jest informacją, a który opinią. Przygotowując się, weź pod uwagę: wydanie online dziennika opinii, portal internetowy i medium społecznościowe."
+    ],
+    "fields": [
+        {"caption": "Wskaż 3 zestawy tekstów, z których przygotujesz karty pracy dla uczestników.", "id": "6a"},
+        {"caption": "Uzasadnij, czym się kierowałaś, dokonując wyboru.", "id": "6b"}
+    ],
+    "max_points": 6
+},
+
+{
+    "id": "7a",
+    "id_show": 7,
+    "type": "edumed_wybor",
+    "description": [
+        "Zaproponuj ćwiczenie poszerzające umiejętności grupy, z którą najczęściej pracujesz, w zakresie (wybierz jeden z trzech)"
+    ],
+    "options": [
+        {"id": 1, "text": "formatowania pliku tekstowego,"},
+        {"id": 2, "text": "obróbki obrazu,"},
+        {"id": 3, "text": "montażu wideo."}
+    ],
+    "answer": [1],
+    "points": 0,
+    "max_points": 12
+},
+
+{
+    "id": "7b",
+    "continuation": true,
+    "type": "open",
+    "description": [],
+    "fields": [
+        {"caption": "Opisz grupę, dla której planujesz ćwiczenie (wiek, posiadane już umiejętności i doświadczenie w korzystaniu z nowych technologii)", "id": "7a"},
+        {"caption": "Podaj cel (cele) ćwiczenia oraz jego rezultaty (po zakończeniu ćwiczenia uczestnik/uczestniczka: 1. wie… 2. rozumie… 3. umie…)", "id": "7b"},
+        {"caption": "Zaplanuj ćwiczenie w czasie (ile czasu potrzebujesz? Ile czasu zajmą poszczególne części ćwiczenia?)", "id": "7c"},
+        {"caption": "Opisz, czego potrzebujesz (materiały, oprogramowanie), żeby je zrealizować. Jeśli ćwiczenie zakłada wykorzystanie przykładowych materiałów (np. tekst, zdjęcie, wideo) – dołącz je do ćwiczenia. Jeśli częścią ćwiczenia jest zdobycie tych materiałów przez uczestników – uwzględnij to w opisie ćwiczenia. ", "id": "7d"},
+        {"caption": "Opisz przebieg ćwiczenia tak, by było ono zrozumiałe nie tylko dla Ciebie, ale dla innych osób chcących je wykorzystać w pracy ze swoimi grupami.", "id": "7e"}
+    ],
+    "max_points": 12
+},
+
+{
+    "id": 8,
+    "type": "open",
+    "description": [
+        "Korzystając z technologii informacyjno-komunikacyjnych (TIK) internauci narażeni są na to, że ktoś wykorzysta ich wizerunek lub twórczość niezgodnie z prawem.  Zaplanuj dla grupy, z którą pracujesz, ćwiczenie przygotowujące jej członków/członkinie do interwencji w takiej sytuacji."
+    ],
+    "fields": [
+        {"caption": "a) Opisz grupę, dla której planujesz ćwiczenie (wiek, posiadane już umiejętności i doświadczenie w korzystaniu z TIK),", "id": "8a"},
+        {"caption": "b) Znajdź (pamiętaj o podaniu źródeł) lub stwórz przykłady dwóch sytuacji dotyczących naruszenia wizerunku i/lub praw autorskich w mediach – pasujących do sytuacji, z jakimi mogą się spotkać uczestnicy/uczestniczki Twoich zajęć.", "id": "8b"},
+        {"caption": "c) Stwórz listę możliwych działań interwencyjnych pasujących do tych sytuacji, które możesz omówić podczas zajęć.", "id": "8c"},
+        {"caption": "d) Opisz przebieg ćwiczenia tak, by było ono zrozumiałe nie tylko dla Ciebie, ale dla innych osób chcących je wykorzystać w pracy z grupami.", "id": "8d"}
+    ],
+    "max_points": 12
+},
+
+{
+    "id": 9,
+    "type": "open",
+    "description": [
+        "Przyjrzyj się, jak w praktyce wygląda komunikacja w sieci. Wykorzystaj do tego własne doświadczenia z portali społecznościowych czy informacyjnych.",
+        "Przypomnij sobie sytuacje, w których zabierałaś głos w toczących się tam dyskusjach. Przyjrzyj się językowi, którego używałaś. Czy sprzyjał on osiągnięciu celów, które sobie zakładałaś włączając się w dyskusję? Czy język, który tam spotkałaś wolny był od agresji, mowy nienawiści i hejtu?",
+        "Jeśli dotąd nie miałaś doświadczenia komunikacji z internautami lub nie umiesz przywołać takich doświadczeń – zdobądź je!",
+        "<br>W odpowiedzi możesz pominąć tematy, na które zabierałaś głos – Twoje poglądy nie mają znaczenia dla oceny zadania. Podczas oceny zadania liczyć się będzie: zwięzły opis konkretnych doświadczeń i sytuacji, które spotkałeś/spotkałaś oraz Twoje pomysły na przełożenie ich na pracę z grupami."
+    ],
+    "fields": [
+        {"caption": "Opisz krótko wnioski z Twoich doświadczeń.", "id": "9a"},
+        {"caption": "Jak wykorzystasz je w pracy z Twoją grupą/grupami? Dlaczego?", "id": "9b"},
+        {"caption": "Jaką aktywność na podstawie swoich wniosków zaproponujesz grupie?", "id": "9c"},
+        {"caption": "Jakie cele chciałabyś osiągnąć swoim ćwiczeniem?", "id": "9d"}
+    ],
+    "max_points": 12
+}
+]
+
diff --git a/src/wtem/fixtures/exercises.json b/src/wtem/fixtures/exercises.json
new file mode 100644 (file)
index 0000000..0637a08
--- /dev/null
@@ -0,0 +1 @@
+[]
\ No newline at end of file
diff --git a/src/wtem/forms.py b/src/wtem/forms.py
new file mode 100644 (file)
index 0000000..ae406a3
--- /dev/null
@@ -0,0 +1,32 @@
+# -*- coding: utf-8 -*-
+import re
+
+from django import forms
+
+from .models import Submission, Attachment, exercises
+
+
+class WTEMForm(forms.ModelForm):
+    class Meta:
+        model = Submission
+        fields = ('answers',)
+
+    def __init__(self, *args, **kwargs):
+        super(WTEMForm, self).__init__(*args, **kwargs)
+        for exercise in exercises:
+            if exercise['type'] != 'file_upload':
+                continue
+            self.fields['attachment_for_' + str(exercise['id'])] = forms.FileField(required=False)
+
+    def save(self, commit=True):
+        submission = super(WTEMForm, self).save(commit=commit)
+        for name, attachment_file in self.files.items():
+            m = re.match(r'attachment_for_(\d+)(?:__(.*))?', name)
+            exercise_id = int(m.group(1))
+            tag = m.group(2) or None
+            try:
+                attachment = Attachment.objects.get(submission=submission, exercise_id=exercise_id, tag=tag)
+            except Attachment.DoesNotExist:
+                attachment = Attachment(submission=submission, exercise_id=exercise_id, tag=tag)
+            attachment.file = attachment_file
+            attachment.save()
diff --git a/src/wtem/management/__init__.py b/src/wtem/management/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/src/wtem/management/commands/__init__.py b/src/wtem/management/commands/__init__.py
new file mode 100644 (file)
index 0000000..e39656a
--- /dev/null
@@ -0,0 +1,17 @@
+from django.core.mail import EmailMessage
+from django.conf import settings
+
+def send_mail(subject, body, to):
+    if not isinstance(to, list):
+        to = [to]
+
+    reply_to = getattr(settings, 'WTEM_REPLY_TO', None)
+    headers = dict()
+    if reply_to:
+        headers['Reply-To'] = reply_to
+
+    email = EmailMessage(subject, body,
+        getattr(settings, 'WTEM_FROM', 'edukacjamedialna@nowoczesnapolska.org.pl'),
+        to, headers = headers)
+    #print email.message()
+    email.send(fail_silently = False)
diff --git a/src/wtem/management/commands/wlem_generate_keys.py b/src/wtem/management/commands/wlem_generate_keys.py
new file mode 100644 (file)
index 0000000..1e7f558
--- /dev/null
@@ -0,0 +1,32 @@
+# -*- coding: utf-8 -*-
+from django.core.management.base import BaseCommand
+
+from contact.models import Contact
+from wtem.models import Submission
+
+
+class Command(BaseCommand):
+
+    def handle(self, *ids, **options):
+        new = 0
+        skipped = 0
+
+        query = Contact.objects.filter(form_tag='wlem').order_by('-created_at')
+        if ids:
+            query = query.filter(pk__in=ids)
+
+        for wlem_contact in query:
+            if not Submission.objects.filter(email=wlem_contact.contact).exists():
+                first_name, last_name = wlem_contact.body['nazwisko'].split()
+                args = {
+                    'email': wlem_contact.contact,
+                    'first_name': first_name,
+                    'last_name': last_name,
+                }
+                Submission.create(**args)
+                new += 1
+            else:
+                self.stdout.write('skipping ' + wlem_contact.contact + ': already exists.')
+                skipped += 1
+
+        self.stdout.write('New: ' + str(new) + ', skipped: ' + str(skipped))
diff --git a/src/wtem/management/commands/wtem_assign_submissions.py b/src/wtem/management/commands/wtem_assign_submissions.py
new file mode 100644 (file)
index 0000000..dcf0466
--- /dev/null
@@ -0,0 +1,54 @@
+# -*- coding: utf-8 -*-
+from optparse import make_option
+
+from django.core.management.base import BaseCommand
+from django.db.models import Count
+from django.contrib.auth.models import User
+
+from wtem.models import Submission, Attachment
+
+
+class Command(BaseCommand):
+
+    option_list = BaseCommand.option_list + (
+        make_option(
+            '--with-attachments-only',
+            action='store_true',
+            dest='attachments_only',
+            default=False,
+            help='Take into account only submissions with attachments'),
+        make_option(
+            '--without-attachments-only',
+            action='store_true',
+            dest='no_attachments_only',
+            default=False,
+            help='Take into account only submissions without attachments'),
+        )
+
+    def handle(self, *args, **options):
+
+        limit_from = int(args[0])
+        limit_to = int(args[1])
+        examiner_names = args[2:]
+
+        users = User.objects.filter(username__in=examiner_names)
+        all_submissions = Submission.objects.annotate(examiners_count=Count('examiners'))
+
+        submissions = all_submissions.exclude(answers=None)
+
+        with_attachment_ids = Attachment.objects.values_list('submission_id', flat=True).all()
+        if options['attachments_only']:
+            submissions = submissions.filter(id__in=with_attachment_ids)
+        if options['no_attachments_only']:
+            submissions = submissions.exclude(id__in=with_attachment_ids)
+
+        for submission in submissions.order_by('id')[limit_from:limit_to]:
+            submission.examiners.add(*users)
+            submission.save()
+            self.stdout.write('added to %s:%s' % (submission.id, submission.email))
+
+        count_by_examiners = dict()
+        for submission in all_submissions.all():
+            count_by_examiners[submission.examiners_count] = \
+                count_by_examiners.get(submission.examiners_count, 0) + 1
+        self.stdout.write('%s' % count_by_examiners)
diff --git a/src/wtem/management/commands/wtem_email_teachers.py b/src/wtem/management/commands/wtem_email_teachers.py
new file mode 100644 (file)
index 0000000..9b5e5e9
--- /dev/null
@@ -0,0 +1,40 @@
+# -*- coding: utf-8 -*-
+
+from django.core.management.base import BaseCommand
+from django.template.loader import render_to_string
+
+from contact.models import Contact
+from wtem.management.commands import send_mail
+
+
+class Command(BaseCommand):
+    def handle(self, *args, **options):
+        sent = 0
+        failed = 0
+
+        query = Contact.objects.filter(form_tag='wtem').order_by('contact').distinct('contact')
+        template_name = args[0]
+        message = render_to_string('wtem/' + template_name + '.txt')
+        subject = render_to_string('wtem/' + template_name + '_subject.txt')
+        
+        answer = raw_input(
+            'Send the following to %d teachers with subject "%s"\n\n %s\n\n?' %
+            (query.count(), subject.encode('utf8'), message.encode('utf8')))
+
+        if answer == 'yes':
+            for contact in query:
+                try:
+                    self.send_message(message, subject, contact.contact)
+                except Exception as e:
+                    failed += 1
+                    self.stdout.write('failed sending to: ' + contact.contact + ' - ' + str(e))
+                else:
+                    sent += 1
+                    self.stdout.write('message sent to: ' + contact.contact)
+
+        self.stdout.write('sent: %s, failed: %s' % (sent, failed))
+
+    def send_message(self, message, subject, email):
+        self.stdout.write('>>> sending to %s' % email)
+        send_mail(subject=subject, body=message, to=[email])
+
diff --git a/src/wtem/management/commands/wtem_generate_keys.py b/src/wtem/management/commands/wtem_generate_keys.py
new file mode 100644 (file)
index 0000000..f49c8b7
--- /dev/null
@@ -0,0 +1,31 @@
+# -*- coding: utf-8 -*-
+from django.core.management.base import BaseCommand
+
+from contact.models import Contact
+from wtem.models import Submission
+
+
+class Command(BaseCommand):
+
+    def handle(self, *ids, **options):
+        new = 0
+        skipped = 0
+
+        query = Contact.objects.filter(form_tag='wtem').order_by('-created_at')
+        if ids:
+            query = query.filter(pk__in=ids)
+
+        for wtem_contact in query:
+            for student in wtem_contact.body['student']:
+                if not Submission.objects.filter(email=student['email']).exists():
+                    args = dict()
+                    for attr in ['first_name', 'last_name', 'email']:
+                        args[attr] = student[attr]
+                    args['contact'] = wtem_contact
+                    Submission.create(**args)
+                    new += 1
+                else:
+                    self.stdout.write('skipping ' + student['email'] + ': already exists.')
+                    skipped += 1
+
+        self.stdout.write('New: ' + str(new) + ', skipped: ' + str(skipped))
diff --git a/src/wtem/management/commands/wtem_send_keys.py b/src/wtem/management/commands/wtem_send_keys.py
new file mode 100644 (file)
index 0000000..96511fb
--- /dev/null
@@ -0,0 +1,69 @@
+# -*- coding: utf-8 -*-
+
+from optparse import make_option
+
+from django.core.management.base import BaseCommand
+from django.conf import settings
+from wtem.management.commands import send_mail
+from django.template.loader import render_to_string
+
+from wtem.models import Submission, DEBUG_KEY
+
+
+class Command(BaseCommand):
+    help = 'Sends personalized links to WTEM contestants'
+    args = '<email_address1>, <email_address2>, ...'
+
+    option_list = BaseCommand.option_list + (
+        make_option(
+            '--all',
+            action='store_true',
+            dest='all',
+            default=False,
+            help='Use all available submissions'),
+        make_option(
+            '--force',
+            action='store_true',
+            dest='force',
+            default=False,
+            help='Force sending key even if one was already sent')
+        )
+
+    def handle(self, *args, **options):
+        if len(args) or options['all']:
+            return self.send_keys(*args, **options)
+        self.stdout.write('No submissions selected')
+
+    def send_keys(self, *args, **options):
+        sent = 0
+        skipped = 0
+        failed = 0
+
+        submissions = Submission.objects.all()
+        if not options['force']:
+            submissions = submissions.filter(key_sent=False)
+        if len(args):
+            submissions = submissions.filter(email__in=args)
+
+        for submission in submissions:
+            assert len(submission.key) == 30 or (settings.DEBUG and submission.key == DEBUG_KEY)
+
+            try:
+                self.send_key(submission)
+            except Exception as e:
+                failed += 1
+                self.stdout.write('failed sending to: ' + submission.email + ' - ' + str(e))
+            else:
+                submission.key_sent = True
+                submission.save()
+                sent += 1
+                self.stdout.write('key sent to: ' + submission.email)
+
+        self.stdout.write('sent: ' + str(sent))
+
+    def send_key(self, submission):
+        self.stdout.write('>>> sending to ' + submission.email)
+        send_mail(
+            subject="WLEM - Twój link do egzaminu",
+            body=render_to_string('wtem/email_key.txt', dict(submission=submission)),
+            to=[submission.email])
diff --git a/src/wtem/management/commands/wtem_send_results.py b/src/wtem/management/commands/wtem_send_results.py
new file mode 100644 (file)
index 0000000..d2dc147
--- /dev/null
@@ -0,0 +1,99 @@
+# -*- coding: utf-8 -*-
+
+from optparse import make_option
+
+from django.core.management.base import BaseCommand
+from wtem.management.commands import send_mail
+from django.utils import translation
+from django.template.loader import render_to_string
+
+from contact.models import Contact
+from wtem.models import Submission
+
+
+def get_submissions():
+    return sorted(Submission.objects.exclude(answers=None).all(), key=lambda s: -s.final_result)
+
+minimum = 52
+
+
+class Command(BaseCommand):
+
+    option_list = BaseCommand.option_list + (
+        make_option(
+            '--to-teachers',
+            action='store_true',
+            dest='to_teachers',
+            default=False,
+            help='Send emails to teachers'),
+        make_option(
+            '--to-students',
+            action='store_true',
+            dest='to_students',
+            default=False,
+            help='Send emails to students'),
+        make_option(
+            '--only-to',
+            action='store',
+            dest='only_to',
+            default=None,
+            help='Send emails only to listed addresses'),
+    )
+
+    def handle(self, *args, **options):
+        translation.activate('pl')
+        for target in ['to_teachers', 'to_students']:
+            if options[target]:
+                self.sent = 0
+                self.failed = 0
+                getattr(self, 'handle_' + target)(*args, **options)
+
+    def handle_to_students(self, *args, **options):
+        self.stdout.write('>>> Sending results to students')
+        subject = 'Wyniki II etapu Wielkiego Turnieju Edukacji Medialnej'
+
+        for submission in get_submissions():
+            if options['only_to'] and submission.email != options['only_to']:
+                continue
+            final_result = submission.final_result
+            if final_result < minimum:
+                template = 'results_student_failed.txt'
+            else:
+                template = 'results_student_passed.txt'
+            message = render_to_string('wtem/' + template, dict(final_result=submission.final_result))
+            self.send_message(message, subject, submission.email)
+
+        self.sum_up()
+
+    def handle_to_teachers(self, *args, **options):
+        self.stdout.write('>>> Sending results to teachers')
+        subject = 'Wyniki II etapu Wielkiego Turnieju Edukacji Medialnej'
+        failed = sent = 0
+
+        submissions_by_contact = dict()
+
+        for submission in get_submissions():
+            if options['only_to'] and submission.contact.contact != options['only_to']:
+                continue
+            submissions_by_contact.setdefault(submission.contact.id, []).append(submission)
+
+        for contact_id, submissions in submissions_by_contact.items():
+            contact = Contact.objects.get(id=contact_id)
+            message = render_to_string('wtem/results_teacher.txt', dict(submissions=submissions))
+            self.send_message(message, subject, contact.contact)
+
+        self.sum_up()
+
+    def sum_up(self):        
+        self.stdout.write('sent: %s, failed: %s' % (self.sent, self.failed))
+
+    def send_message(self, message, subject, email):
+        self.stdout.write('>>> sending results to %s' % email)
+        try:
+            send_mail(subject=subject, body=message, to=[email])
+        except BaseException, e:
+            self.failed += 1
+            self.stdout.write('failed sending to: ' + email + ': ' + str(e))
+        else:
+            self.sent += 1
+            self.stdout.write('message sent to: ' + email)
diff --git a/src/wtem/management/commands/wtem_send_results_csv.py b/src/wtem/management/commands/wtem_send_results_csv.py
new file mode 100644 (file)
index 0000000..97a98eb
--- /dev/null
@@ -0,0 +1,115 @@
+# -*- coding: utf-8 -*-
+
+from optparse import make_option
+
+from django.core.management.base import BaseCommand
+from django.template.loader import render_to_string
+from django.utils import translation
+
+from wtem.management.commands import send_mail
+from wtem.models import Submission
+
+
+def get_submissions():
+    return sorted(Submission.objects.exclude(answers=None).all(), key=lambda s: -s.final_result)
+
+minimum = 52
+
+
+class Command(BaseCommand):
+    args = 'csv_filename'
+
+    option_list = BaseCommand.option_list + (
+        make_option(
+            '--to-teachers',
+            action='store_true',
+            dest='to_teachers',
+            default=False,
+            help='Send emails to teachers'),
+        make_option(
+            '--to-students',
+            action='store_true',
+            dest='to_students',
+            default=False,
+            help='Send emails to students'),
+        make_option(
+            '--only-to',
+            action='store',
+            dest='only_to',
+            default=None,
+            help='Send emails only to listed addresses'),
+    )
+
+    def handle(self, csv_filename, *args, **options):
+        translation.activate('pl')
+        self.results = [line.decode('utf-8').strip('\n').split(',') for line in open(csv_filename)]
+        for target in ['to_teachers', 'to_students']:
+            if options[target]:
+                self.sent = 0
+                self.failed = 0
+                getattr(self, 'handle_' + target)(*args, **options)
+
+    def handle_to_students(self, *args, **options):
+        self.stdout.write('>>> Sending results to students')
+        subject = 'Wyniki II etapu Wielkiego Turnieju Edukacji Medialnej'
+
+        for email, last_name, first_name, final_result in self.results:
+            if options['only_to'] and email != options['only_to']:
+                continue
+            if final_result == 'dyskwalifikacja':
+                template = 'results_student_disqualified.txt'
+            elif float(final_result) < minimum:
+                template = 'results_student_failed.txt'
+            else:
+                template = 'results_student_passed.txt'
+            message = render_to_string('wtem/' + template, dict(final_result=final_result))
+            self.send_message(message, subject, email)
+
+        self.sum_up()
+
+    def handle_to_teachers(self, *args, **options):
+        self.stdout.write('>>> Sending results to teachers')
+        subject = 'Wyniki II etapu Wielkiego Turnieju Edukacji Medialnej'
+
+        submissions_by_contact = dict()
+
+        from decimal import Decimal, InvalidOperation
+
+        def dec_or_0(s):
+            try:
+                return Decimal(s)
+            except InvalidOperation:
+                return Decimal(0)
+
+        sorted_results = sorted(self.results, key=lambda r: dec_or_0(r[3]), reverse=True)
+        for email, last_name, first_name, final_result in sorted_results:
+            submission = Submission.objects.get(email=email)
+            teacher_email = submission.contact.contact
+            if options['only_to'] and teacher_email != options['only_to']:
+                continue
+            submissions_by_contact.setdefault(teacher_email, []).append({
+                'first_name': first_name,
+                'last_name': last_name,
+                'final_result': final_result,
+            })
+
+        for email, submissions in submissions_by_contact.items():
+            # contact = Contact.objects.get(id=contact_id)
+            message = render_to_string('wtem/results_teacher.txt', dict(submissions=submissions))
+            self.send_message(message, subject, email)
+
+        self.sum_up()
+
+    def sum_up(self):        
+        self.stdout.write('sent: %s, failed: %s' % (self.sent, self.failed))
+
+    def send_message(self, message, subject, email):
+        self.stdout.write('>>> sending results to %s' % email)
+        try:
+            send_mail(subject=subject, body=message, to=[email])
+        except BaseException, e:
+            self.failed += 1
+            self.stdout.write('failed sending to: ' + email + ': ' + str(e))
+        else:
+            self.sent += 1
+            self.stdout.write('message sent to: ' + email)
diff --git a/src/wtem/middleware.py b/src/wtem/middleware.py
new file mode 100644 (file)
index 0000000..eb26e41
--- /dev/null
@@ -0,0 +1,15 @@
+# -*- coding: utf-8 -*-
+from threading import local
+
+
+_thread_locals = local()
+
+
+def get_current_request():
+    return getattr(_thread_locals, 'request', None)
+
+
+class ThreadLocalMiddleware(object):
+    @staticmethod
+    def process_request(request):
+        _thread_locals.request = request
diff --git a/src/wtem/migrations/0001_initial.py b/src/wtem/migrations/0001_initial.py
new file mode 100644 (file)
index 0000000..6d22934
--- /dev/null
@@ -0,0 +1,70 @@
+# -*- coding: utf-8 -*-
+import datetime
+from south.db import db
+from south.v2 import SchemaMigration
+from django.db import models
+
+
+class Migration(SchemaMigration):
+
+    def forwards(self, orm):
+        # Adding model 'Submission'
+        db.create_table(u'wtem_submission', (
+            (u'id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
+            ('contact', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['contact.Contact'], null=True)),
+            ('key', self.gf('django.db.models.fields.CharField')(unique=True, max_length=30)),
+            ('first_name', self.gf('django.db.models.fields.CharField')(max_length=100)),
+            ('last_name', self.gf('django.db.models.fields.CharField')(max_length=100)),
+            ('email', self.gf('django.db.models.fields.EmailField')(unique=True, max_length=100)),
+            ('answers', self.gf('django.db.models.fields.CharField')(max_length=65536, null=True, blank=True)),
+        ))
+        db.send_create_signal(u'wtem', ['Submission'])
+
+        # Adding model 'Attachment'
+        db.create_table(u'wtem_attachment', (
+            (u'id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
+            ('submission', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['wtem.Submission'])),
+            ('name', self.gf('django.db.models.fields.CharField')(max_length=100)),
+            ('file', self.gf('django.db.models.fields.files.FileField')(max_length=100)),
+        ))
+        db.send_create_signal(u'wtem', ['Attachment'])
+
+
+    def backwards(self, orm):
+        # Deleting model 'Submission'
+        db.delete_table(u'wtem_submission')
+
+        # Deleting model 'Attachment'
+        db.delete_table(u'wtem_attachment')
+
+
+    models = {
+        u'contact.contact': {
+            'Meta': {'ordering': "('-created_at',)", 'object_name': 'Contact'},
+            'body': ('jsonfield.fields.JSONField', [], {'default': '{}'}),
+            'contact': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
+            'created_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
+            'form_tag': ('django.db.models.fields.CharField', [], {'max_length': '32', 'db_index': 'True'}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'ip': ('django.db.models.fields.IPAddressField', [], {'max_length': '15'})
+        },
+        u'wtem.attachment': {
+            'Meta': {'object_name': 'Attachment'},
+            'file': ('django.db.models.fields.files.FileField', [], {'max_length': '100'}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+            'submission': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['wtem.Submission']"})
+        },
+        u'wtem.submission': {
+            'Meta': {'object_name': 'Submission'},
+            'answers': ('django.db.models.fields.CharField', [], {'max_length': '65536', 'null': 'True', 'blank': 'True'}),
+            'contact': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['contact.Contact']", 'null': 'True'}),
+            'email': ('django.db.models.fields.EmailField', [], {'unique': 'True', 'max_length': '100'}),
+            'first_name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'key': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'}),
+            'last_name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
+        }
+    }
+
+    complete_apps = ['wtem']
\ No newline at end of file
diff --git a/src/wtem/migrations/0002_auto__add_field_submission_key_sent.py b/src/wtem/migrations/0002_auto__add_field_submission_key_sent.py
new file mode 100644 (file)
index 0000000..825da07
--- /dev/null
@@ -0,0 +1,52 @@
+# -*- coding: utf-8 -*-
+import datetime
+from south.db import db
+from south.v2 import SchemaMigration
+from django.db import models
+
+
+class Migration(SchemaMigration):
+
+    def forwards(self, orm):
+        # Adding field 'Submission.key_sent'
+        db.add_column(u'wtem_submission', 'key_sent',
+                      self.gf('django.db.models.fields.BooleanField')(default=False),
+                      keep_default=False)
+
+
+    def backwards(self, orm):
+        # Deleting field 'Submission.key_sent'
+        db.delete_column(u'wtem_submission', 'key_sent')
+
+
+    models = {
+        u'contact.contact': {
+            'Meta': {'ordering': "('-created_at',)", 'object_name': 'Contact'},
+            'body': ('jsonfield.fields.JSONField', [], {'default': '{}'}),
+            'contact': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
+            'created_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
+            'form_tag': ('django.db.models.fields.CharField', [], {'max_length': '32', 'db_index': 'True'}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'ip': ('django.db.models.fields.IPAddressField', [], {'max_length': '15'})
+        },
+        u'wtem.attachment': {
+            'Meta': {'object_name': 'Attachment'},
+            'file': ('django.db.models.fields.files.FileField', [], {'max_length': '100'}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+            'submission': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['wtem.Submission']"})
+        },
+        u'wtem.submission': {
+            'Meta': {'object_name': 'Submission'},
+            'answers': ('django.db.models.fields.CharField', [], {'max_length': '65536', 'null': 'True', 'blank': 'True'}),
+            'contact': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['contact.Contact']", 'null': 'True'}),
+            'email': ('django.db.models.fields.EmailField', [], {'unique': 'True', 'max_length': '100'}),
+            'first_name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'key': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'}),
+            'key_sent': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+            'last_name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
+        }
+    }
+
+    complete_apps = ['wtem']
\ No newline at end of file
diff --git a/src/wtem/migrations/0003_auto__add_assignment.py b/src/wtem/migrations/0003_auto__add_assignment.py
new file mode 100644 (file)
index 0000000..94e6509
--- /dev/null
@@ -0,0 +1,97 @@
+# -*- coding: utf-8 -*-
+import datetime
+from south.db import db
+from south.v2 import SchemaMigration
+from django.db import models
+
+
+class Migration(SchemaMigration):
+
+    def forwards(self, orm):
+        # Adding model 'Assignment'
+        db.create_table(u'wtem_assignment', (
+            (u'id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
+            ('user', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['auth.User'])),
+            ('exercises', self.gf('jsonfield.fields.JSONField')(default={})),
+        ))
+        db.send_create_signal(u'wtem', ['Assignment'])
+
+
+    def backwards(self, orm):
+        # Deleting model 'Assignment'
+        db.delete_table(u'wtem_assignment')
+
+
+    models = {
+        u'auth.group': {
+            'Meta': {'object_name': 'Group'},
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
+            'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
+        },
+        u'auth.permission': {
+            'Meta': {'ordering': "(u'content_type__app_label', u'content_type__model', u'codename')", 'unique_together': "((u'content_type', u'codename'),)", 'object_name': 'Permission'},
+            'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+            'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['contenttypes.ContentType']"}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
+        },
+        u'auth.user': {
+            'Meta': {'object_name': 'User'},
+            'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
+            'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
+            'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
+            'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
+            'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+            'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+            'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
+            'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
+            'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
+            'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
+            'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
+        },
+        u'contact.contact': {
+            'Meta': {'ordering': "('-created_at',)", 'object_name': 'Contact'},
+            'body': ('jsonfield.fields.JSONField', [], {'default': '{}'}),
+            'contact': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
+            'created_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
+            'form_tag': ('django.db.models.fields.CharField', [], {'max_length': '32', 'db_index': 'True'}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'ip': ('django.db.models.fields.IPAddressField', [], {'max_length': '15'})
+        },
+        u'contenttypes.contenttype': {
+            'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
+            'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+            'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
+        },
+        u'wtem.assignment': {
+            'Meta': {'object_name': 'Assignment'},
+            'exercises': ('jsonfield.fields.JSONField', [], {'default': '{}'}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'user': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['auth.User']"})
+        },
+        u'wtem.attachment': {
+            'Meta': {'object_name': 'Attachment'},
+            'file': ('django.db.models.fields.files.FileField', [], {'max_length': '100'}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+            'submission': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['wtem.Submission']"})
+        },
+        u'wtem.submission': {
+            'Meta': {'object_name': 'Submission'},
+            'answers': ('django.db.models.fields.CharField', [], {'max_length': '65536', 'null': 'True', 'blank': 'True'}),
+            'contact': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['contact.Contact']", 'null': 'True'}),
+            'email': ('django.db.models.fields.EmailField', [], {'unique': 'True', 'max_length': '100'}),
+            'first_name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'key': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'}),
+            'key_sent': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+            'last_name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
+        }
+    }
+
+    complete_apps = ['wtem']
\ No newline at end of file
diff --git a/src/wtem/migrations/0004_auto__add_unique_assignment_user.py b/src/wtem/migrations/0004_auto__add_unique_assignment_user.py
new file mode 100644 (file)
index 0000000..7730b9d
--- /dev/null
@@ -0,0 +1,92 @@
+# -*- coding: utf-8 -*-
+import datetime
+from south.db import db
+from south.v2 import SchemaMigration
+from django.db import models
+
+
+class Migration(SchemaMigration):
+
+    def forwards(self, orm):
+        # Adding unique constraint on 'Assignment', fields ['user']
+        db.create_unique(u'wtem_assignment', ['user_id'])
+
+
+    def backwards(self, orm):
+        # Removing unique constraint on 'Assignment', fields ['user']
+        db.delete_unique(u'wtem_assignment', ['user_id'])
+
+
+    models = {
+        u'auth.group': {
+            'Meta': {'object_name': 'Group'},
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
+            'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
+        },
+        u'auth.permission': {
+            'Meta': {'ordering': "(u'content_type__app_label', u'content_type__model', u'codename')", 'unique_together': "((u'content_type', u'codename'),)", 'object_name': 'Permission'},
+            'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+            'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['contenttypes.ContentType']"}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
+        },
+        u'auth.user': {
+            'Meta': {'object_name': 'User'},
+            'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
+            'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
+            'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
+            'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
+            'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+            'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+            'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
+            'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
+            'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
+            'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
+            'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
+        },
+        u'contact.contact': {
+            'Meta': {'ordering': "('-created_at',)", 'object_name': 'Contact'},
+            'body': ('jsonfield.fields.JSONField', [], {'default': '{}'}),
+            'contact': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
+            'created_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
+            'form_tag': ('django.db.models.fields.CharField', [], {'max_length': '32', 'db_index': 'True'}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'ip': ('django.db.models.fields.IPAddressField', [], {'max_length': '15'})
+        },
+        u'contenttypes.contenttype': {
+            'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
+            'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+            'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
+        },
+        u'wtem.assignment': {
+            'Meta': {'object_name': 'Assignment'},
+            'exercises': ('jsonfield.fields.JSONField', [], {'default': '{}'}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'user': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['auth.User']", 'unique': 'True'})
+        },
+        u'wtem.attachment': {
+            'Meta': {'object_name': 'Attachment'},
+            'file': ('django.db.models.fields.files.FileField', [], {'max_length': '100'}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+            'submission': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['wtem.Submission']"})
+        },
+        u'wtem.submission': {
+            'Meta': {'object_name': 'Submission'},
+            'answers': ('django.db.models.fields.CharField', [], {'max_length': '65536', 'null': 'True', 'blank': 'True'}),
+            'contact': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['contact.Contact']", 'null': 'True'}),
+            'email': ('django.db.models.fields.EmailField', [], {'unique': 'True', 'max_length': '100'}),
+            'first_name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'key': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'}),
+            'key_sent': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+            'last_name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
+        }
+    }
+
+    complete_apps = ['wtem']
\ No newline at end of file
diff --git a/src/wtem/migrations/0005_auto__add_field_submission_marks.py b/src/wtem/migrations/0005_auto__add_field_submission_marks.py
new file mode 100644 (file)
index 0000000..bbade28
--- /dev/null
@@ -0,0 +1,95 @@
+# -*- coding: utf-8 -*-
+import datetime
+from south.db import db
+from south.v2 import SchemaMigration
+from django.db import models
+
+
+class Migration(SchemaMigration):
+
+    def forwards(self, orm):
+        # Adding field 'Submission.marks'
+        db.add_column(u'wtem_submission', 'marks',
+                      self.gf('jsonfield.fields.JSONField')(default={}),
+                      keep_default=False)
+
+
+    def backwards(self, orm):
+        # Deleting field 'Submission.marks'
+        db.delete_column(u'wtem_submission', 'marks')
+
+
+    models = {
+        u'auth.group': {
+            'Meta': {'object_name': 'Group'},
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
+            'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
+        },
+        u'auth.permission': {
+            'Meta': {'ordering': "(u'content_type__app_label', u'content_type__model', u'codename')", 'unique_together': "((u'content_type', u'codename'),)", 'object_name': 'Permission'},
+            'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+            'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['contenttypes.ContentType']"}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
+        },
+        u'auth.user': {
+            'Meta': {'object_name': 'User'},
+            'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
+            'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
+            'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
+            'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
+            'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+            'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+            'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
+            'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
+            'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
+            'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
+            'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
+        },
+        u'contact.contact': {
+            'Meta': {'ordering': "('-created_at',)", 'object_name': 'Contact'},
+            'body': ('jsonfield.fields.JSONField', [], {'default': '{}'}),
+            'contact': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
+            'created_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
+            'form_tag': ('django.db.models.fields.CharField', [], {'max_length': '32', 'db_index': 'True'}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'ip': ('django.db.models.fields.IPAddressField', [], {'max_length': '15'})
+        },
+        u'contenttypes.contenttype': {
+            'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
+            'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+            'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
+        },
+        u'wtem.assignment': {
+            'Meta': {'object_name': 'Assignment'},
+            'exercises': ('jsonfield.fields.JSONField', [], {'default': '{}'}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'user': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['auth.User']", 'unique': 'True'})
+        },
+        u'wtem.attachment': {
+            'Meta': {'object_name': 'Attachment'},
+            'file': ('django.db.models.fields.files.FileField', [], {'max_length': '100'}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+            'submission': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['wtem.Submission']"})
+        },
+        u'wtem.submission': {
+            'Meta': {'object_name': 'Submission'},
+            'answers': ('django.db.models.fields.CharField', [], {'max_length': '65536', 'null': 'True', 'blank': 'True'}),
+            'contact': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['contact.Contact']", 'null': 'True'}),
+            'email': ('django.db.models.fields.EmailField', [], {'unique': 'True', 'max_length': '100'}),
+            'first_name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'key': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'}),
+            'key_sent': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+            'last_name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+            'marks': ('jsonfield.fields.JSONField', [], {'default': '{}'})
+        }
+    }
+
+    complete_apps = ['wtem']
\ No newline at end of file
diff --git a/src/wtem/migrations/0006_auto__del_field_attachment_name__add_field_attachment_exercise_id.py b/src/wtem/migrations/0006_auto__del_field_attachment_name__add_field_attachment_exercise_id.py
new file mode 100644 (file)
index 0000000..ff72499
--- /dev/null
@@ -0,0 +1,101 @@
+# -*- coding: utf-8 -*-
+import datetime
+from south.db import db
+from south.v2 import SchemaMigration
+from django.db import models
+
+
+class Migration(SchemaMigration):
+
+    def forwards(self, orm):
+        # Deleting field 'Attachment.name'
+        db.delete_column(u'wtem_attachment', 'name')
+
+        # Adding field 'Attachment.exercise_id'
+        db.add_column(u'wtem_attachment', 'exercise_id',
+                      self.gf('django.db.models.fields.IntegerField')(default=None),
+                      keep_default=False)
+
+
+    def backwards(self, orm):
+
+        # User chose to not deal with backwards NULL issues for 'Attachment.name'
+        raise RuntimeError("Cannot reverse this migration. 'Attachment.name' and its values cannot be restored.")
+        # Deleting field 'Attachment.exercise_id'
+        db.delete_column(u'wtem_attachment', 'exercise_id')
+
+
+    models = {
+        u'auth.group': {
+            'Meta': {'object_name': 'Group'},
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
+            'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
+        },
+        u'auth.permission': {
+            'Meta': {'ordering': "(u'content_type__app_label', u'content_type__model', u'codename')", 'unique_together': "((u'content_type', u'codename'),)", 'object_name': 'Permission'},
+            'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+            'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['contenttypes.ContentType']"}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
+        },
+        u'auth.user': {
+            'Meta': {'object_name': 'User'},
+            'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
+            'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
+            'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
+            'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
+            'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+            'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+            'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
+            'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
+            'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
+            'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
+            'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
+        },
+        u'contact.contact': {
+            'Meta': {'ordering': "('-created_at',)", 'object_name': 'Contact'},
+            'body': ('jsonfield.fields.JSONField', [], {'default': '{}'}),
+            'contact': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
+            'created_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
+            'form_tag': ('django.db.models.fields.CharField', [], {'max_length': '32', 'db_index': 'True'}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'ip': ('django.db.models.fields.IPAddressField', [], {'max_length': '15'})
+        },
+        u'contenttypes.contenttype': {
+            'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
+            'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+            'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
+        },
+        u'wtem.assignment': {
+            'Meta': {'object_name': 'Assignment'},
+            'exercises': ('jsonfield.fields.JSONField', [], {'default': '{}'}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'user': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['auth.User']", 'unique': 'True'})
+        },
+        u'wtem.attachment': {
+            'Meta': {'object_name': 'Attachment'},
+            'exercise_id': ('django.db.models.fields.IntegerField', [], {}),
+            'file': ('django.db.models.fields.files.FileField', [], {'max_length': '100'}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'submission': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['wtem.Submission']"})
+        },
+        u'wtem.submission': {
+            'Meta': {'object_name': 'Submission'},
+            'answers': ('django.db.models.fields.CharField', [], {'max_length': '65536', 'null': 'True', 'blank': 'True'}),
+            'contact': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['contact.Contact']", 'null': 'True'}),
+            'email': ('django.db.models.fields.EmailField', [], {'unique': 'True', 'max_length': '100'}),
+            'first_name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'key': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'}),
+            'key_sent': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+            'last_name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+            'marks': ('jsonfield.fields.JSONField', [], {'default': '{}'})
+        }
+    }
+
+    complete_apps = ['wtem']
\ No newline at end of file
diff --git a/src/wtem/migrations/0007_auto.py b/src/wtem/migrations/0007_auto.py
new file mode 100644 (file)
index 0000000..ab1949f
--- /dev/null
@@ -0,0 +1,99 @@
+# -*- coding: utf-8 -*-
+import datetime
+from south.db import db
+from south.v2 import SchemaMigration
+from django.db import models
+
+
+class Migration(SchemaMigration):
+
+    def forwards(self, orm):
+        # Adding M2M table for field examiners on 'Submission'
+        db.create_table(u'wtem_submission_examiners', (
+            ('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)),
+            ('submission', models.ForeignKey(orm[u'wtem.submission'], null=False)),
+            ('user', models.ForeignKey(orm[u'auth.user'], null=False))
+        ))
+        db.create_unique(u'wtem_submission_examiners', ['submission_id', 'user_id'])
+
+
+    def backwards(self, orm):
+        # Removing M2M table for field examiners on 'Submission'
+        db.delete_table('wtem_submission_examiners')
+
+
+    models = {
+        u'auth.group': {
+            'Meta': {'object_name': 'Group'},
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
+            'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
+        },
+        u'auth.permission': {
+            'Meta': {'ordering': "(u'content_type__app_label', u'content_type__model', u'codename')", 'unique_together': "((u'content_type', u'codename'),)", 'object_name': 'Permission'},
+            'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+            'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['contenttypes.ContentType']"}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
+        },
+        u'auth.user': {
+            'Meta': {'object_name': 'User'},
+            'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
+            'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
+            'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
+            'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
+            'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+            'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+            'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
+            'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
+            'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
+            'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
+            'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
+        },
+        u'contact.contact': {
+            'Meta': {'ordering': "('-created_at',)", 'object_name': 'Contact'},
+            'body': ('jsonfield.fields.JSONField', [], {'default': '{}'}),
+            'contact': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
+            'created_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
+            'form_tag': ('django.db.models.fields.CharField', [], {'max_length': '32', 'db_index': 'True'}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'ip': ('django.db.models.fields.IPAddressField', [], {'max_length': '15'})
+        },
+        u'contenttypes.contenttype': {
+            'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
+            'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+            'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
+        },
+        u'wtem.assignment': {
+            'Meta': {'object_name': 'Assignment'},
+            'exercises': ('jsonfield.fields.JSONField', [], {'default': '{}'}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'user': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['auth.User']", 'unique': 'True'})
+        },
+        u'wtem.attachment': {
+            'Meta': {'object_name': 'Attachment'},
+            'exercise_id': ('django.db.models.fields.IntegerField', [], {}),
+            'file': ('django.db.models.fields.files.FileField', [], {'max_length': '100'}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'submission': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['wtem.Submission']"})
+        },
+        u'wtem.submission': {
+            'Meta': {'object_name': 'Submission'},
+            'answers': ('django.db.models.fields.CharField', [], {'max_length': '65536', 'null': 'True', 'blank': 'True'}),
+            'contact': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['contact.Contact']", 'null': 'True'}),
+            'email': ('django.db.models.fields.EmailField', [], {'unique': 'True', 'max_length': '100'}),
+            'examiners': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['auth.User']", 'symmetrical': 'False'}),
+            'first_name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'key': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'}),
+            'key_sent': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+            'last_name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+            'marks': ('jsonfield.fields.JSONField', [], {'default': '{}'})
+        }
+    }
+
+    complete_apps = ['wtem']
\ No newline at end of file
diff --git a/src/wtem/migrations/0008_auto__add_field_submission_end_time.py b/src/wtem/migrations/0008_auto__add_field_submission_end_time.py
new file mode 100644 (file)
index 0000000..58901c0
--- /dev/null
@@ -0,0 +1,97 @@
+# -*- coding: utf-8 -*-
+import datetime
+from south.db import db
+from south.v2 import SchemaMigration
+from django.db import models
+
+
+class Migration(SchemaMigration):
+
+    def forwards(self, orm):
+        # Adding field 'Submission.end_time'
+        db.add_column(u'wtem_submission', 'end_time',
+                      self.gf('django.db.models.fields.CharField')(max_length=5, null=True, blank=True),
+                      keep_default=False)
+
+
+    def backwards(self, orm):
+        # Deleting field 'Submission.end_time'
+        db.delete_column(u'wtem_submission', 'end_time')
+
+
+    models = {
+        u'auth.group': {
+            'Meta': {'object_name': 'Group'},
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
+            'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
+        },
+        u'auth.permission': {
+            'Meta': {'ordering': "(u'content_type__app_label', u'content_type__model', u'codename')", 'unique_together': "((u'content_type', u'codename'),)", 'object_name': 'Permission'},
+            'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+            'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['contenttypes.ContentType']"}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
+        },
+        u'auth.user': {
+            'Meta': {'object_name': 'User'},
+            'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
+            'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
+            'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
+            'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
+            'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+            'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+            'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
+            'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
+            'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
+            'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
+            'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
+        },
+        u'contact.contact': {
+            'Meta': {'ordering': "('-created_at',)", 'object_name': 'Contact'},
+            'body': ('jsonfield.fields.JSONField', [], {'default': '{}'}),
+            'contact': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
+            'created_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
+            'form_tag': ('django.db.models.fields.CharField', [], {'max_length': '32', 'db_index': 'True'}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'ip': ('django.db.models.fields.IPAddressField', [], {'max_length': '15'})
+        },
+        u'contenttypes.contenttype': {
+            'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
+            'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+            'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
+        },
+        u'wtem.assignment': {
+            'Meta': {'object_name': 'Assignment'},
+            'exercises': ('jsonfield.fields.JSONField', [], {'default': '{}'}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'user': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['auth.User']", 'unique': 'True'})
+        },
+        u'wtem.attachment': {
+            'Meta': {'object_name': 'Attachment'},
+            'exercise_id': ('django.db.models.fields.IntegerField', [], {}),
+            'file': ('django.db.models.fields.files.FileField', [], {'max_length': '100'}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'submission': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['wtem.Submission']"})
+        },
+        u'wtem.submission': {
+            'Meta': {'object_name': 'Submission'},
+            'answers': ('django.db.models.fields.CharField', [], {'max_length': '65536', 'null': 'True', 'blank': 'True'}),
+            'contact': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['contact.Contact']", 'null': 'True'}),
+            'email': ('django.db.models.fields.EmailField', [], {'unique': 'True', 'max_length': '100'}),
+            'end_time': ('django.db.models.fields.CharField', [], {'max_length': '5', 'null': 'True', 'blank': 'True'}),
+            'examiners': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'to': u"orm['auth.User']", 'null': 'True', 'blank': 'True'}),
+            'first_name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'key': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'}),
+            'key_sent': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+            'last_name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+            'marks': ('jsonfield.fields.JSONField', [], {'default': '{}'})
+        }
+    }
+
+    complete_apps = ['wtem']
\ No newline at end of file
diff --git a/src/wtem/migrations/0009_auto__add_field_attachment_tag.py b/src/wtem/migrations/0009_auto__add_field_attachment_tag.py
new file mode 100644 (file)
index 0000000..8ea943a
--- /dev/null
@@ -0,0 +1,98 @@
+# -*- coding: utf-8 -*-
+from south.utils import datetime_utils as datetime
+from south.db import db
+from south.v2 import SchemaMigration
+from django.db import models
+
+
+class Migration(SchemaMigration):
+
+    def forwards(self, orm):
+        # Adding field 'Attachment.tag'
+        db.add_column(u'wtem_attachment', 'tag',
+                      self.gf('django.db.models.fields.CharField')(max_length=128, null=True, blank=True),
+                      keep_default=False)
+
+
+    def backwards(self, orm):
+        # Deleting field 'Attachment.tag'
+        db.delete_column(u'wtem_attachment', 'tag')
+
+
+    models = {
+        u'auth.group': {
+            'Meta': {'object_name': 'Group'},
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
+            'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
+        },
+        u'auth.permission': {
+            'Meta': {'ordering': "(u'content_type__app_label', u'content_type__model', u'codename')", 'unique_together': "((u'content_type', u'codename'),)", 'object_name': 'Permission'},
+            'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+            'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['contenttypes.ContentType']"}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
+        },
+        u'auth.user': {
+            'Meta': {'object_name': 'User'},
+            'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
+            'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
+            'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
+            'groups': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "u'user_set'", 'blank': 'True', 'to': u"orm['auth.Group']"}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
+            'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+            'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+            'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
+            'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
+            'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
+            'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "u'user_set'", 'blank': 'True', 'to': u"orm['auth.Permission']"}),
+            'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
+        },
+        u'contact.contact': {
+            'Meta': {'ordering': "('-created_at',)", 'object_name': 'Contact'},
+            'body': ('jsonfield.fields.JSONField', [], {}),
+            'contact': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
+            'created_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
+            'form_tag': ('django.db.models.fields.CharField', [], {'max_length': '32', 'db_index': 'True'}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'ip': ('django.db.models.fields.IPAddressField', [], {'max_length': '15'})
+        },
+        u'contenttypes.contenttype': {
+            'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
+            'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+            'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
+        },
+        u'wtem.assignment': {
+            'Meta': {'object_name': 'Assignment'},
+            'exercises': ('jsonfield.fields.JSONField', [], {}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'user': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['auth.User']", 'unique': 'True'})
+        },
+        u'wtem.attachment': {
+            'Meta': {'object_name': 'Attachment'},
+            'exercise_id': ('django.db.models.fields.IntegerField', [], {}),
+            'file': ('django.db.models.fields.files.FileField', [], {'max_length': '100'}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'submission': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['wtem.Submission']"}),
+            'tag': ('django.db.models.fields.CharField', [], {'max_length': '128', 'null': 'True', 'blank': 'True'})
+        },
+        u'wtem.submission': {
+            'Meta': {'object_name': 'Submission'},
+            'answers': ('django.db.models.fields.CharField', [], {'max_length': '65536', 'null': 'True', 'blank': 'True'}),
+            'contact': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['contact.Contact']", 'null': 'True'}),
+            'email': ('django.db.models.fields.EmailField', [], {'unique': 'True', 'max_length': '100'}),
+            'end_time': ('django.db.models.fields.CharField', [], {'max_length': '5', 'null': 'True', 'blank': 'True'}),
+            'examiners': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'to': u"orm['auth.User']", 'null': 'True', 'blank': 'True'}),
+            'first_name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'key': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'}),
+            'key_sent': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+            'last_name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+            'marks': ('jsonfield.fields.JSONField', [], {'default': '{}'})
+        }
+    }
+
+    complete_apps = ['wtem']
\ No newline at end of file
diff --git a/src/wtem/migrations/0010_auto__add_confirmation.py b/src/wtem/migrations/0010_auto__add_confirmation.py
new file mode 100644 (file)
index 0000000..63f9d60
--- /dev/null
@@ -0,0 +1,115 @@
+# -*- coding: utf-8 -*-
+from south.utils import datetime_utils as datetime
+from south.db import db
+from south.v2 import SchemaMigration
+from django.db import models
+
+
+class Migration(SchemaMigration):
+
+    def forwards(self, orm):
+        # Adding model 'Confirmation'
+        db.create_table(u'wtem_confirmation', (
+            (u'id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
+            ('first_name', self.gf('django.db.models.fields.CharField')(max_length=100)),
+            ('last_name', self.gf('django.db.models.fields.CharField')(max_length=100)),
+            ('email', self.gf('django.db.models.fields.EmailField')(unique=True, max_length=100)),
+            ('contact', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['contact.Contact'], null=True)),
+            ('key', self.gf('django.db.models.fields.CharField')(max_length=30)),
+            ('confirmed', self.gf('django.db.models.fields.BooleanField')(default=False)),
+        ))
+        db.send_create_signal(u'wtem', ['Confirmation'])
+
+
+    def backwards(self, orm):
+        # Deleting model 'Confirmation'
+        db.delete_table(u'wtem_confirmation')
+
+
+    models = {
+        u'auth.group': {
+            'Meta': {'object_name': 'Group'},
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
+            'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
+        },
+        u'auth.permission': {
+            'Meta': {'ordering': "(u'content_type__app_label', u'content_type__model', u'codename')", 'unique_together': "((u'content_type', u'codename'),)", 'object_name': 'Permission'},
+            'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+            'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['contenttypes.ContentType']"}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
+        },
+        u'auth.user': {
+            'Meta': {'object_name': 'User'},
+            'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
+            'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
+            'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
+            'groups': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "u'user_set'", 'blank': 'True', 'to': u"orm['auth.Group']"}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
+            'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+            'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+            'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
+            'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
+            'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
+            'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "u'user_set'", 'blank': 'True', 'to': u"orm['auth.Permission']"}),
+            'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
+        },
+        u'contact.contact': {
+            'Meta': {'ordering': "('-created_at',)", 'object_name': 'Contact'},
+            'body': ('jsonfield.fields.JSONField', [], {}),
+            'contact': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
+            'created_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
+            'form_tag': ('django.db.models.fields.CharField', [], {'max_length': '32', 'db_index': 'True'}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'ip': ('django.db.models.fields.IPAddressField', [], {'max_length': '15'})
+        },
+        u'contenttypes.contenttype': {
+            'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
+            'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+            'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
+        },
+        u'wtem.assignment': {
+            'Meta': {'object_name': 'Assignment'},
+            'exercises': ('jsonfield.fields.JSONField', [], {}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'user': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['auth.User']", 'unique': 'True'})
+        },
+        u'wtem.attachment': {
+            'Meta': {'object_name': 'Attachment'},
+            'exercise_id': ('django.db.models.fields.IntegerField', [], {}),
+            'file': ('django.db.models.fields.files.FileField', [], {'max_length': '100'}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'submission': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['wtem.Submission']"}),
+            'tag': ('django.db.models.fields.CharField', [], {'max_length': '128', 'null': 'True', 'blank': 'True'})
+        },
+        u'wtem.confirmation': {
+            'Meta': {'object_name': 'Confirmation'},
+            'confirmed': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+            'contact': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['contact.Contact']", 'null': 'True'}),
+            'email': ('django.db.models.fields.EmailField', [], {'unique': 'True', 'max_length': '100'}),
+            'first_name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'key': ('django.db.models.fields.CharField', [], {'max_length': '30'}),
+            'last_name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
+        },
+        u'wtem.submission': {
+            'Meta': {'object_name': 'Submission'},
+            'answers': ('django.db.models.fields.CharField', [], {'max_length': '65536', 'null': 'True', 'blank': 'True'}),
+            'contact': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['contact.Contact']", 'null': 'True'}),
+            'email': ('django.db.models.fields.EmailField', [], {'unique': 'True', 'max_length': '100'}),
+            'end_time': ('django.db.models.fields.CharField', [], {'max_length': '5', 'null': 'True', 'blank': 'True'}),
+            'examiners': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'to': u"orm['auth.User']", 'null': 'True', 'blank': 'True'}),
+            'first_name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'key': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'}),
+            'key_sent': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+            'last_name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+            'marks': ('jsonfield.fields.JSONField', [], {'default': '{}'})
+        }
+    }
+
+    complete_apps = ['wtem']
\ No newline at end of file
diff --git a/src/wtem/migrations/__init__.py b/src/wtem/migrations/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/src/wtem/models.py b/src/wtem/models.py
new file mode 100644 (file)
index 0000000..361bff3
--- /dev/null
@@ -0,0 +1,179 @@
+# -*- coding: utf-8 -*-
+import random
+import string
+import os
+import json
+
+from django.db import models
+from django.contrib.auth.models import User
+from django.core.exceptions import ValidationError
+from django.utils.translation import ugettext as _
+from jsonfield import JSONField
+
+from contact.models import Contact
+
+f = file(os.path.dirname(__file__) + '/fixtures/exercises.json')
+exercises = json.loads(f.read())
+f.close()
+
+DEBUG_KEY = '12345'
+
+
+class Submission(models.Model):
+    contact = models.ForeignKey(Contact, null=True)
+    key = models.CharField(max_length=30, unique=True)
+    first_name = models.CharField(max_length=100)
+    last_name = models.CharField(max_length=100)
+    email = models.EmailField(max_length=100, unique=True)
+    answers = models.CharField(max_length=65536, null=True, blank=True)
+    key_sent = models.BooleanField(default=False)
+    marks = JSONField(default={})
+    examiners = models.ManyToManyField(User, null=True, blank=True)
+    end_time = models.CharField(max_length=5, null=True, blank=True)
+
+    def __unicode__(self):
+        return ', '.join((self.last_name, self.first_name, self.email))
+
+    @classmethod
+    def generate_key(cls):
+        key = ''
+        while not key or key in [record['key'] for record in cls.objects.values('key')]:
+            key = ''.join(random.choice(string.ascii_uppercase + string.ascii_lowercase + string.digits)
+                          for i in range(30))
+        return key
+
+    @classmethod
+    def create(cls, first_name, last_name, email, key=None, contact=None):
+        submission = cls(
+            contact=contact,
+            key=key if key else Submission.generate_key(),
+            first_name=first_name,
+            last_name=last_name,
+            email=email
+        )
+
+        submission.save()
+        return submission
+
+    def get_mark(self, user_id, exercise_id):
+        mark = None
+        user_id = str(user_id)
+        exercise_id = str(exercise_id)
+        if self.marks and user_id in self.marks:
+            mark = self.marks[user_id].get(exercise_id, None)
+        return mark
+
+    def set_mark(self, user_id, exercise_id, mark):
+        user_id = str(user_id)
+        exercise_id = str(exercise_id)
+        if not self.marks:
+            self.marks = dict()
+        
+        self.marks.setdefault(user_id, {})[exercise_id] = mark
+        if mark == 'None':
+            del self.marks[user_id][exercise_id]
+
+    def get_exercise_marks_by_examiner(self, exercise_id):
+        marks = dict()
+        for examiner_id, examiner_marks in self.marks.items():
+            mark = examiner_marks.get(exercise_id, None)
+            if mark is not None:
+                marks[examiner_id] = mark
+        return marks
+
+    def get_final_exercise_mark(self, exercise_id):
+        # exercise = exercises[int(exercise_id)-1]
+        exercise = [e for e in exercises if str(e['id']) == str(exercise_id)][0]
+        if exercise_checked_manually(exercise):
+            marks_by_examiner = self.get_exercise_marks_by_examiner(exercise_id)
+            if len(marks_by_examiner):
+                return sum(map(float, marks_by_examiner.values())) / float(len(marks_by_examiner))
+            else:
+                return None
+        else:
+            if not self.answers:
+                return None
+            answer = json.loads(self.answers)[exercise_id]['closed_part']
+            t = exercise['type']
+            if t == 'edumed_uporzadkuj':
+                return exercise['points'] if map(int, answer) == exercise['answer'] else 0
+            if t == 'edumed_przyporzadkuj':
+                toret = 0
+                for bucket_id, items in answer.items():
+                    for item_id in items:
+                        is_corect = False
+                        if exercise.get('answer_mode', None) == 'possible_buckets_for_item':
+                            is_correct = int(bucket_id) in exercise['answer'].get(item_id)
+                        else:
+                            is_correct = int(item_id) in exercise['answer'].get(bucket_id, [])
+                        if is_correct:
+                            toret += exercise['points_per_hit']
+                return toret
+            if t == 'edumed_wybor':
+                if len(exercise['answer']) == 1:
+                    if len(answer) and int(answer[0]) == exercise['answer'][0]:
+                        return exercise['points']
+                    else:
+                        return 0
+                else:
+                    toret = 0
+                    if exercise.get('answer_mode', None) == 'all_or_nothing':
+                        toret = exercise['points'] if map(int, answer) == exercise['answer'] else 0
+                    else:
+                        for answer_id in map(int, answer):
+                            if answer_id in exercise['answer']:
+                                toret += exercise['points_per_hit']
+                    return toret
+            if t == 'edumed_prawdafalsz':
+                toret = 0
+                for idx, statement in enumerate(exercise['statements']):
+                    if answer[idx] == 'true':
+                        given = True
+                    elif answer[idx] == 'false':
+                        given = False
+                    else:
+                        given = None
+                    if given == statement[1]:
+                        toret += exercise['points_per_hit']
+                return toret
+            raise NotImplementedError
+
+    @property
+    def final_result(self):
+        final = 0
+        # for exercise_id in map(str,range(1, len(exercises) + 1)):
+        for exercise_id in [str(x['id']) for x in exercises]:
+            mark = self.get_final_exercise_mark(exercise_id)
+            if mark is not None:
+                final += mark
+        return final
+
+    @property
+    def final_result_as_string(self):
+        return ('%.2f' % self.final_result).rstrip('0').rstrip('.')
+
+
+class Attachment(models.Model):
+    submission = models.ForeignKey(Submission)
+    exercise_id = models.IntegerField()
+    tag = models.CharField(max_length=128, null=True, blank=True)
+    file = models.FileField(upload_to='wtem/attachment')
+
+
+class Assignment(models.Model):
+    user = models.ForeignKey(User, unique=True)
+    exercises = JSONField()
+
+    def clean(self):
+        if not isinstance(self.exercises, list):
+            raise ValidationError(_('Assigned exercises must be declared in a list format'))
+        # for exercise in self.exercises:
+        #     if not isinstance(exercise, int) or exercise < 1:
+        #         raise ValidationError(_('Invalid exercise id: %s' % exercise))
+
+    def __unicode__(self):
+        return self.user.username + ': ' + ','.join(map(str, self.exercises))
+
+
+def exercise_checked_manually(exercise):
+    return (exercise['type'] in ('open', 'file_upload')) or 'open_part' in exercise
diff --git a/src/wtem/static/wtem/edumed.coffee b/src/wtem/static/wtem/edumed.coffee
new file mode 100644 (file)
index 0000000..ae7aea9
--- /dev/null
@@ -0,0 +1,555 @@
+
+$ = jQuery
+
+class Binding
+  constructor: (@handler, @element) ->
+    $(@element).data(@handler, this)
+
+
+class EduModule extends Binding
+  constructor: (element) ->
+    super 'edumodule', element
+
+    # $("[name=teacher-toggle]").change (ev) =>
+    #   if $(ev.target).is(":checked")
+    #     $(".teacher", @element).addClass "show"
+    #   else
+    #     $(".teacher", @element).removeClass "show"
+
+
+class Exercise extends Binding
+  constructor: (element) ->
+    super 'exercise', element
+    # just save the html to reset the exercise
+    $(@element).data("exercise-html", $(@element).html())
+
+    $(".check", @element).click (ev) =>
+      @check()
+      $(".retry", @element).show()
+      $(".check", @element).hide()
+    $(".retry", @element).click (ev) =>
+      @retry()
+    $('.solutions', @element).click =>
+      @show_solutions()
+      $(".comment", @element).show()
+    $('.reset', @element).click =>
+      @reset()
+
+  retry: ->
+    $(".correct, .incorrect", @element).removeClass("correct incorrect")
+    $(".check", @element).show()
+    $(".retry", @element).hide()
+
+  reset: ->
+    $(@element).html($(@element).data('exercise-html'))
+    exercise @element
+
+  piece_correct: (qpiece) ->
+    $(qpiece).removeClass('incorrect').addClass('correct')
+
+  piece_incorrect: (qpiece) ->
+    $(qpiece).removeClass('correct').addClass('incorrect')
+
+  check: ->
+    scores = []
+    $(".question", @element).each (i, question) =>
+      scores.push(@check_question question)
+
+    score = [0, 0, 0]
+    $.each scores, (i, s) ->
+      score[0] += s[0]
+      score[1] += s[1]
+      score[2] += s[2]
+    @show_score(score)
+
+  show_solutions: ->
+    @reset()
+    $(".question", @element).each (i, question) =>
+      @solve_question question
+
+  get_answers: ->
+    answers = []
+    $('.question', @element).each (i, question) =>
+      answers.push(@get_answer question)
+    return answers
+
+  # Parses a list of values, separated by space or comma.
+  # The list is read from data attribute of elem using data_key
+  # Returns a list with elements
+  # eg.: things_i_need: "house bike tv playstation"
+  # yields ["house", "bike", "tv", "playstation"]
+  # If optional numbers argument is true, returns list of numbers
+  # instead of strings
+  get_value_list: (elem, data_key, numbers) ->
+    vl = $(elem).attr("data-" + data_key).split(/[ ,]+/).map($.trim) #.map((x) -> parseInt(x))
+    if numbers
+      vl = vl.map((x) -> parseInt(x))
+    return vl
+
+  # Parses a list of values, separated by space or comma.
+  # The list is read from data attribute of elem using data_key
+  # Returns a 2-element list with mandatory and optional
+  # items. optional items are marked with a question mark on the end
+  # eg.: things_i_need: "house bike tv? playstation?"
+  # yields [[ "house", "bike"], ["tv", "playstation"]]
+  get_value_optional_list: (elem, data_key) ->
+    vals = @get_value_list(elem, data_key)
+    mandat = []
+    opt = []
+    for v in vals
+      if v.slice(-1) == "?"
+        opt.push v.slice(0, -1)
+      else
+        mandat.push v
+    return [mandat, opt]
+
+  show_score: (score) ->
+    $msg = $(".message", @element)
+    $msg.text("Wynik: #{score[0]} / #{score[2]}")
+    if score[0] >= score[2] and score[1] == 0
+      $msg.addClass("maxscore")
+    else
+      $msg.removeClass("maxscore")
+
+
+  draggable_equal: ($draggable1, $draggable2) ->
+    return false
+
+  draggable_accept: ($draggable, $droppable) ->
+    dropped = $droppable.closest("ul, ol").find(".draggable")
+    for d in dropped
+      if @draggable_equal $draggable, $(d)
+        return false
+    return true
+
+  draggable_move: ($draggable, $placeholder, ismultiple) ->
+    $added = $draggable.clone()
+    $added.data("original", $draggable.get(0))
+    if not ismultiple
+      $draggable.addClass('disabled').draggable('disable')
+
+    $placeholder.after($added)
+    if not $placeholder.hasClass('multiple')
+      $placeholder.hide()
+    if $added.is(".add-li")
+      $added.wrap("<li/>")
+
+    $added.append('<span class="remove">x</span><div class="clr"></div>')
+    $('.remove', $added).click (ev) =>
+      @retry()
+      if not ismultiple
+        $($added.data('original')).removeClass('disabled').draggable('enable')
+
+      if $added.is(".add-li")
+        $added = $added.closest('li')
+      $added.prev(".placeholder:not(.multiple)").show()
+      $added.remove()
+
+
+## XXX co z issortable?
+  dragging: (ismultiple, issortable) ->
+    $(".question", @element).each (i, question) =>
+      draggable_opts =
+        revert: 'invalid'
+        helper: 'clone'
+        start: @retry
+
+      $(".draggable", question).draggable(draggable_opts)
+      self = this
+      $(".placeholder", question).droppable
+        accept: (draggable) ->
+          $draggable = $(draggable)
+          is_accepted = true
+
+          if not $draggable.is(".draggable")
+            is_accepted = false
+
+          if is_accepted
+            is_accepted= self.draggable_accept $draggable, $(this)
+
+          if is_accepted
+            $(this).addClass 'accepting'
+          else
+            $(this).removeClass 'accepting'
+          return is_accepted
+
+        drop: (ev, ui) =>
+          $(ev.target).removeClass 'accepting dragover'
+
+          @draggable_move $(ui.draggable), $(ev.target), ismultiple
+
+          # $added = $(ui.draggable).clone()
+          # $added.data("original", ui.draggable)
+          # if not ismultiple
+          #   $(ui.draggable).addClass('disabled').draggable('disable')
+
+          # $(ev.target).after(added)
+          # if not $(ev.target).hasClass('multiple')
+          #   $(ev.target).hide()
+          # $added.append('<span class="remove">x</span>')
+          # $('.remove', added).click (ev) =>
+          #   $added.prev(".placeholder:not(.multiple)").show()
+          #   if not ismultiple
+          #     $added.data('original').removeClass('disabled').draggable('enable')
+          #   $(added).remove()
+
+        over: (ev, ui) ->
+          $(ev.target).addClass 'dragover'
+
+
+        out: (ev, ui) ->
+          $(ev.target).removeClass 'dragover'
+
+
+
+class Wybor extends Exercise
+  constructor: (element) ->
+    super element
+    $(".question-piece input", element).change(@retry);
+
+
+  check_question: (question) ->
+    all = 0
+    good = 0
+    bad = 0
+    solution = @get_value_list(question, 'solution')
+    $(".question-piece", question).each (i, qpiece) =>
+      piece_no = $(qpiece).attr 'data-no'
+      piece_name = $(qpiece).attr 'data-name'
+      if piece_name
+        should_be_checked = solution.indexOf(piece_name) >= 0
+      else
+        should_be_checked = solution.indexOf(piece_no) >= 0
+      is_checked = $("input", qpiece).is(":checked")
+
+      if should_be_checked
+        all += 1
+
+      if is_checked
+        if should_be_checked
+          good += 1
+          @piece_correct qpiece
+        else
+          bad += 1
+          @piece_incorrect qpiece
+      else
+        $(qpiece).removeClass("correct,incorrect")
+
+    return [good, bad, all]
+
+  solve_question: (question) ->
+    solution = @get_value_list(question, 'solution')
+    $(".question-piece", question).each (i, qpiece) =>
+      piece_no = $(qpiece).attr 'data-no'
+      piece_name = $(qpiece).attr 'data-name'
+      if piece_name
+        should_be_checked = solution.indexOf(piece_name) >= 0
+      else
+        should_be_checked = solution.indexOf(piece_no) >= 0
+      console.log("check " + $("input[type=checkbox]", qpiece).attr("id") + " -> " + should_be_checked)
+      $("input[type=checkbox],input[type=radio]", qpiece).prop 'checked', should_be_checked
+
+  get_answer: (question) ->
+    answer = []
+    $('.question-piece', question).each (i, qpiece) =>
+      $qpiece = $(qpiece)
+      if $("input[type=checkbox],input[type=radio]", qpiece).is(':checked')
+        answer.push($qpiece.attr('data-name'))
+    return answer
+
+
+class Uporzadkuj extends Exercise
+  constructor: (element) ->
+    super element
+    $('ol, ul', @element).sortable({ items: "> li", start: @retry })
+
+  check_question: (question) ->
+    positions = @get_value_list(question, 'original', true)
+    sorted = positions.sort()
+    pkts = $('.question-piece', question)
+
+    correct = 0
+    bad = 0
+    all = 0
+
+    for pkt in [0...pkts.length]
+      all += 1
+      if pkts.eq(pkt).data('pos') == sorted[pkt]
+        correct += 1
+        @piece_correct pkts.eq(pkt)
+      else
+        bad += 1
+        @piece_incorrect pkts.eq(pkt)
+    return [correct, bad, all]
+
+  solve_question: (question) ->
+    positions = @get_value_list(question, 'original', true)
+    sorted = positions.sort()
+    pkts = $('.question-piece', question)
+    pkts.sort (a, b) ->
+      q = $(a).data('pos')
+      w = $(b).data('pos')
+      return 1 if q < w
+      return -1 if q > w
+      return 0
+
+    parent = pkts.eq(0).parent()
+    for p in pkts
+      parent.prepend(p)
+
+  get_answer: (question) ->
+    answer = []
+    $(".question-piece", @element).each (i, qpiece) =>
+      answer.push($(qpiece).attr('data-pos'))
+    return answer
+
+
+# XXX propozycje="1/0"
+class Luki extends Exercise
+  constructor: (element) ->
+    super element
+    @dragging false, false
+
+  check: ->
+    all = $(".placeholder", @element).length
+    correct = 0
+    bad = 0
+    $(".placeholder + .question-piece", @element).each (i, qpiece) =>
+      $placeholder = $(qpiece).prev(".placeholder")
+      if $placeholder.data('solution') == $(qpiece).data('no')
+        @piece_correct qpiece
+        correct += 1
+      else
+        bad += 1
+        @piece_incorrect qpiece
+
+    @show_score [correct, bad, all]
+
+  solve_question: (question) ->
+    $(".placeholder", question).each (i, placeholder) =>
+      $qp = $(".question-piece[data-no=" + $(placeholder).data('solution') + "]", question)
+      @draggable_move $qp, $(placeholder), false
+
+
+class Zastap extends Exercise
+  constructor: (element) ->
+    super element
+    $(".paragraph", @element).each (i, par) =>
+      @wrap_words $(par), $('<span class="placeholder zastap"/>')
+    @dragging false, false
+
+  check: ->
+    all = 0
+    correct = 0
+    bad = 0
+
+    $(".paragraph", @element).each (i, par) =>
+      $(".placeholder", par).each (j, qpiece) =>
+        $qp = $(qpiece)
+        $dragged = $qp.next(".draggable")
+        if $qp.data("solution")
+          if $dragged and $qp.data("solution") == $dragged.data("no")
+            @piece_correct $dragged
+            correct += 1
+#          else -- we dont mark enything here, so not to hint user about solution. He sees he hasn't used all the draggables
+
+          all += 1
+
+    @show_score [correct, bad, all]
+
+  show_solutions: ->
+    @reset()
+    $(".paragraph", @element).each (i, par) =>
+      $(".placeholder[data-solution]", par).each (j, qpiece) =>
+        $qp = $(qpiece)
+        $dr = $(".draggable[data-no=" + $qp.data('solution') + "]", @element)
+        @draggable_move $dr, $qp, false
+
+
+  wrap_words: (element, wrapper) ->
+    # This function wraps each word of element in wrapper, but does not descend into child-tags of element.
+    # It doesn't wrap things between words (defined by ignore RE below). Warning - ignore must begin with ^
+    ignore = /^[ \t.,:;()]+/
+
+    insertWrapped = (txt, elem) ->
+      nw = wrapper.clone()
+      $(document.createTextNode(txt))
+        .wrap(nw).parent().attr("data-original", txt).insertBefore(elem)
+
+    for j in [element.get(0).childNodes.length-1..0]
+      chld = element.get(0).childNodes[j]
+      if chld.nodeType == document.TEXT_NODE
+        len = chld.textContent.length
+        wordb = 0
+        i = 0
+        while i < len
+          space = ignore.exec(chld.textContent.substr(i))
+          if space?
+            if wordb < i
+              insertWrapped(chld.textContent.substr(wordb, i-wordb), chld)
+
+            $(document.createTextNode(space[0])).insertBefore(chld)
+            i += space[0].length
+            wordb = i
+          else
+            i = i + 1
+        if wordb < len - 1
+          insertWrapped(chld.textContent.substr(wordb, len - 1 - wordb), chld)
+        $(chld).remove()
+
+
+class Przyporzadkuj extends Exercise
+  is_multiple: ->
+    for qp in $(".question-piece", @element)
+      if $(qp).attr('data-solution').split(/[ ,]+/).length > 1
+        return true
+    return false
+
+  constructor: (element) ->
+    super element
+
+    @multiple = @is_multiple()
+
+    @dragging @multiple, true
+
+  draggable_equal: (d1, d2) ->
+    return d1.data("no") == d2.data("no")
+
+  draggable_accept: ($draggable, $droppable) ->
+    dropped = $droppable.closest("ul, ol").find(".draggable")
+    return (super $draggable, $droppable) && dropped.length == 0
+
+  check_question: (question) ->
+    # subjects placed in predicates
+    minimum = $(question).data("minimum")
+    count = 0
+    bad_count = 0
+    all = 0
+    if not minimum
+      self = this
+      $(".subject .question-piece", question).each (i, el) ->
+        v = self.get_value_optional_list el, 'solution'
+        mandatory = v[0]
+        all += mandatory.length
+
+    for pred in $(".predicate [data-predicate]", question)
+      pn = $(pred).attr('data-predicate')
+      #if minimum?
+      #  all += minimum
+
+      for qp in $(".question-piece", pred)
+        v = @get_value_optional_list qp, 'solution'
+        mandatory = v[0]
+        optional = v[1]
+
+        if mandatory.indexOf(pn) >= 0 or (minimum and optional.indexOf(pn) >= 0)
+          count += 1
+          @piece_correct qp
+        else
+          bad_count += 1
+          @piece_incorrect qp
+
+    return [count, bad_count, all]
+
+  solve_question: (question) ->
+    minimum = $(question).data("min")
+
+    for qp in $(".subject .question-piece", question)
+      v = @get_value_optional_list qp, 'solution'
+      mandatory = v[0]
+      optional = v[1]
+
+      if minimum
+        draggables = mandatory.count(optional)[0...minimum]
+      else
+        draggables = mandatory
+      for m in draggables
+        $pr = $(".predicate [data-predicate=" + m + "]", question)
+        $ph = $pr.find ".placeholder:visible"
+        @draggable_move $(qp), $ph.eq(0), @multiple
+
+  get_answer: (question) ->
+    answer = {}
+    $(".predicate [data-predicate]", question).each (i, subjects) =>
+      predicate = $(subjects).attr('data-predicate')
+      answer[predicate] = []
+      $('.question-piece', subjects).each (i, qpiece) =>
+        $qpiece = $(qpiece)
+        answer[predicate].push($qpiece.attr('data-id'))
+    return answer
+
+
+class PrawdaFalsz extends Exercise
+  constructor: (element) ->
+    super element
+
+    for qp in $(".question-piece", @element)
+      $(".true", qp).click (ev) =>
+        ev.preventDefault()
+        @retry()
+        $(ev.target).closest(".question-piece").data("value", "true")
+        $(ev.target).addClass('chosen').siblings('a').removeClass('chosen')
+      $(".false", qp).click (ev) =>
+        ev.preventDefault()
+        @retry()
+        $(ev.target).closest(".question-piece").data("value", "false")
+        $(ev.target).addClass('chosen').siblings('a').removeClass('chosen')
+
+
+  check_question: ->
+    all = 0
+    good = 0
+    bad = 0
+    for qp in $(".question-piece", @element)
+      if $(qp).data("solution").toString() == $(qp).data("value")
+        good += 1
+        @piece_correct qp
+      else
+        bad += 1
+        @piece_incorrect qp
+
+      all += 1
+
+    return [good, bad, all]
+
+  show_solutions: ->
+    @reset()
+    for qp in $(".question-piece", @element)
+      if $(qp).data('solution') == true
+        $(".true", qp).click()
+      else
+        $(".false", qp).click()
+
+  get_answer: (question) ->
+    answer = []
+    $(".question-piece", @element).each (i, qpiece) =>
+      answer.push($(qpiece).data('value') || '-')
+    return answer
+
+##########
+
+exercise = (ele) ->
+  es =
+    wybor: Wybor
+    uporzadkuj: Uporzadkuj
+    luki: Luki
+    zastap: Zastap
+    przyporzadkuj: Przyporzadkuj
+    prawdafalsz: PrawdaFalsz
+
+
+  cls = es[$(ele).attr('data-type')]
+  new cls(ele)
+
+
+window.edumed =
+  'EduModule': EduModule
+
+
+
+
+$(document).ready () ->
+  new EduModule($("#book-text"))
+
+  $(".exercise").each (i, el) ->
+    exercise(this)
diff --git a/src/wtem/static/wtem/edumed.js b/src/wtem/static/wtem/edumed.js
new file mode 100644 (file)
index 0000000..940ca54
--- /dev/null
@@ -0,0 +1,740 @@
+// Generated by CoffeeScript 1.6.3
+(function() {
+  var $, Binding, EduModule, Exercise, Luki, PrawdaFalsz, Przyporzadkuj, Uporzadkuj, Wybor, Zastap, exercise,
+    __hasProp = {}.hasOwnProperty,
+    __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
+
+  $ = jQuery;
+
+  Binding = (function() {
+    function Binding(handler, element) {
+      this.handler = handler;
+      this.element = element;
+      $(this.element).data(this.handler, this);
+    }
+
+    return Binding;
+
+  })();
+
+  EduModule = (function(_super) {
+    __extends(EduModule, _super);
+
+    function EduModule(element) {
+      EduModule.__super__.constructor.call(this, 'edumodule', element);
+    }
+
+    return EduModule;
+
+  })(Binding);
+
+  Exercise = (function(_super) {
+    __extends(Exercise, _super);
+
+    function Exercise(element) {
+      var _this = this;
+      Exercise.__super__.constructor.call(this, 'exercise', element);
+      $(this.element).data("exercise-html", $(this.element).html());
+      $(".check", this.element).click(function(ev) {
+        _this.check();
+        $(".retry", _this.element).show();
+        return $(".check", _this.element).hide();
+      });
+      $(".retry", this.element).click(function(ev) {
+        return _this.retry();
+      });
+      $('.solutions', this.element).click(function() {
+        _this.show_solutions();
+        return $(".comment", _this.element).show();
+      });
+      $('.reset', this.element).click(function() {
+        return _this.reset();
+      });
+    }
+
+    Exercise.prototype.retry = function() {
+      $(".correct, .incorrect", this.element).removeClass("correct incorrect");
+      $(".check", this.element).show();
+      return $(".retry", this.element).hide();
+    };
+
+    Exercise.prototype.reset = function() {
+      $(this.element).html($(this.element).data('exercise-html'));
+      return exercise(this.element);
+    };
+
+    Exercise.prototype.piece_correct = function(qpiece) {
+      return $(qpiece).removeClass('incorrect').addClass('correct');
+    };
+
+    Exercise.prototype.piece_incorrect = function(qpiece) {
+      return $(qpiece).removeClass('correct').addClass('incorrect');
+    };
+
+    Exercise.prototype.check = function() {
+      var score, scores,
+        _this = this;
+      scores = [];
+      $(".question", this.element).each(function(i, question) {
+        return scores.push(_this.check_question(question));
+      });
+      score = [0, 0, 0];
+      $.each(scores, function(i, s) {
+        score[0] += s[0];
+        score[1] += s[1];
+        return score[2] += s[2];
+      });
+      return this.show_score(score);
+    };
+
+    Exercise.prototype.show_solutions = function() {
+      var _this = this;
+      this.reset();
+      return $(".question", this.element).each(function(i, question) {
+        return _this.solve_question(question);
+      });
+    };
+
+    Exercise.prototype.get_answers = function() {
+      var answers,
+        _this = this;
+      answers = [];
+      $('.question', this.element).each(function(i, question) {
+        return answers.push(_this.get_answer(question));
+      });
+      return answers;
+    };
+
+    Exercise.prototype.get_value_list = function(elem, data_key, numbers) {
+      var vl;
+      vl = $(elem).attr("data-" + data_key).split(/[ ,]+/).map($.trim);
+      if (numbers) {
+        vl = vl.map(function(x) {
+          return parseInt(x);
+        });
+      }
+      return vl;
+    };
+
+    Exercise.prototype.get_value_optional_list = function(elem, data_key) {
+      var mandat, opt, v, vals, _i, _len;
+      vals = this.get_value_list(elem, data_key);
+      mandat = [];
+      opt = [];
+      for (_i = 0, _len = vals.length; _i < _len; _i++) {
+        v = vals[_i];
+        if (v.slice(-1) === "?") {
+          opt.push(v.slice(0, -1));
+        } else {
+          mandat.push(v);
+        }
+      }
+      return [mandat, opt];
+    };
+
+    Exercise.prototype.show_score = function(score) {
+      var $msg;
+      $msg = $(".message", this.element);
+      $msg.text("Wynik: " + score[0] + " / " + score[2]);
+      if (score[0] >= score[2] && score[1] === 0) {
+        return $msg.addClass("maxscore");
+      } else {
+        return $msg.removeClass("maxscore");
+      }
+    };
+
+    Exercise.prototype.draggable_equal = function($draggable1, $draggable2) {
+      return false;
+    };
+
+    Exercise.prototype.draggable_accept = function($draggable, $droppable) {
+      var d, dropped, _i, _len;
+      dropped = $droppable.closest("ul, ol").find(".draggable");
+      for (_i = 0, _len = dropped.length; _i < _len; _i++) {
+        d = dropped[_i];
+        if (this.draggable_equal($draggable, $(d))) {
+          return false;
+        }
+      }
+      return true;
+    };
+
+    Exercise.prototype.draggable_move = function($draggable, $placeholder, ismultiple) {
+      var $added,
+        _this = this;
+      $added = $draggable.clone();
+      $added.data("original", $draggable.get(0));
+      if (!ismultiple) {
+        $draggable.addClass('disabled').draggable('disable');
+      }
+      $placeholder.after($added);
+      if (!$placeholder.hasClass('multiple')) {
+        $placeholder.hide();
+      }
+      if ($added.is(".add-li")) {
+        $added.wrap("<li/>");
+      }
+      $added.append('<span class="remove">x</span><div class="clr"></div>');
+      return $('.remove', $added).click(function(ev) {
+        _this.retry();
+        if (!ismultiple) {
+          $($added.data('original')).removeClass('disabled').draggable('enable');
+        }
+        if ($added.is(".add-li")) {
+          $added = $added.closest('li');
+        }
+        $added.prev(".placeholder:not(.multiple)").show();
+        return $added.remove();
+      });
+    };
+
+    Exercise.prototype.dragging = function(ismultiple, issortable) {
+      var _this = this;
+      return $(".question", this.element).each(function(i, question) {
+        var draggable_opts, self;
+        draggable_opts = {
+          revert: 'invalid',
+          helper: 'clone',
+          start: _this.retry
+        };
+        $(".draggable", question).draggable(draggable_opts);
+        self = _this;
+        return $(".placeholder", question).droppable({
+          accept: function(draggable) {
+            var $draggable, is_accepted;
+            $draggable = $(draggable);
+            is_accepted = true;
+            if (!$draggable.is(".draggable")) {
+              is_accepted = false;
+            }
+            if (is_accepted) {
+              is_accepted = self.draggable_accept($draggable, $(this));
+            }
+            if (is_accepted) {
+              $(this).addClass('accepting');
+            } else {
+              $(this).removeClass('accepting');
+            }
+            return is_accepted;
+          },
+          drop: function(ev, ui) {
+            $(ev.target).removeClass('accepting dragover');
+            return _this.draggable_move($(ui.draggable), $(ev.target), ismultiple);
+          },
+          over: function(ev, ui) {
+            return $(ev.target).addClass('dragover');
+          },
+          out: function(ev, ui) {
+            return $(ev.target).removeClass('dragover');
+          }
+        });
+      });
+    };
+
+    return Exercise;
+
+  })(Binding);
+
+  Wybor = (function(_super) {
+    __extends(Wybor, _super);
+
+    function Wybor(element) {
+      Wybor.__super__.constructor.call(this, element);
+      $(".question-piece input", element).change(this.retry);
+    }
+
+    Wybor.prototype.check_question = function(question) {
+      var all, bad, good, solution,
+        _this = this;
+      all = 0;
+      good = 0;
+      bad = 0;
+      solution = this.get_value_list(question, 'solution');
+      $(".question-piece", question).each(function(i, qpiece) {
+        var is_checked, piece_name, piece_no, should_be_checked;
+        piece_no = $(qpiece).attr('data-no');
+        piece_name = $(qpiece).attr('data-name');
+        if (piece_name) {
+          should_be_checked = solution.indexOf(piece_name) >= 0;
+        } else {
+          should_be_checked = solution.indexOf(piece_no) >= 0;
+        }
+        is_checked = $("input", qpiece).is(":checked");
+        if (should_be_checked) {
+          all += 1;
+        }
+        if (is_checked) {
+          if (should_be_checked) {
+            good += 1;
+            return _this.piece_correct(qpiece);
+          } else {
+            bad += 1;
+            return _this.piece_incorrect(qpiece);
+          }
+        } else {
+          return $(qpiece).removeClass("correct,incorrect");
+        }
+      });
+      return [good, bad, all];
+    };
+
+    Wybor.prototype.solve_question = function(question) {
+      var solution,
+        _this = this;
+      solution = this.get_value_list(question, 'solution');
+      return $(".question-piece", question).each(function(i, qpiece) {
+        var piece_name, piece_no, should_be_checked;
+        piece_no = $(qpiece).attr('data-no');
+        piece_name = $(qpiece).attr('data-name');
+        if (piece_name) {
+          should_be_checked = solution.indexOf(piece_name) >= 0;
+        } else {
+          should_be_checked = solution.indexOf(piece_no) >= 0;
+        }
+        console.log("check " + $("input[type=checkbox]", qpiece).attr("id") + " -> " + should_be_checked);
+        return $("input[type=checkbox],input[type=radio]", qpiece).prop('checked', should_be_checked);
+      });
+    };
+
+    Wybor.prototype.get_answer = function(question) {
+      var answer,
+        _this = this;
+      answer = [];
+      $('.question-piece', question).each(function(i, qpiece) {
+        var $qpiece;
+        $qpiece = $(qpiece);
+        if ($("input[type=checkbox],input[type=radio]", qpiece).is(':checked')) {
+          return answer.push($qpiece.attr('data-name'));
+        }
+      });
+      return answer;
+    };
+
+    return Wybor;
+
+  })(Exercise);
+
+  Uporzadkuj = (function(_super) {
+    __extends(Uporzadkuj, _super);
+
+    function Uporzadkuj(element) {
+      Uporzadkuj.__super__.constructor.call(this, element);
+      $('ol, ul', this.element).sortable({
+        items: "> li",
+        start: this.retry
+      });
+    }
+
+    Uporzadkuj.prototype.check_question = function(question) {
+      var all, bad, correct, pkt, pkts, positions, sorted, _i, _ref;
+      positions = this.get_value_list(question, 'original', true);
+      sorted = positions.sort();
+      pkts = $('.question-piece', question);
+      correct = 0;
+      bad = 0;
+      all = 0;
+      for (pkt = _i = 0, _ref = pkts.length; 0 <= _ref ? _i < _ref : _i > _ref; pkt = 0 <= _ref ? ++_i : --_i) {
+        all += 1;
+        if (pkts.eq(pkt).data('pos') === sorted[pkt]) {
+          correct += 1;
+          this.piece_correct(pkts.eq(pkt));
+        } else {
+          bad += 1;
+          this.piece_incorrect(pkts.eq(pkt));
+        }
+      }
+      return [correct, bad, all];
+    };
+
+    Uporzadkuj.prototype.solve_question = function(question) {
+      var p, parent, pkts, positions, sorted, _i, _len, _results;
+      positions = this.get_value_list(question, 'original', true);
+      sorted = positions.sort();
+      pkts = $('.question-piece', question);
+      pkts.sort(function(a, b) {
+        var q, w;
+        q = $(a).data('pos');
+        w = $(b).data('pos');
+        if (q < w) {
+          return 1;
+        }
+        if (q > w) {
+          return -1;
+        }
+        return 0;
+      });
+      parent = pkts.eq(0).parent();
+      _results = [];
+      for (_i = 0, _len = pkts.length; _i < _len; _i++) {
+        p = pkts[_i];
+        _results.push(parent.prepend(p));
+      }
+      return _results;
+    };
+
+    Uporzadkuj.prototype.get_answer = function(question) {
+      var answer,
+        _this = this;
+      answer = [];
+      $(".question-piece", this.element).each(function(i, qpiece) {
+        return answer.push($(qpiece).attr('data-pos'));
+      });
+      return answer;
+    };
+
+    return Uporzadkuj;
+
+  })(Exercise);
+
+  Luki = (function(_super) {
+    __extends(Luki, _super);
+
+    function Luki(element) {
+      Luki.__super__.constructor.call(this, element);
+      this.dragging(false, false);
+    }
+
+    Luki.prototype.check = function() {
+      var all, bad, correct,
+        _this = this;
+      all = $(".placeholder", this.element).length;
+      correct = 0;
+      bad = 0;
+      $(".placeholder + .question-piece", this.element).each(function(i, qpiece) {
+        var $placeholder;
+        $placeholder = $(qpiece).prev(".placeholder");
+        if ($placeholder.data('solution') === $(qpiece).data('no')) {
+          _this.piece_correct(qpiece);
+          return correct += 1;
+        } else {
+          bad += 1;
+          return _this.piece_incorrect(qpiece);
+        }
+      });
+      return this.show_score([correct, bad, all]);
+    };
+
+    Luki.prototype.solve_question = function(question) {
+      var _this = this;
+      return $(".placeholder", question).each(function(i, placeholder) {
+        var $qp;
+        $qp = $(".question-piece[data-no=" + $(placeholder).data('solution') + "]", question);
+        return _this.draggable_move($qp, $(placeholder), false);
+      });
+    };
+
+    return Luki;
+
+  })(Exercise);
+
+  Zastap = (function(_super) {
+    __extends(Zastap, _super);
+
+    function Zastap(element) {
+      var _this = this;
+      Zastap.__super__.constructor.call(this, element);
+      $(".paragraph", this.element).each(function(i, par) {
+        return _this.wrap_words($(par), $('<span class="placeholder zastap"/>'));
+      });
+      this.dragging(false, false);
+    }
+
+    Zastap.prototype.check = function() {
+      var all, bad, correct,
+        _this = this;
+      all = 0;
+      correct = 0;
+      bad = 0;
+      $(".paragraph", this.element).each(function(i, par) {
+        return $(".placeholder", par).each(function(j, qpiece) {
+          var $dragged, $qp;
+          $qp = $(qpiece);
+          $dragged = $qp.next(".draggable");
+          if ($qp.data("solution")) {
+            if ($dragged && $qp.data("solution") === $dragged.data("no")) {
+              _this.piece_correct($dragged);
+              correct += 1;
+            }
+            return all += 1;
+          }
+        });
+      });
+      return this.show_score([correct, bad, all]);
+    };
+
+    Zastap.prototype.show_solutions = function() {
+      var _this = this;
+      this.reset();
+      return $(".paragraph", this.element).each(function(i, par) {
+        return $(".placeholder[data-solution]", par).each(function(j, qpiece) {
+          var $dr, $qp;
+          $qp = $(qpiece);
+          $dr = $(".draggable[data-no=" + $qp.data('solution') + "]", _this.element);
+          return _this.draggable_move($dr, $qp, false);
+        });
+      });
+    };
+
+    Zastap.prototype.wrap_words = function(element, wrapper) {
+      var chld, i, ignore, insertWrapped, j, len, space, wordb, _i, _ref, _results;
+      ignore = /^[ \t.,:;()]+/;
+      insertWrapped = function(txt, elem) {
+        var nw;
+        nw = wrapper.clone();
+        return $(document.createTextNode(txt)).wrap(nw).parent().attr("data-original", txt).insertBefore(elem);
+      };
+      _results = [];
+      for (j = _i = _ref = element.get(0).childNodes.length - 1; _ref <= 0 ? _i <= 0 : _i >= 0; j = _ref <= 0 ? ++_i : --_i) {
+        chld = element.get(0).childNodes[j];
+        if (chld.nodeType === document.TEXT_NODE) {
+          len = chld.textContent.length;
+          wordb = 0;
+          i = 0;
+          while (i < len) {
+            space = ignore.exec(chld.textContent.substr(i));
+            if (space != null) {
+              if (wordb < i) {
+                insertWrapped(chld.textContent.substr(wordb, i - wordb), chld);
+              }
+              $(document.createTextNode(space[0])).insertBefore(chld);
+              i += space[0].length;
+              wordb = i;
+            } else {
+              i = i + 1;
+            }
+          }
+          if (wordb < len - 1) {
+            insertWrapped(chld.textContent.substr(wordb, len - 1 - wordb), chld);
+          }
+          _results.push($(chld).remove());
+        } else {
+          _results.push(void 0);
+        }
+      }
+      return _results;
+    };
+
+    return Zastap;
+
+  })(Exercise);
+
+  Przyporzadkuj = (function(_super) {
+    __extends(Przyporzadkuj, _super);
+
+    Przyporzadkuj.prototype.is_multiple = function() {
+      var qp, _i, _len, _ref;
+      _ref = $(".question-piece", this.element);
+      for (_i = 0, _len = _ref.length; _i < _len; _i++) {
+        qp = _ref[_i];
+        if ($(qp).attr('data-solution').split(/[ ,]+/).length > 1) {
+          return true;
+        }
+      }
+      return false;
+    };
+
+    function Przyporzadkuj(element) {
+      Przyporzadkuj.__super__.constructor.call(this, element);
+      this.multiple = this.is_multiple();
+      this.dragging(this.multiple, true);
+    }
+
+    Przyporzadkuj.prototype.draggable_equal = function(d1, d2) {
+      return d1.data("no") === d2.data("no");
+    };
+
+    Przyporzadkuj.prototype.draggable_accept = function($draggable, $droppable) {
+      var dropped;
+      dropped = $droppable.closest("ul, ol").find(".draggable");
+      return (Przyporzadkuj.__super__.draggable_accept.call(this, $draggable, $droppable)) && dropped.length === 0;
+    };
+
+    Przyporzadkuj.prototype.check_question = function(question) {
+      var all, bad_count, count, mandatory, minimum, optional, pn, pred, qp, self, v, _i, _j, _len, _len1, _ref, _ref1;
+      minimum = $(question).data("minimum");
+      count = 0;
+      bad_count = 0;
+      all = 0;
+      if (!minimum) {
+        self = this;
+        $(".subject .question-piece", question).each(function(i, el) {
+          var mandatory, v;
+          v = self.get_value_optional_list(el, 'solution');
+          mandatory = v[0];
+          return all += mandatory.length;
+        });
+      }
+      _ref = $(".predicate [data-predicate]", question);
+      for (_i = 0, _len = _ref.length; _i < _len; _i++) {
+        pred = _ref[_i];
+        pn = $(pred).attr('data-predicate');
+        _ref1 = $(".question-piece", pred);
+        for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) {
+          qp = _ref1[_j];
+          v = this.get_value_optional_list(qp, 'solution');
+          mandatory = v[0];
+          optional = v[1];
+          if (mandatory.indexOf(pn) >= 0 || (minimum && optional.indexOf(pn) >= 0)) {
+            count += 1;
+            this.piece_correct(qp);
+          } else {
+            bad_count += 1;
+            this.piece_incorrect(qp);
+          }
+        }
+      }
+      return [count, bad_count, all];
+    };
+
+    Przyporzadkuj.prototype.solve_question = function(question) {
+      var $ph, $pr, draggables, m, mandatory, minimum, optional, qp, v, _i, _len, _ref, _results;
+      minimum = $(question).data("min");
+      _ref = $(".subject .question-piece", question);
+      _results = [];
+      for (_i = 0, _len = _ref.length; _i < _len; _i++) {
+        qp = _ref[_i];
+        v = this.get_value_optional_list(qp, 'solution');
+        mandatory = v[0];
+        optional = v[1];
+        if (minimum) {
+          draggables = mandatory.count(optional).slice(0, minimum);
+        } else {
+          draggables = mandatory;
+        }
+        _results.push((function() {
+          var _j, _len1, _results1;
+          _results1 = [];
+          for (_j = 0, _len1 = draggables.length; _j < _len1; _j++) {
+            m = draggables[_j];
+            $pr = $(".predicate [data-predicate=" + m + "]", question);
+            $ph = $pr.find(".placeholder:visible");
+            _results1.push(this.draggable_move($(qp), $ph.eq(0), this.multiple));
+          }
+          return _results1;
+        }).call(this));
+      }
+      return _results;
+    };
+
+    Przyporzadkuj.prototype.get_answer = function(question) {
+      var answer,
+        _this = this;
+      answer = {};
+      $(".predicate [data-predicate]", question).each(function(i, subjects) {
+        var predicate;
+        predicate = $(subjects).attr('data-predicate');
+        answer[predicate] = [];
+        return $('.question-piece', subjects).each(function(i, qpiece) {
+          var $qpiece;
+          $qpiece = $(qpiece);
+          return answer[predicate].push($qpiece.attr('data-id'));
+        });
+      });
+      return answer;
+    };
+
+    return Przyporzadkuj;
+
+  })(Exercise);
+
+  PrawdaFalsz = (function(_super) {
+    __extends(PrawdaFalsz, _super);
+
+    function PrawdaFalsz(element) {
+      var qp, _i, _len, _ref,
+        _this = this;
+      PrawdaFalsz.__super__.constructor.call(this, element);
+      _ref = $(".question-piece", this.element);
+      for (_i = 0, _len = _ref.length; _i < _len; _i++) {
+        qp = _ref[_i];
+        $(".true", qp).click(function(ev) {
+          ev.preventDefault();
+          _this.retry();
+          $(ev.target).closest(".question-piece").data("value", "true");
+          return $(ev.target).addClass('chosen').siblings('a').removeClass('chosen');
+        });
+        $(".false", qp).click(function(ev) {
+          ev.preventDefault();
+          _this.retry();
+          $(ev.target).closest(".question-piece").data("value", "false");
+          return $(ev.target).addClass('chosen').siblings('a').removeClass('chosen');
+        });
+      }
+    }
+
+    PrawdaFalsz.prototype.check_question = function() {
+      var all, bad, good, qp, _i, _len, _ref;
+      all = 0;
+      good = 0;
+      bad = 0;
+      _ref = $(".question-piece", this.element);
+      for (_i = 0, _len = _ref.length; _i < _len; _i++) {
+        qp = _ref[_i];
+        if ($(qp).data("solution").toString() === $(qp).data("value")) {
+          good += 1;
+          this.piece_correct(qp);
+        } else {
+          bad += 1;
+          this.piece_incorrect(qp);
+        }
+        all += 1;
+      }
+      return [good, bad, all];
+    };
+
+    PrawdaFalsz.prototype.show_solutions = function() {
+      var qp, _i, _len, _ref, _results;
+      this.reset();
+      _ref = $(".question-piece", this.element);
+      _results = [];
+      for (_i = 0, _len = _ref.length; _i < _len; _i++) {
+        qp = _ref[_i];
+        if ($(qp).data('solution') === true) {
+          _results.push($(".true", qp).click());
+        } else {
+          _results.push($(".false", qp).click());
+        }
+      }
+      return _results;
+    };
+
+    PrawdaFalsz.prototype.get_answer = function(question) {
+      var answer,
+        _this = this;
+      answer = [];
+      $(".question-piece", this.element).each(function(i, qpiece) {
+        return answer.push($(qpiece).data('value') || '-');
+      });
+      return answer;
+    };
+
+    return PrawdaFalsz;
+
+  })(Exercise);
+
+  exercise = function(ele) {
+    var cls, es;
+    es = {
+      wybor: Wybor,
+      uporzadkuj: Uporzadkuj,
+      luki: Luki,
+      zastap: Zastap,
+      przyporzadkuj: Przyporzadkuj,
+      prawdafalsz: PrawdaFalsz
+    };
+    cls = es[$(ele).attr('data-type')];
+    return new cls(ele);
+  };
+
+  window.edumed = {
+    'EduModule': EduModule
+  };
+
+  $(document).ready(function() {
+    new EduModule($("#book-text"));
+    return $(".exercise").each(function(i, el) {
+      return exercise(this);
+    });
+  });
+
+}).call(this);
diff --git a/src/wtem/static/wtem/img/1.png b/src/wtem/static/wtem/img/1.png
new file mode 100644 (file)
index 0000000..48e5969
Binary files /dev/null and b/src/wtem/static/wtem/img/1.png differ
diff --git a/src/wtem/static/wtem/img/1_small.png b/src/wtem/static/wtem/img/1_small.png
new file mode 100644 (file)
index 0000000..7364241
Binary files /dev/null and b/src/wtem/static/wtem/img/1_small.png differ
diff --git a/src/wtem/static/wtem/img/2.png b/src/wtem/static/wtem/img/2.png
new file mode 100644 (file)
index 0000000..7256587
Binary files /dev/null and b/src/wtem/static/wtem/img/2.png differ
diff --git a/src/wtem/static/wtem/img/2_small.png b/src/wtem/static/wtem/img/2_small.png
new file mode 100644 (file)
index 0000000..8d7e31e
Binary files /dev/null and b/src/wtem/static/wtem/img/2_small.png differ
diff --git a/src/wtem/static/wtem/img/3.png b/src/wtem/static/wtem/img/3.png
new file mode 100644 (file)
index 0000000..0d027d5
Binary files /dev/null and b/src/wtem/static/wtem/img/3.png differ
diff --git a/src/wtem/static/wtem/img/3_small.png b/src/wtem/static/wtem/img/3_small.png
new file mode 100644 (file)
index 0000000..d66ecda
Binary files /dev/null and b/src/wtem/static/wtem/img/3_small.png differ
diff --git a/src/wtem/static/wtem/img/komunikat_policyjny.png b/src/wtem/static/wtem/img/komunikat_policyjny.png
new file mode 100644 (file)
index 0000000..7549634
Binary files /dev/null and b/src/wtem/static/wtem/img/komunikat_policyjny.png differ
diff --git a/src/wtem/static/wtem/img/krrit_zrzut_ekranu.png b/src/wtem/static/wtem/img/krrit_zrzut_ekranu.png
new file mode 100644 (file)
index 0000000..5ae4423
Binary files /dev/null and b/src/wtem/static/wtem/img/krrit_zrzut_ekranu.png differ
diff --git a/src/wtem/static/wtem/img/przyp/1.jpg b/src/wtem/static/wtem/img/przyp/1.jpg
new file mode 100644 (file)
index 0000000..7eba4d8
Binary files /dev/null and b/src/wtem/static/wtem/img/przyp/1.jpg differ
diff --git a/src/wtem/static/wtem/img/przyp/2.jpg b/src/wtem/static/wtem/img/przyp/2.jpg
new file mode 100644 (file)
index 0000000..c529dd4
Binary files /dev/null and b/src/wtem/static/wtem/img/przyp/2.jpg differ
diff --git a/src/wtem/static/wtem/img/przyp/3.jpg b/src/wtem/static/wtem/img/przyp/3.jpg
new file mode 100644 (file)
index 0000000..69c2b53
Binary files /dev/null and b/src/wtem/static/wtem/img/przyp/3.jpg differ
diff --git a/src/wtem/static/wtem/img/przyp/4.jpg b/src/wtem/static/wtem/img/przyp/4.jpg
new file mode 100644 (file)
index 0000000..e4557cb
Binary files /dev/null and b/src/wtem/static/wtem/img/przyp/4.jpg differ
diff --git a/src/wtem/static/wtem/img/przyp/5.jpg b/src/wtem/static/wtem/img/przyp/5.jpg
new file mode 100644 (file)
index 0000000..3698534
Binary files /dev/null and b/src/wtem/static/wtem/img/przyp/5.jpg differ
diff --git a/src/wtem/static/wtem/img/przyp2/1.jpg b/src/wtem/static/wtem/img/przyp2/1.jpg
new file mode 100644 (file)
index 0000000..9879cb9
Binary files /dev/null and b/src/wtem/static/wtem/img/przyp2/1.jpg differ
diff --git a/src/wtem/static/wtem/img/przyp2/2.jpg b/src/wtem/static/wtem/img/przyp2/2.jpg
new file mode 100644 (file)
index 0000000..4157d81
Binary files /dev/null and b/src/wtem/static/wtem/img/przyp2/2.jpg differ
diff --git a/src/wtem/static/wtem/img/przyp2/3.jpg b/src/wtem/static/wtem/img/przyp2/3.jpg
new file mode 100644 (file)
index 0000000..05dc855
Binary files /dev/null and b/src/wtem/static/wtem/img/przyp2/3.jpg differ
diff --git a/src/wtem/static/wtem/img/przyp2/4.jpg b/src/wtem/static/wtem/img/przyp2/4.jpg
new file mode 100644 (file)
index 0000000..f0b4b12
Binary files /dev/null and b/src/wtem/static/wtem/img/przyp2/4.jpg differ
diff --git a/src/wtem/static/wtem/img/przyp2/5.jpg b/src/wtem/static/wtem/img/przyp2/5.jpg
new file mode 100644 (file)
index 0000000..38e92cd
Binary files /dev/null and b/src/wtem/static/wtem/img/przyp2/5.jpg differ
diff --git a/src/wtem/static/wtem/json2.js b/src/wtem/static/wtem/json2.js
new file mode 100644 (file)
index 0000000..d89ecc7
--- /dev/null
@@ -0,0 +1,486 @@
+/*
+    json2.js
+    2013-05-26
+
+    Public Domain.
+
+    NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.
+
+    See http://www.JSON.org/js.html
+
+
+    This code should be minified before deployment.
+    See http://javascript.crockford.com/jsmin.html
+
+    USE YOUR OWN COPY. IT IS EXTREMELY UNWISE TO LOAD CODE FROM SERVERS YOU DO
+    NOT CONTROL.
+
+
+    This file creates a global JSON object containing two methods: stringify
+    and parse.
+
+        JSON.stringify(value, replacer, space)
+            value       any JavaScript value, usually an object or array.
+
+            replacer    an optional parameter that determines how object
+                        values are stringified for objects. It can be a
+                        function or an array of strings.
+
+            space       an optional parameter that specifies the indentation
+                        of nested structures. If it is omitted, the text will
+                        be packed without extra whitespace. If it is a number,
+                        it will specify the number of spaces to indent at each
+                        level. If it is a string (such as '\t' or '&nbsp;'),
+                        it contains the characters used to indent at each level.
+
+            This method produces a JSON text from a JavaScript value.
+
+            When an object value is found, if the object contains a toJSON
+            method, its toJSON method will be called and the result will be
+            stringified. A toJSON method does not serialize: it returns the
+            value represented by the name/value pair that should be serialized,
+            or undefined if nothing should be serialized. The toJSON method
+            will be passed the key associated with the value, and this will be
+            bound to the value
+
+            For example, this would serialize Dates as ISO strings.
+
+                Date.prototype.toJSON = function (key) {
+                    function f(n) {
+                        // Format integers to have at least two digits.
+                        return n < 10 ? '0' + n : n;
+                    }
+
+                    return this.getUTCFullYear()   + '-' +
+                         f(this.getUTCMonth() + 1) + '-' +
+                         f(this.getUTCDate())      + 'T' +
+                         f(this.getUTCHours())     + ':' +
+                         f(this.getUTCMinutes())   + ':' +
+                         f(this.getUTCSeconds())   + 'Z';
+                };
+
+            You can provide an optional replacer method. It will be passed the
+            key and value of each member, with this bound to the containing
+            object. The value that is returned from your method will be
+            serialized. If your method returns undefined, then the member will
+            be excluded from the serialization.
+
+            If the replacer parameter is an array of strings, then it will be
+            used to select the members to be serialized. It filters the results
+            such that only members with keys listed in the replacer array are
+            stringified.
+
+            Values that do not have JSON representations, such as undefined or
+            functions, will not be serialized. Such values in objects will be
+            dropped; in arrays they will be replaced with null. You can use
+            a replacer function to replace those with JSON values.
+            JSON.stringify(undefined) returns undefined.
+
+            The optional space parameter produces a stringification of the
+            value that is filled with line breaks and indentation to make it
+            easier to read.
+
+            If the space parameter is a non-empty string, then that string will
+            be used for indentation. If the space parameter is a number, then
+            the indentation will be that many spaces.
+
+            Example:
+
+            text = JSON.stringify(['e', {pluribus: 'unum'}]);
+            // text is '["e",{"pluribus":"unum"}]'
+
+
+            text = JSON.stringify(['e', {pluribus: 'unum'}], null, '\t');
+            // text is '[\n\t"e",\n\t{\n\t\t"pluribus": "unum"\n\t}\n]'
+
+            text = JSON.stringify([new Date()], function (key, value) {
+                return this[key] instanceof Date ?
+                    'Date(' + this[key] + ')' : value;
+            });
+            // text is '["Date(---current time---)"]'
+
+
+        JSON.parse(text, reviver)
+            This method parses a JSON text to produce an object or array.
+            It can throw a SyntaxError exception.
+
+            The optional reviver parameter is a function that can filter and
+            transform the results. It receives each of the keys and values,
+            and its return value is used instead of the original value.
+            If it returns what it received, then the structure is not modified.
+            If it returns undefined then the member is deleted.
+
+            Example:
+
+            // Parse the text. Values that look like ISO date strings will
+            // be converted to Date objects.
+
+            myData = JSON.parse(text, function (key, value) {
+                var a;
+                if (typeof value === 'string') {
+                    a =
+/^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}(?:\.\d*)?)Z$/.exec(value);
+                    if (a) {
+                        return new Date(Date.UTC(+a[1], +a[2] - 1, +a[3], +a[4],
+                            +a[5], +a[6]));
+                    }
+                }
+                return value;
+            });
+
+            myData = JSON.parse('["Date(09/09/2001)"]', function (key, value) {
+                var d;
+                if (typeof value === 'string' &&
+                        value.slice(0, 5) === 'Date(' &&
+                        value.slice(-1) === ')') {
+                    d = new Date(value.slice(5, -1));
+                    if (d) {
+                        return d;
+                    }
+                }
+                return value;
+            });
+
+
+    This is a reference implementation. You are free to copy, modify, or
+    redistribute.
+*/
+
+/*jslint evil: true, regexp: true */
+
+/*members "", "\b", "\t", "\n", "\f", "\r", "\"", JSON, "\\", apply,
+    call, charCodeAt, getUTCDate, getUTCFullYear, getUTCHours,
+    getUTCMinutes, getUTCMonth, getUTCSeconds, hasOwnProperty, join,
+    lastIndex, length, parse, prototype, push, replace, slice, stringify,
+    test, toJSON, toString, valueOf
+*/
+
+
+// Create a JSON object only if one does not already exist. We create the
+// methods in a closure to avoid creating global variables.
+
+if (typeof JSON !== 'object') {
+    JSON = {};
+}
+
+(function () {
+    'use strict';
+
+    function f(n) {
+        // Format integers to have at least two digits.
+        return n < 10 ? '0' + n : n;
+    }
+
+    if (typeof Date.prototype.toJSON !== 'function') {
+
+        Date.prototype.toJSON = function () {
+
+            return isFinite(this.valueOf())
+                ? this.getUTCFullYear()     + '-' +
+                    f(this.getUTCMonth() + 1) + '-' +
+                    f(this.getUTCDate())      + 'T' +
+                    f(this.getUTCHours())     + ':' +
+                    f(this.getUTCMinutes())   + ':' +
+                    f(this.getUTCSeconds())   + 'Z'
+                : null;
+        };
+
+        String.prototype.toJSON      =
+            Number.prototype.toJSON  =
+            Boolean.prototype.toJSON = function () {
+                return this.valueOf();
+            };
+    }
+
+    var cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
+        escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
+        gap,
+        indent,
+        meta = {    // table of character substitutions
+            '\b': '\\b',
+            '\t': '\\t',
+            '\n': '\\n',
+            '\f': '\\f',
+            '\r': '\\r',
+            '"' : '\\"',
+            '\\': '\\\\'
+        },
+        rep;
+
+
+    function quote(string) {
+
+// If the string contains no control characters, no quote characters, and no
+// backslash characters, then we can safely slap some quotes around it.
+// Otherwise we must also replace the offending characters with safe escape
+// sequences.
+
+        escapable.lastIndex = 0;
+        return escapable.test(string) ? '"' + string.replace(escapable, function (a) {
+            var c = meta[a];
+            return typeof c === 'string'
+                ? c
+                : '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
+        }) + '"' : '"' + string + '"';
+    }
+
+
+    function str(key, holder) {
+
+// Produce a string from holder[key].
+
+        var i,          // The loop counter.
+            k,          // The member key.
+            v,          // The member value.
+            length,
+            mind = gap,
+            partial,
+            value = holder[key];
+
+// If the value has a toJSON method, call it to obtain a replacement value.
+
+        if (value && typeof value === 'object' &&
+                typeof value.toJSON === 'function') {
+            value = value.toJSON(key);
+        }
+
+// If we were called with a replacer function, then call the replacer to
+// obtain a replacement value.
+
+        if (typeof rep === 'function') {
+            value = rep.call(holder, key, value);
+        }
+
+// What happens next depends on the value's type.
+
+        switch (typeof value) {
+        case 'string':
+            return quote(value);
+
+        case 'number':
+
+// JSON numbers must be finite. Encode non-finite numbers as null.
+
+            return isFinite(value) ? String(value) : 'null';
+
+        case 'boolean':
+        case 'null':
+
+// If the value is a boolean or null, convert it to a string. Note:
+// typeof null does not produce 'null'. The case is included here in
+// the remote chance that this gets fixed someday.
+
+            return String(value);
+
+// If the type is 'object', we might be dealing with an object or an array or
+// null.
+
+        case 'object':
+
+// Due to a specification blunder in ECMAScript, typeof null is 'object',
+// so watch out for that case.
+
+            if (!value) {
+                return 'null';
+            }
+
+// Make an array to hold the partial results of stringifying this object value.
+
+            gap += indent;
+            partial = [];
+
+// Is the value an array?
+
+            if (Object.prototype.toString.apply(value) === '[object Array]') {
+
+// The value is an array. Stringify every element. Use null as a placeholder
+// for non-JSON values.
+
+                length = value.length;
+                for (i = 0; i < length; i += 1) {
+                    partial[i] = str(i, value) || 'null';
+                }
+
+// Join all of the elements together, separated with commas, and wrap them in
+// brackets.
+
+                v = partial.length === 0
+                    ? '[]'
+                    : gap
+                    ? '[\n' + gap + partial.join(',\n' + gap) + '\n' + mind + ']'
+                    : '[' + partial.join(',') + ']';
+                gap = mind;
+                return v;
+            }
+
+// If the replacer is an array, use it to select the members to be stringified.
+
+            if (rep && typeof rep === 'object') {
+                length = rep.length;
+                for (i = 0; i < length; i += 1) {
+                    if (typeof rep[i] === 'string') {
+                        k = rep[i];
+                        v = str(k, value);
+                        if (v) {
+                            partial.push(quote(k) + (gap ? ': ' : ':') + v);
+                        }
+                    }
+                }
+            } else {
+
+// Otherwise, iterate through all of the keys in the object.
+
+                for (k in value) {
+                    if (Object.prototype.hasOwnProperty.call(value, k)) {
+                        v = str(k, value);
+                        if (v) {
+                            partial.push(quote(k) + (gap ? ': ' : ':') + v);
+                        }
+                    }
+                }
+            }
+
+// Join all of the member texts together, separated with commas,
+// and wrap them in braces.
+
+            v = partial.length === 0
+                ? '{}'
+                : gap
+                ? '{\n' + gap + partial.join(',\n' + gap) + '\n' + mind + '}'
+                : '{' + partial.join(',') + '}';
+            gap = mind;
+            return v;
+        }
+    }
+
+// If the JSON object does not yet have a stringify method, give it one.
+
+    if (typeof JSON.stringify !== 'function') {
+        JSON.stringify = function (value, replacer, space) {
+
+// The stringify method takes a value and an optional replacer, and an optional
+// space parameter, and returns a JSON text. The replacer can be a function
+// that can replace values, or an array of strings that will select the keys.
+// A default replacer method can be provided. Use of the space parameter can
+// produce text that is more easily readable.
+
+            var i;
+            gap = '';
+            indent = '';
+
+// If the space parameter is a number, make an indent string containing that
+// many spaces.
+
+            if (typeof space === 'number') {
+                for (i = 0; i < space; i += 1) {
+                    indent += ' ';
+                }
+
+// If the space parameter is a string, it will be used as the indent string.
+
+            } else if (typeof space === 'string') {
+                indent = space;
+            }
+
+// If there is a replacer, it must be a function or an array.
+// Otherwise, throw an error.
+
+            rep = replacer;
+            if (replacer && typeof replacer !== 'function' &&
+                    (typeof replacer !== 'object' ||
+                    typeof replacer.length !== 'number')) {
+                throw new Error('JSON.stringify');
+            }
+
+// Make a fake root object containing our value under the key of ''.
+// Return the result of stringifying the value.
+
+            return str('', {'': value});
+        };
+    }
+
+
+// If the JSON object does not yet have a parse method, give it one.
+
+    if (typeof JSON.parse !== 'function') {
+        JSON.parse = function (text, reviver) {
+
+// The parse method takes a text and an optional reviver function, and returns
+// a JavaScript value if the text is a valid JSON text.
+
+            var j;
+
+            function walk(holder, key) {
+
+// The walk method is used to recursively walk the resulting structure so
+// that modifications can be made.
+
+                var k, v, value = holder[key];
+                if (value && typeof value === 'object') {
+                    for (k in value) {
+                        if (Object.prototype.hasOwnProperty.call(value, k)) {
+                            v = walk(value, k);
+                            if (v !== undefined) {
+                                value[k] = v;
+                            } else {
+                                delete value[k];
+                            }
+                        }
+                    }
+                }
+                return reviver.call(holder, key, value);
+            }
+
+
+// Parsing happens in four stages. In the first stage, we replace certain
+// Unicode characters with escape sequences. JavaScript handles many characters
+// incorrectly, either silently deleting them, or treating them as line endings.
+
+            text = String(text);
+            cx.lastIndex = 0;
+            if (cx.test(text)) {
+                text = text.replace(cx, function (a) {
+                    return '\\u' +
+                        ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
+                });
+            }
+
+// In the second stage, we run the text against regular expressions that look
+// for non-JSON patterns. We are especially concerned with '()' and 'new'
+// because they can cause invocation, and '=' because it can cause mutation.
+// But just to be safe, we want to reject all unexpected forms.
+
+// We split the second stage into 4 regexp operations in order to work around
+// crippling inefficiencies in IE's and Safari's regexp engines. First we
+// replace the JSON backslash pairs with '@' (a non-JSON character). Second, we
+// replace all simple value tokens with ']' characters. Third, we delete all
+// open brackets that follow a colon or comma or that begin the text. Finally,
+// we look to see that the remaining characters are only whitespace or ']' or
+// ',' or ':' or '{' or '}'. If that is so, then the text is safe for eval.
+
+            if (/^[\],:{}\s]*$/
+                    .test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@')
+                        .replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']')
+                        .replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) {
+
+// In the third stage we use the eval function to compile the text into a
+// JavaScript structure. The '{' operator is subject to a syntactic ambiguity
+// in JavaScript: it can begin a block or an object literal. We wrap the text
+// in parens to eliminate the ambiguity.
+
+                j = eval('(' + text + ')');
+
+// In the optional fourth stage, we recursively walk the new structure, passing
+// each name/value pair to a reviver function for possible transformation.
+
+                return typeof reviver === 'function'
+                    ? walk({'': j}, '')
+                    : j;
+            }
+
+// If the text is not JSON parseable, then a SyntaxError is thrown.
+
+            throw new SyntaxError('JSON.parse');
+        };
+    }
+}());
diff --git a/src/wtem/static/wtem/spinner.gif b/src/wtem/static/wtem/spinner.gif
new file mode 100644 (file)
index 0000000..ec0ad80
Binary files /dev/null and b/src/wtem/static/wtem/spinner.gif differ
diff --git a/src/wtem/static/wtem/wtem.js b/src/wtem/static/wtem/wtem.js
new file mode 100644 (file)
index 0000000..e481b92
--- /dev/null
@@ -0,0 +1,75 @@
+$(function() {
+
+    var to_submit;
+
+    $('form').submit(function(e) {
+        //e.preventDefault();
+        to_submit = {};
+        spinner.show();
+
+        $('.exercise-wtem').each(function() {
+            var el = $(this);
+            if(el.hasClass('exercise')) {
+                handlers.edumed(el);
+            } else {
+                var type = el.attr('data-type');
+                if(handlers[type]) {
+                    handlers[type](el);
+                }
+            }
+        });
+        $('input[name=answers]').val(JSON.stringify(to_submit));
+    });
+
+    var push_answer = function(el, answer) {
+        to_submit[el.attr('data-id')] = answer
+    };
+
+    var handlers = {
+        edumed: function(el) {
+            var exercise = el.data('exercise'),
+                to_push = {},
+                open_part;
+            if(exercise.get_answers) {
+                to_push.closed_part = exercise.get_answers()[0];
+            }
+            open_part = el.find('.open_part')
+            if(open_part.length) {
+                to_push.open_part = open_part.find('textarea').val();
+            }
+
+            push_answer(el, to_push);
+        },
+
+        open: function(el) {
+            var textareas = el.find('textarea'),
+                to_push;
+            if(textareas.length === 1) {
+                to_push = el.find('textarea').val();
+            } else {
+                to_push = [];
+                textareas.each(function() {
+                    var textarea = $(this);
+                    to_push.push({'id': textarea.attr('data-field-id'), 'text': textarea.val()});
+                });
+            }
+            push_answer(el, to_push);
+        }
+    }
+
+    var sms_handler = function() {
+        var textarea = $(this),
+            label_suffix = textarea.parent().find('.label_suffix'),
+            left = 140 - textarea.val().length;
+            to_insert = '(pozostało: ' + left + ')';
+        if(left < 0) {
+            to_insert = '<span style="color:red">' + to_insert + '</span>';
+        }
+        label_suffix.html(to_insert);
+    };
+
+    $('#wtem_sms').change(sms_handler).keyup(sms_handler);
+
+    var spinner = $('.wtem_spinner');
+    spinner.hide();
+});
\ No newline at end of file
diff --git a/src/wtem/templates/admin/wtem/submission/change_list.html b/src/wtem/templates/admin/wtem/submission/change_list.html
new file mode 100644 (file)
index 0000000..e73e9bc
--- /dev/null
@@ -0,0 +1,24 @@
+{% extends "admin/change_list.html" %}
+{% load i18n %}
+{% load admin_urls %}
+
+
+{% block object-tools-items %}
+    {{block.super}}
+    <li>
+        <a href="{% url 'admin:wtem_admin_report' %}">
+            Wyniki w CSV
+        </a>
+    </li>
+{% endblock %}
+
+{% block result_list %}
+    {% if examiners %}
+        <p>
+        {% for examiner in examiners %}
+            {{examiner.name}}: {{examiner.todo}} {% if not forloop.last %}, {% endif %}
+        {% endfor %}
+    </p>
+    {% endif %}
+    {{block.super}}
+{% endblock %}
\ No newline at end of file
diff --git a/src/wtem/templates/wtem/admin_report.csv b/src/wtem/templates/wtem/admin_report.csv
new file mode 100644 (file)
index 0000000..c6ef91f
--- /dev/null
@@ -0,0 +1,2 @@
+{% load wtem_csv %}email,nazwisko,imie,suma{% for exercise_id in exercise_ids %}{% csv_header exercise_id submissionsSet %}{% endfor %}{% for submission in submissionsSet.submissions %}
+{{submission.email}},{{submission.last_name}},{{submission.first_name}},{{submission.final_result_as_string}}{% for exercise_id in exercise_ids %},{% csv_row_fragment exercise_id submission submissionsSet %}{% endfor %}{% endfor %}
\ No newline at end of file
diff --git a/src/wtem/templates/wtem/disabled_contact_form.html b/src/wtem/templates/wtem/disabled_contact_form.html
new file mode 100644 (file)
index 0000000..6ce8f45
--- /dev/null
@@ -0,0 +1,13 @@
+{% extends "base.html" %}
+
+{% block title %}{{ title }}{% endblock %}
+
+{% block body %}
+
+    <h1>{{ title }}</h1>
+
+    {% block contact_form_description %}
+    <p class="notice">Rejestracja uczestników została zamknięta.</p>
+    {% endblock %}
+
+{% endblock %}
diff --git a/src/wtem/templates/wtem/email_key.txt b/src/wtem/templates/wtem/email_key.txt
new file mode 100644 (file)
index 0000000..3a1da0d
--- /dev/null
@@ -0,0 +1,15 @@
+Poniżej znajduje się wygenerowany specjalnie dla Ciebie link, pod którym będziesz mogła rozwiązać zadania w ramach egzaminu dla Warszawskich liderek Edukacji medialnej.
+
+https://edukacjamedialna.edu.pl{% url 'wtem_form' key=submission.key %}
+
+Egzamin rozpocznie się w piątek, 14 października i potrwa do 30 października. Aby rozwiązać test, potrzebny Ci będzie komputer ze stabilnym łączem internetowym oraz zainstalowaną i zaktualizowaną przeglądarką.
+Egzamin możesz rozwiązywać w kilku podejściach - pamiętaj, żeby za każdym razem zapisać swoje odpowiedzi (klikając przycisk: Wyślij moje odpowiedzi). Za każdym razem korzystaj z przypisanego Ci linku.
+
+Każda z Was otrzymała indywidualny link, pod którym może rozwiązywać zadania samodzielnie.
+
+W razie dodatkowych pytań możesz kontaktować się ze mną pod adresem barbarakrywoszejew@nowoczesnapolska.org.pl lub numerem telefonu +48 22 465 15 35.
+
+Powodzenia!
+
+Barbara Krywoszejew
+fundacja Nowoczesna Polska
\ No newline at end of file
diff --git a/src/wtem/templates/wtem/email_teacher_before.txt b/src/wtem/templates/wtem/email_teacher_before.txt
new file mode 100644 (file)
index 0000000..bd50ba0
--- /dev/null
@@ -0,0 +1,18 @@
+Szanowni Państwo,
+
+Informujemy, że na podane przez Państwa adresy e-mail uczestników i uczestniczek Wielkiego Turnieju Edukacji Medialnej zostały wysłane indywidualne linki, które pozwolą im przystąpić do I etapu Turnieju.
+
+Uprzejmie prosimy o sprawdzenie, czy wszyscy otrzymali wiadomość z linkiem. Jeśli któryś z uczestników nie otrzymał swojej instrukcji, prosimy o informację na adres edukacjamedialna@nowoczesnapolska.org.pl najpóźniej do poniedziałku 17 listopada do godz. 12.00. Zgłoszenie problemu powinno zawierać:
+* imię, nazwisko, adres e-mail uczestnika, który nie otrzymał wiadomości z linkiem,
+* imię, nazwisko, adres e-mail Opiekuna/Opiekunki (zgodnie z danymi z formularza zgłoszeniowego).
+
+Pierwszy etap Turnieju odbędzie się we wtorek 18 listopada o godz. 16.30. Na rozwiązanie testu uczestnicy będą mieć ok. 90 min. Aby rozwiązać test, potrzebny jest komputer ze stabilnym łączem internetowym oraz zainstalowaną i zaktualizowaną przeglądarką.
+
+Przypominamy, że główną nagrodą w Turnieju jest tygodniowy pobyt na Digital Media Summer Camp na Mercer University w Macon (Georgia, USA).
+
+W razie dodatkowych pytań prosimy kontaktować się z nami pod adresem edukacjamedialna@nowoczesnapolska.org.pl lub pod numerem telefonu +48 22 621-30-17.
+
+Z pozdrowieniami
+
+Zespół Edukacji Medialnej
+fundacja Nowoczesna Polska
\ No newline at end of file
diff --git a/src/wtem/templates/wtem/email_teacher_before_subject.txt b/src/wtem/templates/wtem/email_teacher_before_subject.txt
new file mode 100644 (file)
index 0000000..5649e56
--- /dev/null
@@ -0,0 +1 @@
+Pierwszy etap Wielkiego Turnieju Edukacji Medialnej już wkrótce
\ No newline at end of file
diff --git a/src/wtem/templates/wtem/exercises/edumed_prawdafalsz.html b/src/wtem/templates/wtem/exercises/edumed_prawdafalsz.html
new file mode 100644 (file)
index 0000000..67bf0ae
--- /dev/null
@@ -0,0 +1,26 @@
+<div class="exercise exercise-wtem prawdafalsz" data-type="prawdafalsz" data-id="{{exercise.id}}">
+
+    {% include "wtem/exercises/exercise_no.html" %}
+
+    <div class="question" data-no="1">
+        <div class="description">
+        {% for para in exercise.description %}
+            <p class="paragraph">
+                {{para}}
+            </p>
+        {% endfor %}
+        </div>
+
+        <ul class="lista punkt ">
+            {% for statement in exercise.statements %}
+                <li class="question-piece">
+                    <span class="buttons">
+                        <a href="#" data-value="true" class="true">Prawda</a>
+                        <a href="#" data-value="false" class="false">Fałsz</a>  
+                    </span>
+                    {{statement.0}}
+                </li>
+            {% endfor %}
+        </ul>
+    </div>
+</div>
\ No newline at end of file
diff --git a/src/wtem/templates/wtem/exercises/edumed_przyporzadkuj.html b/src/wtem/templates/wtem/exercises/edumed_przyporzadkuj.html
new file mode 100644 (file)
index 0000000..bdb17af
--- /dev/null
@@ -0,0 +1,85 @@
+<div class="exercise exercise-wtem przyporzadkuj" data-type="przyporzadkuj" data-id="{{exercise.id}}">
+
+    {% include "wtem/exercises/exercise_no.html" %}
+    
+    <div class="question" data-no="1">
+
+        <div class="description">
+        {% for para in exercise.description %}
+            <p class="paragraph">
+                {{para}}
+            </p>
+
+        {% endfor %}
+        </div>
+
+        <p class="paragraph">{{exercise.buckets_name|default:"kategorie"|capfirst}}:</p>
+
+        <ul class="lista punkt predicate" data-name="kategorie">
+            {% for bucket in exercise.buckets %}
+                <li data-predicate="{{bucket.id}}">
+                    {{bucket.title}}
+                    <ul class="subjects">
+                        <li class="placeholder multiple ui-droppable accepting"></li>
+                    </ul>
+                </li>
+            {% endfor %}
+        </ul>
+        <br class="clr">
+
+        <div class="description" style="margin-bottom:10px;">
+            <p class="paragraph">{{exercise.items_name|capfirst}}:</p>
+            {% if not exercise.hide_default_instruction %}
+                <span class="instruction">Przeciągnij i upuść numery odpowiedzi w wybranym polu powyżej.</span>
+            {% endif %}
+            {% if exercise.items_instruction %}
+                <span class="instruction">{{exercise.items_instruction}}</span>
+            {% endif %}
+        </div>
+         
+        <ul class="lista punkt subject {% if exercise.items_inline %}wtem-items-inline{% endif %}" data-target="kategorie">
+            {% for item in exercise.items %}
+                {% comment %}
+                data-solution set to single bogus value only to indicate that this piece has no multiple solutions, not used otherwise (see: is_multiple in edumed.coffee). 
+                {% endcomment %}
+                
+                {% if item.img or item.desc %}
+                    <li style="magin-bottom:5px;">
+                        <span data-solution="1" data-no="{{forloop.counter}}" data-id="{{item.id}}" class="question-piece draggable ui-draggable">{{item.text}}</span>
+                        
+                        {% if item.img %}
+                            {% if item.href %}
+                                <a href="{% if not item.href_absolute %}/static/wtem/img/{% endif %}{{item.href}}" target="wtem_aside">
+                            {% endif %}
+                            
+                            <img src="/static/wtem/img/{{item.img}}"/>
+                            
+                            {% if item.href %}</a>{% endif %}
+                        {% endif %}
+                        {% if item.desc %}
+                            {{item.desc}}
+                        {% endif %}
+                    </li>
+                {% else %}
+                    <li data-solution="1" data-no="{{forloop.counter}}" data-id="{{item.id}}" class="question-piece draggable ui-draggable">{{item.text}}</li>
+                {% endif %}
+            
+            {% endfor %}
+        </ul>
+
+        <br class="clr">
+
+        {% if exercise.description_after %}
+            {% autoescape off %}
+            {% for para in exercise.description_after %}
+                <p class="paragraph">
+                    {{para}}
+                </p>
+            {% endfor %}
+            {% endautoescape %}
+        {% endif %}
+
+    </div>
+
+</div>
+
diff --git a/src/wtem/templates/wtem/exercises/edumed_uporzadkuj.html b/src/wtem/templates/wtem/exercises/edumed_uporzadkuj.html
new file mode 100644 (file)
index 0000000..200271e
--- /dev/null
@@ -0,0 +1,23 @@
+<div class="exercise exercise-wtem uporzadkuj" data-type="uporzadkuj" data-id="{{exercise.id}}">
+
+    {% include "wtem/exercises/exercise_no.html" %}
+
+    <div class="question" data-no="1">
+        <div class="description">
+        {% for para in exercise.description %}
+            <p class="paragraph">
+                {{para}}
+            </p>
+        {% endfor %}
+            <span class="instruction">Kliknij i przytrzymaj wybraną odpowiedź, następnie przeciągnij w nowe miejsce.</span>
+        </div>
+
+        <ol class="lista num ui-sortable">
+            {% for item in exercise.items %}
+                <li class="question-piece" data-pos="{{item.id}}">{{item.text}}</li>
+            {% endfor %}
+        </ol>
+
+    </div>
+</div>
+
diff --git a/src/wtem/templates/wtem/exercises/edumed_wybor.html b/src/wtem/templates/wtem/exercises/edumed_wybor.html
new file mode 100644 (file)
index 0000000..edd9dad
--- /dev/null
@@ -0,0 +1,46 @@
+<div class="exercise exercise-wtem wybor" data-type="wybor" data-id="{{exercise.id}}">
+
+    {% include "wtem/exercises/exercise_no.html" %}
+    {% autoescape off %}
+    <div class="description">
+        {% for para in exercise.description %}
+            <p class="paragraph">
+                {{para}}
+            </p>
+        {% endfor %}
+        {% if exercise.points %}
+            <span class="instruction">
+                {% if exercise.answer|length == 1 %}
+                    Tylko jedna odpowiedź jest prawidłowa.
+                {% else %}
+                    Zaznacz wszystkie prawidłowe odpowiedzi.
+                {% endif %}
+            </span>
+        {% endif %}
+    </div>
+    {% endautoescape %}
+    <div class="question" data-no="1">
+        <ol class="lista num">
+            {% for option in exercise.options %}
+                <li class="question-piece" data-name="{{option.id}}">
+                    <input type="{% if exercise.answer|length == 1 %}radio{% else %}checkbox{% endif %}" name="{% if exercise.answer|length == 1 %}e{{no}}{% else %}e{{no}}_{{option.id}}{% endif %}" id="e{{no}}_{{option.id}}"{% if option.id|stringformat:"s" in exercise.saved_answer.closed_part %} checked="checked"{% endif %}>
+                    <label for="e{{no}}_{{option.id}}">{{option.text}}</label>
+                </li>
+            {% endfor %}
+        </ol>
+    </div>
+
+    {% if exercise.open_part %}
+    <div class="open_part">
+        <div class="description">
+            {% for para in exercise.open_part %}
+                <p class="paragraph">
+                    {{para}}
+                </p>
+            {% endfor %}
+        </div>
+        <textarea style="width: 100%; margin-top:10px;" rows="{{exercise.open_part_rows|default:10}}">{{ exercise.saved_answer.open_part }}</textarea>
+    </div>
+    {% endif %}
+
+</div>
diff --git a/src/wtem/templates/wtem/exercises/exercise_no.html b/src/wtem/templates/wtem/exercises/exercise_no.html
new file mode 100644 (file)
index 0000000..ce394cf
--- /dev/null
@@ -0,0 +1,3 @@
+{% if not exercise.continuation %}
+    <h3>Zadanie {{exercise.id_show|default:exercise.id}} ({{ exercise.max_points }} pkt)</h3>
+{% endif %}
\ No newline at end of file
diff --git a/src/wtem/templates/wtem/exercises/file_upload.html b/src/wtem/templates/wtem/exercises/file_upload.html
new file mode 100644 (file)
index 0000000..b452070
--- /dev/null
@@ -0,0 +1,28 @@
+<div class="exercise-wtem" data-type="file" data-id="{{exercise.id}}">
+
+    {% include "wtem/exercises/exercise_no.html" %}
+
+    <div class="description">
+        {% for para in exercise.description %}
+            <p class="paragraph">
+                {{para}}
+            </p>
+        {% endfor %}
+    </div>
+
+    {% if exercise.max_file_size_string %}
+        <p style="font-weight: bold;">Plik nie powinien być większy niż {{exercise.max_file_size_string}}.</p>
+    {% endif %}
+    <div style="margin: 15px auto; width:300px;">
+        <input style="float: left;" type="file" name="attachment_for_{{exercise.id}}"/>
+        <div style="clear:both;"></div>
+    </div>
+    
+
+    {% autoescape off %}
+    {% for para in exercise.description_after %}
+        <p>{{para}}</p>
+    {% endfor %}
+    {% endautoescape %}
+
+</div>
diff --git a/src/wtem/templates/wtem/exercises/open.html b/src/wtem/templates/wtem/exercises/open.html
new file mode 100644 (file)
index 0000000..c30a5b0
--- /dev/null
@@ -0,0 +1,53 @@
+<div class="exercise-wtem" data-type="open" data-id="{{exercise.id}}">
+
+    {% include "wtem/exercises/exercise_no.html" %}
+
+    <div class="description">
+        {% autoescape off %}
+        {% for para in exercise.description %}
+            <p class="paragraph">
+                {{para}}
+            </p>
+        {% endfor %}
+        {% endautoescape %}
+    </div>
+
+    {% if exercise.instruction %}
+        <span class="instruction">{{ exercise.instruction }}</span>
+    {% endif %}
+
+    {% if exercise.fields %}
+        {% for field in exercise.fields %}
+            <div class="wtem-open-field">
+                <label class="wtem-caption">{{field.caption|safe}} <span class="label_suffix"></span></label>
+                {% if field.type == 'file' %}
+                    <div style="margin: 15px auto; width:300px;">
+                        <input style="float: left;" type="file" name="attachment_for_{{exercise.id}}__{{field.id}}"/>
+                        <div style="clear:both;"></div>
+                    </div>
+                {% else %}
+                    <textarea style="width: 100%;" rows="{{field.rows|default:10}}" data-field-id="{{field.id}}"
+                              {% if field.max_length %}maxlength="{{field.max_length}}"{% endif %}
+                              {% if field.input_id %}id="{{field.input_id}}"{% endif %}>{{ field.saved_answer }}</textarea>
+                {% endif %}
+            </div>
+        {% endfor %}
+    {% else %}
+        <textarea style="width: 100%; margin-top:10px;" rows="{{field.rows|default:10}}"
+                  {% if field.max_length %}maxlength="{{field.max_length}}"{% endif %}
+                  {% if field.input_id %}id="#{{field.input_id}}"{% endif %}>{{ exercise.answer }}</textarea>
+    {% endif %}
+
+    {% if exercise.description_after %}
+        <div class="description">
+            {% autoescape off %}
+            {% for para in exercise.description_after %}
+                <p class="paragraph">
+                    {{para}}
+                </p>
+            {% endfor %}
+            {% endautoescape %}
+        </div>
+    {% endif%}
+
+</div>
diff --git a/src/wtem/templates/wtem/key_not_found.html b/src/wtem/templates/wtem/key_not_found.html
new file mode 100644 (file)
index 0000000..c8b54ed
--- /dev/null
@@ -0,0 +1,9 @@
+{% extends 'base_super.html' %}
+
+{% block body %}
+<h1>{% include "wtem/title.html" %}</h1>
+<h2>Niepoprawny link</h2>
+
+<p>Podany adres jest niepoprawny. Żeby móc rozwiązywać zadania, musisz przejść pod dokładnie ten sam adres, co podany w wysłanej do Ciebie wiadomości e-mail.</p>
+
+{% endblock %}
diff --git a/src/wtem/templates/wtem/key_not_found_before.html b/src/wtem/templates/wtem/key_not_found_before.html
new file mode 100644 (file)
index 0000000..0a64226
--- /dev/null
@@ -0,0 +1,9 @@
+{% extends 'base_super.html' %}
+
+{% block body %}
+<h1>{% include "wtem/title.html" %}</h1>
+<h2>Niepoprawny link</h2>
+
+<p>Podany adres jest niepoprawny. Żeby móc rozwiązywać zadania, musisz przejść pod dokładnie ten sam adres, co podany w wysłanej do Ciebie wiadomości e-mail. Jeśli masz z tym kłopot, skontaktuj się z nami pod adresem <a href="mailto:barbarakrywoszejew@nowoczesnapolska.org.pl">barbarakrywoszejew@nowoczesnapolska.org.pl</a>.</p>
+
+{% endblock %}
\ No newline at end of file
diff --git a/src/wtem/templates/wtem/main.html b/src/wtem/templates/wtem/main.html
new file mode 100644 (file)
index 0000000..a9ec10b
--- /dev/null
@@ -0,0 +1,82 @@
+{% extends 'base_super.html' %}
+{% load compressed %}
+{% load static %}
+{% load cache %}
+
+{% block extra_script %}
+    {% compressed_js 'wtem' %}
+{% endblock %}
+
+
+
+{% block body %}
+<style>
+    .wtem-open-field {
+        margin: 10px 0;
+    }
+    .wtem-open-field textarea {
+        margin-top:0;
+    }
+    .wtem-fixed-info {
+        top: 20px;
+        left: 20px;
+        border: 1px solid black;
+        background: #16a487;
+        border-radius: 0.938em;
+        padding: 5px 2px;
+        color: white;
+        text-align: center;
+        font-weight: bold;
+    }
+    .wtem-items-inline li {
+        display: inline-block;
+    }
+    .instruction {
+        font-weight: bold;
+    }
+    .wtem-disclaimer {
+        font-style: italic;
+        font-size: .9em;
+    }
+
+</style>
+
+<h1>{% include "wtem/title.html" %}</h1>
+<div class="wtem-fixed-info">Rozwiązania można wysyłać do 30 października do godziny {{end_time|default:"24:00"}}. <strong>Nie czekaj na ostatnią chwilę!</strong></div>
+
+<p>Witamy na egzaminie dla Warszawskich Liderek Edukacji Medialnej. Na rozwiązanie zadań masz czas do 30 października do godz. {{end_time|default:"24:00"}}. Możesz go rozwiązać na raz lub w kilku (kilkunastu - ile będziesz chciała) podejściach. Za każdym razem pamiętaj o kliknięciu przycisku: Wyślij moje odpowiedzi (na dole strony). Aby ponownie edytować swoje odpowiedzi musisz skorzytać z otrzymanego linku. Za każdym razem zobaczysz swoje odpowiedzi (ostatnią zapisaną wersję).
+
+Test składa się z 9 pytań. Wszystkie mają charakter otwarty.</p>
+
+<p>Powodzenia!<br/>
+Zespół Edukacji Medialnej, fundacja Nowoczesna Polska</p>
+
+<form method="post" enctype="multipart/form-data">
+
+{% cache 30 wtem %}
+{% for exercise in exercises %}
+    {% with 'wtem/exercises/'|add:exercise.type|add:'.html' as template_name %}
+    {% include  template_name with exercise=exercise no=exercise.id %}
+    {% endwith %}
+{% endfor %}
+{% endcache %}
+
+
+<hr/>
+<input type="hidden" name="answers" value=""/>
+
+<p style="text-align:center; margin-top:20px;">Sprawdź jeszcze raz wszystkie swoje odpowiedzi, a następnie wyślij je do nas, klikając w poniższy przycisk:<br/><br/>
+<input type="submit" value="Wyślij moje odpowiedzi" style="display: block; margin: auto;"/>
+<br/>
+<span class="wtem_spinner">
+    <span>Wysyłanie rozwiązań w toku...</span>
+    <img src="{% static 'wtem/spinner.gif' %}"/>
+    <span>Spróbuj jeszcze raz, jeśli wysyłanie trwa dłużej niż kilka minut.</span>
+</span>
+</p>
+
+<div class="wtem-fixed-info" style="margin-top:15px;">Rozwiązania można wysyłać do 30 października do godziny {{end_time|default:"24:00"}}. <strong>Nie czekaj na ostatnią chwilę! Do 30 października do godziny 24:00 możesz edytować swoje odpowiedzi - wejdź ponownie w otrzymany od nas link, uzupełnij/zmień swoje opowiedzi i wyślij je do nas!</strong></div>
+
+</form>
+
+{% endblock %}
\ No newline at end of file
diff --git a/src/wtem/templates/wtem/main_after.html b/src/wtem/templates/wtem/main_after.html
new file mode 100644 (file)
index 0000000..1af8151
--- /dev/null
@@ -0,0 +1,9 @@
+{% extends 'base_super.html' %}
+
+{% block body %}
+
+<h1>{% include "wtem/title.html" %}</h1>
+
+<p>Egzamin dla Warszawskich Liderek Edukacji Medialnej został zakończony.</p>
+
+{% endblock %}
diff --git a/src/wtem/templates/wtem/main_before.html b/src/wtem/templates/wtem/main_before.html
new file mode 100644 (file)
index 0000000..83bb979
--- /dev/null
@@ -0,0 +1,9 @@
+{% extends 'base_super.html' %}
+
+{% block body %}
+
+<h1>{% include "wtem/title.html" %}</h1>
+
+<p>Egzamin dla Warszawskich Liderek Edukacji Medialnej, 14 październka. Na wypełenie egzaminu masz czas do 30 października do godziny 24:00.</p>
+
+{% endblock %}
\ No newline at end of file
diff --git a/src/wtem/templates/wtem/results_student_disqualified.txt b/src/wtem/templates/wtem/results_student_disqualified.txt
new file mode 100644 (file)
index 0000000..984e34f
--- /dev/null
@@ -0,0 +1,13 @@
+{% load l10n %}Witaj,
+
+Informujemy, że wszystkie testy rozwiązane w ramach II etapu III edycji Wielkiego Turnieju Edukacji Medialnej zostały ocenione. 
+
+Niestety, ze względu na wykrycie niesamodzielnego rozwiązywania przez Ciebie testu, Twoja praca została zdysfkwalifikowana.
+
+Przypominamy, że zgodnie z § 6. pkt. 2. istnieje możliwość odwołania od decyzji Kapituły WTEM. Regulamin dostępny jest na stronie Turnieju: http://edukacjamedialna.edu.pl/info/turniej/.
+
+W razie jakichkolwiek pytań prosimy o kontakt.
+
+Pozdrawiamy,
+Zespół Edukacji Medialnej
+fundacja Nowoczesna Polska
diff --git a/src/wtem/templates/wtem/results_student_failed.txt b/src/wtem/templates/wtem/results_student_failed.txt
new file mode 100644 (file)
index 0000000..d13b19c
--- /dev/null
@@ -0,0 +1,13 @@
+{% load l10n %}Witaj,
+
+Informujemy, że wszystkie testy rozwiązane w ramach II etapu III edycji Wielkiego Turnieju Edukacji Medialnej zostały ocenione. 
+
+Liczba punktów zdobytych przez Ciebie w teście to {% localize on %}{{final_result}}{% endlocalize %}.
+
+Niestety, ten wynik nie uprawnia Cię do wzięcia udziału w III etapie Turnieju. Liczba punktów, która uprawnia do wzięcia udziału w finale to 52. Zachęcamy do zgłębiania wiedzy za zakresu edukacji medialnej i wzięcia udziału w kolejnej edycji Wielkiego Turnieju Edukacji Medialnej.
+
+W razie jakichkolwiek pytań prosimy o kontakt.
+
+Pozdrawiamy,
+Zespół Edukacji Medialnej
+fundacja Nowoczesna Polska
diff --git a/src/wtem/templates/wtem/results_student_passed.txt b/src/wtem/templates/wtem/results_student_passed.txt
new file mode 100644 (file)
index 0000000..ffaa1ed
--- /dev/null
@@ -0,0 +1,13 @@
+{% load l10n %}Witaj,
+
+Informujemy, że wszystkie testy rozwiązane w ramach II etapu III edycji Wielkiego Turnieju Edukacji Medialnej zostały ocenione. 
+
+Liczba punktów zdobytych przez Ciebie w teście to {% localize on %}{{final_result}}{% endlocalize %}.
+
+Wynik ten uprawnia Cię do wzięcia udziału III etapie Turnieju. Gratulujemy! Zawody finałowe odbędą się w drugiej połowie kwietnia. Niebawem prześlemy Ci szczegółowe informacje na ten temat.
+
+W razie jakichkolwiek pytań prosimy o kontakt.
+
+Pozdrawiamy,
+Zespół Edukacji Medialnej
+fundacja Nowoczesna Polska
diff --git a/src/wtem/templates/wtem/results_teacher.txt b/src/wtem/templates/wtem/results_teacher.txt
new file mode 100644 (file)
index 0000000..cba6e84
--- /dev/null
@@ -0,0 +1,18 @@
+Dzień dobry,
+
+Informujemy, że wszystkie testy rozwiązane w ramach II etapu III edycji Wielkiego Turnieju Edukacji Medialnej zostały ocenione. 
+
+Poniżej znajdują się wyniki uzyskane przez zgłoszonych przez Panią/Pana uczniów i uczennice, którzy rozwiązali test. Liczba punktów, która uprawnia do wzięcia udziału w zawodach finałowych to 52. Gratulujemy tym, którym się to udało. Zawody finałowe odbędą się w drugiej połowie kwietnia. Niebawem prześlemy szczegółowe informacje na ten temat.
+
+Wyniki uzyskane przez Pani/Pana podopiecznych:
+
+{% for submission in submissions %}{{submission.first_name.strip}} {{submission.last_name.strip}}: {{submission.final_result}}
+{% endfor %}
+
+Informacje o wynikach zostały przesłane również uczestnikom i uczestniczkom. Prosimy upewnić się, że wszyscy otrzymali wiadomość. Jeśli jednak do nich nie dotarła, prosimy o podanie danych kontaktowych tych osób (imię i nazwisko, adres e-mail).
+
+W razie jakichkolwiek pytań prosimy o kontakt.
+
+Pozdrawiamy,
+Zespół Edukacji Medialnej
+fundacja Nowoczesna Polska
diff --git a/src/wtem/templates/wtem/thanks.html b/src/wtem/templates/wtem/thanks.html
new file mode 100644 (file)
index 0000000..65c9a14
--- /dev/null
@@ -0,0 +1,15 @@
+{% extends 'base_super.html' %}
+
+{% block body %}
+
+<h1>Twoje rozwiązania zostały wysłane</h1>
+
+<p>Dziękujemy za udział w egzaminie dla Warszawskich Liderek Edukacji Medialnej.
+Twoja praca została wysłana i poprawnie przyjęta przez system.</p>
+
+<p>Jeśli chcesz zmienić którąś z odpowiedzi, do 30 października do godz. {{end_time|default:"24:00"}} możesz ponownie wysłać rozwiązanie zadań, korzystając z przypisanego Ci linku. W ocenie weźmiemy pod uwagę tylko ostatnie zgłoszenie. Pamiętaj, w zależności od zachowania Twojej przeglądarki, po powrocie do strony z zadaniami część zadań możesz być zmuszona rozwiązać ponownie.</p>
+
+<p>Zespół Edukacji Medialnej
+fundacja Nowoczesna Polska</p>
+
+{% endblock %}
\ No newline at end of file
diff --git a/src/wtem/templates/wtem/title.html b/src/wtem/templates/wtem/title.html
new file mode 100644 (file)
index 0000000..32860e3
--- /dev/null
@@ -0,0 +1 @@
+Egzamin dla Warszawskich Liderek Edukacji Medialnej
\ No newline at end of file
diff --git a/src/wtem/templatetags/__init__.py b/src/wtem/templatetags/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/src/wtem/templatetags/wtem_csv.py b/src/wtem/templatetags/wtem_csv.py
new file mode 100644 (file)
index 0000000..028836c
--- /dev/null
@@ -0,0 +1,32 @@
+# -*- coding: utf-8 -*-
+from django import template
+
+register = template.Library()
+
+
+@register.simple_tag
+def csv_header(exercise_id, submissionSet):
+    examiners = submissionSet.examiners_by_exercise.get(exercise_id, [])
+    examiners_string = ','.join(['zad %s - %s' % (exercise_id, user.username) for user in examiners])
+    toret = ',zad %s' % exercise_id
+    if examiners_string:
+        toret += ',' + examiners_string
+    return toret
+
+
+@register.simple_tag
+def csv_row_fragment(exercise_id, submission, submissionSet):
+    final_mark = submission.get_final_exercise_mark(exercise_id)
+    if final_mark is not None:
+        final_mark = ('%.2f' % final_mark).rstrip('0').rstrip('.')
+    toret = final_mark if final_mark else '-'
+    examiners = submissionSet.examiners_by_exercise.get(exercise_id, [])
+    marks_by_examiner = submission.get_exercise_marks_by_examiner(exercise_id)
+    for examiner in examiners:
+        mark = marks_by_examiner.get(str(examiner.id), None)
+        toret += ','
+        if mark is None:
+            toret += '"-"'
+        else:
+            toret += str(mark)
+    return toret
diff --git a/src/wtem/urls.py b/src/wtem/urls.py
new file mode 100644 (file)
index 0000000..3e96c2e
--- /dev/null
@@ -0,0 +1,9 @@
+# -*- coding: utf-8 -*-
+from django.conf.urls import patterns, url
+from .views import form, form_during
+
+urlpatterns = patterns(
+    '',
+    url(r'^_test/(?P<key>.*)/$', form_during),
+    url(r'^(?P<key>.*)/$', form, name='wtem_form')
+)
diff --git a/src/wtem/views.py b/src/wtem/views.py
new file mode 100644 (file)
index 0000000..0696174
--- /dev/null
@@ -0,0 +1,70 @@
+# -*- coding: utf-8 -*-
+import json
+from copy import deepcopy
+
+from django.conf import settings
+from django.http import HttpResponseForbidden
+from django.shortcuts import render
+from django.views.decorators.cache import never_cache
+from django.views.decorators.csrf import csrf_exempt
+
+from .forms import WTEMForm
+from .models import Submission, DEBUG_KEY, exercises
+
+WTEM_CONTEST_STAGE = getattr(settings, 'WTEM_CONTEST_STAGE', 'before')
+
+
+@csrf_exempt
+def form(request, key):
+    return globals()['form_' + WTEM_CONTEST_STAGE](request, key)
+
+
+def form_before(request, key):
+    try:
+        Submission.objects.get(key=key)
+    except Submission.DoesNotExist:
+        return render(request, 'wtem/key_not_found_before.html')
+    else:
+        return render(request, 'wtem/main_before.html')
+
+
+def form_after(request, key):
+    return render(request, 'wtem/main_after.html')
+
+
+@never_cache
+@csrf_exempt
+def form_during(request, key):
+
+    if WTEM_CONTEST_STAGE != 'during':
+        if request.META['REMOTE_ADDR'] not in getattr(settings, 'WTEM_CONTEST_IP_ALLOW', []):
+            return HttpResponseForbidden('Not allowed')
+
+    try:
+        submission = Submission.objects.get(key=key)
+    except Submission.DoesNotExist:
+        if settings.DEBUG and key == DEBUG_KEY:
+            submission = Submission.create(
+                first_name='Debug', last_name='Debug', email='debug@debug.com', key=DEBUG_KEY)
+        else:
+            return render(request, 'wtem/key_not_found.html')
+    exercises_with_answers = deepcopy(exercises)
+    if submission.answers:
+        answers = json.loads(submission.answers)
+    else:
+        answers = {}
+    for exercise in exercises_with_answers:
+        exercise['saved_answer'] = answers.get(str(exercise['id']), '')
+        if exercise['type'] == 'open' and exercise.get('fields'):
+            field_answers = {field['id']: field['text'] for field in exercise['saved_answer']}
+            for field in exercise['fields']:
+                field['saved_answer'] = field_answers.get(field['id'], '')
+    if request.method == 'GET':
+        return render(request, 'wtem/main.html', {'exercises': exercises_with_answers, 'end_time': submission.end_time})
+    elif request.method == 'POST':
+        form = WTEMForm(request.POST, request.FILES, instance=submission)
+        if form.is_valid():
+            form.save()
+            return render(request, 'wtem/thanks.html', dict(end_time=submission.end_time))
+        else:
+            raise Exception
diff --git a/wtem/__init__.py b/wtem/__init__.py
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/wtem/admin.py b/wtem/admin.py
deleted file mode 100644 (file)
index 03c4446..0000000
+++ /dev/null
@@ -1,239 +0,0 @@
-# -*- coding: utf-8 -*-
-import json
-
-from django import forms
-from django.conf.urls import url, patterns
-from django.contrib import admin
-from django.contrib.auth.models import User
-from django.core.urlresolvers import reverse
-from django.http import HttpResponse
-from django.template.loader import render_to_string
-from django.utils.safestring import mark_safe
-
-from .middleware import get_current_request
-from .models import Submission, Assignment, Attachment, exercises
-
-
-def get_user_exercises(user):
-    try:
-        assignment = Assignment.objects.get(user=user)
-        return [e for e in exercises if e['id'] in assignment.exercises]
-    except Assignment.DoesNotExist:
-        return []
-
-
-readonly_fields = ('submitted_by', 'first_name', 'last_name', 'email', 'key', 'key_sent')
-
-
-class AttachmentWidget(forms.Widget):
-    def render(self, name, value, *args, **kwargs):
-        if value:
-            a_tag = '<a href="%s">%s</a>' % (value, value)
-        else:
-            a_tag = 'brak'
-        return mark_safe(('<input type="hidden" name="%s" value="%s"/>' % (name, value)) + a_tag)
-
-
-class TextareaWithLinks(forms.Textarea):
-    def render(self, name, value, *args, **kwargs):
-        t, links = value
-        self.links = links
-        output = super(TextareaWithLinks, self).render(name, t, *args, **kwargs)
-        moreoutput = "<div style='margin-left: 106px'>"
-        for k, n, v in links:
-            moreoutput += u"<br>%s: %s" % (k, AttachmentWidget().render(n, v))
-        output += mark_safe(moreoutput + "</div>")
-        return output
-
-
-class SubmissionFormBase(forms.ModelForm):
-    class Meta:
-        model = Submission
-        exclude = ('answers', 'marks', 'contact', 'end_time') + readonly_fields
-
-
-def get_open_answer(answers, exercise):
-    def get_option(options, id):
-        for option in options:
-            if str(option['id']) == id:
-                return option
-
-    exercise_id = str(exercise['id'])
-    answer = answers[exercise_id]
-    if exercise['type'] == 'open':
-        if isinstance(answer, list):
-            toret = ''
-            for part in answer:
-                field = get_option(exercise['fields'], part['id'])
-                toret += '- %s:\n\n%s\n\n' % (field['caption'], part['text'])
-        else:
-            toret = answer
-    if exercise['type'] == 'edumed_wybor':
-        ok = set(map(str, exercise['answer'])) == set(map(str, answer['closed_part']))
-        toret = u'Czesc testowa [%s]:\n' % ('poprawna' if ok else 'niepoprawna')
-        if len(answer['closed_part']):
-            for selected in answer['closed_part']:
-                option = get_option(exercise['options'], selected)
-                toret += '%s: %s\n' % (selected, option['text'])
-        else:
-            toret += u'<nie wybrano odpowiedzi>\n'
-        toret += u'\nCzesc otwarta (%s):\n\n' % ' '.join(exercise['open_part'])
-        toret += answer['open_part']
-
-    return toret
-
-
-def get_form(request, submission):
-    fields = dict()
-    if submission and submission.answers:
-        answers = json.loads(submission.answers)
-        user_exercises = get_user_exercises(request.user)
-        for exercise in exercises:
-            if exercise not in user_exercises:
-                continue
-            
-            answer_field_name = 'exercise_%s' % exercise['id']
-            mark_field_name = 'markof_%s_by_%s' % (exercise['id'], request.user.id)
-            if exercise['type'] in ('open', 'file_upload') or exercise.get('open_part', None):
-                if exercise['type'] == 'file_upload':
-                    try:
-                        attachment = Attachment.objects.get(submission=submission, exercise_id=exercise['id'])
-                    except Attachment.DoesNotExist:
-                        attachment = None
-                    widget = AttachmentWidget
-                    initial = attachment.file.url if attachment else None
-                else:
-                    # widget = forms.Textarea(attrs={'readonly':True})
-                    widget = TextareaWithLinks(attrs={'readonly': True})
-                    links = []
-                    qfiles = []
-                    for qfield in exercise.get('fields', []):
-                        if qfield.get('type') == 'file':
-                            qfiles.append((qfield['id'], qfield['caption']))
-                    if qfiles:
-                        eid = int(exercise['id'])
-                        by_tag = {}
-                        for att in Attachment.objects.filter(submission=submission, exercise_id=eid).order_by('tag'):
-                            by_tag[att.tag] = att.file.url
-                        for tag, caption in qfiles:
-                            v = by_tag.get(tag)
-                            if v:
-                                links.append((caption, "file_%s__%s" % (eid, tag), v))
-                    initial = get_open_answer(answers, exercise), links
-
-                fields[answer_field_name] = forms.CharField(
-                    widget=widget,
-                    initial=initial,
-                    label=u'Rozwiązanie zadania %s' % exercise['id'],
-                    required=False
-                )
-
-                choices = [(None, '-')]  # + [(i,i) for i in range(exercise['max_points']+1)],
-                i = 0
-                while i <= exercise['max_points']:
-                    choices.append((i, i))
-                    i += .5
-                fields[mark_field_name] = forms.ChoiceField(
-                    choices=choices,
-                    initial=submission.get_mark(user_id=request.user.id, exercise_id=exercise['id']),
-                    label=u'Twoja ocena zadania %s' % exercise['id']
-                )
-
-    if not request.user.is_superuser:
-        class Meta(SubmissionFormBase.Meta):
-            pass
-        Meta.exclude += ('examiners',)
-        fields['Meta'] = Meta
-
-    return type('SubmissionForm', (SubmissionFormBase,), fields)
-
-
-class SubmissionAdmin(admin.ModelAdmin):
-    list_display = ('__unicode__', 'todo', 'examiners_repr')
-    readonly_fields = readonly_fields
-
-    def get_form(self, request, obj=None, **kwargs):
-        return get_form(request, obj)
-
-    def submitted_by(self, instance):
-        if instance.contact:
-            return '<a href="%s">%s</a>' % (
-                reverse('admin:contact_contact_change', args=[instance.contact.id]),
-                instance.contact.contact
-            )
-        return '-'
-    submitted_by.allow_tags = True
-    submitted_by.short_description = "Zgłoszony/a przez"
-
-    def todo(self, submission):
-        user = get_current_request().user
-        user_exercises = get_user_exercises(user)
-        user_marks = submission.marks.get(str(user.id), {})
-        return ','.join([str(e['id']) for e in user_exercises if str(e['id']) not in user_marks.keys()])
-    todo.short_description = 'Twoje nieocenione zadania'
-
-    def examiners_repr(self, submission):
-        return ', '.join([u.username for u in submission.examiners.all()])
-    examiners_repr.short_description = 'Przypisani do zgłoszenia'
-
-    def save_model(self, request, submission, form, change):
-        for name, value in form.cleaned_data.items():
-            if name.startswith('markof_'):
-                parts = name.split('_')
-                exercise_id = parts[1]
-                user_id = parts[3]
-                submission.set_mark(user_id=user_id, exercise_id=exercise_id, mark=value)
-        submission.save()
-
-    def changelist_view(self, request, extra_context=None):
-        context = dict(examiners=[])
-        assignments = Assignment.objects.all()
-        if not request.user.is_superuser:
-            assignments = assignments.filter(user=request.user)
-        for assignment in assignments:
-            examiner = dict(name=assignment.user.username, todo=0)
-            for submission in Submission.objects.filter(examiners=assignment.user):
-                for exercise_id in assignment.exercises:
-                    if submission.get_mark(user_id=assignment.user.id, exercise_id=exercise_id) is None:
-                        examiner['todo'] += 1
-            context['examiners'].append(examiner)
-        return super(SubmissionAdmin, self).changelist_view(request, extra_context=context)
-
-    def queryset(self, request):
-        qs = super(SubmissionAdmin, self).queryset(request)
-        if not request.user.is_superuser:
-            qs = qs.filter(examiners=request.user)
-        return qs
-
-    def get_urls(self):
-        urls = super(SubmissionAdmin, self).get_urls()
-        return patterns(
-            '',
-            url(r'^report/$', self.admin_site.admin_view(report_view), name='wtem_admin_report')
-        ) + super(SubmissionAdmin, self).get_urls()
-
-
-class SubmissionsSet:
-    def __init__(self, submissions):
-        self.submissions = submissions
-        self.examiners_by_exercise = {}
-        for submission in submissions:
-            for user_id, marks in submission.marks.items():
-                user = User.objects.get(pk=user_id)
-                for exercise_id in marks.keys():
-                    examiners = self.examiners_by_exercise.setdefault(exercise_id, [])
-                    if user not in examiners:
-                        examiners.append(user)
-
-
-def report_view(request):
-    submissions = sorted(Submission.objects.all(), key=lambda s: -s.final_result)
-    toret = render_to_string('wtem/admin_report.csv', {
-        'submissionsSet': SubmissionsSet(submissions),
-        'exercise_ids': [str(e['id']) for e in exercises]})
-    response = HttpResponse(toret, content_type='text/csv')
-    response['Content-Disposition'] = 'attachment; filename="wyniki.csv"'
-    return response
-
-admin.site.register(Submission, SubmissionAdmin)
-admin.site.register(Assignment)
diff --git a/wtem/fixtures/exercises-2013.json b/wtem/fixtures/exercises-2013.json
deleted file mode 100644 (file)
index 8fc52f7..0000000
+++ /dev/null
@@ -1,418 +0,0 @@
-[
-
-{
-    "id": 1,
-    "type": "edumed_uporzadkuj",
-    "description": ["Ułóż propozycje haseł internetowych w kolejności od najmniej do najbardziej bezpiecznego."],
-    "items": [
-        {"id": "1", "text": "Gdzi3.j3$t.N3m0"},
-        {"id": "2", "text": "abc123"},
-        {"id": "3", "text": "mojazor17"},
-        {"id": "4", "text": "czarnyKotbialyKot"},
-        {"id": "5", "text": "qwerty456"}
-    ],
-    "answer": [2, 5, 3, 4, 1],
-    "points": 1
-},
-
-{
-    "id": 2,
-    "type": "edumed_przyporzadkuj",
-    "hide_default_instruction": 1,
-    "description": ["Rozpoznaj i nazwij typy reklam"],
-    "buckets":  [
-        {"id": 1, "title": "lokowanie produktu"},
-        {"id": 2, "title": "baner"},
-        {"id": 3, "title": "infomercial"},
-        {"id": 4, "title": "power content"},
-        {"id": 5, "title": "sponsoring"},
-        {"id": 6, "title": "AdWords"}
-    ],
-    "buckets_name": "typy",
-    "items": [
-        {"id": 1, "text": "1", "img": "1_small.png", "href": "1.png"},
-        {"id": 2, "text": "2", "img": "2_small.png", "href": "2.png"},
-        {"id": 3, "text": "3", "img": "3_small.png", "href": "3.png"}
-    ],
-    "items_name": "reklamy",
-    "items_inline": 1,
-    "items_instruction": "Przeciągnij numery zdjęć do odpowiednich szarych pól powyżej; kliknij w obrazek, aby powiększyć",
-    "answer": {
-        "1": [2],
-        "4": [3],
-        "6": [1]
-    },
-    "points_per_hit": 1
-},
-
-{
-    "id": 3,
-    "type": "edumed_wybor",
-    "description": ["Wykonałeś/wykonałaś remiks cudzych utworów. W jakich sytuacjach możesz rozpowszechnić swój utwór?"],
-    "options": [
-        {"id": 1, "text": "Mam zgodę autora/autorki oryginalnego utworu."},
-        {"id": 2, "text": "Materiały do remiksu zostały ściągnięte z serwisu do przechowywania plików."},
-        {"id": 3, "text": "Wykorzystane piosenki przesłała mi na Facebooku koleżanka."},
-        {"id": 4, "text": "Zezwala na to licencja, na której są opublikowane wykorzystane utwory."},
-        {"id": 5, "text": "Wykorzystane w remiksie utwory są dostępne w domenie publicznej (minęło 70 lat od śmierci autora)."},
-        {"id": 6, "text": "Utwory użyte w remiksie były udostępnione do odsłuchania na stronach twórców w formie plików mp3."}
-    ],
-    "answer": [1, 4, 5],
-    "points_per_hit": 1
-},
-
-{
-    "id": 4,
-    "type": "edumed_wybor",
-    "description": ["Jedziesz na wakacje do Turcji. Ustal, jaki termin ważnosci musi mieć Twój paszport."],
-    "options": [
-        {"id": 1, "text": "3 miesiące od daty wyjazdu z Polski"},
-        {"id": 2, "text": "12 miesięcy od daty powrotu do Polski"},
-        {"id": 3, "text": "6 miesięcy od daty wyjazdu z Polski"},
-        {"id": 4, "text": "nie muszę mieć paszportu, by wyjechać do Turcji"}
-    ],
-    "answer": [3],
-    "points": 1
-},
-
-{
-    "id": 5,
-    "type": "edumed_przyporzadkuj",
-    "description": ["Który z poniższych tekstów jest informacją, opinią, perswazją?"],
-    "buckets": [
-        {"id": 1, "title": "informacja"},
-        {"id": 2, "title": "opinia"},
-        {"id": 3, "title": "perswazja"}
-    ],
-    "buckets_name": "kategorie",
-    "items": [
-        {"id": 1, "text": "1", "desc": "Serdecznie zapraszamy do udziału w V Festiwalu Poezji Lokalnej im. Zbigniewa Herberta. Przyjdź i zaprezentuj swoją twórczość literacką biorąc udział w tradycyjnym już Turnieju Jednego Wiersza! Dla najlepszych poetów – atrakcyjne nagrody!"},
-        {"id": 2, "text": "2", "desc": "22 grudnia w Domu Kultury Miejskiej przy ul. Wielebskiego 3 uczestniczyliśmy w kolejnym V Festiwalu Poezji Lokalnej im. Zbigniewa Herberta. Swoje wiersze zaprezentowało blisko 30 poetów, zarówno z naszego miasta jak i przybyłych gości. Tradycyjny już Turniej Jednego Wiersza wygrał Jan Kowalski z Krętowa."},
-        {"id": 3, "text": "3", "desc": "Atmosfera V Festiwalu Poezji Lokalnej była bardzo podniosła. Nie wiedziałem, że mamy tak wielu dobrych poetów w naszym mieście i regionie. Uważam, że to jeden z najlepszych tego typu przeglądów i turniejów literackich w Polsce. Profesjonalnie przygotowany, o wysokim poziomie artystycznym. Warto było przyjechać."}
-    ],
-    "items_name": "źródła",
-    "answer": {
-        "1": [2],
-        "2": [3],
-        "3": [1]
-    },
-    "points_per_hit": 1
-},
-
-{
-    "id": 6,
-    "type": "edumed_wybor",
-    "description": ["W jaki sposób zwiększysz niezależność wyników wyszukiwania od wcześniej wprowadzanych do wyszukiwarki fraz i przeglądanych stron internetowych?"],
-    "options": [
-        {"id": 1, "text": "ustawię tryb prywatny w przeglądarce (incognito)"},
-        {"id": 2, "text": "wyloguję się z serwisu społecznościowego"},
-        {"id": 3, "text": "skorzystam z innej niż zazwyczaj wyszukiwarki"},
-        {"id": 4, "text": "skorzystam z innej niż zazwyczaj przeglądarki"},
-        {"id": 5, "text": "zamknę zakładkę z portalem społecznościowym"},
-        {"id": 6, "text": "usunę historię wyszukiwania i ciasteczka"},
-        {"id": 7, "text": "zrestartuję przeglądarkę"}
-    ],
-    "answer": [1,4,6],
-    "points_per_hit": 1
-},
-
-{
-    "id": 7,
-    "type": "edumed_wybor",
-    "description": ["Jesteś w Olsztynie na przystanku Plac Roosevelta. Którym autobusem nie dojedziesz bezpośrednio na przystanek Szpital Wojewódzki?"],
-    "options": [
-        {"id": 1, "text": "13"},
-        {"id": 2, "text": "6"},
-        {"id": 3, "text": "22"},
-        {"id": 4, "text": "3"}
-    ],
-    "open_part": ["W jaki sposób dotarłeś/aś do tej informacji? Wklej adres strony, z której skorzystałeś/aś."],
-    "open_part_rows": 1,
-    "answer": [4],
-    "max_points": 2
-},
-
-{
-    "id": 8,
-    "type": "edumed_wybor",
-    "description": ["Kupiłeś płytę CD z nowym albumem ulubionego zespołu. Co możesz z nim zrobić?"],
-    "options": [
-        {"id": 1, "text": "umieścić pliki w sieci, tak by inni mogli ściągnąć album"},
-        {"id": 2, "text": "zgrać pliki na swoje urządzenia (laptop, smartfon, odtwarzacz mp3 itp.)"},
-        {"id": 3, "text": "skopiować płytę najbliższym znajomym i rodzinie"},
-        {"id": 4, "text": "skopiować płytę nauczycielce/nauczycielowi, która lubi podobną muzykę"},
-        {"id": 5, "text": "nagrać kopie albumu na płyty CD i odsprzedać je w szkole zainteresowanym osobom"},
-        {"id": 6, "text": "odsprzedać płytę z albumem w serwisie aukcyjnym"}
-    ],
-    "answer": [2,3,6],
-    "points_per_hit": 1
-
-},
-
-{
-    "id": 9,
-    "type": "edumed_przyporzadkuj",
-    "description": ["Przyporządkuj poniższe pojęcia ich definicjom."],
-    "buckets": [
-        {"id": 1, "title": "infotainment"},
-        {"id": 2, "title": "cyfrowe narracje"},
-        {"id": 3, "title": "gatunek"},
-        {"id": 4, "title": "konwencja"},
-        {"id": 5, "title": "remiks"}
-
-    ],
-    "buckets_name": "pojęcia",
-    "items": [
-        {"id": 1, "text": "1", "desc": "zbiór cech utworów (artystycznych, dziennikarskich itp.) wielokrotnie powtarzany i wykorzystywany. Może być typowy dla jednego twórcy, grupy czy okresu. Składać się na niego mogą różne elementy utworu – zarówno te związane formą, jak i treścią."},
-        {"id": 2, "text": "2", "desc": "utwór, w którym wykorzystano i połączono elementy różnych innych dzieł. Dzięki nowemu kontekstowi zmieniają one swoje znaczenie. Pierwotnie termin ten odnosił się tylko do utworów muzycznych i oznaczał zmianę aranżacji piosenki, połączenie jej pierwotnej wersji z innymi elementami dźwiękowymi."},
-        {"id": 3, "text": "3", "desc": "zjawisko zacierania różnic pomiędzy przekazami informacyjnymi i rozrywkowymi. Obserwujemy je we współczesnych mediach."},
-        {"id": 4, "text": "4", "desc": "opowieść w formie multimedialnej. Jej autor przekazuje treść za pomocą połączenia różnych form przekazu, np. tekstu, animacji, dźwięku, obrazu, wideo. Może przybierać formę hipertekstu, prezentacji, filmu."},
-        {"id": 5, "text": "5", "desc": "typ, odmiana czegoś. W odniesieniu do tekstów kultury: określony sposób organizacji przekazu, zależny od jego celu. Utwory tego samego gatunku mają zwykle podobą formę, wykorzystują te same konwencje."}
-    ],
-    "items_name": "definicje",
-    "answer": {
-        "1": [3],
-        "2": [4],
-        "3": [5],
-        "4": [1],
-        "5": [2]
-    },
-    "points_per_hit": 0.5
-},
-
-{
-    "id": 10,
-    "type": "edumed_wybor",
-    "description": ["<div>Widzisz, że na ekranie Twojego kolegi strona <a href=\"http://www.krrit.gov.pl/\">http://www.krrit.gov.pl/</a> wyświetla się w ten sposób:</div> <img src=\"/static/wtem/img/krrit_zrzut_ekranu.png\"/ style=\"margin-bottom:10px; margin-top:10px;\"> Dlaczego?"],
-    "options": [
-        {"id": 1, "text": "Kolega ma starą wersję przeglądarki, która nie obsługuje zaawansowanej grafiki strony."},
-        {"id": 2, "text": "Został użyty przycisk “wersja kontrastowa”, który pomaga osobom słabowidzącym zapoznać się z treścią strony."},
-        {"id": 3, "text": "Komputer został zaatakowany wirusem typu Trojan."},
-        {"id": 4, "text": "Kolega wyświetla stronę przygotowaną do wydruku."}
-    ],
-    "answer": [2],
-    "points": 1
-},
-
-{
-    "id": 11,
-    "type": "edumed_wybor",
-    "description": ["Wskaż bezpośrednie zagrożenia, które wiążą się z posiadaniem profilu na portalu społecznościowym."],
-    "options": [
-        {"id": 1, "text": "możliwość niekontrolowanego wycieku prywatnych informacji (niedoskonała ochrona danych osobowych)"},
-        {"id": 2, "text": "stalking"},
-        {"id": 3, "text": "zablokowanie komputera"},
-        {"id": 4, "text": "kradzież tożsamości (profilu)"},
-        {"id": 5, "text": "kradzież pieniędzy z konta bankowego"},
-        {"id": 6, "text": "phishing"},
-        {"id": 7, "text": "cenzurowanie publikowanych i otrzymywanych treści"},
-        {"id": 8, "text": "fałszerstwo dokumentu tożsamości"},
-        {"id": 9, "text": "śledzenie aktywności użytkownika w internecie"}
-    ],
-    "answer": [1,2,4,6,7,9],
-    "points_per_hit": 0.5
-},
-
-{
-    "id": 12,
-    "type": "edumed_przyporzadkuj",
-    "description": ["Do jakiej instytucji zwrócisz się w konkretnej sprawie?"],
-    "buckets": [
-        {"id": 1, "title": "GIODO"},
-        {"id": 2, "title": "UOKiK"},
-        {"id": 3, "title": "RPD"},
-        {"id": 4, "title": "KRRiT"},
-        {"id": 5, "title": "UKE"}
-
-    ],
-    "buckets_name": "instytucje",
-    "items": [
-        {"id": 1, "text": "1", "desc": "sklep internetowy nie chce oddać Ci pieniędzy za towar zwrócony w ciągu 10 dni od daty zakupu"},
-        {"id": 2, "text": "2", "desc": "wiesz, że kolega z młodszej klasy jest prześladowany w internecie, a lokalne instytucje nie reagują na problem"},
-        {"id": 3, "text": "3", "desc": "w audycji radiowej prowadzący obrażał cudzoziemców mieszkających w Polsce"}
-    ],
-    "items_name": "sprawy",
-    "answer": {
-        "2": [1],
-        "3": [2],
-        "4": [3]
-    },
-    "points_per_hit": 1
-},
-
-{
-    "id": 13,
-    "type": "edumed_wybor",
-    "description": ["Chcesz dowiedzieć się, co sklep internetowy robi z Twoimi danymi osobowymi. Gdzie szukasz tej informacji?"],
-    "options": [
-        {"id": 1, "text": "w zakładce “O nas”"},
-        {"id": 2, "text": "w zakładce “Twój profil”"},
-        {"id": 3, "text": "w “Polityce prywatności”"},
-        {"id": 4, "text": "w “Regulaminie zakupów”"}
-    ],
-    "answer": [3],
-    "points": 1
-},
-
-{
-    "id": 14,
-    "type": "edumed_wybor",
-    "description": ["Jak należy oznaczyć zdjęcie ściągnięte z Wikipedii, które chcesz opublikować na swoim blogu?"],
-    "options": [
-        {"id": 1, "text": "Należy podać informację, że zdjęcie pochodzi z internetu (źródło: internet)."},
-        {"id": 2, "text": "Należy podać nazwisko/pseudonim autorki lub autora."},
-        {"id": 3, "text": "Należy podać informacje o licencji, na której opublikowane jest zdjęcie."},
-        {"id": 4, "text": "Należy podać link do strony, z której ściągnięto zdjęcie."}
-    ],
-    "answer": [2,3,4],
-    "answer_mode": "all_or_nothing",
-    "points": 1
-},
-
-{
-    "id": 15,
-    "type": "edumed_wybor",
-    "description": ["Na ostatniej imprezie karaoke zrobiłaś/eś świetne zdjęcie swojej koleżanki śpiewającej przeboje Abby. Wiesz, że pewnie nie będzie się jej podobać, ale chcesz, żeby jak najwięcej osób zapamiętało ten wieczór. Co robisz?"],
-    "options": [
-        {"id": 1, "text": "wysyłasz zdjęcie do wszystkich uczestników imprezy mailem"},
-        {"id": 2, "text": "wrzucasz zdjęcie na swój publiczny profil w portalu społecznościowym, a potem informujesz o tym koleżankę"},
-        {"id": 3, "text": "pytasz koleżankę, czy zgadza się na publikację zdjęcia, a potem udostępniasz je tylko osobom, które były na imprezie"},
-        {"id": 4, "text": "wrzucasz zdjęcie na swojego bloga, ale zamazujesz twarz koleżanki"}
-    ],
-    "answer": [3],
-    "points": 1
-},
-
-{
-    "id": 16,
-    "type": "edumed_wybor",
-    "description": ["Twój starszy brat chce podczas imprezy urodzinowej w Sopocie puszczać ze znajomymi tzw. chińskie lampiony. Jakie zezwolenie jest mu potrzebne?"],
-    "options": [
-        {"id": 1, "text": "zezwolenie Państwowej Straży Pożarnej"},
-        {"id": 2, "text": "zezwolenie Polskiej Agencji Żeglugi Powietrznej"},
-        {"id": 3, "text": "zezwolenie Urzędu Miasta"},
-        {"id": 4, "text": "zezwolenie Sanepidu"}
-    ],
-    "answer": [2],
-    "open_part": ["Co wpisałeś/aś w okno wyszukiwarki, żeby znaleźć tę informację?"],
-    "max_points": 2
-},
-
-{
-    "id": 17,
-    "type": "edumed_wybor",
-    "description": ["Na pulpicie Twojego komputera wyświetla się taki komunikat. Komputer faktycznie zostaje zablokowany. Co robisz?",
-        "<img src=\"/static/wtem/img/komunikat_policyjny.png\"/>"
-    ],
-    "options": [
-        {"id": 1, "text": "pokazujesz komunikat rodzicom/opiekunom"},
-        {"id": 2, "text": "sprawdzasz prawdziwość zawartych w komunikacie informacji, np. wymienionych artykułów prawnych"},
-        {"id": 3, "text": "dokonujesz zalecanej płatności"},
-        {"id": 4, "text": "sprawdzasz w wyszukiwarce internetowej (z telefonu komórkowego lub innego komputera) co należy zrobić w takiej sytuacji"},
-        {"id": 5, "text": "restartujesz komputer"},
-        {"id": 6, "text": "podejrzewasz, że może to być wirus komputerowy i zgłaszasz to osobie kompetentnej, np. informatykowi"}
-    ],
-    "answer": [1,2,4,6],
-    "points_per_hit": 0.5
-},
-
-{
-    "id": 18,
-    "type": "edumed_przyporzadkuj",
-    "hide_default_instruction": 1,
-    "description": ["Wyobraź sobie, że poniższe zdjęcia przedstawiają Twój wizerunek. Jak i gdzie można je wykorzystać? Połącz w pary zdjęcia i miejsca ich publikacji."],
-    "buckets": [
-        {"id": 1, "title": "dostępny dla wszystkich album ze zdjęciami na towarzyskim portalu społecznościowym"},
-        {"id": 2, "title": "dostępny tylko dla najbliższych znajomych album ze zdjęciami na towarzyskim portalu społecznościowym"},
-        {"id": 3, "title": "avatar na forum dotyczącym pracy w bankowości"},
-        {"id": 4, "title": "formularz rekrutacyjny na wakacyjną wymianę młodzieży"},
-        {"id": 5, "title": "nie publikuję tego zdjęcia w sieci"}
-
-    ],
-    "buckets_name": "miejsca",
-    "items": [
-        {"id": 1, "text": "1", "href_absolute": 1, "href": "http://www.flickr.com/photos/kk/5443214980/sizes/s/in/photostream/", "img": "przyp/1.jpg"},
-        {"id": 2, "text": "2", "href_absolute": 1, "href": "http://www.flickr.com/photos/keithusc/2799394010/sizes/s/in/photostream/","img": "przyp/2.jpg"},
-        {"id": 3, "text": "3", "href_absolute": 1, "href": "http://www.flickr.com/photos/mike-burns/7459087/sizes/s/in/photostream/","img": "przyp/3.jpg"},
-        {"id": 4, "text": "4", "href_absolute": 1, "href": "http://www.flickr.com/photos/76029035@N02/6829334723/sizes/s/in/photostream/","img": "przyp/4.jpg"},
-        {"id": 5, "text": "5", "href_absolute": 1, "href": "http://www.flickr.com/photos/84502900@N00/3502014745", "img": "przyp/5.jpg"}
-    ],
-    "items_name": "zdjęcia",
-    "items_instruction": "Przeciągnij numery zdjęć do odpowiednich szarych poł powyżej",
-    "items_inline": 1,
-    "description_after": ["<span class=\"wtem-disclaimer\">(Wszystkie użyte zdjęcia dostępne na CC-BY-SA - źródła/autorzy dostępni po kliknięciu w obrazek)</span>"],
-    "points_per_hit": 0.5,
-    "answer_mode": "possible_buckets_for_item",
-    "answer": {
-        "1": [1,2,3,4],
-        "2": [5],
-        "3": [2,5],
-        "4": [1,2,3,4],
-        "5": [1,2]
-    }
-},
-
-{
-    "id": 19,
-    "type": "edumed_wybor",
-    "description": ["Jaki jest symbol klasyfikacji bibliotecznej najnowszego wydania książki “Ekonomia w jednej lekcji” autorstwa Henry’ego Hazlitta w zbiorach Biblioteki Uniwersyteckiej w Warszawie?"],
-    "options": [
-        {"id": 1, "text": "HG229 .H39165 2007"},
-        {"id": 2, "text": "1151471"},
-        {"id": 3, "text": "PS3515.A96 T56165 2011"},
-        {"id": 4, "text": "HB171 .H445165 2012"}
-    ],
-    "answer": [4],
-    "points": 1
-},
-
-{
-    "id": 20,
-    "type": "edumed_prawdafalsz",
-    "description": ["Oznacz poniższe zdania jako prawdziwe lub fałszywe."],
-    "statements": [
-        ["Telewizja TVN finansowana jest ze środków pochodzących z abonamentu radiowo - telewizyjnego.", false],
-        ["Polskie Radio nie może nadawać żadnych reklam.", false],
-        ["TVP Historia należy do mediów publicznych.", true],
-        ["TVP Kultura nie jest nastawiona na zysk.", true],
-        ["Radiowa Czwórka jest stacją komercyjną.", false],
-        ["Działalność mediów publicznych ma charakter misyjny.", true]
-    ],
-    "points_per_hit": 0.5
-},
-
-{
-    "id": 21,
-    "type": "open",
-    "description": ["Przygotuj komunikat na podstawie podanych niżej wiadomości w formie:"],
-    "fields": [
-        {"caption": "1. oficjalnego zaproszenia wysyłanego mailem", "id": 1},
-        {"caption": "2. sms-a do znajomych, maksymalnie 140 znaków", "id": 2, "max_length": 140, "rows": 2, "input_id": "wtem_sms"},
-        {"caption": "3. informacji prasowej do lokalnej gazety", "id": 3}
-    ],
-    "description_after": [
-        "Twój przyjaciel – Krzysztof Gawroński, znany w środowisku jako Gawron – jest gitarzystą i wokalistą w zespole rockowo-metalowym „The Urban Jungle”. 22 stycznia br. o 19. odbędzie się koncert zespołu w Domu Kultury Miejskiej przy ul. Wielebskiego 3 w Krętowie. Zespół zagra m.in. covery Metallicy, Black Sabbath, ale też własne utwory. Bilety mają być w cenie 15 zł. Oprócz Krzysztofa w zespole grają także Michał Kordowski na gitarze basowej i Tomasz Bielewski na perkusji. Ostatnio miałeś okazję się z nimi spotkać i porozmawiać o ich twórczości. Planują występ w programie „Must be the music”, a wcześniej małą trasę koncertową po powiecie bełżeckim, odwiedzając – oprócz Krętowa – Bełżec, Wielkie Głazy i Niechorzów. Gawron zwierzył Ci się, że napisał 2 nowe utwory, które po raz pierwszy zostaną zaprezentowane na koncercie 22 stycznia. Jeśli uda im się zebrać pieniądze (ok. 15 tys. zł) chcą zacząć nagrywanie swojej pierwsze płyty."
-    ],
-    "max_points": 9
-},
-
-{
-    "id": 22,
-    "type": "file_upload",
-    "description": [
-        "Na podstawie poniższego fragmentu tekstu przygotuj 1 slajd prezentacji przeznaczonej dla uczniów 2 klasy szkoły podstawowej. Wykorzystaj też zdjęcie dostępne w interencie, które jest udostępnione na licencji umożliwiającej jego dalsze przetwarzanie i rozpowszechnianie.",
-        "Zapisz przygotowany slajd na dysku swojego komputera, a następnie, korzystając z poniższego przycisku załącz go do zadania"
-    ],
-    "description_after": [
-        "<cite>Puszcza Białowieska – kompleks leśny położony na terenie Polski i Białorusi, odznaczający się dużymi walorami przyrodniczymi i historycznymi. W Puszczy Białowieskiej zachowały się ostatnie fragmenty lasu o charakterze pierwotnym. Tutaj mieszka największa populacja wolnego żubra na świecie.</cite>",
-        "<cite>Puszcza Białowieska leży w strefie klimatu umiarkowanego przejściowego, stosunkowo chłodnego i z dominacją wpływów kontynentalnych w związku z czym w pewnych klasyfikacjach bywa on określany jako klimat leśny subkontynentalny strefy umiarkowanie chłodnej.</cite>",
-        "<cite>Według danych z Białowieskiego Parku Narodowego średnia roczna temperatura powietrza w latach 1955-2001 wynosiła 6,8 °C. Odnotowane temperatury mieściły się w zakresie od +34,5 °C do –38,7 °C (rekord zimna w 1950 r.).</cite>",
-        "<cite>Średnia ilość opadów wynosi 633 mm na rok, z czego większość w sezonie wegetacyjnym który względem Polski zachodniej jest krótszy o miesiąc i trwa 205 dni. Zima natomiast jest długa, z pokrywą śnieżną utrzymującą się średnio ponad 92 dni.</cite>",
-        "<cite>Na terenie Puszczy białowieskiej żyje 58 gatunków ssaków co stanowi ponad 70 procent fauny niżowej Polski w obrębie tej grupy. Z pośród występujących tu gatunków 33 podlegają w Polsce ochronie prawnej, a 12 figuruje w Polskiej Czerwonej Księdze Zwierząt.</cite>",
-        "Żródło: Puszcza Białowieska, <a href=\"http://pl.wikipedia.org/w/index.php?title=Puszcza_Bia%C5%82owieska&oldid=37917751\">http//pl.wikipedia.org/w/index.php?title=Puszcza_Bia%C5%82owieska&oldid=37917751</a> (dostęp 18.11.2013), CC BY-SA"
-    ],
-    "max_points": 9,
-    "max_file_size_string": "5 megabajtów"
-}
-
-]
\ No newline at end of file
diff --git a/wtem/fixtures/exercises-2014.json b/wtem/fixtures/exercises-2014.json
deleted file mode 100644 (file)
index 0793ce5..0000000
+++ /dev/null
@@ -1,266 +0,0 @@
-[
-
-{
-    "id": 1,
-    "type": "edumed_wybor",
-    "description": ["Z jaką licencją Creative Commons jest zgodna OGL (Open Government License) i w jakim kraju się ją stosuje?"],
-    "options": [
-        {"id": 1, "text": "CC BY-SA, w Nowej Zelandii,"},
-        {"id": 2, "text": "CC BY-ND, w Kanadzie,"},
-        {"id": 3, "text": "CC BY-SA, w Wlk. Brytanii,"},
-        {"id": 4, "text": "CC BY, w Wlk. Brytanii."}
-    ],
-    "answer": [4],
-    "points": 1
-},
-
-{
-    "id": 2,
-    "type": "edumed_przyporzadkuj",
-    "description": ["Dopasuj definicje do pojęć:"],
-    "buckets":  [
-        {"id": 1, "title": "plonk"},
-        {"id": 2, "title": "OZZ"},
-        {"id": 3, "title": "DRM"},
-        {"id": 4, "title": "booksprint"},
-        {"id": 5, "title": "protokół HTTPS"}
-    ],
-    "buckets_name": "Pojęcia",
-    "items": [
-        {"id": 1, "text": "1", "desc": "Oprogramowanie i sprzęt mające uniemożliwić działania niezgodne z prawem autorskim lub warunkami serwisu/wolą producenta. Stosuje się w muzyce, filmach, grach i innych mediach. Opiera się na mechanizmach kryptograficznych, zabezpieczając np. przed nieautoryzowanym odczytem lub skopiowaniem."},
-        {"id": 2, "text": "2", "desc": "Forma współpracy, polegająca na bardzo szybkim (od kilku godzin do kilku dni) stworzeniu książki przez zespół autorów. Zwykle zespół ten zbiera się przez internet, a książka wydawana jest w formie elektronicznej."},
-        {"id": 3, "text": "4", "desc": "Jeden z protokołów umożliwiający przesyłanie w sieci zaszyfrowanych informacji, dzięki czemu dostęp do treści mają jedynie nadawca oraz odbiorca komunikatu."},
-        {"id": 4, "text": "5", "desc": "Dodanie osoby, której postów nie chcemy czytać, do mechanizmu automatycznego usuwania wiadomości."},
-        {"id": 5, "text": "6", "desc": "Podmiot zarządzający majątkowymi prawami autorskimi, głównie poprzez wydawanie licencji na korzystanie z utworów."}
-    ],
-    "items_name": "Definicje",
-    "answer": {
-        "1": [4],
-        "2": [5],
-        "3": [1],
-        "4": [2],
-        "5": [3]
-    },
-    "points_per_hit": 1
-},
-
-{
-    "id": 3,
-    "type": "open",
-    "description": ["Co Myszka Miki ma wspólnego z wydłużeniem okresu obowiązywania majątkowych praw autorskich? O ile został wydłużony okres obowiązywania praw majątkowych w stosunku do wcześniejszych przepisów?"],
-    "open_part": ["W jaki sposób dotarłeś/aś do tej informacji? Wklej adres strony, z której skorzystałeś/aś."],
-    "open_part_rows": 1,
-    "max_points": 2
-},
-
-{
-    "id": 4,
-    "type": "edumed_wybor",
-    "description": ["W którym z tych miast dojedziesz trolejbusem nr 150 z dworca PKP do al. Racławickich?"],
-    "options": [
-        {"id": 1, "text": "w Lublinie"},
-        {"id": 2, "text": "w Tychach"},
-        {"id": 3, "text": "w Gdyni"}
-    ],
-    "answer": [1],
-    "points": 1,
-    "open_part": ["W jaki sposób dotarłeś/aś do tej informacji? Wklej adres strony, z której skorzystałeś/aś."],
-    "open_part_rows": 1,
-    "max_points": 1.5
-},
-
-{
-    "id": 5,
-    "type": "edumed_wybor",
-    "description": ["Którą frazę należy dodać do zapytania w wyszukiwarce internetowej Google.com, aby wyszukać tylko prezentacje w formacie OpenDocument?"],
-    "options": [
-        {"id": 1, "text": "tylko prezentacje"},
-        {"id": 2, "text": "OpenDocument"},
-        {"id": 3, "text": "filetype:ppt"},
-        {"id": 4, "text": "filetype:odp"}
-    ],
-    "answer": [4],
-    "points": 1
-},
-
-{
-    "id": 6,
-    "type": "edumed_wybor",
-    "description": ["Do jakiej organizacji powinieneś/-nnaś się zwrócić, jeśli zapłaciłeś/-aś za zamówiony przez internet  towar i go nie otrzymałeś/-aś, a ze sprzedawcą nie ma kontaktu?"],
-    "options": [
-        {"id": 1, "text": "UOKiK"},
-        {"id": 2, "text": "UKE"},
-        {"id": 3, "text": "RZP"},
-        {"id": 4, "text": "KNF"}
-    ],
-    "answer": [1],
-    "points": 1
-},
-
-{
-    "id": 7,
-    "type": "open",
-    "description": ["Ile czasu, zgodnie z polskim prawem, klient ma na zwrot towaru/usługi zakupionych przez internet? Czy można to zrobić bez podawania przyczyny? Podaj, jaki akt prawny to reguluje."],
-    "max_points": 3
-},
-
-{
-    "id": 8,
-    "type": "open",
-    "description": ["Jakie poziomy widoczności swoich postów możesz ustawić na Facebooku? Wskaż co najmniej dwa."],
-    "max_points": 2
-},
-
-{
-    "id": 9,
-    "type": "open",
-    "description": ["Podaj przykład inicjatywy sfinansowanej metodą crowdfundingu. Czy w Polsce można finansować tą metodą różne przedsięwzięcia? Jeśli tak, to na jakiej podstawie prawnej?"],
-    "max_points": 2
-},
-
-{
-    "id": 10,
-    "type": "edumed_prawdafalsz",
-    "description": ["Oznacz poniższe zdania jako prawdziwe lub fałszywe."],
-    "statements": [
-        ["Akcyza to jeden z elementów polityki antymonopolowej.", false],
-        ["Większość (98%) treści w serwisie ninateka.pl jest dostępna za darmo bez konieczności logowania.", true],
-        ["GIODO to instytucja uprawniona do kontroli zgodności przetwarzanych danych z przepisami o ochronie danych osobowych.", true],
-        ["Polska telewizja publiczna utrzymuje się jedynie z wpływów finansowych z abonamentu radiowo-telewizyjnego.", false],
-        ["Grupa ITI jest właścicielem TV TVN oraz serwisu sympatia.pl.", true]
-    ],
-    "points_per_hit": 0.5
-},
-
-{
-    "id": 11,
-    "type": "open",
-    "description": ["Znajdź w sieci krótki przykład (tekstowy lub filmowy) każdego z podanych poniżej gatunków. W przypadku tekstu - wklej go i podaj jego źródło. Jeśli prezentujesz film - wklej link do strony, na której się znajduje."],
-    "fields": [
-        {"caption": "reportaż", "id": 1},
-        {"caption": "felieton", "id": 2},
-        {"caption": "wywiad", "id": 3}
-    ],
-    "max_points": 3
-},
-
-{
-    "id": 12,
-    "type": "open",
-    "description": ["Na podstawie poniższego tekstu przygotuj:"],
-    "fields": [
-        {"caption": "a. komunikat zawierający Twoją  opinię nt. proponowanych w rozporządzeniu zmian. Staraj się uargumentować swoje stanowisko.", "id": 1},
-        {"caption": "b. komunikat perswazyjny będący częścią kampanii informacyjno-promocyjnej nowych przepisów.", "id": 2}
-    ],
-    "description_after": [
-        "Opakowania,  pojemniki lub komory ładunkowe w środkach transportu powinny być  oznakowane w sposób trwały i czytelny, umożliwiać identyfikację rodzaju  transportowanych odpadów oraz posiadać widoczne odporne na warunki  atmosferyczne oznakowanie identyfikujące zawierające:<br/>1) kod odpadów w nich transportowanych zgodnie z katalogiem odpadów;<br/>2) imię i nazwisko oraz adres zamieszkania lub nazwę i adres siedziby wytwórcy odpadów. (...)"
-    ],
-    "max_points": 4
-},
-
-{
-    "id": 13,
-    "type": "edumed_wybor",
-    "description": ["Czy możesz opublikować niekomercyjnie remiks wierszy dostępnych w bibliotece internetowej Wolne Lektury? Dlaczego?"],
-    "options": [
-        {"id": 1, "text": "Nie mogę."},
-        {"id": 2, "text": "Mogę, ale dopiero kiedy uzyskam zgodę autorów/autorek lub ich spadkobierców."},
-        {"id": 3, "text": "Mogę. Uiściłem/-am opłaty na rzecz Funduszu Promocji Twórczości."},
-        {"id": 4, "text": "Mogę, wiersze z biblioteki Wolne Lektury znajdują się w domenie publicznej albo publikowane są na licencji CC BY-SA 3.0, która umożliwia taką publikację."}
-    ],
-    "answer": [4],
-    "points": 1
-},
-
-{
-    "id": 14,
-    "type": "open",
-    "description": ["Na czym polega tzw. otwarty dostęp? Podaj dwa przykłady inicjatyw realizowanych zgodnie z tym hasłem.  Podaj adres(y) stron(y), na której/ych znalazłeś(-aś) te informacje."],
-    "max_points": 3
-},
-
-{
-    "id": 15,
-    "type": "edumed_wybor",
-    "description": ["Wskaż wszystkie prawidłowe odpowiedzi dotyczące Urzędu Komisji Nadzoru Finansowego:"],
-    "options": [
-        {"id": 1, "text": "wydaje zezwolenia na prowadzenie działalności na rynku finansowym"},
-        {"id": 2, "text": "realizuje postanowienia KNF"},
-        {"id": 3, "text": "pracownicy Urzędu należą do korpusu służby cywilnej"},
-        {"id": 4, "text": "w skład urzędu wchodzi Departament Nadzoru Inwestycji Emerytalnych"}
-    ],
-    "answer": [2, 4],
-    "points_per_hit": 1
-},
-
-{
-    "id": 16,
-    "type": "edumed_wybor",
-    "description": ["Administrator strony zgodnej z <em>Wytycznymi dla dostępności treści internetowych</em> na najwyższym poziomie zgodności (AAA) może:"],
-    "options": [
-        {"id": 1, "text": "umieszczać na niej skany dokumentów bez OCR"},
-        {"id": 2, "text": "zamieszczać najważniejsze informacje w postaci audio lub wideo, dołączając alternatywną wersję tekstową"},
-        {"id": 3, "text": "wymagać od użytkownika wpisania słowa odczytanego z obrazka"},
-        {"id": 4, "text": "pisać, stosując żargon naukowy i nie wyjaśniając znaczenia trudniejszych pojęć"}
-    ],
-    "answer": [2],
-    "points": 1
-},
-
-{
-    "id": 17,
-    "type": "open",
-    "description": ["W  pobliskim domu kultury odbywa się koncert Twojej ulubionej grupy. Zaproś swojego nauczyciela języka polskiego (napisz e-mail). Poinformuj o tym wydarzeniu swoich znajomych na Facebooku. Pamiętaj, aby każdy z komunikatów był sformułowany zgodnie z zasadami medialnego savoire vivre'u."],
-    "fields": [
-        {"caption": "e-mail do nauczyciela", "id": 1},
-        {"caption": "wiadomość do znajomych", "id": 2}
-    ],
-    "max_points": 4
-},
-
-{
-    "id": 18,
-    "type": "edumed_wybor",
-    "description": [" Kolega prosi Cię w komentarzu na Facebooku o podanie numeru telefonu wspólnego znajomego. Co robisz?"],
-    "options": [
-        {"id": 1, "text": "telefonujesz do znajomego i pytasz go, czy możesz przekażać nr telefonu koledze"},
-        {"id": 2, "text": "przekazujesz nr znajomego smsem lub w prywatnej wiadomości"},
-        {"id": 3, "text": "podajesz nr telefonu w kolejnym komentarzu"}
-    ],
-    "answer": [1, 2],
-    "answer_mode": "all_or_nothing",
-    "points": 1
-},
-
-{
-    "id": 19,
-    "type": "file_upload",
-    "description": [
-        "Poszukujesz materiałów z blogów lub innych serwisów internetowych dotyczących księcia Józefa Poniatowskiego. Zależy Ci jednak, aby materiały te można było swobodnie wykorzystywać, udostępniać i modyfikować, także w celach komercyjnych. Stwórz odpowiednie zapytanie w wyszukiwarce; zrób zrzut ekranu przedstawiający zapytanie."
-    ],
-    "max_points": 2,
-    "max_file_size_string": "5 megabajtów"
-},
-
-{
-    "id": 20,
-    "type": "edumed_wybor",
-    "description": ["W przypadku logowania się w ramach sieci TOR dostawca internetu użytkownika zna:"],
-    "options": [
-        {"id": 1, "text": "numer IP użytkownika"},
-        {"id": 2, "text": "loginy i hasła użytkownika"},
-        {"id": 3, "text": "dane, które użytkownik przesyła i odbiera"},
-        {"id": 4, "text": "adresy stron, które użytkownik odwiedza"}
-    ],
-    "answer": [1],
-    "points": 1
-},
-
-{
-    "id": 21,
-    "type": "open",
-    "description": ["Podaj trzy przykłady wolnego oprogramowania."],
-    "max_points": 3
-}
-
-]
diff --git a/wtem/fixtures/exercises-2015.json b/wtem/fixtures/exercises-2015.json
deleted file mode 100644 (file)
index aa98785..0000000
+++ /dev/null
@@ -1,327 +0,0 @@
-[
-{
-    "id": 1,
-    "type": "edumed_przyporzadkuj",
-    "hide_default_instruction": 1,
-    "description": ["Które z fotografii umieścił(a)byś jako zdjęcie profilowe na portalu Facebook, które na LinkedIn, a które z nich na żadnej z tych stron?"],
-    "buckets": [
-        {"id": 1, "title": "Facebook"},
-        {"id": 2, "title": "Facebook"},
-        {"id": 3, "title": "Facebook"},
-        {"id": 4, "title": "Facebook"},
-        {"id": 5, "title": "LinkedIn"},
-        {"id": 6, "title": "LinkedIn"},
-        {"id": 7, "title": "LinkedIn"},
-        {"id": 8, "title": "LinkedIn"},
-        {"id": 9, "title": "nigdzie"},
-        {"id": 10, "title": "nigdzie"},
-        {"id": 11, "title": "nigdzie"},
-        {"id": 12, "title": "nigdzie"}
-    ],
-    "buckets_name": "strony",
-    "items": [
-        {"id": 1, "text": "1", "href_absolute": 1, "href": "https://www.flickr.com/photos/seeminglee/3942177783/", "img": "przyp2/1.jpg"},
-        {"id": 2, "text": "2", "href_absolute": 1, "href": "https://www.flickr.com/photos/davebloggs007/14573899083/","img": "przyp2/2.jpg"},
-        {"id": 3, "text": "3", "href_absolute": 1, "href": "https://www.flickr.com/photos/125303894@N06/14365668676/","img": "przyp2/3.jpg"},
-        {"id": 4, "text": "4", "href_absolute": 1, "href": "https://www.flickr.com/photos/gagilas/4224108472/","img": "przyp2/4.jpg"},
-        {"id": 5, "text": "5", "href_absolute": 1, "href": "https://www.flickr.com/photos/conejoazul/1455987854/", "img": "przyp2/5.jpg"}
-    ],
-    "items_name": "zdjęcia",
-    "items_instruction": "Przeciągnij numery zdjęć do odpowiednich szarych pól powyżej. W każdym szarym polu można umieścić tylko jeden numer.",
-    "items_inline": 1,
-    "description_after": ["<span class=\"wtem-disclaimer\">(Wszystkie użyte zdjęcia dostępne na CC BY lub CC BY-SA – źródła/autorzy dostępni po kliknięciu w obrazek)</span>"],
-    "points_per_hit": 0.5,
-    "answer_mode": "possible_buckets_for_item",
-    "answer": {
-        "1": [1,2,3,4],
-        "2": [1,2,3,4],
-        "3": [1,2,3,4,5,6,7,8],
-        "4": [9,10,11,12],
-        "5": [9,10,11,12]
-    }
-},
-
-{
-    "id": 2,
-    "type": "open",
-    "description": ["Twoja koleżanka wygrała ogólnopolski konkurs muzyczny, na którym zyskała uznanie jury i publiczności. Pogratuluj sukcesu w określonej poniżej formie:"],
-    "fields": [
-        {"id": 1, "caption": "1. tweet"},
-        {"id": 2, "caption": "2. wpis na tablicy na Facebooku"},
-        {"id": 3, "caption": "3. krótki mail do jej rodziców"}
-    ],
-    "max_points": 6
-},
-
-{
-    "id": 3,
-    "type": "open",
-    "description": ["Twoja mama jest początkującą użytkowniczką internetu. Prosi cię o rady, jak bezpiecznie korzystać z sieci. Przekaż jej co najmniej pięć wskazówek, które będzie mogła wykorzystać podczas codziennej pracy przy komputerze."],
-    "max_points": 5
-},
-
-{
-    "id": 4,
-    "type": "edumed_przyporzadkuj",
-    "description": ["Dopasuj nazwę wtyczki do jej działania:"],
-    "buckets": [
-        {"id": 1, "title": "AdBlock"},
-        {"id": 2, "title": "CookieMonster"},
-        {"id": 3, "title": "NoScript"},
-        {"id": 4, "title": "FlashBlock"}
-    ],
-    "buckets_name": "wtyczki",
-    "items": [
-        {"id": 1, "text": "1", "desc": "rozszerzenie do przeglądarek internetowych, automatycznie blokuje skrypty uruchamiane i zewnętrzne zasoby pobierane przez strony internetowe w przeglądarce."},
-        {"id": 2, "text": "2", "desc": "rozszerzenie do przeglądarek internetowych domyślnie blokujące wszystkie filmiki typu flash na stronach internetowych, pozwalające je uruchomić jednym kliknięciem myszki."},
-        {"id": 3, "text": "3", "desc": "rozszerzenie do przeglądarek internetowych, automatycznie blokuje i usuwa reklamy ze stron internetowych. Zwiększa wygodę i bezpieczeństwo korzystania z sieci. Ogranicza przepływ informacji o historii przeglądania."},
-        {"id": 4, "text": "4", "desc": "rozszerzenie do przeglądarek internetowych, pozwala bardzo dokładnie kontrolować ciasteczka i to, jakie strony (i na jak długo) mogą je ustawiać."}
-    ],
-    "items_name": "działania",
-    "answer": {
-        "1": [3],
-        "2": [4],
-        "3": [1],
-        "4": [2]
-    },
-    "points_per_hit": 0.5
-},
-
-{
-    "id": 5,
-    "type": "open",
-    "description": ["Podaj po jednym przykładzie serwisu (konkretne nazwy), który umożliwia podane niżej akcje."],
-    "instruction": "Każda strona może byc podana tylko jeden raz.",
-    "fields": [
-        {"id": 1, "caption": "budowanie i podtrzymywanie relacji", "rows": 1},
-        {"id": 2, "caption": "komunikację, dyskusję", "rows": 1},
-        {"id": 3, "caption": "bieżące informowanie i odnoszenie się do aktualności", "rows": 1},
-        {"id": 4, "caption": "prezentacja opinii i poglądów", "rows": 1},
-        {"id": 5, "caption": "współdzielenie plików", "rows": 1},
-        {"id": 6, "caption": "współtworzenie dokumentów", "rows": 1}
-    ],
-    "max_points": 3
-},
-
-{
-    "id": 6,
-    "type": "open",
-    "description": ["Wraz ze znajomymi 5 marca 2016 r. chcecie wybrać się w podróż z Zakopanego do Gdańska. Żadne z was nie posiada prawa jazdy i samochodu, nie chcecie korzystać z pomocy rodziców. Zależy wam, aby podróż trwała jak najkrócej i była jak najtańsza. Zaplanuj waszą podróż środkami transportu publicznego. Podaj godzinę rozpoczęcia i zakończenia podróży, szczegóły trasy i usług komunikacyjnych, z których skorzystacie.", "Podaj adres(y) stron(y), z których skorzystałeś/-aś."],
-    "max_points": 6
-},
-
-{
-    "id": 7,
-    "type": "open",
-    "description": ["Podaj cztery aspekty (obszary) prywatności człowieka."],
-    "max_points": 2
-},
-
-{
-    "id": 8,
-    "type": "open",
-    "description": ["Wyjaśnij krótko, na czym polega hakowanie w pozytywnym aspekcie tego zjawiska."],
-    "max_points": 5
-},
-
-{
-    "id": 9,
-    "type": "open",
-    "description": ["Wymień trzy przykłady projektów, które powstają i rozwijają się dzięki crowdsourcingowi."],
-    "max_points": 1.5
-},
-
-{
-    "id": 10,
-    "type": "edumed_przyporzadkuj",
-    "description": ["Dopasuj pojęcie do definicji:"],
-    "buckets": [
-        {"id": 1, "title": "dyskryminacja"},
-        {"id": 2, "title": "kryptoreklama"},
-        {"id": 3, "title": "cyberprzemoc"},
-        {"id": 4, "title": "koncesja"}
-    ],
-    "buckets_name": "pojęcia",
-    "items": [
-        {"id": 1, "text": "1", "desc": "stosowanie przemocy poprzez: prześladowanie, zastraszanie, nękanie,wyśmiewanie innych osób przy pomocy narzędzi typu elektronicznego,np. SMS, e-mail, witryny internetowe, fora dyskusyjne."},
-        {"id": 2, "text": "2", "desc": "traktowanie pewnych osób lub grup społecznych w inny sposób, zwykle mniej sprawiedliwy, niż innych osób i grup."},
-        {"id": 3, "text": "3", "desc": "zezwolenie,upoważnienie do prowadzenia jakiejś działalności."},
-        {"id": 4, "text": "4", "desc": "przekaz handlowy polegający na przedstawieniu lub nawiązywaniu do towaru, usługi lub ich znaku towarowego w taki sposób, że stanowią one element samej audycji."}
-    ],
-    "items_name": "definicje",
-    "answer": {
-        "1": [2],
-        "2": [4],
-        "3": [1],
-        "4": [3]
-    },
-    "points_per_hit": 0.5
-},
-
-{
-    "id": 11,
-    "type": "open",
-    "description": ["Istnieje dwanaście wytycznych dotyczących dostępności treści internetowych (WCAG). Każdą wytyczną przyporządkuj do jednej z czterech zasad."],
-    "instruction": "Wpisz litery do odpowiednich pól tekstowych.",
-    "fields": [
-        {"id": 1, "caption": "zrozumiałość", "rows": 1},
-        {"id": 2, "caption": "brak przeszkód w obsłudze", "rows": 1},
-        {"id": 3, "caption": "postrzegalność zmysłowa", "rows": 1},
-        {"id": 4, "caption": "solidne wykonanie", "rows": 1}
-    ],
-    "description_after": [
-        "a) teksty są czytelne i łatwe w odbiorze",
-        "b) treść ma swój odpowiednik: obrazom i filmom towarzyszą opisy tekstowe, głosowe,napisy, tłumaczenia na język migowy",
-        "c) treść jest eksponowana za pomocą najnowszych technologii uwzględniających wytyczne dotyczące dostępności",
-        "d) prezentacja treści (kształt graficzny, styl) nie wpływa na odbiór",
-        "e) strona jest możliwa w obsłudze przy użyciu klawiatury",
-        "f) do treści można dotrzeć różnymi drogami (urządzenia, oprogramowanie)",
-        "g) interfejs jest intuicyjny i logicznie zbudowany",
-        "h) trudno popełnić błąd w obsłudze interfejsu",
-        "i) nie ma limitów czasowych w korzystaniu z serwisu",
-        "j) informacje pierwszoplanowe nie zlewają się z tłem",
-        "k) sekcje na stronie mają jednoznaczne tytuły i są logicznie podzielone",
-        "l) można pominąć szkodliwe dla wzroku i słuchu komunikaty"
-    ],
-    "max_points": 6
-},
-
-{
-    "id": 12,
-    "type": "edumed_wybor",
-    "description": ["Na co NIE pozwala ci dozwolony użytek?"],
-    "options": [
-        {"id": 1, "text": "na sprzedawanie kopii płyt z muzyką twojego ulubionego zespołu"},
-        {"id": 2, "text": "na oglądanie filmu pobranego z internetu"},
-        {"id": 3, "text": "na nagranie serialu na płytę i obejrzenie go z rodziną"},
-        {"id": 4, "text": "żadna z powyższych odpowiedzi nie jest prawidłowa"}
-    ],
-    "answer": [1],
-    "points": 1
-},
-
-{
-    "id": 13,
-    "type": "edumed_wybor",
-    "description": ["Chcesz opublikować swoje opowiadanie na wolnej licencji. Zezwalasz na jego kopiowanie, zmienianie, remiksowanie, rozprowadzanie i wykonanie, ale pod warunkiem, że ewentualne utwory zależne -- np. tłumaczenia -- będą przez ich autorów udostępnione na takiej samej licencji. Którą z licencji wybierzesz?"],
-    "options": [
-        {"id": 1, "text": "CC BY-SA"},
-        {"id": 2, "text": "CC BY-NC"},
-        {"id": 3, "text": "CC BY"},
-        {"id": 4, "text": "żadną z wymienionych"}
-    ],
-    "answer": [1],
-    "points": 1
-},
-
-{
-    "id": 14,
-    "type": "edumed_wybor",
-    "description": ["Do nawyków higieny informacyjnej należą:"],
-    "options": [
-        {"id": 1, "text": "tworzenie kopii zapasowych informacji, na których nam zależy"},
-        {"id": 2, "text": "odczytywanie informacji na specjalnym czytniku"},
-        {"id": 3, "text": "robienie przerw co 20 minut, aby uporządkować informacje"},
-        {"id": 4, "text": "ograniczenie korzystania z „usług w chmurze”"},
-        {"id": 5, "text": "szyfrowanie danych na dysku twardym"},
-        {"id": 6, "text": "korzystanie z technologii anonimizujących"},
-        {"id": 7, "text": "mycie rąk po skorzystaniu z komputera"}
-    ],
-    "answer": [1,4,5,6],
-    "answer_mode": "all_or_nothing",
-    "points": 2
-},
-
-{
-    "id": 15,
-    "type": "edumed_przyporzadkuj",
-    "description": ["Dopasuj rodzaj formatu do jego cech charakterystycznych."],
-    "buckets": [
-        {"id": 1, "title": "JPG"},
-        {"id": 2, "title": "PDF"},
-        {"id": 3, "title": "OpenDocument"},
-        {"id": 4, "title": "PNG"},
-        {"id": 5, "title": "EPUB"}
-    ],
-    "buckets_name": "formaty",
-    "items": [
-        {"id": 1, "text": "1", "desc": "format plików służący do prezentacji, przenoszenia i drukowania treści tekstowo-graficznych. Jego zastosowanie zapewnia to, że po otwarciu w innym programie nie zmieni się to, jak wyglądają poszczególne strony."},
-        {"id": 2, "text": "2", "desc": "format obrazów rastrowych (bitmap), najlepiej sprawdzający się przy zapisie fotografii oraz obrazów naturalnych (pejzaży, portretów itp.), w których barwy płynnie przechodzą i w których nie ma wiele ostrych krawędzi czy drobnych detali. Przy zapisie w tym formacie dokonywana jest stratna kompresja, co sprawia, że część informacji zostaje bezpowrotnie utracona."},
-        {"id": 3, "text": "3", "desc": "otwarty standard,oparty na języku XML, służący do publikowania elektronicznych książek. Tworzone w nim książki nie mają podziału na strony,choć istnieje możliwość wyświetlania na marginesie numeru strony pochodzącego z książki drukowanej."},
-        {"id": 4, "text": "4", "desc": "format plików pakietów biurowych, będący otwartym standardem ISO (Międzynarodowej Organizacji Normalizacyjnej), podstawowy dla wolnych programów do edycji tekstu."},
-        {"id": 5, "text": "5", "desc": "rastrowy format plików graficznych, korzystający z kompresji bezstratnej."}
-    ],
-    "items_name": "definicje",
-    "answer": {
-        "1": [2],
-        "2": [1],
-        "3": [4],
-        "4": [5],
-        "5": [3]
-    },
-    "points_per_hit": 0.5
-},
-
-{
-    "id": 16,
-    "type": "open",
-    "description": ["Podaj min. 3 objawy obecności wirusa na twoim komputerze."],
-    "max_points": 3
-},
-
-{
-    "id": 17,
-    "type": "open",
-    "description": ["Wyszukaj w odpowiednim katalogu Biblioteki Narodowej artykuły z polskich czasopism opublikowane w 2010 roku, które dotyczyły edukacji medialnej. Podaj liczbę tekstów oraz 3 tytuły czasopism, w których je opublikowano."],
-    "max_points": 6
-},
-
-{
-    "id": 18,
-    "type": "open",
-    "description": ["Podaj co najmniej 3 działania, które możesz podjąć, aby wyjść z bańki filtrującej."],
-    "max_points": 3
-},
-
-{
-    "id": 19,
-    "type": "open",
-    "description": ["Zauważyłeś/-aś, że twój kolega coraz rzadziej wychodzi z domu i ma coraz gorsze wyniki w nauce, za to ciągle siedzi przed komputerem. Domyślasz się, że jest uzależniony od internetu. Udziel mu co najmniej trzech rad, jak uwolnić się od tego nałogu."],
-    "max_points": 3
-},
-
-{
-    "id": 20,
-    "type": "edumed_wybor",
-    "description": ["Z poniższej listy wybierz czynności i rzeczy, na podstawie których stosowane jest profilowanie w sieci."],
-    "options": [
-        {"id": 1, "text": "przeglądane strony internetowe"},
-        {"id": 2, "text": "słowa wpisywane w wyszukiwarce internetowej"},
-        {"id": 3, "text": "informacje o sobie publikowane w sieci (np. wiek, płeć, zainteresowania)"},
-        {"id": 4, "text": "odpowiedzi na internetowe ankiety"},
-        {"id": 5, "text": "„polubienia” w serwisie społecznościowym"},
-        {"id": 6, "text": "informacje o geolokalizacji"},
-        {"id": 7, "text": "przedmioty oglądane w sklepach internetowych"},
-        {"id": 8, "text": "przedmioty kupione w sklepach internetowych"}
-    ],
-    "answer": [1,2,3,4,5,6,7,8],
-    "answer_mode": "all_or_nothing",
-    "points": 2
-},
-
-{
-    "id": 21,
-    "type": "open",
-    "description": ["Chcesz usunąć profil na Facebooku, ale nie chciał(a)byś utracić danych i treści, które udostępniałeś. Jak je zdobyć? Jakie dane ocaleją (wymień 3 rodzaje)?"],
-    "max_points": 2.5
-},
-
-{
-    "id": 22,
-    "type": "open",
-    "description": ["Znajdź informacje o 2 organizacjach pozarządowych, które działają w Twojej okolicy. Komu pomagają?",
-        "W jaki sposób dotarłeś/aś do tej informacji? Wklej adres strony, z której skorzystałeś/aś."],
-    "max_points": 3
-}
-
-]
\ No newline at end of file
diff --git a/wtem/fixtures/exercises-tem.json b/wtem/fixtures/exercises-tem.json
deleted file mode 100644 (file)
index 6ad8716..0000000
+++ /dev/null
@@ -1,173 +0,0 @@
-[
-
-{
-    "id": 1,
-    "type": "open",
-    "description": ["Zbieranie literatury, aby przygotować własne wystąpienie to trudne zadanie, ale dzięki zasobom internetu może obecnie odbywać się w dużej części on-line. Przygotuj wystąpienie, które może być częścią szkolenia z edukcji medialnej. Wymyśl temat, do którego należy zebrać literaturę . Opisz w 3-5 zdaniach, czego dotyczyć będzie referat i wskaż do jakiej grupy docelowej będzie skierowany. Zaproponuj 2 źródła informacji w Internecie, które mogą się okazać użyteczne (uzasadnij dokonany wybór dla każdego ze źródeł). Dla każdego ze źródeł informacji wskaż, jak będzie wyglądać instrukcja wyszukiwawcza (używane terminy, odpowiednie operatory logiczne, ew. maskowanie końcówek, itd.)."],
-    "fields": [
-        {"caption": "Temat", "rows": 3, "id": "temat"},
-        {"caption": "Krótki opis wystąpienia", "id": "opis"},
-        {"caption": "Grupa docelowa", "id": "grupa"},
-        {"caption": "Źródło 1 (link, uzasadnienie, instrukcja wyszukiwawcza)", "id": "zrodlo1"},
-        {"caption": "Źródło 2 (link, uzasadnienie, instrukcja wyszukiwawcza)", "id": "zrodlo2"}
-    ],
-    "max_points": 12
-},
-
-{
-    "id": 2,
-    "type": "open",
-    "description": [
-        "Wykorzystaj znalezione w zadaniu 1 materiały i zawarte w nich informacje, aby przygotować graficzną ilustrację treści przedstawianych w wystąpieniu (infografika lub prezentacja multimedilana - maks. długośc prezentacji 12 slajdów). Zwróć uwagę na logiczne i klarowne przedstawienie informacji - toku rozumowania. Zadbaj o kwestie właściwego wskazania źródeł prezentownych informacji. Postaraj się rozwiązaniami graficznymi estetycznie wzmocnić przekaz wystąpienia."
-    ],
-    "fields": [
-        {"caption": "Plik z prezentacją", "type": "file", "id": "plik"},
-        {"caption": "Ew. link do prezentacji", "rows": 1, "id": "link"}
-    ],
-    "max_points": 8
-},
-
-{
-    "id": 3,
-    "type": "open",
-    "description": [
-        "Uczestnik Twoich warsztatów zwrócił się do Ciebie z prośbą o poradę w stworzeniu strony internetowej. Od kilku lat interesuje się modą, myśli o założeniu własnego bloga. Zależy mu na tym, żeby już teraz, mimo młodego wieku, świadomie budować w sieci swój wizerunek eksperta. Prosi Cię o polecenie trzech blogów, którymi według Ciebie mógłby się inspirować.",
-        "Podaj trzy strony oraz uzasadnij jakimi kryteriami się kierowałaś/eś, wybierając każdą z nich. Stwórz również mini katalog zasad, którymi wg Ciebie powinien się kierować przy prowadzeniu własnego bloga (min. 5 zasad)."
-    ],
-    "fields": [
-        {"caption": "Link + uzasadnienie (1)", "id": "link1"},
-        {"caption": "Link + uzasadnienie (2)", "id": "link2"},
-        {"caption": "Link + uzasadnienie (3)", "id": "link3"},
-        {"caption": "Katalog zasad", "id": "zasady"}
-    ],
-    "max_points": 11
-},
-
-{
-    "id": 4,
-    "type": "open",
-    "description": [
-        "Na nasz wizerunek w internecie wpływa między innymi język, jakim się posługujemy oraz umiejętność dyskutowania. Młodzież często ma problemy z określeniem granicy pomiędzy wolnością słowa a hejtowaniem czy mową nienawiści. „Konstytucja przecież gwarantuje nam wolnośćwypowiedzi, więc…!” - często słyszysz to zdanie, pracując ze swoją grupą. Postanawiasz więc przygotować warsztaty dotyczące powyższego zagadnienia.",
-        "Znajdź w internecie po jednym przykładzie obrazującym: mowę nienawiści, hejt, wolność słowa. Uzasadnij swój wybór. Przykłady przedstaw w postaci zrzutów ekranu (pamiętaj o ich odpowiednim przygotowaniu: np. wymazaniu danych osobowych i/lub zdjęcia profilowego)."
-    ],
-    "fields": [
-        {"caption": "Zrzut ekranu (1)", "type": "file", "id": "zrzut1"},
-        {"caption": "Uzasadnienie (1)", "id": "uzasadnienie1"},
-        {"caption": "Zrzut ekranu (2)", "type": "file", "id": "zrzut2"},
-        {"caption": "Uzasadnienie (2)", "id": "uzasadnienie2"},
-        {"caption": "Zrzut ekranu (3)", "type": "file", "id": "zrzut3"},
-        {"caption": "Uzasadnienie (3)", "id": "uzasadnienie3"}
-    ],
-    "max_points": 9
-},
-
-{
-    "id": 5,
-    "type": "open",
-    "description": [
-        "Przeczytaj polecenie poniżej. Wykonanie proponowanego zadania w tej formie niesie ze sobą pewne ryzyka. Jakich informacji w nim brakuje? Na co powinieneś/powinnaś zwrócić uwagę uczestniczek i uczestników?",
-        "Zadanie: Zdjęcia w sieci. Poproś uczniów o przygotowanie na lekcję dwóch zdjęć: jednego które wykonają sami, na którym będzie widnieć ktoś spośród innych uczniów z ich szkoły oraz drugiego zdjęcia, które mogą wykonać sami lub znaleźć w sieci, na którym widnieje znana osoba np. aktor lub pisarz. Następnie na lekcji poproś aby wybrali najlepszy technicznie serwis, w którym umieszczą te zdjęcia i opublikowali je, wybierając dla nich jedną z licencji Creative Commons."
-    ],
-    "max_points": 10
-},  
-
-{
-    "id": 6,
-    "type": "open",
-    "description": [
-        "W sieci dostępnych jest wiele utworów, do których prawa autorskie już wygasły (znajdują się w domenie publicznej) i można z nich swobodnie korzystać. Niestety wiele z nich nie jest wcale jasno opisanych i często nie wiemy, jakie mamy do nich prawa.",
-        "Przygotowujesz zajęcia na temat domeny publicznej. Utwory, które chcesz pokazać uczniom, o których wiesz, że prawa do nich wygałsy, w sieci często są opisane znaczkiem „copyright” lub podobnymi infomacjami. Chcesz przygotować zajęcia tak, aby omówić ten problem i pomóc uczestnikom uniknąć pomyłki w przyszłości.",
-        "a) Znajdź w sieci przykład utworu np. obrazu lub fotografii, który znajduje się w domenie publicznej, ale nie we wszystkich, nawet oficjalnych źródłach, jest tak opisany. Podaj linki do dwóch różnych miejsc w sieci, gdzie ten sam utwór jest oznaczony jako domena publiczna i drugiego, gdzie brakuje takiego opisu lub utwór jest oznaczony jako chroniony."
-    ],
-    "fields": [
-        {"caption": "Utwór", "rows": 1, "id": "a-utwor"},
-        {"caption": "Link (1)", "rows": 1, "id": "a-link-1"},
-        {"caption": "Link (2)", "rows": 1, "id": "a-link-2"},
-        {"caption": "b) Podaj dwa przykłady tego, jak można oznaczyć utwór znajdujący się w domenie publicznej, które będziesz mógł/mogła zasugerować uczniom, aby łatwiej było im rozpoznać takie utwory.", "id": "b"},
-        {"caption": "c) Podaj co najmniej trzy przykłady serwisów w sieci, które możesz polecić uczniom, w których nie będą oni mieli problemów z rozpoznaniem praw do danego utworu.<br><br>Link(1)", "rows": 1, "id": "c-1"},
-        {"caption": "Link (2)", "rows": 1, "id": "c-link-2"},
-        {"caption": "Link (3)", "rows": 1, "id": "c-link-3"}
-    ],  
-    "max_points": 10
-},  
-
-{
-    "id": 7,
-    "type": "open",
-    "description": [
-        "Znajdź w Internecie zdjęcie lub krótki film, które odwoływać się będą do zjawiska cyberprzemocy. Na ich podstawie zbuduj dwa zadania dla uczniów i uczennic gimnazjum, z których:",
-        "a. Pierwsze będzie analizą tekstu kultury (np.karta pracy, ankieta).",
-        "b. Drugie będzie omawiać zjawisko (w powiązaniu z tekstem kultury)."
-    ],
-    "fields": [
-        {"caption": "Link do znalezionego materiału", "rows": 1, "id": "link"},
-        {"caption": "Plik (1)", "type": "file", "id": "plik1"},
-        {"caption": "Plik (2)", "type": "file", "id": "plik2"}
-    ],
-    "max_points": 12
-},
-
-{
-    "id": 8,
-    "type": "file_upload",
-    "description": [
-        "Zaproponuj ćwiczenie, które będzie doskonaliło umiejętność pracy w chmurze na poziomie liceum. Młodzież na wykonanie zadania ma 45 minut. W sali są komputery (przy komputerze siedzą dwie osoby), wszyscy mają dostęp do internetu w telefonach komórkowych."
-    ],
-    "max_points": 8
-},
-
-{
-    "id": "9a",
-    "id_show": 9,
-    "type": "edumed_wybor",
-    "description": [
-        "Przygotowujesz się do przeprowadzenia zajęć poświęconych cyfrowym narracjom i publikowaniu własnych materiałów multimedialnych w sieci.",
-        "a) Wybierz prawidłową definicję terminu „narracja cyfrowa”:"],
-    "options": [
-        {"id": 1, "text": "Narracja cyfrowa to zaszyfrowana opowieść tekstowa zapisana w formie kodu binarnego."},
-        {"id": 2, "text": "Narracja cyfrowa to opowieść (filmowa, złożona z kolekcji zdjęć lub nagrania radiowego) nadawana na żywo w internecie."},
-        {"id": 3, "text": "Narracja cyfrowa to nagrany za pomocą cyfrowej kamery wideo film, opublikowany następnie w serwisie YouTube lub Vimeo."},
-        {"id": 4, "text": "Narracja cyfrowa to opowieść przygotowana w formie filmu lub podcastu, składająca się - w zależności od ostatecznej formy ze zdjęć, wideo, nagranego głosu lub dźwięków otoczenia."}
-    ],
-    "answer": [4],
-    "points": 2,
-    "max_points": 11
-},
-
-{
-    "id": "9b",
-    "continuation": true,
-    "type": "open",
-    "description": ["b) Znajdź w internecie trzy przykłady cyfrowych narracji."],
-    "fields": [
-        {"caption": "Link (1)", "rows": 1, "id": "link-1"},
-        {"caption": "Link (2)", "rows": 1, "id": "link-2"},
-        {"caption": "Link (3)", "rows": 1, "id": "link-3"}
-    ],
-    "max_points": 3
-},
-
-{
-    "id": "9c",
-    "continuation": true,
-    "type": "open",
-    "description": ["c) Wskaż trzy źródła treści, które można legalnie wykorzystać do tworzenia własnych materiałów multimedialnych (np. własnego vloga, prezentacji multimedialnej, podcastu, wpisu blogowego). Przy każdym wskazanym źródle wyjaśnij w jednym zdaniu, dlaczego można z niego skorzystać."
-    ],
-    "fields": [
-        {"caption": "Źródło zdjęć i grafik (link + uzasadnienie)", "id": "link-1"},
-        {"caption": "Źródło materiałów dźwiękowych (link + uzasadnienie)", "id": "link-2"},
-        {"caption": "Źródło materiałów wideo (link + uzasadnienie)", "id": "link-3"}
-    ],
-    "max_points": 6
-},
-
-{
-    "id": 10,
-    "type": "file_upload",
-    "description": [
-        "Zaplanuj przygotowania do realizacji wspólnej narracji cyfrowej przez całą klasę na wybranym przez Ciebie etapie edukacyjnym. Wyznacz i uzasadnij kolejne kroki realizacji w formie harmonogramu.  Zaproponuj, jak podzielisz klasę na grupy i przydzielisz im konkretne zadania. Opisz, jaki będzie efekt końcowy i jakie należy Twoim zdaniem spełnić warunki, żeby współpraca pomiędzy grupami była możliwa i przyczyniła się do wysokiej jakości realizacji narracji cyfrowej. Wskaż i uzasadnij, jakich narzędzi użyłbyś/użyłabyś na kolejnych etapach realizacji projektu."
-    ],
-    "max_points": 9
-}
-
-]
diff --git a/wtem/fixtures/exercises-wlem.json b/wtem/fixtures/exercises-wlem.json
deleted file mode 100644 (file)
index fac4005..0000000
+++ /dev/null
@@ -1,152 +0,0 @@
-[
-
-{
-    "id": 1,
-    "type": "open",
-    "description": [
-        "W sieci nieustannie pojawiają się nowe zagrożenia, która bardzo często celują w naszą nieuwagę i słabą higienę pracy z komputerem. Są to m.in. phishing, a ostatnio ransomware. Chcesz przygotować uczestników zajęć na to, by potrafili rozpoznawać je i unikać ryzykowanych sytuacji. Twoim zadaniem jest przygotowanie zajęć, które wyczulą uczestników na sygnały, które mogą świadczyć o zbliżającym się zagrożeniu.",
-        ""
-    ],
-    "fields": [
-        {"caption": "a) Wypisz 2 oznaki tego, że mail, strona WWW lub sms mogą być atakiem phishingowym.", "id": "1a"},
-        {"caption": "b) Wypisz 2 porady jak możesz zabezpieczyć się przed konsekwencjami działania ransomware.", "id": "1b"},
-        {"caption": "c) Wymyśl i opisz krótko propozycję ćwiczenia, które w praktyczny sposób nauczy jak odróżniać groźne wiadomości mailowe, strony WWW czy sms-y, które mogą być atakami. Wybierz jeden z tych sposobów ataku, znajdź w sieci jeden przykład historii ataku w Polsce, który będzie mógł posłużyć Ci za przykład w ćwiczeniu. Przygotuj krótką instrukcje dla uczestników zajęć – co mają zrobić w ramach ćwiczenia? Uwaga! Nie podpowiadaj uczestnikom za bardzo, spróbuj pobudzić ich czujność i samodzielność.", "id": "1c"}
-    ],
-    "max_points": 10
-},
-
-{
-    "id": 2,
-    "type": "open",
-    "description": [
-        "Twoja instytucja/organizacja posiada współczesnego patrona (np. Jana Nowaka-Jeziorańskiego). Chcesz zorganizować publiczną wystawę na jego temat oraz wspomnień o nim jego bliskich, rodziny i przyjaciół. Będziecie potrzebować do tego zdjęć Nowaka-Jeziorańskiego oraz zdjęć jego bliskich. Zdjęcia do wystawy mają pozyskać uczestnicy Twoich zajęć."
-    ],
-    "fields": [
-        {"caption": "a) Na co powinnaś zwrócić im uwagę: podaj jakie obszary prawa mogą być ważne w tym zadaniu?", "id": "2a"},
-        {"caption": "b) Co zawrzesz w instrukcji dot. Pozyskiwania praw do zdjęć? Podaj 3 przykładowe porady z dwóch różnych obszarów prawa.", "id": "2b"}
-    ],
-    "max_points": 11
-},
-
-{
-    "id": 3,
-    "type": "open",
-    "description": [
-        "Czy wiesz, kiedy autorzy i prawo wymagają, by podczas wykorzystania cudzego utworu podpisać odpowiednio utwór? Co możesz zrobić z utworem który cytujesz, a co z takim dostępnym na jednej z licencji CC?"
-    ],
-    "fields": [
-        {"caption": "a) Znajdź w sieci przykład utworu literackiego chronionego przez prawo autorskie, który mogłabyś użyć w krytycznym opracowaniu na temat jego autora/ki. Opisz ten cytat tak jakbyś zrobiła to w.w. publikacji.", "id": "3a"},
-        {"caption": "b) Napisz krótkie uzasadnienie, co pozwala Ci zacytować ten utwór w powyższej sytuacji.", "id": "3b"},
-        {"caption": "c) Znajdź w sieci przykłady utworów (po jednym do każdej sytuacji). Podaj linki do nich razem z opisem licencji/praw.<br><br>na licencji Creative Commons Uznanie autorstwa – Użycie niekomercyjne,", "id": "cc-by-nc"},
-        {"caption": "na licencji Creative Commons Uznanie autorstwa – bez utworów zależnych,", "id": "cc-by-nd"},
-        {"caption": "utworu z domeny publicznej.", "id": "pd"},
-        {"caption": "d) Uszereguj wszystkie utwory z pkt. a) i c) wg swobody wykorzystania (od tych z najszerszą swobodą)", "id": "3d"}
-    ],
-    "max_points": 12
-},
-
-{
-    "id": 4,
-    "type": "open",
-    "description": [
-        "Doceniając potencjał mediów społecznościowych i wykorzystując ich różne formy, przygotuj trasę wycieczki: „Najpiękniejsze murale w Polsce”."
-    ],
-    "fields": [
-        {"caption": "a) Opisz w maksymalnie 7 punktach przebieg wycieczki.", "id": "4a"},
-        {"caption": "b) Wskaż minimum 3 źródła informacji, z których skorzystałaś, uzasadniając ich użyteczność i kryteria wyboru, którymi się kierowałaś. Weź pod uwagę różnorodność mediów społecznościowych i ich różne funkcje.", "id": "4b"}
-    ],
-    "max_points": 8
-},
-
-{
-    "id": 5,
-    "type": "open",
-    "description": [
-        "Wyjaśnij, jakie są różnice między telenowelą dokumentalną a mockumentem. Podaj 2 wiarygodne źródła, gdzie można znaleźć informacje na ten temat."
-    ],
-    "fields": [
-        {"caption": "a) Różnice", "id": "5a"},
-        {"caption": "b) Źródła informacji.", "id": "5b"}
-    ],
-    "max_points": 3
-},  
-
-{
-    "id": 6,
-    "type": "open",
-    "description": [
-        "Zostałaś poproszona przez swojego pracodawcę o przygotowanie warsztatu z zakresu edukacji medialnej na temat: „Informacja a opinia. Jak je rozróżnić?”. Wyszukaj w internecie po 3 zestawy tekstów, z których przygotujesz karty pracy dla uczestników. W każdym zestawie uczestnik warsztatów będzie musiał wskazać, który tekst jest informacją, a który opinią. Przygotowując się, weź pod uwagę: wydanie online dziennika opinii, portal internetowy i medium społecznościowe."
-    ],
-    "fields": [
-        {"caption": "Wskaż 3 zestawy tekstów, z których przygotujesz karty pracy dla uczestników.", "id": "6a"},
-        {"caption": "Uzasadnij, czym się kierowałaś, dokonując wyboru.", "id": "6b"}
-    ],
-    "max_points": 6
-},
-
-{
-    "id": "7a",
-    "id_show": 7,
-    "type": "edumed_wybor",
-    "description": [
-        "Zaproponuj ćwiczenie poszerzające umiejętności grupy, z którą najczęściej pracujesz, w zakresie (wybierz jeden z trzech)"
-    ],
-    "options": [
-        {"id": 1, "text": "formatowania pliku tekstowego,"},
-        {"id": 2, "text": "obróbki obrazu,"},
-        {"id": 3, "text": "montażu wideo."}
-    ],
-    "answer": [1],
-    "points": 0,
-    "max_points": 12
-},
-
-{
-    "id": "7b",
-    "continuation": true,
-    "type": "open",
-    "description": [],
-    "fields": [
-        {"caption": "Opisz grupę, dla której planujesz ćwiczenie (wiek, posiadane już umiejętności i doświadczenie w korzystaniu z nowych technologii)", "id": "7a"},
-        {"caption": "Podaj cel (cele) ćwiczenia oraz jego rezultaty (po zakończeniu ćwiczenia uczestnik/uczestniczka: 1. wie… 2. rozumie… 3. umie…)", "id": "7b"},
-        {"caption": "Zaplanuj ćwiczenie w czasie (ile czasu potrzebujesz? Ile czasu zajmą poszczególne części ćwiczenia?)", "id": "7c"},
-        {"caption": "Opisz, czego potrzebujesz (materiały, oprogramowanie), żeby je zrealizować. Jeśli ćwiczenie zakłada wykorzystanie przykładowych materiałów (np. tekst, zdjęcie, wideo) – dołącz je do ćwiczenia. Jeśli częścią ćwiczenia jest zdobycie tych materiałów przez uczestników – uwzględnij to w opisie ćwiczenia. ", "id": "7d"},
-        {"caption": "Opisz przebieg ćwiczenia tak, by było ono zrozumiałe nie tylko dla Ciebie, ale dla innych osób chcących je wykorzystać w pracy ze swoimi grupami.", "id": "7e"}
-    ],
-    "max_points": 12
-},
-
-{
-    "id": 8,
-    "type": "open",
-    "description": [
-        "Korzystając z technologii informacyjno-komunikacyjnych (TIK) internauci narażeni są na to, że ktoś wykorzysta ich wizerunek lub twórczość niezgodnie z prawem.  Zaplanuj dla grupy, z którą pracujesz, ćwiczenie przygotowujące jej członków/członkinie do interwencji w takiej sytuacji."
-    ],
-    "fields": [
-        {"caption": "a) Opisz grupę, dla której planujesz ćwiczenie (wiek, posiadane już umiejętności i doświadczenie w korzystaniu z TIK),", "id": "8a"},
-        {"caption": "b) Znajdź (pamiętaj o podaniu źródeł) lub stwórz przykłady dwóch sytuacji dotyczących naruszenia wizerunku i/lub praw autorskich w mediach – pasujących do sytuacji, z jakimi mogą się spotkać uczestnicy/uczestniczki Twoich zajęć.", "id": "8b"},
-        {"caption": "c) Stwórz listę możliwych działań interwencyjnych pasujących do tych sytuacji, które możesz omówić podczas zajęć.", "id": "8c"},
-        {"caption": "d) Opisz przebieg ćwiczenia tak, by było ono zrozumiałe nie tylko dla Ciebie, ale dla innych osób chcących je wykorzystać w pracy z grupami.", "id": "8d"}
-    ],
-    "max_points": 12
-},
-
-{
-    "id": 9,
-    "type": "open",
-    "description": [
-        "Przyjrzyj się, jak w praktyce wygląda komunikacja w sieci. Wykorzystaj do tego własne doświadczenia z portali społecznościowych czy informacyjnych.",
-        "Przypomnij sobie sytuacje, w których zabierałaś głos w toczących się tam dyskusjach. Przyjrzyj się językowi, którego używałaś. Czy sprzyjał on osiągnięciu celów, które sobie zakładałaś włączając się w dyskusję? Czy język, który tam spotkałaś wolny był od agresji, mowy nienawiści i hejtu?",
-        "Jeśli dotąd nie miałaś doświadczenia komunikacji z internautami lub nie umiesz przywołać takich doświadczeń – zdobądź je!",
-        "<br>W odpowiedzi możesz pominąć tematy, na które zabierałaś głos – Twoje poglądy nie mają znaczenia dla oceny zadania. Podczas oceny zadania liczyć się będzie: zwięzły opis konkretnych doświadczeń i sytuacji, które spotkałeś/spotkałaś oraz Twoje pomysły na przełożenie ich na pracę z grupami."
-    ],
-    "fields": [
-        {"caption": "Opisz krótko wnioski z Twoich doświadczeń.", "id": "9a"},
-        {"caption": "Jak wykorzystasz je w pracy z Twoją grupą/grupami? Dlaczego?", "id": "9b"},
-        {"caption": "Jaką aktywność na podstawie swoich wniosków zaproponujesz grupie?", "id": "9c"},
-        {"caption": "Jakie cele chciałabyś osiągnąć swoim ćwiczeniem?", "id": "9d"}
-    ],
-    "max_points": 12
-}
-]
-
diff --git a/wtem/fixtures/exercises.json b/wtem/fixtures/exercises.json
deleted file mode 100644 (file)
index 0637a08..0000000
+++ /dev/null
@@ -1 +0,0 @@
-[]
\ No newline at end of file
diff --git a/wtem/forms.py b/wtem/forms.py
deleted file mode 100644 (file)
index ae406a3..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-# -*- coding: utf-8 -*-
-import re
-
-from django import forms
-
-from .models import Submission, Attachment, exercises
-
-
-class WTEMForm(forms.ModelForm):
-    class Meta:
-        model = Submission
-        fields = ('answers',)
-
-    def __init__(self, *args, **kwargs):
-        super(WTEMForm, self).__init__(*args, **kwargs)
-        for exercise in exercises:
-            if exercise['type'] != 'file_upload':
-                continue
-            self.fields['attachment_for_' + str(exercise['id'])] = forms.FileField(required=False)
-
-    def save(self, commit=True):
-        submission = super(WTEMForm, self).save(commit=commit)
-        for name, attachment_file in self.files.items():
-            m = re.match(r'attachment_for_(\d+)(?:__(.*))?', name)
-            exercise_id = int(m.group(1))
-            tag = m.group(2) or None
-            try:
-                attachment = Attachment.objects.get(submission=submission, exercise_id=exercise_id, tag=tag)
-            except Attachment.DoesNotExist:
-                attachment = Attachment(submission=submission, exercise_id=exercise_id, tag=tag)
-            attachment.file = attachment_file
-            attachment.save()
diff --git a/wtem/management/__init__.py b/wtem/management/__init__.py
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/wtem/management/commands/__init__.py b/wtem/management/commands/__init__.py
deleted file mode 100644 (file)
index e39656a..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-from django.core.mail import EmailMessage
-from django.conf import settings
-
-def send_mail(subject, body, to):
-    if not isinstance(to, list):
-        to = [to]
-
-    reply_to = getattr(settings, 'WTEM_REPLY_TO', None)
-    headers = dict()
-    if reply_to:
-        headers['Reply-To'] = reply_to
-
-    email = EmailMessage(subject, body,
-        getattr(settings, 'WTEM_FROM', 'edukacjamedialna@nowoczesnapolska.org.pl'),
-        to, headers = headers)
-    #print email.message()
-    email.send(fail_silently = False)
diff --git a/wtem/management/commands/wlem_generate_keys.py b/wtem/management/commands/wlem_generate_keys.py
deleted file mode 100644 (file)
index 1e7f558..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-# -*- coding: utf-8 -*-
-from django.core.management.base import BaseCommand
-
-from contact.models import Contact
-from wtem.models import Submission
-
-
-class Command(BaseCommand):
-
-    def handle(self, *ids, **options):
-        new = 0
-        skipped = 0
-
-        query = Contact.objects.filter(form_tag='wlem').order_by('-created_at')
-        if ids:
-            query = query.filter(pk__in=ids)
-
-        for wlem_contact in query:
-            if not Submission.objects.filter(email=wlem_contact.contact).exists():
-                first_name, last_name = wlem_contact.body['nazwisko'].split()
-                args = {
-                    'email': wlem_contact.contact,
-                    'first_name': first_name,
-                    'last_name': last_name,
-                }
-                Submission.create(**args)
-                new += 1
-            else:
-                self.stdout.write('skipping ' + wlem_contact.contact + ': already exists.')
-                skipped += 1
-
-        self.stdout.write('New: ' + str(new) + ', skipped: ' + str(skipped))
diff --git a/wtem/management/commands/wtem_assign_submissions.py b/wtem/management/commands/wtem_assign_submissions.py
deleted file mode 100644 (file)
index dcf0466..0000000
+++ /dev/null
@@ -1,54 +0,0 @@
-# -*- coding: utf-8 -*-
-from optparse import make_option
-
-from django.core.management.base import BaseCommand
-from django.db.models import Count
-from django.contrib.auth.models import User
-
-from wtem.models import Submission, Attachment
-
-
-class Command(BaseCommand):
-
-    option_list = BaseCommand.option_list + (
-        make_option(
-            '--with-attachments-only',
-            action='store_true',
-            dest='attachments_only',
-            default=False,
-            help='Take into account only submissions with attachments'),
-        make_option(
-            '--without-attachments-only',
-            action='store_true',
-            dest='no_attachments_only',
-            default=False,
-            help='Take into account only submissions without attachments'),
-        )
-
-    def handle(self, *args, **options):
-
-        limit_from = int(args[0])
-        limit_to = int(args[1])
-        examiner_names = args[2:]
-
-        users = User.objects.filter(username__in=examiner_names)
-        all_submissions = Submission.objects.annotate(examiners_count=Count('examiners'))
-
-        submissions = all_submissions.exclude(answers=None)
-
-        with_attachment_ids = Attachment.objects.values_list('submission_id', flat=True).all()
-        if options['attachments_only']:
-            submissions = submissions.filter(id__in=with_attachment_ids)
-        if options['no_attachments_only']:
-            submissions = submissions.exclude(id__in=with_attachment_ids)
-
-        for submission in submissions.order_by('id')[limit_from:limit_to]:
-            submission.examiners.add(*users)
-            submission.save()
-            self.stdout.write('added to %s:%s' % (submission.id, submission.email))
-
-        count_by_examiners = dict()
-        for submission in all_submissions.all():
-            count_by_examiners[submission.examiners_count] = \
-                count_by_examiners.get(submission.examiners_count, 0) + 1
-        self.stdout.write('%s' % count_by_examiners)
diff --git a/wtem/management/commands/wtem_email_teachers.py b/wtem/management/commands/wtem_email_teachers.py
deleted file mode 100644 (file)
index 9b5e5e9..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-# -*- coding: utf-8 -*-
-
-from django.core.management.base import BaseCommand
-from django.template.loader import render_to_string
-
-from contact.models import Contact
-from wtem.management.commands import send_mail
-
-
-class Command(BaseCommand):
-    def handle(self, *args, **options):
-        sent = 0
-        failed = 0
-
-        query = Contact.objects.filter(form_tag='wtem').order_by('contact').distinct('contact')
-        template_name = args[0]
-        message = render_to_string('wtem/' + template_name + '.txt')
-        subject = render_to_string('wtem/' + template_name + '_subject.txt')
-        
-        answer = raw_input(
-            'Send the following to %d teachers with subject "%s"\n\n %s\n\n?' %
-            (query.count(), subject.encode('utf8'), message.encode('utf8')))
-
-        if answer == 'yes':
-            for contact in query:
-                try:
-                    self.send_message(message, subject, contact.contact)
-                except Exception as e:
-                    failed += 1
-                    self.stdout.write('failed sending to: ' + contact.contact + ' - ' + str(e))
-                else:
-                    sent += 1
-                    self.stdout.write('message sent to: ' + contact.contact)
-
-        self.stdout.write('sent: %s, failed: %s' % (sent, failed))
-
-    def send_message(self, message, subject, email):
-        self.stdout.write('>>> sending to %s' % email)
-        send_mail(subject=subject, body=message, to=[email])
-
diff --git a/wtem/management/commands/wtem_generate_keys.py b/wtem/management/commands/wtem_generate_keys.py
deleted file mode 100644 (file)
index f49c8b7..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-# -*- coding: utf-8 -*-
-from django.core.management.base import BaseCommand
-
-from contact.models import Contact
-from wtem.models import Submission
-
-
-class Command(BaseCommand):
-
-    def handle(self, *ids, **options):
-        new = 0
-        skipped = 0
-
-        query = Contact.objects.filter(form_tag='wtem').order_by('-created_at')
-        if ids:
-            query = query.filter(pk__in=ids)
-
-        for wtem_contact in query:
-            for student in wtem_contact.body['student']:
-                if not Submission.objects.filter(email=student['email']).exists():
-                    args = dict()
-                    for attr in ['first_name', 'last_name', 'email']:
-                        args[attr] = student[attr]
-                    args['contact'] = wtem_contact
-                    Submission.create(**args)
-                    new += 1
-                else:
-                    self.stdout.write('skipping ' + student['email'] + ': already exists.')
-                    skipped += 1
-
-        self.stdout.write('New: ' + str(new) + ', skipped: ' + str(skipped))
diff --git a/wtem/management/commands/wtem_send_keys.py b/wtem/management/commands/wtem_send_keys.py
deleted file mode 100644 (file)
index 96511fb..0000000
+++ /dev/null
@@ -1,69 +0,0 @@
-# -*- coding: utf-8 -*-
-
-from optparse import make_option
-
-from django.core.management.base import BaseCommand
-from django.conf import settings
-from wtem.management.commands import send_mail
-from django.template.loader import render_to_string
-
-from wtem.models import Submission, DEBUG_KEY
-
-
-class Command(BaseCommand):
-    help = 'Sends personalized links to WTEM contestants'
-    args = '<email_address1>, <email_address2>, ...'
-
-    option_list = BaseCommand.option_list + (
-        make_option(
-            '--all',
-            action='store_true',
-            dest='all',
-            default=False,
-            help='Use all available submissions'),
-        make_option(
-            '--force',
-            action='store_true',
-            dest='force',
-            default=False,
-            help='Force sending key even if one was already sent')
-        )
-
-    def handle(self, *args, **options):
-        if len(args) or options['all']:
-            return self.send_keys(*args, **options)
-        self.stdout.write('No submissions selected')
-
-    def send_keys(self, *args, **options):
-        sent = 0
-        skipped = 0
-        failed = 0
-
-        submissions = Submission.objects.all()
-        if not options['force']:
-            submissions = submissions.filter(key_sent=False)
-        if len(args):
-            submissions = submissions.filter(email__in=args)
-
-        for submission in submissions:
-            assert len(submission.key) == 30 or (settings.DEBUG and submission.key == DEBUG_KEY)
-
-            try:
-                self.send_key(submission)
-            except Exception as e:
-                failed += 1
-                self.stdout.write('failed sending to: ' + submission.email + ' - ' + str(e))
-            else:
-                submission.key_sent = True
-                submission.save()
-                sent += 1
-                self.stdout.write('key sent to: ' + submission.email)
-
-        self.stdout.write('sent: ' + str(sent))
-
-    def send_key(self, submission):
-        self.stdout.write('>>> sending to ' + submission.email)
-        send_mail(
-            subject="WLEM - Twój link do egzaminu",
-            body=render_to_string('wtem/email_key.txt', dict(submission=submission)),
-            to=[submission.email])
diff --git a/wtem/management/commands/wtem_send_results.py b/wtem/management/commands/wtem_send_results.py
deleted file mode 100644 (file)
index d2dc147..0000000
+++ /dev/null
@@ -1,99 +0,0 @@
-# -*- coding: utf-8 -*-
-
-from optparse import make_option
-
-from django.core.management.base import BaseCommand
-from wtem.management.commands import send_mail
-from django.utils import translation
-from django.template.loader import render_to_string
-
-from contact.models import Contact
-from wtem.models import Submission
-
-
-def get_submissions():
-    return sorted(Submission.objects.exclude(answers=None).all(), key=lambda s: -s.final_result)
-
-minimum = 52
-
-
-class Command(BaseCommand):
-
-    option_list = BaseCommand.option_list + (
-        make_option(
-            '--to-teachers',
-            action='store_true',
-            dest='to_teachers',
-            default=False,
-            help='Send emails to teachers'),
-        make_option(
-            '--to-students',
-            action='store_true',
-            dest='to_students',
-            default=False,
-            help='Send emails to students'),
-        make_option(
-            '--only-to',
-            action='store',
-            dest='only_to',
-            default=None,
-            help='Send emails only to listed addresses'),
-    )
-
-    def handle(self, *args, **options):
-        translation.activate('pl')
-        for target in ['to_teachers', 'to_students']:
-            if options[target]:
-                self.sent = 0
-                self.failed = 0
-                getattr(self, 'handle_' + target)(*args, **options)
-
-    def handle_to_students(self, *args, **options):
-        self.stdout.write('>>> Sending results to students')
-        subject = 'Wyniki II etapu Wielkiego Turnieju Edukacji Medialnej'
-
-        for submission in get_submissions():
-            if options['only_to'] and submission.email != options['only_to']:
-                continue
-            final_result = submission.final_result
-            if final_result < minimum:
-                template = 'results_student_failed.txt'
-            else:
-                template = 'results_student_passed.txt'
-            message = render_to_string('wtem/' + template, dict(final_result=submission.final_result))
-            self.send_message(message, subject, submission.email)
-
-        self.sum_up()
-
-    def handle_to_teachers(self, *args, **options):
-        self.stdout.write('>>> Sending results to teachers')
-        subject = 'Wyniki II etapu Wielkiego Turnieju Edukacji Medialnej'
-        failed = sent = 0
-
-        submissions_by_contact = dict()
-
-        for submission in get_submissions():
-            if options['only_to'] and submission.contact.contact != options['only_to']:
-                continue
-            submissions_by_contact.setdefault(submission.contact.id, []).append(submission)
-
-        for contact_id, submissions in submissions_by_contact.items():
-            contact = Contact.objects.get(id=contact_id)
-            message = render_to_string('wtem/results_teacher.txt', dict(submissions=submissions))
-            self.send_message(message, subject, contact.contact)
-
-        self.sum_up()
-
-    def sum_up(self):        
-        self.stdout.write('sent: %s, failed: %s' % (self.sent, self.failed))
-
-    def send_message(self, message, subject, email):
-        self.stdout.write('>>> sending results to %s' % email)
-        try:
-            send_mail(subject=subject, body=message, to=[email])
-        except BaseException, e:
-            self.failed += 1
-            self.stdout.write('failed sending to: ' + email + ': ' + str(e))
-        else:
-            self.sent += 1
-            self.stdout.write('message sent to: ' + email)
diff --git a/wtem/management/commands/wtem_send_results_csv.py b/wtem/management/commands/wtem_send_results_csv.py
deleted file mode 100644 (file)
index 97a98eb..0000000
+++ /dev/null
@@ -1,115 +0,0 @@
-# -*- coding: utf-8 -*-
-
-from optparse import make_option
-
-from django.core.management.base import BaseCommand
-from django.template.loader import render_to_string
-from django.utils import translation
-
-from wtem.management.commands import send_mail
-from wtem.models import Submission
-
-
-def get_submissions():
-    return sorted(Submission.objects.exclude(answers=None).all(), key=lambda s: -s.final_result)
-
-minimum = 52
-
-
-class Command(BaseCommand):
-    args = 'csv_filename'
-
-    option_list = BaseCommand.option_list + (
-        make_option(
-            '--to-teachers',
-            action='store_true',
-            dest='to_teachers',
-            default=False,
-            help='Send emails to teachers'),
-        make_option(
-            '--to-students',
-            action='store_true',
-            dest='to_students',
-            default=False,
-            help='Send emails to students'),
-        make_option(
-            '--only-to',
-            action='store',
-            dest='only_to',
-            default=None,
-            help='Send emails only to listed addresses'),
-    )
-
-    def handle(self, csv_filename, *args, **options):
-        translation.activate('pl')
-        self.results = [line.decode('utf-8').strip('\n').split(',') for line in open(csv_filename)]
-        for target in ['to_teachers', 'to_students']:
-            if options[target]:
-                self.sent = 0
-                self.failed = 0
-                getattr(self, 'handle_' + target)(*args, **options)
-
-    def handle_to_students(self, *args, **options):
-        self.stdout.write('>>> Sending results to students')
-        subject = 'Wyniki II etapu Wielkiego Turnieju Edukacji Medialnej'
-
-        for email, last_name, first_name, final_result in self.results:
-            if options['only_to'] and email != options['only_to']:
-                continue
-            if final_result == 'dyskwalifikacja':
-                template = 'results_student_disqualified.txt'
-            elif float(final_result) < minimum:
-                template = 'results_student_failed.txt'
-            else:
-                template = 'results_student_passed.txt'
-            message = render_to_string('wtem/' + template, dict(final_result=final_result))
-            self.send_message(message, subject, email)
-
-        self.sum_up()
-
-    def handle_to_teachers(self, *args, **options):
-        self.stdout.write('>>> Sending results to teachers')
-        subject = 'Wyniki II etapu Wielkiego Turnieju Edukacji Medialnej'
-
-        submissions_by_contact = dict()
-
-        from decimal import Decimal, InvalidOperation
-
-        def dec_or_0(s):
-            try:
-                return Decimal(s)
-            except InvalidOperation:
-                return Decimal(0)
-
-        sorted_results = sorted(self.results, key=lambda r: dec_or_0(r[3]), reverse=True)
-        for email, last_name, first_name, final_result in sorted_results:
-            submission = Submission.objects.get(email=email)
-            teacher_email = submission.contact.contact
-            if options['only_to'] and teacher_email != options['only_to']:
-                continue
-            submissions_by_contact.setdefault(teacher_email, []).append({
-                'first_name': first_name,
-                'last_name': last_name,
-                'final_result': final_result,
-            })
-
-        for email, submissions in submissions_by_contact.items():
-            # contact = Contact.objects.get(id=contact_id)
-            message = render_to_string('wtem/results_teacher.txt', dict(submissions=submissions))
-            self.send_message(message, subject, email)
-
-        self.sum_up()
-
-    def sum_up(self):        
-        self.stdout.write('sent: %s, failed: %s' % (self.sent, self.failed))
-
-    def send_message(self, message, subject, email):
-        self.stdout.write('>>> sending results to %s' % email)
-        try:
-            send_mail(subject=subject, body=message, to=[email])
-        except BaseException, e:
-            self.failed += 1
-            self.stdout.write('failed sending to: ' + email + ': ' + str(e))
-        else:
-            self.sent += 1
-            self.stdout.write('message sent to: ' + email)
diff --git a/wtem/middleware.py b/wtem/middleware.py
deleted file mode 100644 (file)
index eb26e41..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-# -*- coding: utf-8 -*-
-from threading import local
-
-
-_thread_locals = local()
-
-
-def get_current_request():
-    return getattr(_thread_locals, 'request', None)
-
-
-class ThreadLocalMiddleware(object):
-    @staticmethod
-    def process_request(request):
-        _thread_locals.request = request
diff --git a/wtem/migrations/0001_initial.py b/wtem/migrations/0001_initial.py
deleted file mode 100644 (file)
index 6d22934..0000000
+++ /dev/null
@@ -1,70 +0,0 @@
-# -*- coding: utf-8 -*-
-import datetime
-from south.db import db
-from south.v2 import SchemaMigration
-from django.db import models
-
-
-class Migration(SchemaMigration):
-
-    def forwards(self, orm):
-        # Adding model 'Submission'
-        db.create_table(u'wtem_submission', (
-            (u'id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
-            ('contact', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['contact.Contact'], null=True)),
-            ('key', self.gf('django.db.models.fields.CharField')(unique=True, max_length=30)),
-            ('first_name', self.gf('django.db.models.fields.CharField')(max_length=100)),
-            ('last_name', self.gf('django.db.models.fields.CharField')(max_length=100)),
-            ('email', self.gf('django.db.models.fields.EmailField')(unique=True, max_length=100)),
-            ('answers', self.gf('django.db.models.fields.CharField')(max_length=65536, null=True, blank=True)),
-        ))
-        db.send_create_signal(u'wtem', ['Submission'])
-
-        # Adding model 'Attachment'
-        db.create_table(u'wtem_attachment', (
-            (u'id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
-            ('submission', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['wtem.Submission'])),
-            ('name', self.gf('django.db.models.fields.CharField')(max_length=100)),
-            ('file', self.gf('django.db.models.fields.files.FileField')(max_length=100)),
-        ))
-        db.send_create_signal(u'wtem', ['Attachment'])
-
-
-    def backwards(self, orm):
-        # Deleting model 'Submission'
-        db.delete_table(u'wtem_submission')
-
-        # Deleting model 'Attachment'
-        db.delete_table(u'wtem_attachment')
-
-
-    models = {
-        u'contact.contact': {
-            'Meta': {'ordering': "('-created_at',)", 'object_name': 'Contact'},
-            'body': ('jsonfield.fields.JSONField', [], {'default': '{}'}),
-            'contact': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
-            'created_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
-            'form_tag': ('django.db.models.fields.CharField', [], {'max_length': '32', 'db_index': 'True'}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'ip': ('django.db.models.fields.IPAddressField', [], {'max_length': '15'})
-        },
-        u'wtem.attachment': {
-            'Meta': {'object_name': 'Attachment'},
-            'file': ('django.db.models.fields.files.FileField', [], {'max_length': '100'}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'submission': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['wtem.Submission']"})
-        },
-        u'wtem.submission': {
-            'Meta': {'object_name': 'Submission'},
-            'answers': ('django.db.models.fields.CharField', [], {'max_length': '65536', 'null': 'True', 'blank': 'True'}),
-            'contact': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['contact.Contact']", 'null': 'True'}),
-            'email': ('django.db.models.fields.EmailField', [], {'unique': 'True', 'max_length': '100'}),
-            'first_name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'key': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'}),
-            'last_name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
-        }
-    }
-
-    complete_apps = ['wtem']
\ No newline at end of file
diff --git a/wtem/migrations/0002_auto__add_field_submission_key_sent.py b/wtem/migrations/0002_auto__add_field_submission_key_sent.py
deleted file mode 100644 (file)
index 825da07..0000000
+++ /dev/null
@@ -1,52 +0,0 @@
-# -*- coding: utf-8 -*-
-import datetime
-from south.db import db
-from south.v2 import SchemaMigration
-from django.db import models
-
-
-class Migration(SchemaMigration):
-
-    def forwards(self, orm):
-        # Adding field 'Submission.key_sent'
-        db.add_column(u'wtem_submission', 'key_sent',
-                      self.gf('django.db.models.fields.BooleanField')(default=False),
-                      keep_default=False)
-
-
-    def backwards(self, orm):
-        # Deleting field 'Submission.key_sent'
-        db.delete_column(u'wtem_submission', 'key_sent')
-
-
-    models = {
-        u'contact.contact': {
-            'Meta': {'ordering': "('-created_at',)", 'object_name': 'Contact'},
-            'body': ('jsonfield.fields.JSONField', [], {'default': '{}'}),
-            'contact': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
-            'created_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
-            'form_tag': ('django.db.models.fields.CharField', [], {'max_length': '32', 'db_index': 'True'}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'ip': ('django.db.models.fields.IPAddressField', [], {'max_length': '15'})
-        },
-        u'wtem.attachment': {
-            'Meta': {'object_name': 'Attachment'},
-            'file': ('django.db.models.fields.files.FileField', [], {'max_length': '100'}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'submission': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['wtem.Submission']"})
-        },
-        u'wtem.submission': {
-            'Meta': {'object_name': 'Submission'},
-            'answers': ('django.db.models.fields.CharField', [], {'max_length': '65536', 'null': 'True', 'blank': 'True'}),
-            'contact': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['contact.Contact']", 'null': 'True'}),
-            'email': ('django.db.models.fields.EmailField', [], {'unique': 'True', 'max_length': '100'}),
-            'first_name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'key': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'}),
-            'key_sent': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'last_name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
-        }
-    }
-
-    complete_apps = ['wtem']
\ No newline at end of file
diff --git a/wtem/migrations/0003_auto__add_assignment.py b/wtem/migrations/0003_auto__add_assignment.py
deleted file mode 100644 (file)
index 94e6509..0000000
+++ /dev/null
@@ -1,97 +0,0 @@
-# -*- coding: utf-8 -*-
-import datetime
-from south.db import db
-from south.v2 import SchemaMigration
-from django.db import models
-
-
-class Migration(SchemaMigration):
-
-    def forwards(self, orm):
-        # Adding model 'Assignment'
-        db.create_table(u'wtem_assignment', (
-            (u'id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
-            ('user', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['auth.User'])),
-            ('exercises', self.gf('jsonfield.fields.JSONField')(default={})),
-        ))
-        db.send_create_signal(u'wtem', ['Assignment'])
-
-
-    def backwards(self, orm):
-        # Deleting model 'Assignment'
-        db.delete_table(u'wtem_assignment')
-
-
-    models = {
-        u'auth.group': {
-            'Meta': {'object_name': 'Group'},
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
-            'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
-        },
-        u'auth.permission': {
-            'Meta': {'ordering': "(u'content_type__app_label', u'content_type__model', u'codename')", 'unique_together': "((u'content_type', u'codename'),)", 'object_name': 'Permission'},
-            'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['contenttypes.ContentType']"}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
-        },
-        u'auth.user': {
-            'Meta': {'object_name': 'User'},
-            'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
-            'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
-            'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
-            'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
-            'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
-            'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
-            'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
-            'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
-            'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
-        },
-        u'contact.contact': {
-            'Meta': {'ordering': "('-created_at',)", 'object_name': 'Contact'},
-            'body': ('jsonfield.fields.JSONField', [], {'default': '{}'}),
-            'contact': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
-            'created_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
-            'form_tag': ('django.db.models.fields.CharField', [], {'max_length': '32', 'db_index': 'True'}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'ip': ('django.db.models.fields.IPAddressField', [], {'max_length': '15'})
-        },
-        u'contenttypes.contenttype': {
-            'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
-            'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
-        },
-        u'wtem.assignment': {
-            'Meta': {'object_name': 'Assignment'},
-            'exercises': ('jsonfield.fields.JSONField', [], {'default': '{}'}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'user': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['auth.User']"})
-        },
-        u'wtem.attachment': {
-            'Meta': {'object_name': 'Attachment'},
-            'file': ('django.db.models.fields.files.FileField', [], {'max_length': '100'}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'submission': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['wtem.Submission']"})
-        },
-        u'wtem.submission': {
-            'Meta': {'object_name': 'Submission'},
-            'answers': ('django.db.models.fields.CharField', [], {'max_length': '65536', 'null': 'True', 'blank': 'True'}),
-            'contact': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['contact.Contact']", 'null': 'True'}),
-            'email': ('django.db.models.fields.EmailField', [], {'unique': 'True', 'max_length': '100'}),
-            'first_name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'key': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'}),
-            'key_sent': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'last_name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
-        }
-    }
-
-    complete_apps = ['wtem']
\ No newline at end of file
diff --git a/wtem/migrations/0004_auto__add_unique_assignment_user.py b/wtem/migrations/0004_auto__add_unique_assignment_user.py
deleted file mode 100644 (file)
index 7730b9d..0000000
+++ /dev/null
@@ -1,92 +0,0 @@
-# -*- coding: utf-8 -*-
-import datetime
-from south.db import db
-from south.v2 import SchemaMigration
-from django.db import models
-
-
-class Migration(SchemaMigration):
-
-    def forwards(self, orm):
-        # Adding unique constraint on 'Assignment', fields ['user']
-        db.create_unique(u'wtem_assignment', ['user_id'])
-
-
-    def backwards(self, orm):
-        # Removing unique constraint on 'Assignment', fields ['user']
-        db.delete_unique(u'wtem_assignment', ['user_id'])
-
-
-    models = {
-        u'auth.group': {
-            'Meta': {'object_name': 'Group'},
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
-            'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
-        },
-        u'auth.permission': {
-            'Meta': {'ordering': "(u'content_type__app_label', u'content_type__model', u'codename')", 'unique_together': "((u'content_type', u'codename'),)", 'object_name': 'Permission'},
-            'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['contenttypes.ContentType']"}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
-        },
-        u'auth.user': {
-            'Meta': {'object_name': 'User'},
-            'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
-            'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
-            'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
-            'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
-            'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
-            'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
-            'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
-            'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
-            'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
-        },
-        u'contact.contact': {
-            'Meta': {'ordering': "('-created_at',)", 'object_name': 'Contact'},
-            'body': ('jsonfield.fields.JSONField', [], {'default': '{}'}),
-            'contact': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
-            'created_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
-            'form_tag': ('django.db.models.fields.CharField', [], {'max_length': '32', 'db_index': 'True'}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'ip': ('django.db.models.fields.IPAddressField', [], {'max_length': '15'})
-        },
-        u'contenttypes.contenttype': {
-            'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
-            'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
-        },
-        u'wtem.assignment': {
-            'Meta': {'object_name': 'Assignment'},
-            'exercises': ('jsonfield.fields.JSONField', [], {'default': '{}'}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'user': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['auth.User']", 'unique': 'True'})
-        },
-        u'wtem.attachment': {
-            'Meta': {'object_name': 'Attachment'},
-            'file': ('django.db.models.fields.files.FileField', [], {'max_length': '100'}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'submission': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['wtem.Submission']"})
-        },
-        u'wtem.submission': {
-            'Meta': {'object_name': 'Submission'},
-            'answers': ('django.db.models.fields.CharField', [], {'max_length': '65536', 'null': 'True', 'blank': 'True'}),
-            'contact': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['contact.Contact']", 'null': 'True'}),
-            'email': ('django.db.models.fields.EmailField', [], {'unique': 'True', 'max_length': '100'}),
-            'first_name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'key': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'}),
-            'key_sent': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'last_name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
-        }
-    }
-
-    complete_apps = ['wtem']
\ No newline at end of file
diff --git a/wtem/migrations/0005_auto__add_field_submission_marks.py b/wtem/migrations/0005_auto__add_field_submission_marks.py
deleted file mode 100644 (file)
index bbade28..0000000
+++ /dev/null
@@ -1,95 +0,0 @@
-# -*- coding: utf-8 -*-
-import datetime
-from south.db import db
-from south.v2 import SchemaMigration
-from django.db import models
-
-
-class Migration(SchemaMigration):
-
-    def forwards(self, orm):
-        # Adding field 'Submission.marks'
-        db.add_column(u'wtem_submission', 'marks',
-                      self.gf('jsonfield.fields.JSONField')(default={}),
-                      keep_default=False)
-
-
-    def backwards(self, orm):
-        # Deleting field 'Submission.marks'
-        db.delete_column(u'wtem_submission', 'marks')
-
-
-    models = {
-        u'auth.group': {
-            'Meta': {'object_name': 'Group'},
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
-            'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
-        },
-        u'auth.permission': {
-            'Meta': {'ordering': "(u'content_type__app_label', u'content_type__model', u'codename')", 'unique_together': "((u'content_type', u'codename'),)", 'object_name': 'Permission'},
-            'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['contenttypes.ContentType']"}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
-        },
-        u'auth.user': {
-            'Meta': {'object_name': 'User'},
-            'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
-            'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
-            'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
-            'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
-            'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
-            'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
-            'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
-            'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
-            'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
-        },
-        u'contact.contact': {
-            'Meta': {'ordering': "('-created_at',)", 'object_name': 'Contact'},
-            'body': ('jsonfield.fields.JSONField', [], {'default': '{}'}),
-            'contact': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
-            'created_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
-            'form_tag': ('django.db.models.fields.CharField', [], {'max_length': '32', 'db_index': 'True'}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'ip': ('django.db.models.fields.IPAddressField', [], {'max_length': '15'})
-        },
-        u'contenttypes.contenttype': {
-            'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
-            'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
-        },
-        u'wtem.assignment': {
-            'Meta': {'object_name': 'Assignment'},
-            'exercises': ('jsonfield.fields.JSONField', [], {'default': '{}'}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'user': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['auth.User']", 'unique': 'True'})
-        },
-        u'wtem.attachment': {
-            'Meta': {'object_name': 'Attachment'},
-            'file': ('django.db.models.fields.files.FileField', [], {'max_length': '100'}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'submission': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['wtem.Submission']"})
-        },
-        u'wtem.submission': {
-            'Meta': {'object_name': 'Submission'},
-            'answers': ('django.db.models.fields.CharField', [], {'max_length': '65536', 'null': 'True', 'blank': 'True'}),
-            'contact': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['contact.Contact']", 'null': 'True'}),
-            'email': ('django.db.models.fields.EmailField', [], {'unique': 'True', 'max_length': '100'}),
-            'first_name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'key': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'}),
-            'key_sent': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'last_name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'marks': ('jsonfield.fields.JSONField', [], {'default': '{}'})
-        }
-    }
-
-    complete_apps = ['wtem']
\ No newline at end of file
diff --git a/wtem/migrations/0006_auto__del_field_attachment_name__add_field_attachment_exercise_id.py b/wtem/migrations/0006_auto__del_field_attachment_name__add_field_attachment_exercise_id.py
deleted file mode 100644 (file)
index ff72499..0000000
+++ /dev/null
@@ -1,101 +0,0 @@
-# -*- coding: utf-8 -*-
-import datetime
-from south.db import db
-from south.v2 import SchemaMigration
-from django.db import models
-
-
-class Migration(SchemaMigration):
-
-    def forwards(self, orm):
-        # Deleting field 'Attachment.name'
-        db.delete_column(u'wtem_attachment', 'name')
-
-        # Adding field 'Attachment.exercise_id'
-        db.add_column(u'wtem_attachment', 'exercise_id',
-                      self.gf('django.db.models.fields.IntegerField')(default=None),
-                      keep_default=False)
-
-
-    def backwards(self, orm):
-
-        # User chose to not deal with backwards NULL issues for 'Attachment.name'
-        raise RuntimeError("Cannot reverse this migration. 'Attachment.name' and its values cannot be restored.")
-        # Deleting field 'Attachment.exercise_id'
-        db.delete_column(u'wtem_attachment', 'exercise_id')
-
-
-    models = {
-        u'auth.group': {
-            'Meta': {'object_name': 'Group'},
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
-            'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
-        },
-        u'auth.permission': {
-            'Meta': {'ordering': "(u'content_type__app_label', u'content_type__model', u'codename')", 'unique_together': "((u'content_type', u'codename'),)", 'object_name': 'Permission'},
-            'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['contenttypes.ContentType']"}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
-        },
-        u'auth.user': {
-            'Meta': {'object_name': 'User'},
-            'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
-            'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
-            'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
-            'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
-            'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
-            'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
-            'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
-            'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
-            'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
-        },
-        u'contact.contact': {
-            'Meta': {'ordering': "('-created_at',)", 'object_name': 'Contact'},
-            'body': ('jsonfield.fields.JSONField', [], {'default': '{}'}),
-            'contact': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
-            'created_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
-            'form_tag': ('django.db.models.fields.CharField', [], {'max_length': '32', 'db_index': 'True'}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'ip': ('django.db.models.fields.IPAddressField', [], {'max_length': '15'})
-        },
-        u'contenttypes.contenttype': {
-            'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
-            'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
-        },
-        u'wtem.assignment': {
-            'Meta': {'object_name': 'Assignment'},
-            'exercises': ('jsonfield.fields.JSONField', [], {'default': '{}'}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'user': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['auth.User']", 'unique': 'True'})
-        },
-        u'wtem.attachment': {
-            'Meta': {'object_name': 'Attachment'},
-            'exercise_id': ('django.db.models.fields.IntegerField', [], {}),
-            'file': ('django.db.models.fields.files.FileField', [], {'max_length': '100'}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'submission': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['wtem.Submission']"})
-        },
-        u'wtem.submission': {
-            'Meta': {'object_name': 'Submission'},
-            'answers': ('django.db.models.fields.CharField', [], {'max_length': '65536', 'null': 'True', 'blank': 'True'}),
-            'contact': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['contact.Contact']", 'null': 'True'}),
-            'email': ('django.db.models.fields.EmailField', [], {'unique': 'True', 'max_length': '100'}),
-            'first_name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'key': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'}),
-            'key_sent': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'last_name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'marks': ('jsonfield.fields.JSONField', [], {'default': '{}'})
-        }
-    }
-
-    complete_apps = ['wtem']
\ No newline at end of file
diff --git a/wtem/migrations/0007_auto.py b/wtem/migrations/0007_auto.py
deleted file mode 100644 (file)
index ab1949f..0000000
+++ /dev/null
@@ -1,99 +0,0 @@
-# -*- coding: utf-8 -*-
-import datetime
-from south.db import db
-from south.v2 import SchemaMigration
-from django.db import models
-
-
-class Migration(SchemaMigration):
-
-    def forwards(self, orm):
-        # Adding M2M table for field examiners on 'Submission'
-        db.create_table(u'wtem_submission_examiners', (
-            ('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)),
-            ('submission', models.ForeignKey(orm[u'wtem.submission'], null=False)),
-            ('user', models.ForeignKey(orm[u'auth.user'], null=False))
-        ))
-        db.create_unique(u'wtem_submission_examiners', ['submission_id', 'user_id'])
-
-
-    def backwards(self, orm):
-        # Removing M2M table for field examiners on 'Submission'
-        db.delete_table('wtem_submission_examiners')
-
-
-    models = {
-        u'auth.group': {
-            'Meta': {'object_name': 'Group'},
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
-            'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
-        },
-        u'auth.permission': {
-            'Meta': {'ordering': "(u'content_type__app_label', u'content_type__model', u'codename')", 'unique_together': "((u'content_type', u'codename'),)", 'object_name': 'Permission'},
-            'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['contenttypes.ContentType']"}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
-        },
-        u'auth.user': {
-            'Meta': {'object_name': 'User'},
-            'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
-            'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
-            'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
-            'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
-            'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
-            'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
-            'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
-            'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
-            'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
-        },
-        u'contact.contact': {
-            'Meta': {'ordering': "('-created_at',)", 'object_name': 'Contact'},
-            'body': ('jsonfield.fields.JSONField', [], {'default': '{}'}),
-            'contact': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
-            'created_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
-            'form_tag': ('django.db.models.fields.CharField', [], {'max_length': '32', 'db_index': 'True'}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'ip': ('django.db.models.fields.IPAddressField', [], {'max_length': '15'})
-        },
-        u'contenttypes.contenttype': {
-            'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
-            'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
-        },
-        u'wtem.assignment': {
-            'Meta': {'object_name': 'Assignment'},
-            'exercises': ('jsonfield.fields.JSONField', [], {'default': '{}'}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'user': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['auth.User']", 'unique': 'True'})
-        },
-        u'wtem.attachment': {
-            'Meta': {'object_name': 'Attachment'},
-            'exercise_id': ('django.db.models.fields.IntegerField', [], {}),
-            'file': ('django.db.models.fields.files.FileField', [], {'max_length': '100'}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'submission': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['wtem.Submission']"})
-        },
-        u'wtem.submission': {
-            'Meta': {'object_name': 'Submission'},
-            'answers': ('django.db.models.fields.CharField', [], {'max_length': '65536', 'null': 'True', 'blank': 'True'}),
-            'contact': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['contact.Contact']", 'null': 'True'}),
-            'email': ('django.db.models.fields.EmailField', [], {'unique': 'True', 'max_length': '100'}),
-            'examiners': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['auth.User']", 'symmetrical': 'False'}),
-            'first_name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'key': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'}),
-            'key_sent': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'last_name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'marks': ('jsonfield.fields.JSONField', [], {'default': '{}'})
-        }
-    }
-
-    complete_apps = ['wtem']
\ No newline at end of file
diff --git a/wtem/migrations/0008_auto__add_field_submission_end_time.py b/wtem/migrations/0008_auto__add_field_submission_end_time.py
deleted file mode 100644 (file)
index 58901c0..0000000
+++ /dev/null
@@ -1,97 +0,0 @@
-# -*- coding: utf-8 -*-
-import datetime
-from south.db import db
-from south.v2 import SchemaMigration
-from django.db import models
-
-
-class Migration(SchemaMigration):
-
-    def forwards(self, orm):
-        # Adding field 'Submission.end_time'
-        db.add_column(u'wtem_submission', 'end_time',
-                      self.gf('django.db.models.fields.CharField')(max_length=5, null=True, blank=True),
-                      keep_default=False)
-
-
-    def backwards(self, orm):
-        # Deleting field 'Submission.end_time'
-        db.delete_column(u'wtem_submission', 'end_time')
-
-
-    models = {
-        u'auth.group': {
-            'Meta': {'object_name': 'Group'},
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
-            'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
-        },
-        u'auth.permission': {
-            'Meta': {'ordering': "(u'content_type__app_label', u'content_type__model', u'codename')", 'unique_together': "((u'content_type', u'codename'),)", 'object_name': 'Permission'},
-            'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['contenttypes.ContentType']"}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
-        },
-        u'auth.user': {
-            'Meta': {'object_name': 'User'},
-            'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
-            'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
-            'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
-            'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
-            'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
-            'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
-            'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
-            'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
-            'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
-        },
-        u'contact.contact': {
-            'Meta': {'ordering': "('-created_at',)", 'object_name': 'Contact'},
-            'body': ('jsonfield.fields.JSONField', [], {'default': '{}'}),
-            'contact': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
-            'created_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
-            'form_tag': ('django.db.models.fields.CharField', [], {'max_length': '32', 'db_index': 'True'}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'ip': ('django.db.models.fields.IPAddressField', [], {'max_length': '15'})
-        },
-        u'contenttypes.contenttype': {
-            'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
-            'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
-        },
-        u'wtem.assignment': {
-            'Meta': {'object_name': 'Assignment'},
-            'exercises': ('jsonfield.fields.JSONField', [], {'default': '{}'}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'user': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['auth.User']", 'unique': 'True'})
-        },
-        u'wtem.attachment': {
-            'Meta': {'object_name': 'Attachment'},
-            'exercise_id': ('django.db.models.fields.IntegerField', [], {}),
-            'file': ('django.db.models.fields.files.FileField', [], {'max_length': '100'}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'submission': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['wtem.Submission']"})
-        },
-        u'wtem.submission': {
-            'Meta': {'object_name': 'Submission'},
-            'answers': ('django.db.models.fields.CharField', [], {'max_length': '65536', 'null': 'True', 'blank': 'True'}),
-            'contact': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['contact.Contact']", 'null': 'True'}),
-            'email': ('django.db.models.fields.EmailField', [], {'unique': 'True', 'max_length': '100'}),
-            'end_time': ('django.db.models.fields.CharField', [], {'max_length': '5', 'null': 'True', 'blank': 'True'}),
-            'examiners': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'to': u"orm['auth.User']", 'null': 'True', 'blank': 'True'}),
-            'first_name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'key': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'}),
-            'key_sent': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'last_name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'marks': ('jsonfield.fields.JSONField', [], {'default': '{}'})
-        }
-    }
-
-    complete_apps = ['wtem']
\ No newline at end of file
diff --git a/wtem/migrations/0009_auto__add_field_attachment_tag.py b/wtem/migrations/0009_auto__add_field_attachment_tag.py
deleted file mode 100644 (file)
index 8ea943a..0000000
+++ /dev/null
@@ -1,98 +0,0 @@
-# -*- coding: utf-8 -*-
-from south.utils import datetime_utils as datetime
-from south.db import db
-from south.v2 import SchemaMigration
-from django.db import models
-
-
-class Migration(SchemaMigration):
-
-    def forwards(self, orm):
-        # Adding field 'Attachment.tag'
-        db.add_column(u'wtem_attachment', 'tag',
-                      self.gf('django.db.models.fields.CharField')(max_length=128, null=True, blank=True),
-                      keep_default=False)
-
-
-    def backwards(self, orm):
-        # Deleting field 'Attachment.tag'
-        db.delete_column(u'wtem_attachment', 'tag')
-
-
-    models = {
-        u'auth.group': {
-            'Meta': {'object_name': 'Group'},
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
-            'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
-        },
-        u'auth.permission': {
-            'Meta': {'ordering': "(u'content_type__app_label', u'content_type__model', u'codename')", 'unique_together': "((u'content_type', u'codename'),)", 'object_name': 'Permission'},
-            'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['contenttypes.ContentType']"}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
-        },
-        u'auth.user': {
-            'Meta': {'object_name': 'User'},
-            'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
-            'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
-            'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
-            'groups': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "u'user_set'", 'blank': 'True', 'to': u"orm['auth.Group']"}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
-            'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
-            'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
-            'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
-            'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "u'user_set'", 'blank': 'True', 'to': u"orm['auth.Permission']"}),
-            'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
-        },
-        u'contact.contact': {
-            'Meta': {'ordering': "('-created_at',)", 'object_name': 'Contact'},
-            'body': ('jsonfield.fields.JSONField', [], {}),
-            'contact': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
-            'created_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
-            'form_tag': ('django.db.models.fields.CharField', [], {'max_length': '32', 'db_index': 'True'}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'ip': ('django.db.models.fields.IPAddressField', [], {'max_length': '15'})
-        },
-        u'contenttypes.contenttype': {
-            'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
-            'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
-        },
-        u'wtem.assignment': {
-            'Meta': {'object_name': 'Assignment'},
-            'exercises': ('jsonfield.fields.JSONField', [], {}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'user': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['auth.User']", 'unique': 'True'})
-        },
-        u'wtem.attachment': {
-            'Meta': {'object_name': 'Attachment'},
-            'exercise_id': ('django.db.models.fields.IntegerField', [], {}),
-            'file': ('django.db.models.fields.files.FileField', [], {'max_length': '100'}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'submission': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['wtem.Submission']"}),
-            'tag': ('django.db.models.fields.CharField', [], {'max_length': '128', 'null': 'True', 'blank': 'True'})
-        },
-        u'wtem.submission': {
-            'Meta': {'object_name': 'Submission'},
-            'answers': ('django.db.models.fields.CharField', [], {'max_length': '65536', 'null': 'True', 'blank': 'True'}),
-            'contact': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['contact.Contact']", 'null': 'True'}),
-            'email': ('django.db.models.fields.EmailField', [], {'unique': 'True', 'max_length': '100'}),
-            'end_time': ('django.db.models.fields.CharField', [], {'max_length': '5', 'null': 'True', 'blank': 'True'}),
-            'examiners': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'to': u"orm['auth.User']", 'null': 'True', 'blank': 'True'}),
-            'first_name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'key': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'}),
-            'key_sent': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'last_name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'marks': ('jsonfield.fields.JSONField', [], {'default': '{}'})
-        }
-    }
-
-    complete_apps = ['wtem']
\ No newline at end of file
diff --git a/wtem/migrations/0010_auto__add_confirmation.py b/wtem/migrations/0010_auto__add_confirmation.py
deleted file mode 100644 (file)
index 63f9d60..0000000
+++ /dev/null
@@ -1,115 +0,0 @@
-# -*- coding: utf-8 -*-
-from south.utils import datetime_utils as datetime
-from south.db import db
-from south.v2 import SchemaMigration
-from django.db import models
-
-
-class Migration(SchemaMigration):
-
-    def forwards(self, orm):
-        # Adding model 'Confirmation'
-        db.create_table(u'wtem_confirmation', (
-            (u'id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
-            ('first_name', self.gf('django.db.models.fields.CharField')(max_length=100)),
-            ('last_name', self.gf('django.db.models.fields.CharField')(max_length=100)),
-            ('email', self.gf('django.db.models.fields.EmailField')(unique=True, max_length=100)),
-            ('contact', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['contact.Contact'], null=True)),
-            ('key', self.gf('django.db.models.fields.CharField')(max_length=30)),
-            ('confirmed', self.gf('django.db.models.fields.BooleanField')(default=False)),
-        ))
-        db.send_create_signal(u'wtem', ['Confirmation'])
-
-
-    def backwards(self, orm):
-        # Deleting model 'Confirmation'
-        db.delete_table(u'wtem_confirmation')
-
-
-    models = {
-        u'auth.group': {
-            'Meta': {'object_name': 'Group'},
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
-            'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
-        },
-        u'auth.permission': {
-            'Meta': {'ordering': "(u'content_type__app_label', u'content_type__model', u'codename')", 'unique_together': "((u'content_type', u'codename'),)", 'object_name': 'Permission'},
-            'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['contenttypes.ContentType']"}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
-        },
-        u'auth.user': {
-            'Meta': {'object_name': 'User'},
-            'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
-            'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
-            'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
-            'groups': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "u'user_set'", 'blank': 'True', 'to': u"orm['auth.Group']"}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
-            'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
-            'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
-            'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
-            'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "u'user_set'", 'blank': 'True', 'to': u"orm['auth.Permission']"}),
-            'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
-        },
-        u'contact.contact': {
-            'Meta': {'ordering': "('-created_at',)", 'object_name': 'Contact'},
-            'body': ('jsonfield.fields.JSONField', [], {}),
-            'contact': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
-            'created_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
-            'form_tag': ('django.db.models.fields.CharField', [], {'max_length': '32', 'db_index': 'True'}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'ip': ('django.db.models.fields.IPAddressField', [], {'max_length': '15'})
-        },
-        u'contenttypes.contenttype': {
-            'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
-            'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
-        },
-        u'wtem.assignment': {
-            'Meta': {'object_name': 'Assignment'},
-            'exercises': ('jsonfield.fields.JSONField', [], {}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'user': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['auth.User']", 'unique': 'True'})
-        },
-        u'wtem.attachment': {
-            'Meta': {'object_name': 'Attachment'},
-            'exercise_id': ('django.db.models.fields.IntegerField', [], {}),
-            'file': ('django.db.models.fields.files.FileField', [], {'max_length': '100'}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'submission': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['wtem.Submission']"}),
-            'tag': ('django.db.models.fields.CharField', [], {'max_length': '128', 'null': 'True', 'blank': 'True'})
-        },
-        u'wtem.confirmation': {
-            'Meta': {'object_name': 'Confirmation'},
-            'confirmed': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'contact': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['contact.Contact']", 'null': 'True'}),
-            'email': ('django.db.models.fields.EmailField', [], {'unique': 'True', 'max_length': '100'}),
-            'first_name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'key': ('django.db.models.fields.CharField', [], {'max_length': '30'}),
-            'last_name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
-        },
-        u'wtem.submission': {
-            'Meta': {'object_name': 'Submission'},
-            'answers': ('django.db.models.fields.CharField', [], {'max_length': '65536', 'null': 'True', 'blank': 'True'}),
-            'contact': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['contact.Contact']", 'null': 'True'}),
-            'email': ('django.db.models.fields.EmailField', [], {'unique': 'True', 'max_length': '100'}),
-            'end_time': ('django.db.models.fields.CharField', [], {'max_length': '5', 'null': 'True', 'blank': 'True'}),
-            'examiners': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'to': u"orm['auth.User']", 'null': 'True', 'blank': 'True'}),
-            'first_name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'key': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'}),
-            'key_sent': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'last_name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'marks': ('jsonfield.fields.JSONField', [], {'default': '{}'})
-        }
-    }
-
-    complete_apps = ['wtem']
\ No newline at end of file
diff --git a/wtem/migrations/__init__.py b/wtem/migrations/__init__.py
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/wtem/models.py b/wtem/models.py
deleted file mode 100644 (file)
index 361bff3..0000000
+++ /dev/null
@@ -1,179 +0,0 @@
-# -*- coding: utf-8 -*-
-import random
-import string
-import os
-import json
-
-from django.db import models
-from django.contrib.auth.models import User
-from django.core.exceptions import ValidationError
-from django.utils.translation import ugettext as _
-from jsonfield import JSONField
-
-from contact.models import Contact
-
-f = file(os.path.dirname(__file__) + '/fixtures/exercises.json')
-exercises = json.loads(f.read())
-f.close()
-
-DEBUG_KEY = '12345'
-
-
-class Submission(models.Model):
-    contact = models.ForeignKey(Contact, null=True)
-    key = models.CharField(max_length=30, unique=True)
-    first_name = models.CharField(max_length=100)
-    last_name = models.CharField(max_length=100)
-    email = models.EmailField(max_length=100, unique=True)
-    answers = models.CharField(max_length=65536, null=True, blank=True)
-    key_sent = models.BooleanField(default=False)
-    marks = JSONField(default={})
-    examiners = models.ManyToManyField(User, null=True, blank=True)
-    end_time = models.CharField(max_length=5, null=True, blank=True)
-
-    def __unicode__(self):
-        return ', '.join((self.last_name, self.first_name, self.email))
-
-    @classmethod
-    def generate_key(cls):
-        key = ''
-        while not key or key in [record['key'] for record in cls.objects.values('key')]:
-            key = ''.join(random.choice(string.ascii_uppercase + string.ascii_lowercase + string.digits)
-                          for i in range(30))
-        return key
-
-    @classmethod
-    def create(cls, first_name, last_name, email, key=None, contact=None):
-        submission = cls(
-            contact=contact,
-            key=key if key else Submission.generate_key(),
-            first_name=first_name,
-            last_name=last_name,
-            email=email
-        )
-
-        submission.save()
-        return submission
-
-    def get_mark(self, user_id, exercise_id):
-        mark = None
-        user_id = str(user_id)
-        exercise_id = str(exercise_id)
-        if self.marks and user_id in self.marks:
-            mark = self.marks[user_id].get(exercise_id, None)
-        return mark
-
-    def set_mark(self, user_id, exercise_id, mark):
-        user_id = str(user_id)
-        exercise_id = str(exercise_id)
-        if not self.marks:
-            self.marks = dict()
-        
-        self.marks.setdefault(user_id, {})[exercise_id] = mark
-        if mark == 'None':
-            del self.marks[user_id][exercise_id]
-
-    def get_exercise_marks_by_examiner(self, exercise_id):
-        marks = dict()
-        for examiner_id, examiner_marks in self.marks.items():
-            mark = examiner_marks.get(exercise_id, None)
-            if mark is not None:
-                marks[examiner_id] = mark
-        return marks
-
-    def get_final_exercise_mark(self, exercise_id):
-        # exercise = exercises[int(exercise_id)-1]
-        exercise = [e for e in exercises if str(e['id']) == str(exercise_id)][0]
-        if exercise_checked_manually(exercise):
-            marks_by_examiner = self.get_exercise_marks_by_examiner(exercise_id)
-            if len(marks_by_examiner):
-                return sum(map(float, marks_by_examiner.values())) / float(len(marks_by_examiner))
-            else:
-                return None
-        else:
-            if not self.answers:
-                return None
-            answer = json.loads(self.answers)[exercise_id]['closed_part']
-            t = exercise['type']
-            if t == 'edumed_uporzadkuj':
-                return exercise['points'] if map(int, answer) == exercise['answer'] else 0
-            if t == 'edumed_przyporzadkuj':
-                toret = 0
-                for bucket_id, items in answer.items():
-                    for item_id in items:
-                        is_corect = False
-                        if exercise.get('answer_mode', None) == 'possible_buckets_for_item':
-                            is_correct = int(bucket_id) in exercise['answer'].get(item_id)
-                        else:
-                            is_correct = int(item_id) in exercise['answer'].get(bucket_id, [])
-                        if is_correct:
-                            toret += exercise['points_per_hit']
-                return toret
-            if t == 'edumed_wybor':
-                if len(exercise['answer']) == 1:
-                    if len(answer) and int(answer[0]) == exercise['answer'][0]:
-                        return exercise['points']
-                    else:
-                        return 0
-                else:
-                    toret = 0
-                    if exercise.get('answer_mode', None) == 'all_or_nothing':
-                        toret = exercise['points'] if map(int, answer) == exercise['answer'] else 0
-                    else:
-                        for answer_id in map(int, answer):
-                            if answer_id in exercise['answer']:
-                                toret += exercise['points_per_hit']
-                    return toret
-            if t == 'edumed_prawdafalsz':
-                toret = 0
-                for idx, statement in enumerate(exercise['statements']):
-                    if answer[idx] == 'true':
-                        given = True
-                    elif answer[idx] == 'false':
-                        given = False
-                    else:
-                        given = None
-                    if given == statement[1]:
-                        toret += exercise['points_per_hit']
-                return toret
-            raise NotImplementedError
-
-    @property
-    def final_result(self):
-        final = 0
-        # for exercise_id in map(str,range(1, len(exercises) + 1)):
-        for exercise_id in [str(x['id']) for x in exercises]:
-            mark = self.get_final_exercise_mark(exercise_id)
-            if mark is not None:
-                final += mark
-        return final
-
-    @property
-    def final_result_as_string(self):
-        return ('%.2f' % self.final_result).rstrip('0').rstrip('.')
-
-
-class Attachment(models.Model):
-    submission = models.ForeignKey(Submission)
-    exercise_id = models.IntegerField()
-    tag = models.CharField(max_length=128, null=True, blank=True)
-    file = models.FileField(upload_to='wtem/attachment')
-
-
-class Assignment(models.Model):
-    user = models.ForeignKey(User, unique=True)
-    exercises = JSONField()
-
-    def clean(self):
-        if not isinstance(self.exercises, list):
-            raise ValidationError(_('Assigned exercises must be declared in a list format'))
-        # for exercise in self.exercises:
-        #     if not isinstance(exercise, int) or exercise < 1:
-        #         raise ValidationError(_('Invalid exercise id: %s' % exercise))
-
-    def __unicode__(self):
-        return self.user.username + ': ' + ','.join(map(str, self.exercises))
-
-
-def exercise_checked_manually(exercise):
-    return (exercise['type'] in ('open', 'file_upload')) or 'open_part' in exercise
diff --git a/wtem/static/wtem/edumed.coffee b/wtem/static/wtem/edumed.coffee
deleted file mode 100644 (file)
index ae7aea9..0000000
+++ /dev/null
@@ -1,555 +0,0 @@
-
-$ = jQuery
-
-class Binding
-  constructor: (@handler, @element) ->
-    $(@element).data(@handler, this)
-
-
-class EduModule extends Binding
-  constructor: (element) ->
-    super 'edumodule', element
-
-    # $("[name=teacher-toggle]").change (ev) =>
-    #   if $(ev.target).is(":checked")
-    #     $(".teacher", @element).addClass "show"
-    #   else
-    #     $(".teacher", @element).removeClass "show"
-
-
-class Exercise extends Binding
-  constructor: (element) ->
-    super 'exercise', element
-    # just save the html to reset the exercise
-    $(@element).data("exercise-html", $(@element).html())
-
-    $(".check", @element).click (ev) =>
-      @check()
-      $(".retry", @element).show()
-      $(".check", @element).hide()
-    $(".retry", @element).click (ev) =>
-      @retry()
-    $('.solutions', @element).click =>
-      @show_solutions()
-      $(".comment", @element).show()
-    $('.reset', @element).click =>
-      @reset()
-
-  retry: ->
-    $(".correct, .incorrect", @element).removeClass("correct incorrect")
-    $(".check", @element).show()
-    $(".retry", @element).hide()
-
-  reset: ->
-    $(@element).html($(@element).data('exercise-html'))
-    exercise @element
-
-  piece_correct: (qpiece) ->
-    $(qpiece).removeClass('incorrect').addClass('correct')
-
-  piece_incorrect: (qpiece) ->
-    $(qpiece).removeClass('correct').addClass('incorrect')
-
-  check: ->
-    scores = []
-    $(".question", @element).each (i, question) =>
-      scores.push(@check_question question)
-
-    score = [0, 0, 0]
-    $.each scores, (i, s) ->
-      score[0] += s[0]
-      score[1] += s[1]
-      score[2] += s[2]
-    @show_score(score)
-
-  show_solutions: ->
-    @reset()
-    $(".question", @element).each (i, question) =>
-      @solve_question question
-
-  get_answers: ->
-    answers = []
-    $('.question', @element).each (i, question) =>
-      answers.push(@get_answer question)
-    return answers
-
-  # Parses a list of values, separated by space or comma.
-  # The list is read from data attribute of elem using data_key
-  # Returns a list with elements
-  # eg.: things_i_need: "house bike tv playstation"
-  # yields ["house", "bike", "tv", "playstation"]
-  # If optional numbers argument is true, returns list of numbers
-  # instead of strings
-  get_value_list: (elem, data_key, numbers) ->
-    vl = $(elem).attr("data-" + data_key).split(/[ ,]+/).map($.trim) #.map((x) -> parseInt(x))
-    if numbers
-      vl = vl.map((x) -> parseInt(x))
-    return vl
-
-  # Parses a list of values, separated by space or comma.
-  # The list is read from data attribute of elem using data_key
-  # Returns a 2-element list with mandatory and optional
-  # items. optional items are marked with a question mark on the end
-  # eg.: things_i_need: "house bike tv? playstation?"
-  # yields [[ "house", "bike"], ["tv", "playstation"]]
-  get_value_optional_list: (elem, data_key) ->
-    vals = @get_value_list(elem, data_key)
-    mandat = []
-    opt = []
-    for v in vals
-      if v.slice(-1) == "?"
-        opt.push v.slice(0, -1)
-      else
-        mandat.push v
-    return [mandat, opt]
-
-  show_score: (score) ->
-    $msg = $(".message", @element)
-    $msg.text("Wynik: #{score[0]} / #{score[2]}")
-    if score[0] >= score[2] and score[1] == 0
-      $msg.addClass("maxscore")
-    else
-      $msg.removeClass("maxscore")
-
-
-  draggable_equal: ($draggable1, $draggable2) ->
-    return false
-
-  draggable_accept: ($draggable, $droppable) ->
-    dropped = $droppable.closest("ul, ol").find(".draggable")
-    for d in dropped
-      if @draggable_equal $draggable, $(d)
-        return false
-    return true
-
-  draggable_move: ($draggable, $placeholder, ismultiple) ->
-    $added = $draggable.clone()
-    $added.data("original", $draggable.get(0))
-    if not ismultiple
-      $draggable.addClass('disabled').draggable('disable')
-
-    $placeholder.after($added)
-    if not $placeholder.hasClass('multiple')
-      $placeholder.hide()
-    if $added.is(".add-li")
-      $added.wrap("<li/>")
-
-    $added.append('<span class="remove">x</span><div class="clr"></div>')
-    $('.remove', $added).click (ev) =>
-      @retry()
-      if not ismultiple
-        $($added.data('original')).removeClass('disabled').draggable('enable')
-
-      if $added.is(".add-li")
-        $added = $added.closest('li')
-      $added.prev(".placeholder:not(.multiple)").show()
-      $added.remove()
-
-
-## XXX co z issortable?
-  dragging: (ismultiple, issortable) ->
-    $(".question", @element).each (i, question) =>
-      draggable_opts =
-        revert: 'invalid'
-        helper: 'clone'
-        start: @retry
-
-      $(".draggable", question).draggable(draggable_opts)
-      self = this
-      $(".placeholder", question).droppable
-        accept: (draggable) ->
-          $draggable = $(draggable)
-          is_accepted = true
-
-          if not $draggable.is(".draggable")
-            is_accepted = false
-
-          if is_accepted
-            is_accepted= self.draggable_accept $draggable, $(this)
-
-          if is_accepted
-            $(this).addClass 'accepting'
-          else
-            $(this).removeClass 'accepting'
-          return is_accepted
-
-        drop: (ev, ui) =>
-          $(ev.target).removeClass 'accepting dragover'
-
-          @draggable_move $(ui.draggable), $(ev.target), ismultiple
-
-          # $added = $(ui.draggable).clone()
-          # $added.data("original", ui.draggable)
-          # if not ismultiple
-          #   $(ui.draggable).addClass('disabled').draggable('disable')
-
-          # $(ev.target).after(added)
-          # if not $(ev.target).hasClass('multiple')
-          #   $(ev.target).hide()
-          # $added.append('<span class="remove">x</span>')
-          # $('.remove', added).click (ev) =>
-          #   $added.prev(".placeholder:not(.multiple)").show()
-          #   if not ismultiple
-          #     $added.data('original').removeClass('disabled').draggable('enable')
-          #   $(added).remove()
-
-        over: (ev, ui) ->
-          $(ev.target).addClass 'dragover'
-
-
-        out: (ev, ui) ->
-          $(ev.target).removeClass 'dragover'
-
-
-
-class Wybor extends Exercise
-  constructor: (element) ->
-    super element
-    $(".question-piece input", element).change(@retry);
-
-
-  check_question: (question) ->
-    all = 0
-    good = 0
-    bad = 0
-    solution = @get_value_list(question, 'solution')
-    $(".question-piece", question).each (i, qpiece) =>
-      piece_no = $(qpiece).attr 'data-no'
-      piece_name = $(qpiece).attr 'data-name'
-      if piece_name
-        should_be_checked = solution.indexOf(piece_name) >= 0
-      else
-        should_be_checked = solution.indexOf(piece_no) >= 0
-      is_checked = $("input", qpiece).is(":checked")
-
-      if should_be_checked
-        all += 1
-
-      if is_checked
-        if should_be_checked
-          good += 1
-          @piece_correct qpiece
-        else
-          bad += 1
-          @piece_incorrect qpiece
-      else
-        $(qpiece).removeClass("correct,incorrect")
-
-    return [good, bad, all]
-
-  solve_question: (question) ->
-    solution = @get_value_list(question, 'solution')
-    $(".question-piece", question).each (i, qpiece) =>
-      piece_no = $(qpiece).attr 'data-no'
-      piece_name = $(qpiece).attr 'data-name'
-      if piece_name
-        should_be_checked = solution.indexOf(piece_name) >= 0
-      else
-        should_be_checked = solution.indexOf(piece_no) >= 0
-      console.log("check " + $("input[type=checkbox]", qpiece).attr("id") + " -> " + should_be_checked)
-      $("input[type=checkbox],input[type=radio]", qpiece).prop 'checked', should_be_checked
-
-  get_answer: (question) ->
-    answer = []
-    $('.question-piece', question).each (i, qpiece) =>
-      $qpiece = $(qpiece)
-      if $("input[type=checkbox],input[type=radio]", qpiece).is(':checked')
-        answer.push($qpiece.attr('data-name'))
-    return answer
-
-
-class Uporzadkuj extends Exercise
-  constructor: (element) ->
-    super element
-    $('ol, ul', @element).sortable({ items: "> li", start: @retry })
-
-  check_question: (question) ->
-    positions = @get_value_list(question, 'original', true)
-    sorted = positions.sort()
-    pkts = $('.question-piece', question)
-
-    correct = 0
-    bad = 0
-    all = 0
-
-    for pkt in [0...pkts.length]
-      all += 1
-      if pkts.eq(pkt).data('pos') == sorted[pkt]
-        correct += 1
-        @piece_correct pkts.eq(pkt)
-      else
-        bad += 1
-        @piece_incorrect pkts.eq(pkt)
-    return [correct, bad, all]
-
-  solve_question: (question) ->
-    positions = @get_value_list(question, 'original', true)
-    sorted = positions.sort()
-    pkts = $('.question-piece', question)
-    pkts.sort (a, b) ->
-      q = $(a).data('pos')
-      w = $(b).data('pos')
-      return 1 if q < w
-      return -1 if q > w
-      return 0
-
-    parent = pkts.eq(0).parent()
-    for p in pkts
-      parent.prepend(p)
-
-  get_answer: (question) ->
-    answer = []
-    $(".question-piece", @element).each (i, qpiece) =>
-      answer.push($(qpiece).attr('data-pos'))
-    return answer
-
-
-# XXX propozycje="1/0"
-class Luki extends Exercise
-  constructor: (element) ->
-    super element
-    @dragging false, false
-
-  check: ->
-    all = $(".placeholder", @element).length
-    correct = 0
-    bad = 0
-    $(".placeholder + .question-piece", @element).each (i, qpiece) =>
-      $placeholder = $(qpiece).prev(".placeholder")
-      if $placeholder.data('solution') == $(qpiece).data('no')
-        @piece_correct qpiece
-        correct += 1
-      else
-        bad += 1
-        @piece_incorrect qpiece
-
-    @show_score [correct, bad, all]
-
-  solve_question: (question) ->
-    $(".placeholder", question).each (i, placeholder) =>
-      $qp = $(".question-piece[data-no=" + $(placeholder).data('solution') + "]", question)
-      @draggable_move $qp, $(placeholder), false
-
-
-class Zastap extends Exercise
-  constructor: (element) ->
-    super element
-    $(".paragraph", @element).each (i, par) =>
-      @wrap_words $(par), $('<span class="placeholder zastap"/>')
-    @dragging false, false
-
-  check: ->
-    all = 0
-    correct = 0
-    bad = 0
-
-    $(".paragraph", @element).each (i, par) =>
-      $(".placeholder", par).each (j, qpiece) =>
-        $qp = $(qpiece)
-        $dragged = $qp.next(".draggable")
-        if $qp.data("solution")
-          if $dragged and $qp.data("solution") == $dragged.data("no")
-            @piece_correct $dragged
-            correct += 1
-#          else -- we dont mark enything here, so not to hint user about solution. He sees he hasn't used all the draggables
-
-          all += 1
-
-    @show_score [correct, bad, all]
-
-  show_solutions: ->
-    @reset()
-    $(".paragraph", @element).each (i, par) =>
-      $(".placeholder[data-solution]", par).each (j, qpiece) =>
-        $qp = $(qpiece)
-        $dr = $(".draggable[data-no=" + $qp.data('solution') + "]", @element)
-        @draggable_move $dr, $qp, false
-
-
-  wrap_words: (element, wrapper) ->
-    # This function wraps each word of element in wrapper, but does not descend into child-tags of element.
-    # It doesn't wrap things between words (defined by ignore RE below). Warning - ignore must begin with ^
-    ignore = /^[ \t.,:;()]+/
-
-    insertWrapped = (txt, elem) ->
-      nw = wrapper.clone()
-      $(document.createTextNode(txt))
-        .wrap(nw).parent().attr("data-original", txt).insertBefore(elem)
-
-    for j in [element.get(0).childNodes.length-1..0]
-      chld = element.get(0).childNodes[j]
-      if chld.nodeType == document.TEXT_NODE
-        len = chld.textContent.length
-        wordb = 0
-        i = 0
-        while i < len
-          space = ignore.exec(chld.textContent.substr(i))
-          if space?
-            if wordb < i
-              insertWrapped(chld.textContent.substr(wordb, i-wordb), chld)
-
-            $(document.createTextNode(space[0])).insertBefore(chld)
-            i += space[0].length
-            wordb = i
-          else
-            i = i + 1
-        if wordb < len - 1
-          insertWrapped(chld.textContent.substr(wordb, len - 1 - wordb), chld)
-        $(chld).remove()
-
-
-class Przyporzadkuj extends Exercise
-  is_multiple: ->
-    for qp in $(".question-piece", @element)
-      if $(qp).attr('data-solution').split(/[ ,]+/).length > 1
-        return true
-    return false
-
-  constructor: (element) ->
-    super element
-
-    @multiple = @is_multiple()
-
-    @dragging @multiple, true
-
-  draggable_equal: (d1, d2) ->
-    return d1.data("no") == d2.data("no")
-
-  draggable_accept: ($draggable, $droppable) ->
-    dropped = $droppable.closest("ul, ol").find(".draggable")
-    return (super $draggable, $droppable) && dropped.length == 0
-
-  check_question: (question) ->
-    # subjects placed in predicates
-    minimum = $(question).data("minimum")
-    count = 0
-    bad_count = 0
-    all = 0
-    if not minimum
-      self = this
-      $(".subject .question-piece", question).each (i, el) ->
-        v = self.get_value_optional_list el, 'solution'
-        mandatory = v[0]
-        all += mandatory.length
-
-    for pred in $(".predicate [data-predicate]", question)
-      pn = $(pred).attr('data-predicate')
-      #if minimum?
-      #  all += minimum
-
-      for qp in $(".question-piece", pred)
-        v = @get_value_optional_list qp, 'solution'
-        mandatory = v[0]
-        optional = v[1]
-
-        if mandatory.indexOf(pn) >= 0 or (minimum and optional.indexOf(pn) >= 0)
-          count += 1
-          @piece_correct qp
-        else
-          bad_count += 1
-          @piece_incorrect qp
-
-    return [count, bad_count, all]
-
-  solve_question: (question) ->
-    minimum = $(question).data("min")
-
-    for qp in $(".subject .question-piece", question)
-      v = @get_value_optional_list qp, 'solution'
-      mandatory = v[0]
-      optional = v[1]
-
-      if minimum
-        draggables = mandatory.count(optional)[0...minimum]
-      else
-        draggables = mandatory
-      for m in draggables
-        $pr = $(".predicate [data-predicate=" + m + "]", question)
-        $ph = $pr.find ".placeholder:visible"
-        @draggable_move $(qp), $ph.eq(0), @multiple
-
-  get_answer: (question) ->
-    answer = {}
-    $(".predicate [data-predicate]", question).each (i, subjects) =>
-      predicate = $(subjects).attr('data-predicate')
-      answer[predicate] = []
-      $('.question-piece', subjects).each (i, qpiece) =>
-        $qpiece = $(qpiece)
-        answer[predicate].push($qpiece.attr('data-id'))
-    return answer
-
-
-class PrawdaFalsz extends Exercise
-  constructor: (element) ->
-    super element
-
-    for qp in $(".question-piece", @element)
-      $(".true", qp).click (ev) =>
-        ev.preventDefault()
-        @retry()
-        $(ev.target).closest(".question-piece").data("value", "true")
-        $(ev.target).addClass('chosen').siblings('a').removeClass('chosen')
-      $(".false", qp).click (ev) =>
-        ev.preventDefault()
-        @retry()
-        $(ev.target).closest(".question-piece").data("value", "false")
-        $(ev.target).addClass('chosen').siblings('a').removeClass('chosen')
-
-
-  check_question: ->
-    all = 0
-    good = 0
-    bad = 0
-    for qp in $(".question-piece", @element)
-      if $(qp).data("solution").toString() == $(qp).data("value")
-        good += 1
-        @piece_correct qp
-      else
-        bad += 1
-        @piece_incorrect qp
-
-      all += 1
-
-    return [good, bad, all]
-
-  show_solutions: ->
-    @reset()
-    for qp in $(".question-piece", @element)
-      if $(qp).data('solution') == true
-        $(".true", qp).click()
-      else
-        $(".false", qp).click()
-
-  get_answer: (question) ->
-    answer = []
-    $(".question-piece", @element).each (i, qpiece) =>
-      answer.push($(qpiece).data('value') || '-')
-    return answer
-
-##########
-
-exercise = (ele) ->
-  es =
-    wybor: Wybor
-    uporzadkuj: Uporzadkuj
-    luki: Luki
-    zastap: Zastap
-    przyporzadkuj: Przyporzadkuj
-    prawdafalsz: PrawdaFalsz
-
-
-  cls = es[$(ele).attr('data-type')]
-  new cls(ele)
-
-
-window.edumed =
-  'EduModule': EduModule
-
-
-
-
-$(document).ready () ->
-  new EduModule($("#book-text"))
-
-  $(".exercise").each (i, el) ->
-    exercise(this)
diff --git a/wtem/static/wtem/edumed.js b/wtem/static/wtem/edumed.js
deleted file mode 100644 (file)
index 940ca54..0000000
+++ /dev/null
@@ -1,740 +0,0 @@
-// Generated by CoffeeScript 1.6.3
-(function() {
-  var $, Binding, EduModule, Exercise, Luki, PrawdaFalsz, Przyporzadkuj, Uporzadkuj, Wybor, Zastap, exercise,
-    __hasProp = {}.hasOwnProperty,
-    __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
-
-  $ = jQuery;
-
-  Binding = (function() {
-    function Binding(handler, element) {
-      this.handler = handler;
-      this.element = element;
-      $(this.element).data(this.handler, this);
-    }
-
-    return Binding;
-
-  })();
-
-  EduModule = (function(_super) {
-    __extends(EduModule, _super);
-
-    function EduModule(element) {
-      EduModule.__super__.constructor.call(this, 'edumodule', element);
-    }
-
-    return EduModule;
-
-  })(Binding);
-
-  Exercise = (function(_super) {
-    __extends(Exercise, _super);
-
-    function Exercise(element) {
-      var _this = this;
-      Exercise.__super__.constructor.call(this, 'exercise', element);
-      $(this.element).data("exercise-html", $(this.element).html());
-      $(".check", this.element).click(function(ev) {
-        _this.check();
-        $(".retry", _this.element).show();
-        return $(".check", _this.element).hide();
-      });
-      $(".retry", this.element).click(function(ev) {
-        return _this.retry();
-      });
-      $('.solutions', this.element).click(function() {
-        _this.show_solutions();
-        return $(".comment", _this.element).show();
-      });
-      $('.reset', this.element).click(function() {
-        return _this.reset();
-      });
-    }
-
-    Exercise.prototype.retry = function() {
-      $(".correct, .incorrect", this.element).removeClass("correct incorrect");
-      $(".check", this.element).show();
-      return $(".retry", this.element).hide();
-    };
-
-    Exercise.prototype.reset = function() {
-      $(this.element).html($(this.element).data('exercise-html'));
-      return exercise(this.element);
-    };
-
-    Exercise.prototype.piece_correct = function(qpiece) {
-      return $(qpiece).removeClass('incorrect').addClass('correct');
-    };
-
-    Exercise.prototype.piece_incorrect = function(qpiece) {
-      return $(qpiece).removeClass('correct').addClass('incorrect');
-    };
-
-    Exercise.prototype.check = function() {
-      var score, scores,
-        _this = this;
-      scores = [];
-      $(".question", this.element).each(function(i, question) {
-        return scores.push(_this.check_question(question));
-      });
-      score = [0, 0, 0];
-      $.each(scores, function(i, s) {
-        score[0] += s[0];
-        score[1] += s[1];
-        return score[2] += s[2];
-      });
-      return this.show_score(score);
-    };
-
-    Exercise.prototype.show_solutions = function() {
-      var _this = this;
-      this.reset();
-      return $(".question", this.element).each(function(i, question) {
-        return _this.solve_question(question);
-      });
-    };
-
-    Exercise.prototype.get_answers = function() {
-      var answers,
-        _this = this;
-      answers = [];
-      $('.question', this.element).each(function(i, question) {
-        return answers.push(_this.get_answer(question));
-      });
-      return answers;
-    };
-
-    Exercise.prototype.get_value_list = function(elem, data_key, numbers) {
-      var vl;
-      vl = $(elem).attr("data-" + data_key).split(/[ ,]+/).map($.trim);
-      if (numbers) {
-        vl = vl.map(function(x) {
-          return parseInt(x);
-        });
-      }
-      return vl;
-    };
-
-    Exercise.prototype.get_value_optional_list = function(elem, data_key) {
-      var mandat, opt, v, vals, _i, _len;
-      vals = this.get_value_list(elem, data_key);
-      mandat = [];
-      opt = [];
-      for (_i = 0, _len = vals.length; _i < _len; _i++) {
-        v = vals[_i];
-        if (v.slice(-1) === "?") {
-          opt.push(v.slice(0, -1));
-        } else {
-          mandat.push(v);
-        }
-      }
-      return [mandat, opt];
-    };
-
-    Exercise.prototype.show_score = function(score) {
-      var $msg;
-      $msg = $(".message", this.element);
-      $msg.text("Wynik: " + score[0] + " / " + score[2]);
-      if (score[0] >= score[2] && score[1] === 0) {
-        return $msg.addClass("maxscore");
-      } else {
-        return $msg.removeClass("maxscore");
-      }
-    };
-
-    Exercise.prototype.draggable_equal = function($draggable1, $draggable2) {
-      return false;
-    };
-
-    Exercise.prototype.draggable_accept = function($draggable, $droppable) {
-      var d, dropped, _i, _len;
-      dropped = $droppable.closest("ul, ol").find(".draggable");
-      for (_i = 0, _len = dropped.length; _i < _len; _i++) {
-        d = dropped[_i];
-        if (this.draggable_equal($draggable, $(d))) {
-          return false;
-        }
-      }
-      return true;
-    };
-
-    Exercise.prototype.draggable_move = function($draggable, $placeholder, ismultiple) {
-      var $added,
-        _this = this;
-      $added = $draggable.clone();
-      $added.data("original", $draggable.get(0));
-      if (!ismultiple) {
-        $draggable.addClass('disabled').draggable('disable');
-      }
-      $placeholder.after($added);
-      if (!$placeholder.hasClass('multiple')) {
-        $placeholder.hide();
-      }
-      if ($added.is(".add-li")) {
-        $added.wrap("<li/>");
-      }
-      $added.append('<span class="remove">x</span><div class="clr"></div>');
-      return $('.remove', $added).click(function(ev) {
-        _this.retry();
-        if (!ismultiple) {
-          $($added.data('original')).removeClass('disabled').draggable('enable');
-        }
-        if ($added.is(".add-li")) {
-          $added = $added.closest('li');
-        }
-        $added.prev(".placeholder:not(.multiple)").show();
-        return $added.remove();
-      });
-    };
-
-    Exercise.prototype.dragging = function(ismultiple, issortable) {
-      var _this = this;
-      return $(".question", this.element).each(function(i, question) {
-        var draggable_opts, self;
-        draggable_opts = {
-          revert: 'invalid',
-          helper: 'clone',
-          start: _this.retry
-        };
-        $(".draggable", question).draggable(draggable_opts);
-        self = _this;
-        return $(".placeholder", question).droppable({
-          accept: function(draggable) {
-            var $draggable, is_accepted;
-            $draggable = $(draggable);
-            is_accepted = true;
-            if (!$draggable.is(".draggable")) {
-              is_accepted = false;
-            }
-            if (is_accepted) {
-              is_accepted = self.draggable_accept($draggable, $(this));
-            }
-            if (is_accepted) {
-              $(this).addClass('accepting');
-            } else {
-              $(this).removeClass('accepting');
-            }
-            return is_accepted;
-          },
-          drop: function(ev, ui) {
-            $(ev.target).removeClass('accepting dragover');
-            return _this.draggable_move($(ui.draggable), $(ev.target), ismultiple);
-          },
-          over: function(ev, ui) {
-            return $(ev.target).addClass('dragover');
-          },
-          out: function(ev, ui) {
-            return $(ev.target).removeClass('dragover');
-          }
-        });
-      });
-    };
-
-    return Exercise;
-
-  })(Binding);
-
-  Wybor = (function(_super) {
-    __extends(Wybor, _super);
-
-    function Wybor(element) {
-      Wybor.__super__.constructor.call(this, element);
-      $(".question-piece input", element).change(this.retry);
-    }
-
-    Wybor.prototype.check_question = function(question) {
-      var all, bad, good, solution,
-        _this = this;
-      all = 0;
-      good = 0;
-      bad = 0;
-      solution = this.get_value_list(question, 'solution');
-      $(".question-piece", question).each(function(i, qpiece) {
-        var is_checked, piece_name, piece_no, should_be_checked;
-        piece_no = $(qpiece).attr('data-no');
-        piece_name = $(qpiece).attr('data-name');
-        if (piece_name) {
-          should_be_checked = solution.indexOf(piece_name) >= 0;
-        } else {
-          should_be_checked = solution.indexOf(piece_no) >= 0;
-        }
-        is_checked = $("input", qpiece).is(":checked");
-        if (should_be_checked) {
-          all += 1;
-        }
-        if (is_checked) {
-          if (should_be_checked) {
-            good += 1;
-            return _this.piece_correct(qpiece);
-          } else {
-            bad += 1;
-            return _this.piece_incorrect(qpiece);
-          }
-        } else {
-          return $(qpiece).removeClass("correct,incorrect");
-        }
-      });
-      return [good, bad, all];
-    };
-
-    Wybor.prototype.solve_question = function(question) {
-      var solution,
-        _this = this;
-      solution = this.get_value_list(question, 'solution');
-      return $(".question-piece", question).each(function(i, qpiece) {
-        var piece_name, piece_no, should_be_checked;
-        piece_no = $(qpiece).attr('data-no');
-        piece_name = $(qpiece).attr('data-name');
-        if (piece_name) {
-          should_be_checked = solution.indexOf(piece_name) >= 0;
-        } else {
-          should_be_checked = solution.indexOf(piece_no) >= 0;
-        }
-        console.log("check " + $("input[type=checkbox]", qpiece).attr("id") + " -> " + should_be_checked);
-        return $("input[type=checkbox],input[type=radio]", qpiece).prop('checked', should_be_checked);
-      });
-    };
-
-    Wybor.prototype.get_answer = function(question) {
-      var answer,
-        _this = this;
-      answer = [];
-      $('.question-piece', question).each(function(i, qpiece) {
-        var $qpiece;
-        $qpiece = $(qpiece);
-        if ($("input[type=checkbox],input[type=radio]", qpiece).is(':checked')) {
-          return answer.push($qpiece.attr('data-name'));
-        }
-      });
-      return answer;
-    };
-
-    return Wybor;
-
-  })(Exercise);
-
-  Uporzadkuj = (function(_super) {
-    __extends(Uporzadkuj, _super);
-
-    function Uporzadkuj(element) {
-      Uporzadkuj.__super__.constructor.call(this, element);
-      $('ol, ul', this.element).sortable({
-        items: "> li",
-        start: this.retry
-      });
-    }
-
-    Uporzadkuj.prototype.check_question = function(question) {
-      var all, bad, correct, pkt, pkts, positions, sorted, _i, _ref;
-      positions = this.get_value_list(question, 'original', true);
-      sorted = positions.sort();
-      pkts = $('.question-piece', question);
-      correct = 0;
-      bad = 0;
-      all = 0;
-      for (pkt = _i = 0, _ref = pkts.length; 0 <= _ref ? _i < _ref : _i > _ref; pkt = 0 <= _ref ? ++_i : --_i) {
-        all += 1;
-        if (pkts.eq(pkt).data('pos') === sorted[pkt]) {
-          correct += 1;
-          this.piece_correct(pkts.eq(pkt));
-        } else {
-          bad += 1;
-          this.piece_incorrect(pkts.eq(pkt));
-        }
-      }
-      return [correct, bad, all];
-    };
-
-    Uporzadkuj.prototype.solve_question = function(question) {
-      var p, parent, pkts, positions, sorted, _i, _len, _results;
-      positions = this.get_value_list(question, 'original', true);
-      sorted = positions.sort();
-      pkts = $('.question-piece', question);
-      pkts.sort(function(a, b) {
-        var q, w;
-        q = $(a).data('pos');
-        w = $(b).data('pos');
-        if (q < w) {
-          return 1;
-        }
-        if (q > w) {
-          return -1;
-        }
-        return 0;
-      });
-      parent = pkts.eq(0).parent();
-      _results = [];
-      for (_i = 0, _len = pkts.length; _i < _len; _i++) {
-        p = pkts[_i];
-        _results.push(parent.prepend(p));
-      }
-      return _results;
-    };
-
-    Uporzadkuj.prototype.get_answer = function(question) {
-      var answer,
-        _this = this;
-      answer = [];
-      $(".question-piece", this.element).each(function(i, qpiece) {
-        return answer.push($(qpiece).attr('data-pos'));
-      });
-      return answer;
-    };
-
-    return Uporzadkuj;
-
-  })(Exercise);
-
-  Luki = (function(_super) {
-    __extends(Luki, _super);
-
-    function Luki(element) {
-      Luki.__super__.constructor.call(this, element);
-      this.dragging(false, false);
-    }
-
-    Luki.prototype.check = function() {
-      var all, bad, correct,
-        _this = this;
-      all = $(".placeholder", this.element).length;
-      correct = 0;
-      bad = 0;
-      $(".placeholder + .question-piece", this.element).each(function(i, qpiece) {
-        var $placeholder;
-        $placeholder = $(qpiece).prev(".placeholder");
-        if ($placeholder.data('solution') === $(qpiece).data('no')) {
-          _this.piece_correct(qpiece);
-          return correct += 1;
-        } else {
-          bad += 1;
-          return _this.piece_incorrect(qpiece);
-        }
-      });
-      return this.show_score([correct, bad, all]);
-    };
-
-    Luki.prototype.solve_question = function(question) {
-      var _this = this;
-      return $(".placeholder", question).each(function(i, placeholder) {
-        var $qp;
-        $qp = $(".question-piece[data-no=" + $(placeholder).data('solution') + "]", question);
-        return _this.draggable_move($qp, $(placeholder), false);
-      });
-    };
-
-    return Luki;
-
-  })(Exercise);
-
-  Zastap = (function(_super) {
-    __extends(Zastap, _super);
-
-    function Zastap(element) {
-      var _this = this;
-      Zastap.__super__.constructor.call(this, element);
-      $(".paragraph", this.element).each(function(i, par) {
-        return _this.wrap_words($(par), $('<span class="placeholder zastap"/>'));
-      });
-      this.dragging(false, false);
-    }
-
-    Zastap.prototype.check = function() {
-      var all, bad, correct,
-        _this = this;
-      all = 0;
-      correct = 0;
-      bad = 0;
-      $(".paragraph", this.element).each(function(i, par) {
-        return $(".placeholder", par).each(function(j, qpiece) {
-          var $dragged, $qp;
-          $qp = $(qpiece);
-          $dragged = $qp.next(".draggable");
-          if ($qp.data("solution")) {
-            if ($dragged && $qp.data("solution") === $dragged.data("no")) {
-              _this.piece_correct($dragged);
-              correct += 1;
-            }
-            return all += 1;
-          }
-        });
-      });
-      return this.show_score([correct, bad, all]);
-    };
-
-    Zastap.prototype.show_solutions = function() {
-      var _this = this;
-      this.reset();
-      return $(".paragraph", this.element).each(function(i, par) {
-        return $(".placeholder[data-solution]", par).each(function(j, qpiece) {
-          var $dr, $qp;
-          $qp = $(qpiece);
-          $dr = $(".draggable[data-no=" + $qp.data('solution') + "]", _this.element);
-          return _this.draggable_move($dr, $qp, false);
-        });
-      });
-    };
-
-    Zastap.prototype.wrap_words = function(element, wrapper) {
-      var chld, i, ignore, insertWrapped, j, len, space, wordb, _i, _ref, _results;
-      ignore = /^[ \t.,:;()]+/;
-      insertWrapped = function(txt, elem) {
-        var nw;
-        nw = wrapper.clone();
-        return $(document.createTextNode(txt)).wrap(nw).parent().attr("data-original", txt).insertBefore(elem);
-      };
-      _results = [];
-      for (j = _i = _ref = element.get(0).childNodes.length - 1; _ref <= 0 ? _i <= 0 : _i >= 0; j = _ref <= 0 ? ++_i : --_i) {
-        chld = element.get(0).childNodes[j];
-        if (chld.nodeType === document.TEXT_NODE) {
-          len = chld.textContent.length;
-          wordb = 0;
-          i = 0;
-          while (i < len) {
-            space = ignore.exec(chld.textContent.substr(i));
-            if (space != null) {
-              if (wordb < i) {
-                insertWrapped(chld.textContent.substr(wordb, i - wordb), chld);
-              }
-              $(document.createTextNode(space[0])).insertBefore(chld);
-              i += space[0].length;
-              wordb = i;
-            } else {
-              i = i + 1;
-            }
-          }
-          if (wordb < len - 1) {
-            insertWrapped(chld.textContent.substr(wordb, len - 1 - wordb), chld);
-          }
-          _results.push($(chld).remove());
-        } else {
-          _results.push(void 0);
-        }
-      }
-      return _results;
-    };
-
-    return Zastap;
-
-  })(Exercise);
-
-  Przyporzadkuj = (function(_super) {
-    __extends(Przyporzadkuj, _super);
-
-    Przyporzadkuj.prototype.is_multiple = function() {
-      var qp, _i, _len, _ref;
-      _ref = $(".question-piece", this.element);
-      for (_i = 0, _len = _ref.length; _i < _len; _i++) {
-        qp = _ref[_i];
-        if ($(qp).attr('data-solution').split(/[ ,]+/).length > 1) {
-          return true;
-        }
-      }
-      return false;
-    };
-
-    function Przyporzadkuj(element) {
-      Przyporzadkuj.__super__.constructor.call(this, element);
-      this.multiple = this.is_multiple();
-      this.dragging(this.multiple, true);
-    }
-
-    Przyporzadkuj.prototype.draggable_equal = function(d1, d2) {
-      return d1.data("no") === d2.data("no");
-    };
-
-    Przyporzadkuj.prototype.draggable_accept = function($draggable, $droppable) {
-      var dropped;
-      dropped = $droppable.closest("ul, ol").find(".draggable");
-      return (Przyporzadkuj.__super__.draggable_accept.call(this, $draggable, $droppable)) && dropped.length === 0;
-    };
-
-    Przyporzadkuj.prototype.check_question = function(question) {
-      var all, bad_count, count, mandatory, minimum, optional, pn, pred, qp, self, v, _i, _j, _len, _len1, _ref, _ref1;
-      minimum = $(question).data("minimum");
-      count = 0;
-      bad_count = 0;
-      all = 0;
-      if (!minimum) {
-        self = this;
-        $(".subject .question-piece", question).each(function(i, el) {
-          var mandatory, v;
-          v = self.get_value_optional_list(el, 'solution');
-          mandatory = v[0];
-          return all += mandatory.length;
-        });
-      }
-      _ref = $(".predicate [data-predicate]", question);
-      for (_i = 0, _len = _ref.length; _i < _len; _i++) {
-        pred = _ref[_i];
-        pn = $(pred).attr('data-predicate');
-        _ref1 = $(".question-piece", pred);
-        for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) {
-          qp = _ref1[_j];
-          v = this.get_value_optional_list(qp, 'solution');
-          mandatory = v[0];
-          optional = v[1];
-          if (mandatory.indexOf(pn) >= 0 || (minimum && optional.indexOf(pn) >= 0)) {
-            count += 1;
-            this.piece_correct(qp);
-          } else {
-            bad_count += 1;
-            this.piece_incorrect(qp);
-          }
-        }
-      }
-      return [count, bad_count, all];
-    };
-
-    Przyporzadkuj.prototype.solve_question = function(question) {
-      var $ph, $pr, draggables, m, mandatory, minimum, optional, qp, v, _i, _len, _ref, _results;
-      minimum = $(question).data("min");
-      _ref = $(".subject .question-piece", question);
-      _results = [];
-      for (_i = 0, _len = _ref.length; _i < _len; _i++) {
-        qp = _ref[_i];
-        v = this.get_value_optional_list(qp, 'solution');
-        mandatory = v[0];
-        optional = v[1];
-        if (minimum) {
-          draggables = mandatory.count(optional).slice(0, minimum);
-        } else {
-          draggables = mandatory;
-        }
-        _results.push((function() {
-          var _j, _len1, _results1;
-          _results1 = [];
-          for (_j = 0, _len1 = draggables.length; _j < _len1; _j++) {
-            m = draggables[_j];
-            $pr = $(".predicate [data-predicate=" + m + "]", question);
-            $ph = $pr.find(".placeholder:visible");
-            _results1.push(this.draggable_move($(qp), $ph.eq(0), this.multiple));
-          }
-          return _results1;
-        }).call(this));
-      }
-      return _results;
-    };
-
-    Przyporzadkuj.prototype.get_answer = function(question) {
-      var answer,
-        _this = this;
-      answer = {};
-      $(".predicate [data-predicate]", question).each(function(i, subjects) {
-        var predicate;
-        predicate = $(subjects).attr('data-predicate');
-        answer[predicate] = [];
-        return $('.question-piece', subjects).each(function(i, qpiece) {
-          var $qpiece;
-          $qpiece = $(qpiece);
-          return answer[predicate].push($qpiece.attr('data-id'));
-        });
-      });
-      return answer;
-    };
-
-    return Przyporzadkuj;
-
-  })(Exercise);
-
-  PrawdaFalsz = (function(_super) {
-    __extends(PrawdaFalsz, _super);
-
-    function PrawdaFalsz(element) {
-      var qp, _i, _len, _ref,
-        _this = this;
-      PrawdaFalsz.__super__.constructor.call(this, element);
-      _ref = $(".question-piece", this.element);
-      for (_i = 0, _len = _ref.length; _i < _len; _i++) {
-        qp = _ref[_i];
-        $(".true", qp).click(function(ev) {
-          ev.preventDefault();
-          _this.retry();
-          $(ev.target).closest(".question-piece").data("value", "true");
-          return $(ev.target).addClass('chosen').siblings('a').removeClass('chosen');
-        });
-        $(".false", qp).click(function(ev) {
-          ev.preventDefault();
-          _this.retry();
-          $(ev.target).closest(".question-piece").data("value", "false");
-          return $(ev.target).addClass('chosen').siblings('a').removeClass('chosen');
-        });
-      }
-    }
-
-    PrawdaFalsz.prototype.check_question = function() {
-      var all, bad, good, qp, _i, _len, _ref;
-      all = 0;
-      good = 0;
-      bad = 0;
-      _ref = $(".question-piece", this.element);
-      for (_i = 0, _len = _ref.length; _i < _len; _i++) {
-        qp = _ref[_i];
-        if ($(qp).data("solution").toString() === $(qp).data("value")) {
-          good += 1;
-          this.piece_correct(qp);
-        } else {
-          bad += 1;
-          this.piece_incorrect(qp);
-        }
-        all += 1;
-      }
-      return [good, bad, all];
-    };
-
-    PrawdaFalsz.prototype.show_solutions = function() {
-      var qp, _i, _len, _ref, _results;
-      this.reset();
-      _ref = $(".question-piece", this.element);
-      _results = [];
-      for (_i = 0, _len = _ref.length; _i < _len; _i++) {
-        qp = _ref[_i];
-        if ($(qp).data('solution') === true) {
-          _results.push($(".true", qp).click());
-        } else {
-          _results.push($(".false", qp).click());
-        }
-      }
-      return _results;
-    };
-
-    PrawdaFalsz.prototype.get_answer = function(question) {
-      var answer,
-        _this = this;
-      answer = [];
-      $(".question-piece", this.element).each(function(i, qpiece) {
-        return answer.push($(qpiece).data('value') || '-');
-      });
-      return answer;
-    };
-
-    return PrawdaFalsz;
-
-  })(Exercise);
-
-  exercise = function(ele) {
-    var cls, es;
-    es = {
-      wybor: Wybor,
-      uporzadkuj: Uporzadkuj,
-      luki: Luki,
-      zastap: Zastap,
-      przyporzadkuj: Przyporzadkuj,
-      prawdafalsz: PrawdaFalsz
-    };
-    cls = es[$(ele).attr('data-type')];
-    return new cls(ele);
-  };
-
-  window.edumed = {
-    'EduModule': EduModule
-  };
-
-  $(document).ready(function() {
-    new EduModule($("#book-text"));
-    return $(".exercise").each(function(i, el) {
-      return exercise(this);
-    });
-  });
-
-}).call(this);
diff --git a/wtem/static/wtem/img/1.png b/wtem/static/wtem/img/1.png
deleted file mode 100644 (file)
index 48e5969..0000000
Binary files a/wtem/static/wtem/img/1.png and /dev/null differ
diff --git a/wtem/static/wtem/img/1_small.png b/wtem/static/wtem/img/1_small.png
deleted file mode 100644 (file)
index 7364241..0000000
Binary files a/wtem/static/wtem/img/1_small.png and /dev/null differ
diff --git a/wtem/static/wtem/img/2.png b/wtem/static/wtem/img/2.png
deleted file mode 100644 (file)
index 7256587..0000000
Binary files a/wtem/static/wtem/img/2.png and /dev/null differ
diff --git a/wtem/static/wtem/img/2_small.png b/wtem/static/wtem/img/2_small.png
deleted file mode 100644 (file)
index 8d7e31e..0000000
Binary files a/wtem/static/wtem/img/2_small.png and /dev/null differ
diff --git a/wtem/static/wtem/img/3.png b/wtem/static/wtem/img/3.png
deleted file mode 100644 (file)
index 0d027d5..0000000
Binary files a/wtem/static/wtem/img/3.png and /dev/null differ
diff --git a/wtem/static/wtem/img/3_small.png b/wtem/static/wtem/img/3_small.png
deleted file mode 100644 (file)
index d66ecda..0000000
Binary files a/wtem/static/wtem/img/3_small.png and /dev/null differ
diff --git a/wtem/static/wtem/img/komunikat_policyjny.png b/wtem/static/wtem/img/komunikat_policyjny.png
deleted file mode 100644 (file)
index 7549634..0000000
Binary files a/wtem/static/wtem/img/komunikat_policyjny.png and /dev/null differ
diff --git a/wtem/static/wtem/img/krrit_zrzut_ekranu.png b/wtem/static/wtem/img/krrit_zrzut_ekranu.png
deleted file mode 100644 (file)
index 5ae4423..0000000
Binary files a/wtem/static/wtem/img/krrit_zrzut_ekranu.png and /dev/null differ
diff --git a/wtem/static/wtem/img/przyp/1.jpg b/wtem/static/wtem/img/przyp/1.jpg
deleted file mode 100644 (file)
index 7eba4d8..0000000
Binary files a/wtem/static/wtem/img/przyp/1.jpg and /dev/null differ
diff --git a/wtem/static/wtem/img/przyp/2.jpg b/wtem/static/wtem/img/przyp/2.jpg
deleted file mode 100644 (file)
index c529dd4..0000000
Binary files a/wtem/static/wtem/img/przyp/2.jpg and /dev/null differ
diff --git a/wtem/static/wtem/img/przyp/3.jpg b/wtem/static/wtem/img/przyp/3.jpg
deleted file mode 100644 (file)
index 69c2b53..0000000
Binary files a/wtem/static/wtem/img/przyp/3.jpg and /dev/null differ
diff --git a/wtem/static/wtem/img/przyp/4.jpg b/wtem/static/wtem/img/przyp/4.jpg
deleted file mode 100644 (file)
index e4557cb..0000000
Binary files a/wtem/static/wtem/img/przyp/4.jpg and /dev/null differ
diff --git a/wtem/static/wtem/img/przyp/5.jpg b/wtem/static/wtem/img/przyp/5.jpg
deleted file mode 100644 (file)
index 3698534..0000000
Binary files a/wtem/static/wtem/img/przyp/5.jpg and /dev/null differ
diff --git a/wtem/static/wtem/img/przyp2/1.jpg b/wtem/static/wtem/img/przyp2/1.jpg
deleted file mode 100644 (file)
index 9879cb9..0000000
Binary files a/wtem/static/wtem/img/przyp2/1.jpg and /dev/null differ
diff --git a/wtem/static/wtem/img/przyp2/2.jpg b/wtem/static/wtem/img/przyp2/2.jpg
deleted file mode 100644 (file)
index 4157d81..0000000
Binary files a/wtem/static/wtem/img/przyp2/2.jpg and /dev/null differ
diff --git a/wtem/static/wtem/img/przyp2/3.jpg b/wtem/static/wtem/img/przyp2/3.jpg
deleted file mode 100644 (file)
index 05dc855..0000000
Binary files a/wtem/static/wtem/img/przyp2/3.jpg and /dev/null differ
diff --git a/wtem/static/wtem/img/przyp2/4.jpg b/wtem/static/wtem/img/przyp2/4.jpg
deleted file mode 100644 (file)
index f0b4b12..0000000
Binary files a/wtem/static/wtem/img/przyp2/4.jpg and /dev/null differ
diff --git a/wtem/static/wtem/img/przyp2/5.jpg b/wtem/static/wtem/img/przyp2/5.jpg
deleted file mode 100644 (file)
index 38e92cd..0000000
Binary files a/wtem/static/wtem/img/przyp2/5.jpg and /dev/null differ
diff --git a/wtem/static/wtem/json2.js b/wtem/static/wtem/json2.js
deleted file mode 100644 (file)
index d89ecc7..0000000
+++ /dev/null
@@ -1,486 +0,0 @@
-/*
-    json2.js
-    2013-05-26
-
-    Public Domain.
-
-    NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.
-
-    See http://www.JSON.org/js.html
-
-
-    This code should be minified before deployment.
-    See http://javascript.crockford.com/jsmin.html
-
-    USE YOUR OWN COPY. IT IS EXTREMELY UNWISE TO LOAD CODE FROM SERVERS YOU DO
-    NOT CONTROL.
-
-
-    This file creates a global JSON object containing two methods: stringify
-    and parse.
-
-        JSON.stringify(value, replacer, space)
-            value       any JavaScript value, usually an object or array.
-
-            replacer    an optional parameter that determines how object
-                        values are stringified for objects. It can be a
-                        function or an array of strings.
-
-            space       an optional parameter that specifies the indentation
-                        of nested structures. If it is omitted, the text will
-                        be packed without extra whitespace. If it is a number,
-                        it will specify the number of spaces to indent at each
-                        level. If it is a string (such as '\t' or '&nbsp;'),
-                        it contains the characters used to indent at each level.
-
-            This method produces a JSON text from a JavaScript value.
-
-            When an object value is found, if the object contains a toJSON
-            method, its toJSON method will be called and the result will be
-            stringified. A toJSON method does not serialize: it returns the
-            value represented by the name/value pair that should be serialized,
-            or undefined if nothing should be serialized. The toJSON method
-            will be passed the key associated with the value, and this will be
-            bound to the value
-
-            For example, this would serialize Dates as ISO strings.
-
-                Date.prototype.toJSON = function (key) {
-                    function f(n) {
-                        // Format integers to have at least two digits.
-                        return n < 10 ? '0' + n : n;
-                    }
-
-                    return this.getUTCFullYear()   + '-' +
-                         f(this.getUTCMonth() + 1) + '-' +
-                         f(this.getUTCDate())      + 'T' +
-                         f(this.getUTCHours())     + ':' +
-                         f(this.getUTCMinutes())   + ':' +
-                         f(this.getUTCSeconds())   + 'Z';
-                };
-
-            You can provide an optional replacer method. It will be passed the
-            key and value of each member, with this bound to the containing
-            object. The value that is returned from your method will be
-            serialized. If your method returns undefined, then the member will
-            be excluded from the serialization.
-
-            If the replacer parameter is an array of strings, then it will be
-            used to select the members to be serialized. It filters the results
-            such that only members with keys listed in the replacer array are
-            stringified.
-
-            Values that do not have JSON representations, such as undefined or
-            functions, will not be serialized. Such values in objects will be
-            dropped; in arrays they will be replaced with null. You can use
-            a replacer function to replace those with JSON values.
-            JSON.stringify(undefined) returns undefined.
-
-            The optional space parameter produces a stringification of the
-            value that is filled with line breaks and indentation to make it
-            easier to read.
-
-            If the space parameter is a non-empty string, then that string will
-            be used for indentation. If the space parameter is a number, then
-            the indentation will be that many spaces.
-
-            Example:
-
-            text = JSON.stringify(['e', {pluribus: 'unum'}]);
-            // text is '["e",{"pluribus":"unum"}]'
-
-
-            text = JSON.stringify(['e', {pluribus: 'unum'}], null, '\t');
-            // text is '[\n\t"e",\n\t{\n\t\t"pluribus": "unum"\n\t}\n]'
-
-            text = JSON.stringify([new Date()], function (key, value) {
-                return this[key] instanceof Date ?
-                    'Date(' + this[key] + ')' : value;
-            });
-            // text is '["Date(---current time---)"]'
-
-
-        JSON.parse(text, reviver)
-            This method parses a JSON text to produce an object or array.
-            It can throw a SyntaxError exception.
-
-            The optional reviver parameter is a function that can filter and
-            transform the results. It receives each of the keys and values,
-            and its return value is used instead of the original value.
-            If it returns what it received, then the structure is not modified.
-            If it returns undefined then the member is deleted.
-
-            Example:
-
-            // Parse the text. Values that look like ISO date strings will
-            // be converted to Date objects.
-
-            myData = JSON.parse(text, function (key, value) {
-                var a;
-                if (typeof value === 'string') {
-                    a =
-/^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}(?:\.\d*)?)Z$/.exec(value);
-                    if (a) {
-                        return new Date(Date.UTC(+a[1], +a[2] - 1, +a[3], +a[4],
-                            +a[5], +a[6]));
-                    }
-                }
-                return value;
-            });
-
-            myData = JSON.parse('["Date(09/09/2001)"]', function (key, value) {
-                var d;
-                if (typeof value === 'string' &&
-                        value.slice(0, 5) === 'Date(' &&
-                        value.slice(-1) === ')') {
-                    d = new Date(value.slice(5, -1));
-                    if (d) {
-                        return d;
-                    }
-                }
-                return value;
-            });
-
-
-    This is a reference implementation. You are free to copy, modify, or
-    redistribute.
-*/
-
-/*jslint evil: true, regexp: true */
-
-/*members "", "\b", "\t", "\n", "\f", "\r", "\"", JSON, "\\", apply,
-    call, charCodeAt, getUTCDate, getUTCFullYear, getUTCHours,
-    getUTCMinutes, getUTCMonth, getUTCSeconds, hasOwnProperty, join,
-    lastIndex, length, parse, prototype, push, replace, slice, stringify,
-    test, toJSON, toString, valueOf
-*/
-
-
-// Create a JSON object only if one does not already exist. We create the
-// methods in a closure to avoid creating global variables.
-
-if (typeof JSON !== 'object') {
-    JSON = {};
-}
-
-(function () {
-    'use strict';
-
-    function f(n) {
-        // Format integers to have at least two digits.
-        return n < 10 ? '0' + n : n;
-    }
-
-    if (typeof Date.prototype.toJSON !== 'function') {
-
-        Date.prototype.toJSON = function () {
-
-            return isFinite(this.valueOf())
-                ? this.getUTCFullYear()     + '-' +
-                    f(this.getUTCMonth() + 1) + '-' +
-                    f(this.getUTCDate())      + 'T' +
-                    f(this.getUTCHours())     + ':' +
-                    f(this.getUTCMinutes())   + ':' +
-                    f(this.getUTCSeconds())   + 'Z'
-                : null;
-        };
-
-        String.prototype.toJSON      =
-            Number.prototype.toJSON  =
-            Boolean.prototype.toJSON = function () {
-                return this.valueOf();
-            };
-    }
-
-    var cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
-        escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
-        gap,
-        indent,
-        meta = {    // table of character substitutions
-            '\b': '\\b',
-            '\t': '\\t',
-            '\n': '\\n',
-            '\f': '\\f',
-            '\r': '\\r',
-            '"' : '\\"',
-            '\\': '\\\\'
-        },
-        rep;
-
-
-    function quote(string) {
-
-// If the string contains no control characters, no quote characters, and no
-// backslash characters, then we can safely slap some quotes around it.
-// Otherwise we must also replace the offending characters with safe escape
-// sequences.
-
-        escapable.lastIndex = 0;
-        return escapable.test(string) ? '"' + string.replace(escapable, function (a) {
-            var c = meta[a];
-            return typeof c === 'string'
-                ? c
-                : '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
-        }) + '"' : '"' + string + '"';
-    }
-
-
-    function str(key, holder) {
-
-// Produce a string from holder[key].
-
-        var i,          // The loop counter.
-            k,          // The member key.
-            v,          // The member value.
-            length,
-            mind = gap,
-            partial,
-            value = holder[key];
-
-// If the value has a toJSON method, call it to obtain a replacement value.
-
-        if (value && typeof value === 'object' &&
-                typeof value.toJSON === 'function') {
-            value = value.toJSON(key);
-        }
-
-// If we were called with a replacer function, then call the replacer to
-// obtain a replacement value.
-
-        if (typeof rep === 'function') {
-            value = rep.call(holder, key, value);
-        }
-
-// What happens next depends on the value's type.
-
-        switch (typeof value) {
-        case 'string':
-            return quote(value);
-
-        case 'number':
-
-// JSON numbers must be finite. Encode non-finite numbers as null.
-
-            return isFinite(value) ? String(value) : 'null';
-
-        case 'boolean':
-        case 'null':
-
-// If the value is a boolean or null, convert it to a string. Note:
-// typeof null does not produce 'null'. The case is included here in
-// the remote chance that this gets fixed someday.
-
-            return String(value);
-
-// If the type is 'object', we might be dealing with an object or an array or
-// null.
-
-        case 'object':
-
-// Due to a specification blunder in ECMAScript, typeof null is 'object',
-// so watch out for that case.
-
-            if (!value) {
-                return 'null';
-            }
-
-// Make an array to hold the partial results of stringifying this object value.
-
-            gap += indent;
-            partial = [];
-
-// Is the value an array?
-
-            if (Object.prototype.toString.apply(value) === '[object Array]') {
-
-// The value is an array. Stringify every element. Use null as a placeholder
-// for non-JSON values.
-
-                length = value.length;
-                for (i = 0; i < length; i += 1) {
-                    partial[i] = str(i, value) || 'null';
-                }
-
-// Join all of the elements together, separated with commas, and wrap them in
-// brackets.
-
-                v = partial.length === 0
-                    ? '[]'
-                    : gap
-                    ? '[\n' + gap + partial.join(',\n' + gap) + '\n' + mind + ']'
-                    : '[' + partial.join(',') + ']';
-                gap = mind;
-                return v;
-            }
-
-// If the replacer is an array, use it to select the members to be stringified.
-
-            if (rep && typeof rep === 'object') {
-                length = rep.length;
-                for (i = 0; i < length; i += 1) {
-                    if (typeof rep[i] === 'string') {
-                        k = rep[i];
-                        v = str(k, value);
-                        if (v) {
-                            partial.push(quote(k) + (gap ? ': ' : ':') + v);
-                        }
-                    }
-                }
-            } else {
-
-// Otherwise, iterate through all of the keys in the object.
-
-                for (k in value) {
-                    if (Object.prototype.hasOwnProperty.call(value, k)) {
-                        v = str(k, value);
-                        if (v) {
-                            partial.push(quote(k) + (gap ? ': ' : ':') + v);
-                        }
-                    }
-                }
-            }
-
-// Join all of the member texts together, separated with commas,
-// and wrap them in braces.
-
-            v = partial.length === 0
-                ? '{}'
-                : gap
-                ? '{\n' + gap + partial.join(',\n' + gap) + '\n' + mind + '}'
-                : '{' + partial.join(',') + '}';
-            gap = mind;
-            return v;
-        }
-    }
-
-// If the JSON object does not yet have a stringify method, give it one.
-
-    if (typeof JSON.stringify !== 'function') {
-        JSON.stringify = function (value, replacer, space) {
-
-// The stringify method takes a value and an optional replacer, and an optional
-// space parameter, and returns a JSON text. The replacer can be a function
-// that can replace values, or an array of strings that will select the keys.
-// A default replacer method can be provided. Use of the space parameter can
-// produce text that is more easily readable.
-
-            var i;
-            gap = '';
-            indent = '';
-
-// If the space parameter is a number, make an indent string containing that
-// many spaces.
-
-            if (typeof space === 'number') {
-                for (i = 0; i < space; i += 1) {
-                    indent += ' ';
-                }
-
-// If the space parameter is a string, it will be used as the indent string.
-
-            } else if (typeof space === 'string') {
-                indent = space;
-            }
-
-// If there is a replacer, it must be a function or an array.
-// Otherwise, throw an error.
-
-            rep = replacer;
-            if (replacer && typeof replacer !== 'function' &&
-                    (typeof replacer !== 'object' ||
-                    typeof replacer.length !== 'number')) {
-                throw new Error('JSON.stringify');
-            }
-
-// Make a fake root object containing our value under the key of ''.
-// Return the result of stringifying the value.
-
-            return str('', {'': value});
-        };
-    }
-
-
-// If the JSON object does not yet have a parse method, give it one.
-
-    if (typeof JSON.parse !== 'function') {
-        JSON.parse = function (text, reviver) {
-
-// The parse method takes a text and an optional reviver function, and returns
-// a JavaScript value if the text is a valid JSON text.
-
-            var j;
-
-            function walk(holder, key) {
-
-// The walk method is used to recursively walk the resulting structure so
-// that modifications can be made.
-
-                var k, v, value = holder[key];
-                if (value && typeof value === 'object') {
-                    for (k in value) {
-                        if (Object.prototype.hasOwnProperty.call(value, k)) {
-                            v = walk(value, k);
-                            if (v !== undefined) {
-                                value[k] = v;
-                            } else {
-                                delete value[k];
-                            }
-                        }
-                    }
-                }
-                return reviver.call(holder, key, value);
-            }
-
-
-// Parsing happens in four stages. In the first stage, we replace certain
-// Unicode characters with escape sequences. JavaScript handles many characters
-// incorrectly, either silently deleting them, or treating them as line endings.
-
-            text = String(text);
-            cx.lastIndex = 0;
-            if (cx.test(text)) {
-                text = text.replace(cx, function (a) {
-                    return '\\u' +
-                        ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
-                });
-            }
-
-// In the second stage, we run the text against regular expressions that look
-// for non-JSON patterns. We are especially concerned with '()' and 'new'
-// because they can cause invocation, and '=' because it can cause mutation.
-// But just to be safe, we want to reject all unexpected forms.
-
-// We split the second stage into 4 regexp operations in order to work around
-// crippling inefficiencies in IE's and Safari's regexp engines. First we
-// replace the JSON backslash pairs with '@' (a non-JSON character). Second, we
-// replace all simple value tokens with ']' characters. Third, we delete all
-// open brackets that follow a colon or comma or that begin the text. Finally,
-// we look to see that the remaining characters are only whitespace or ']' or
-// ',' or ':' or '{' or '}'. If that is so, then the text is safe for eval.
-
-            if (/^[\],:{}\s]*$/
-                    .test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@')
-                        .replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']')
-                        .replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) {
-
-// In the third stage we use the eval function to compile the text into a
-// JavaScript structure. The '{' operator is subject to a syntactic ambiguity
-// in JavaScript: it can begin a block or an object literal. We wrap the text
-// in parens to eliminate the ambiguity.
-
-                j = eval('(' + text + ')');
-
-// In the optional fourth stage, we recursively walk the new structure, passing
-// each name/value pair to a reviver function for possible transformation.
-
-                return typeof reviver === 'function'
-                    ? walk({'': j}, '')
-                    : j;
-            }
-
-// If the text is not JSON parseable, then a SyntaxError is thrown.
-
-            throw new SyntaxError('JSON.parse');
-        };
-    }
-}());
diff --git a/wtem/static/wtem/spinner.gif b/wtem/static/wtem/spinner.gif
deleted file mode 100644 (file)
index ec0ad80..0000000
Binary files a/wtem/static/wtem/spinner.gif and /dev/null differ
diff --git a/wtem/static/wtem/wtem.js b/wtem/static/wtem/wtem.js
deleted file mode 100644 (file)
index e481b92..0000000
+++ /dev/null
@@ -1,75 +0,0 @@
-$(function() {
-
-    var to_submit;
-
-    $('form').submit(function(e) {
-        //e.preventDefault();
-        to_submit = {};
-        spinner.show();
-
-        $('.exercise-wtem').each(function() {
-            var el = $(this);
-            if(el.hasClass('exercise')) {
-                handlers.edumed(el);
-            } else {
-                var type = el.attr('data-type');
-                if(handlers[type]) {
-                    handlers[type](el);
-                }
-            }
-        });
-        $('input[name=answers]').val(JSON.stringify(to_submit));
-    });
-
-    var push_answer = function(el, answer) {
-        to_submit[el.attr('data-id')] = answer
-    };
-
-    var handlers = {
-        edumed: function(el) {
-            var exercise = el.data('exercise'),
-                to_push = {},
-                open_part;
-            if(exercise.get_answers) {
-                to_push.closed_part = exercise.get_answers()[0];
-            }
-            open_part = el.find('.open_part')
-            if(open_part.length) {
-                to_push.open_part = open_part.find('textarea').val();
-            }
-
-            push_answer(el, to_push);
-        },
-
-        open: function(el) {
-            var textareas = el.find('textarea'),
-                to_push;
-            if(textareas.length === 1) {
-                to_push = el.find('textarea').val();
-            } else {
-                to_push = [];
-                textareas.each(function() {
-                    var textarea = $(this);
-                    to_push.push({'id': textarea.attr('data-field-id'), 'text': textarea.val()});
-                });
-            }
-            push_answer(el, to_push);
-        }
-    }
-
-    var sms_handler = function() {
-        var textarea = $(this),
-            label_suffix = textarea.parent().find('.label_suffix'),
-            left = 140 - textarea.val().length;
-            to_insert = '(pozostało: ' + left + ')';
-        if(left < 0) {
-            to_insert = '<span style="color:red">' + to_insert + '</span>';
-        }
-        label_suffix.html(to_insert);
-    };
-
-    $('#wtem_sms').change(sms_handler).keyup(sms_handler);
-
-    var spinner = $('.wtem_spinner');
-    spinner.hide();
-});
\ No newline at end of file
diff --git a/wtem/templates/admin/wtem/submission/change_list.html b/wtem/templates/admin/wtem/submission/change_list.html
deleted file mode 100644 (file)
index e73e9bc..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-{% extends "admin/change_list.html" %}
-{% load i18n %}
-{% load admin_urls %}
-
-
-{% block object-tools-items %}
-    {{block.super}}
-    <li>
-        <a href="{% url 'admin:wtem_admin_report' %}">
-            Wyniki w CSV
-        </a>
-    </li>
-{% endblock %}
-
-{% block result_list %}
-    {% if examiners %}
-        <p>
-        {% for examiner in examiners %}
-            {{examiner.name}}: {{examiner.todo}} {% if not forloop.last %}, {% endif %}
-        {% endfor %}
-    </p>
-    {% endif %}
-    {{block.super}}
-{% endblock %}
\ No newline at end of file
diff --git a/wtem/templates/wtem/admin_report.csv b/wtem/templates/wtem/admin_report.csv
deleted file mode 100644 (file)
index c6ef91f..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-{% load wtem_csv %}email,nazwisko,imie,suma{% for exercise_id in exercise_ids %}{% csv_header exercise_id submissionsSet %}{% endfor %}{% for submission in submissionsSet.submissions %}
-{{submission.email}},{{submission.last_name}},{{submission.first_name}},{{submission.final_result_as_string}}{% for exercise_id in exercise_ids %},{% csv_row_fragment exercise_id submission submissionsSet %}{% endfor %}{% endfor %}
\ No newline at end of file
diff --git a/wtem/templates/wtem/disabled_contact_form.html b/wtem/templates/wtem/disabled_contact_form.html
deleted file mode 100644 (file)
index 6ce8f45..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-{% extends "base.html" %}
-
-{% block title %}{{ title }}{% endblock %}
-
-{% block body %}
-
-    <h1>{{ title }}</h1>
-
-    {% block contact_form_description %}
-    <p class="notice">Rejestracja uczestników została zamknięta.</p>
-    {% endblock %}
-
-{% endblock %}
diff --git a/wtem/templates/wtem/email_key.txt b/wtem/templates/wtem/email_key.txt
deleted file mode 100644 (file)
index 3a1da0d..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-Poniżej znajduje się wygenerowany specjalnie dla Ciebie link, pod którym będziesz mogła rozwiązać zadania w ramach egzaminu dla Warszawskich liderek Edukacji medialnej.
-
-https://edukacjamedialna.edu.pl{% url 'wtem_form' key=submission.key %}
-
-Egzamin rozpocznie się w piątek, 14 października i potrwa do 30 października. Aby rozwiązać test, potrzebny Ci będzie komputer ze stabilnym łączem internetowym oraz zainstalowaną i zaktualizowaną przeglądarką.
-Egzamin możesz rozwiązywać w kilku podejściach - pamiętaj, żeby za każdym razem zapisać swoje odpowiedzi (klikając przycisk: Wyślij moje odpowiedzi). Za każdym razem korzystaj z przypisanego Ci linku.
-
-Każda z Was otrzymała indywidualny link, pod którym może rozwiązywać zadania samodzielnie.
-
-W razie dodatkowych pytań możesz kontaktować się ze mną pod adresem barbarakrywoszejew@nowoczesnapolska.org.pl lub numerem telefonu +48 22 465 15 35.
-
-Powodzenia!
-
-Barbara Krywoszejew
-fundacja Nowoczesna Polska
\ No newline at end of file
diff --git a/wtem/templates/wtem/email_teacher_before.txt b/wtem/templates/wtem/email_teacher_before.txt
deleted file mode 100644 (file)
index bd50ba0..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-Szanowni Państwo,
-
-Informujemy, że na podane przez Państwa adresy e-mail uczestników i uczestniczek Wielkiego Turnieju Edukacji Medialnej zostały wysłane indywidualne linki, które pozwolą im przystąpić do I etapu Turnieju.
-
-Uprzejmie prosimy o sprawdzenie, czy wszyscy otrzymali wiadomość z linkiem. Jeśli któryś z uczestników nie otrzymał swojej instrukcji, prosimy o informację na adres edukacjamedialna@nowoczesnapolska.org.pl najpóźniej do poniedziałku 17 listopada do godz. 12.00. Zgłoszenie problemu powinno zawierać:
-* imię, nazwisko, adres e-mail uczestnika, który nie otrzymał wiadomości z linkiem,
-* imię, nazwisko, adres e-mail Opiekuna/Opiekunki (zgodnie z danymi z formularza zgłoszeniowego).
-
-Pierwszy etap Turnieju odbędzie się we wtorek 18 listopada o godz. 16.30. Na rozwiązanie testu uczestnicy będą mieć ok. 90 min. Aby rozwiązać test, potrzebny jest komputer ze stabilnym łączem internetowym oraz zainstalowaną i zaktualizowaną przeglądarką.
-
-Przypominamy, że główną nagrodą w Turnieju jest tygodniowy pobyt na Digital Media Summer Camp na Mercer University w Macon (Georgia, USA).
-
-W razie dodatkowych pytań prosimy kontaktować się z nami pod adresem edukacjamedialna@nowoczesnapolska.org.pl lub pod numerem telefonu +48 22 621-30-17.
-
-Z pozdrowieniami
-
-Zespół Edukacji Medialnej
-fundacja Nowoczesna Polska
\ No newline at end of file
diff --git a/wtem/templates/wtem/email_teacher_before_subject.txt b/wtem/templates/wtem/email_teacher_before_subject.txt
deleted file mode 100644 (file)
index 5649e56..0000000
+++ /dev/null
@@ -1 +0,0 @@
-Pierwszy etap Wielkiego Turnieju Edukacji Medialnej już wkrótce
\ No newline at end of file
diff --git a/wtem/templates/wtem/exercises/edumed_prawdafalsz.html b/wtem/templates/wtem/exercises/edumed_prawdafalsz.html
deleted file mode 100644 (file)
index 67bf0ae..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-<div class="exercise exercise-wtem prawdafalsz" data-type="prawdafalsz" data-id="{{exercise.id}}">
-
-    {% include "wtem/exercises/exercise_no.html" %}
-
-    <div class="question" data-no="1">
-        <div class="description">
-        {% for para in exercise.description %}
-            <p class="paragraph">
-                {{para}}
-            </p>
-        {% endfor %}
-        </div>
-
-        <ul class="lista punkt ">
-            {% for statement in exercise.statements %}
-                <li class="question-piece">
-                    <span class="buttons">
-                        <a href="#" data-value="true" class="true">Prawda</a>
-                        <a href="#" data-value="false" class="false">Fałsz</a>  
-                    </span>
-                    {{statement.0}}
-                </li>
-            {% endfor %}
-        </ul>
-    </div>
-</div>
\ No newline at end of file
diff --git a/wtem/templates/wtem/exercises/edumed_przyporzadkuj.html b/wtem/templates/wtem/exercises/edumed_przyporzadkuj.html
deleted file mode 100644 (file)
index bdb17af..0000000
+++ /dev/null
@@ -1,85 +0,0 @@
-<div class="exercise exercise-wtem przyporzadkuj" data-type="przyporzadkuj" data-id="{{exercise.id}}">
-
-    {% include "wtem/exercises/exercise_no.html" %}
-    
-    <div class="question" data-no="1">
-
-        <div class="description">
-        {% for para in exercise.description %}
-            <p class="paragraph">
-                {{para}}
-            </p>
-
-        {% endfor %}
-        </div>
-
-        <p class="paragraph">{{exercise.buckets_name|default:"kategorie"|capfirst}}:</p>
-
-        <ul class="lista punkt predicate" data-name="kategorie">
-            {% for bucket in exercise.buckets %}
-                <li data-predicate="{{bucket.id}}">
-                    {{bucket.title}}
-                    <ul class="subjects">
-                        <li class="placeholder multiple ui-droppable accepting"></li>
-                    </ul>
-                </li>
-            {% endfor %}
-        </ul>
-        <br class="clr">
-
-        <div class="description" style="margin-bottom:10px;">
-            <p class="paragraph">{{exercise.items_name|capfirst}}:</p>
-            {% if not exercise.hide_default_instruction %}
-                <span class="instruction">Przeciągnij i upuść numery odpowiedzi w wybranym polu powyżej.</span>
-            {% endif %}
-            {% if exercise.items_instruction %}
-                <span class="instruction">{{exercise.items_instruction}}</span>
-            {% endif %}
-        </div>
-         
-        <ul class="lista punkt subject {% if exercise.items_inline %}wtem-items-inline{% endif %}" data-target="kategorie">
-            {% for item in exercise.items %}
-                {% comment %}
-                data-solution set to single bogus value only to indicate that this piece has no multiple solutions, not used otherwise (see: is_multiple in edumed.coffee). 
-                {% endcomment %}
-                
-                {% if item.img or item.desc %}
-                    <li style="magin-bottom:5px;">
-                        <span data-solution="1" data-no="{{forloop.counter}}" data-id="{{item.id}}" class="question-piece draggable ui-draggable">{{item.text}}</span>
-                        
-                        {% if item.img %}
-                            {% if item.href %}
-                                <a href="{% if not item.href_absolute %}/static/wtem/img/{% endif %}{{item.href}}" target="wtem_aside">
-                            {% endif %}
-                            
-                            <img src="/static/wtem/img/{{item.img}}"/>
-                            
-                            {% if item.href %}</a>{% endif %}
-                        {% endif %}
-                        {% if item.desc %}
-                            {{item.desc}}
-                        {% endif %}
-                    </li>
-                {% else %}
-                    <li data-solution="1" data-no="{{forloop.counter}}" data-id="{{item.id}}" class="question-piece draggable ui-draggable">{{item.text}}</li>
-                {% endif %}
-            
-            {% endfor %}
-        </ul>
-
-        <br class="clr">
-
-        {% if exercise.description_after %}
-            {% autoescape off %}
-            {% for para in exercise.description_after %}
-                <p class="paragraph">
-                    {{para}}
-                </p>
-            {% endfor %}
-            {% endautoescape %}
-        {% endif %}
-
-    </div>
-
-</div>
-
diff --git a/wtem/templates/wtem/exercises/edumed_uporzadkuj.html b/wtem/templates/wtem/exercises/edumed_uporzadkuj.html
deleted file mode 100644 (file)
index 200271e..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-<div class="exercise exercise-wtem uporzadkuj" data-type="uporzadkuj" data-id="{{exercise.id}}">
-
-    {% include "wtem/exercises/exercise_no.html" %}
-
-    <div class="question" data-no="1">
-        <div class="description">
-        {% for para in exercise.description %}
-            <p class="paragraph">
-                {{para}}
-            </p>
-        {% endfor %}
-            <span class="instruction">Kliknij i przytrzymaj wybraną odpowiedź, następnie przeciągnij w nowe miejsce.</span>
-        </div>
-
-        <ol class="lista num ui-sortable">
-            {% for item in exercise.items %}
-                <li class="question-piece" data-pos="{{item.id}}">{{item.text}}</li>
-            {% endfor %}
-        </ol>
-
-    </div>
-</div>
-
diff --git a/wtem/templates/wtem/exercises/edumed_wybor.html b/wtem/templates/wtem/exercises/edumed_wybor.html
deleted file mode 100644 (file)
index edd9dad..0000000
+++ /dev/null
@@ -1,46 +0,0 @@
-<div class="exercise exercise-wtem wybor" data-type="wybor" data-id="{{exercise.id}}">
-
-    {% include "wtem/exercises/exercise_no.html" %}
-    {% autoescape off %}
-    <div class="description">
-        {% for para in exercise.description %}
-            <p class="paragraph">
-                {{para}}
-            </p>
-        {% endfor %}
-        {% if exercise.points %}
-            <span class="instruction">
-                {% if exercise.answer|length == 1 %}
-                    Tylko jedna odpowiedź jest prawidłowa.
-                {% else %}
-                    Zaznacz wszystkie prawidłowe odpowiedzi.
-                {% endif %}
-            </span>
-        {% endif %}
-    </div>
-    {% endautoescape %}
-    <div class="question" data-no="1">
-        <ol class="lista num">
-            {% for option in exercise.options %}
-                <li class="question-piece" data-name="{{option.id}}">
-                    <input type="{% if exercise.answer|length == 1 %}radio{% else %}checkbox{% endif %}" name="{% if exercise.answer|length == 1 %}e{{no}}{% else %}e{{no}}_{{option.id}}{% endif %}" id="e{{no}}_{{option.id}}"{% if option.id|stringformat:"s" in exercise.saved_answer.closed_part %} checked="checked"{% endif %}>
-                    <label for="e{{no}}_{{option.id}}">{{option.text}}</label>
-                </li>
-            {% endfor %}
-        </ol>
-    </div>
-
-    {% if exercise.open_part %}
-    <div class="open_part">
-        <div class="description">
-            {% for para in exercise.open_part %}
-                <p class="paragraph">
-                    {{para}}
-                </p>
-            {% endfor %}
-        </div>
-        <textarea style="width: 100%; margin-top:10px;" rows="{{exercise.open_part_rows|default:10}}">{{ exercise.saved_answer.open_part }}</textarea>
-    </div>
-    {% endif %}
-
-</div>
diff --git a/wtem/templates/wtem/exercises/exercise_no.html b/wtem/templates/wtem/exercises/exercise_no.html
deleted file mode 100644 (file)
index ce394cf..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-{% if not exercise.continuation %}
-    <h3>Zadanie {{exercise.id_show|default:exercise.id}} ({{ exercise.max_points }} pkt)</h3>
-{% endif %}
\ No newline at end of file
diff --git a/wtem/templates/wtem/exercises/file_upload.html b/wtem/templates/wtem/exercises/file_upload.html
deleted file mode 100644 (file)
index b452070..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-<div class="exercise-wtem" data-type="file" data-id="{{exercise.id}}">
-
-    {% include "wtem/exercises/exercise_no.html" %}
-
-    <div class="description">
-        {% for para in exercise.description %}
-            <p class="paragraph">
-                {{para}}
-            </p>
-        {% endfor %}
-    </div>
-
-    {% if exercise.max_file_size_string %}
-        <p style="font-weight: bold;">Plik nie powinien być większy niż {{exercise.max_file_size_string}}.</p>
-    {% endif %}
-    <div style="margin: 15px auto; width:300px;">
-        <input style="float: left;" type="file" name="attachment_for_{{exercise.id}}"/>
-        <div style="clear:both;"></div>
-    </div>
-    
-
-    {% autoescape off %}
-    {% for para in exercise.description_after %}
-        <p>{{para}}</p>
-    {% endfor %}
-    {% endautoescape %}
-
-</div>
diff --git a/wtem/templates/wtem/exercises/open.html b/wtem/templates/wtem/exercises/open.html
deleted file mode 100644 (file)
index c30a5b0..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-<div class="exercise-wtem" data-type="open" data-id="{{exercise.id}}">
-
-    {% include "wtem/exercises/exercise_no.html" %}
-
-    <div class="description">
-        {% autoescape off %}
-        {% for para in exercise.description %}
-            <p class="paragraph">
-                {{para}}
-            </p>
-        {% endfor %}
-        {% endautoescape %}
-    </div>
-
-    {% if exercise.instruction %}
-        <span class="instruction">{{ exercise.instruction }}</span>
-    {% endif %}
-
-    {% if exercise.fields %}
-        {% for field in exercise.fields %}
-            <div class="wtem-open-field">
-                <label class="wtem-caption">{{field.caption|safe}} <span class="label_suffix"></span></label>
-                {% if field.type == 'file' %}
-                    <div style="margin: 15px auto; width:300px;">
-                        <input style="float: left;" type="file" name="attachment_for_{{exercise.id}}__{{field.id}}"/>
-                        <div style="clear:both;"></div>
-                    </div>
-                {% else %}
-                    <textarea style="width: 100%;" rows="{{field.rows|default:10}}" data-field-id="{{field.id}}"
-                              {% if field.max_length %}maxlength="{{field.max_length}}"{% endif %}
-                              {% if field.input_id %}id="{{field.input_id}}"{% endif %}>{{ field.saved_answer }}</textarea>
-                {% endif %}
-            </div>
-        {% endfor %}
-    {% else %}
-        <textarea style="width: 100%; margin-top:10px;" rows="{{field.rows|default:10}}"
-                  {% if field.max_length %}maxlength="{{field.max_length}}"{% endif %}
-                  {% if field.input_id %}id="#{{field.input_id}}"{% endif %}>{{ exercise.answer }}</textarea>
-    {% endif %}
-
-    {% if exercise.description_after %}
-        <div class="description">
-            {% autoescape off %}
-            {% for para in exercise.description_after %}
-                <p class="paragraph">
-                    {{para}}
-                </p>
-            {% endfor %}
-            {% endautoescape %}
-        </div>
-    {% endif%}
-
-</div>
diff --git a/wtem/templates/wtem/key_not_found.html b/wtem/templates/wtem/key_not_found.html
deleted file mode 100644 (file)
index c8b54ed..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-{% extends 'base_super.html' %}
-
-{% block body %}
-<h1>{% include "wtem/title.html" %}</h1>
-<h2>Niepoprawny link</h2>
-
-<p>Podany adres jest niepoprawny. Żeby móc rozwiązywać zadania, musisz przejść pod dokładnie ten sam adres, co podany w wysłanej do Ciebie wiadomości e-mail.</p>
-
-{% endblock %}
diff --git a/wtem/templates/wtem/key_not_found_before.html b/wtem/templates/wtem/key_not_found_before.html
deleted file mode 100644 (file)
index 0a64226..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-{% extends 'base_super.html' %}
-
-{% block body %}
-<h1>{% include "wtem/title.html" %}</h1>
-<h2>Niepoprawny link</h2>
-
-<p>Podany adres jest niepoprawny. Żeby móc rozwiązywać zadania, musisz przejść pod dokładnie ten sam adres, co podany w wysłanej do Ciebie wiadomości e-mail. Jeśli masz z tym kłopot, skontaktuj się z nami pod adresem <a href="mailto:barbarakrywoszejew@nowoczesnapolska.org.pl">barbarakrywoszejew@nowoczesnapolska.org.pl</a>.</p>
-
-{% endblock %}
\ No newline at end of file
diff --git a/wtem/templates/wtem/main.html b/wtem/templates/wtem/main.html
deleted file mode 100644 (file)
index a9ec10b..0000000
+++ /dev/null
@@ -1,82 +0,0 @@
-{% extends 'base_super.html' %}
-{% load compressed %}
-{% load static %}
-{% load cache %}
-
-{% block extra_script %}
-    {% compressed_js 'wtem' %}
-{% endblock %}
-
-
-
-{% block body %}
-<style>
-    .wtem-open-field {
-        margin: 10px 0;
-    }
-    .wtem-open-field textarea {
-        margin-top:0;
-    }
-    .wtem-fixed-info {
-        top: 20px;
-        left: 20px;
-        border: 1px solid black;
-        background: #16a487;
-        border-radius: 0.938em;
-        padding: 5px 2px;
-        color: white;
-        text-align: center;
-        font-weight: bold;
-    }
-    .wtem-items-inline li {
-        display: inline-block;
-    }
-    .instruction {
-        font-weight: bold;
-    }
-    .wtem-disclaimer {
-        font-style: italic;
-        font-size: .9em;
-    }
-
-</style>
-
-<h1>{% include "wtem/title.html" %}</h1>
-<div class="wtem-fixed-info">Rozwiązania można wysyłać do 30 października do godziny {{end_time|default:"24:00"}}. <strong>Nie czekaj na ostatnią chwilę!</strong></div>
-
-<p>Witamy na egzaminie dla Warszawskich Liderek Edukacji Medialnej. Na rozwiązanie zadań masz czas do 30 października do godz. {{end_time|default:"24:00"}}. Możesz go rozwiązać na raz lub w kilku (kilkunastu - ile będziesz chciała) podejściach. Za każdym razem pamiętaj o kliknięciu przycisku: Wyślij moje odpowiedzi (na dole strony). Aby ponownie edytować swoje odpowiedzi musisz skorzytać z otrzymanego linku. Za każdym razem zobaczysz swoje odpowiedzi (ostatnią zapisaną wersję).
-
-Test składa się z 9 pytań. Wszystkie mają charakter otwarty.</p>
-
-<p>Powodzenia!<br/>
-Zespół Edukacji Medialnej, fundacja Nowoczesna Polska</p>
-
-<form method="post" enctype="multipart/form-data">
-
-{% cache 30 wtem %}
-{% for exercise in exercises %}
-    {% with 'wtem/exercises/'|add:exercise.type|add:'.html' as template_name %}
-    {% include  template_name with exercise=exercise no=exercise.id %}
-    {% endwith %}
-{% endfor %}
-{% endcache %}
-
-
-<hr/>
-<input type="hidden" name="answers" value=""/>
-
-<p style="text-align:center; margin-top:20px;">Sprawdź jeszcze raz wszystkie swoje odpowiedzi, a następnie wyślij je do nas, klikając w poniższy przycisk:<br/><br/>
-<input type="submit" value="Wyślij moje odpowiedzi" style="display: block; margin: auto;"/>
-<br/>
-<span class="wtem_spinner">
-    <span>Wysyłanie rozwiązań w toku...</span>
-    <img src="{% static 'wtem/spinner.gif' %}"/>
-    <span>Spróbuj jeszcze raz, jeśli wysyłanie trwa dłużej niż kilka minut.</span>
-</span>
-</p>
-
-<div class="wtem-fixed-info" style="margin-top:15px;">Rozwiązania można wysyłać do 30 października do godziny {{end_time|default:"24:00"}}. <strong>Nie czekaj na ostatnią chwilę! Do 30 października do godziny 24:00 możesz edytować swoje odpowiedzi - wejdź ponownie w otrzymany od nas link, uzupełnij/zmień swoje opowiedzi i wyślij je do nas!</strong></div>
-
-</form>
-
-{% endblock %}
\ No newline at end of file
diff --git a/wtem/templates/wtem/main_after.html b/wtem/templates/wtem/main_after.html
deleted file mode 100644 (file)
index 1af8151..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-{% extends 'base_super.html' %}
-
-{% block body %}
-
-<h1>{% include "wtem/title.html" %}</h1>
-
-<p>Egzamin dla Warszawskich Liderek Edukacji Medialnej został zakończony.</p>
-
-{% endblock %}
diff --git a/wtem/templates/wtem/main_before.html b/wtem/templates/wtem/main_before.html
deleted file mode 100644 (file)
index 83bb979..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-{% extends 'base_super.html' %}
-
-{% block body %}
-
-<h1>{% include "wtem/title.html" %}</h1>
-
-<p>Egzamin dla Warszawskich Liderek Edukacji Medialnej, 14 październka. Na wypełenie egzaminu masz czas do 30 października do godziny 24:00.</p>
-
-{% endblock %}
\ No newline at end of file
diff --git a/wtem/templates/wtem/results_student_disqualified.txt b/wtem/templates/wtem/results_student_disqualified.txt
deleted file mode 100644 (file)
index 984e34f..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-{% load l10n %}Witaj,
-
-Informujemy, że wszystkie testy rozwiązane w ramach II etapu III edycji Wielkiego Turnieju Edukacji Medialnej zostały ocenione. 
-
-Niestety, ze względu na wykrycie niesamodzielnego rozwiązywania przez Ciebie testu, Twoja praca została zdysfkwalifikowana.
-
-Przypominamy, że zgodnie z § 6. pkt. 2. istnieje możliwość odwołania od decyzji Kapituły WTEM. Regulamin dostępny jest na stronie Turnieju: http://edukacjamedialna.edu.pl/info/turniej/.
-
-W razie jakichkolwiek pytań prosimy o kontakt.
-
-Pozdrawiamy,
-Zespół Edukacji Medialnej
-fundacja Nowoczesna Polska
diff --git a/wtem/templates/wtem/results_student_failed.txt b/wtem/templates/wtem/results_student_failed.txt
deleted file mode 100644 (file)
index d13b19c..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-{% load l10n %}Witaj,
-
-Informujemy, że wszystkie testy rozwiązane w ramach II etapu III edycji Wielkiego Turnieju Edukacji Medialnej zostały ocenione. 
-
-Liczba punktów zdobytych przez Ciebie w teście to {% localize on %}{{final_result}}{% endlocalize %}.
-
-Niestety, ten wynik nie uprawnia Cię do wzięcia udziału w III etapie Turnieju. Liczba punktów, która uprawnia do wzięcia udziału w finale to 52. Zachęcamy do zgłębiania wiedzy za zakresu edukacji medialnej i wzięcia udziału w kolejnej edycji Wielkiego Turnieju Edukacji Medialnej.
-
-W razie jakichkolwiek pytań prosimy o kontakt.
-
-Pozdrawiamy,
-Zespół Edukacji Medialnej
-fundacja Nowoczesna Polska
diff --git a/wtem/templates/wtem/results_student_passed.txt b/wtem/templates/wtem/results_student_passed.txt
deleted file mode 100644 (file)
index ffaa1ed..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-{% load l10n %}Witaj,
-
-Informujemy, że wszystkie testy rozwiązane w ramach II etapu III edycji Wielkiego Turnieju Edukacji Medialnej zostały ocenione. 
-
-Liczba punktów zdobytych przez Ciebie w teście to {% localize on %}{{final_result}}{% endlocalize %}.
-
-Wynik ten uprawnia Cię do wzięcia udziału III etapie Turnieju. Gratulujemy! Zawody finałowe odbędą się w drugiej połowie kwietnia. Niebawem prześlemy Ci szczegółowe informacje na ten temat.
-
-W razie jakichkolwiek pytań prosimy o kontakt.
-
-Pozdrawiamy,
-Zespół Edukacji Medialnej
-fundacja Nowoczesna Polska
diff --git a/wtem/templates/wtem/results_teacher.txt b/wtem/templates/wtem/results_teacher.txt
deleted file mode 100644 (file)
index cba6e84..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-Dzień dobry,
-
-Informujemy, że wszystkie testy rozwiązane w ramach II etapu III edycji Wielkiego Turnieju Edukacji Medialnej zostały ocenione. 
-
-Poniżej znajdują się wyniki uzyskane przez zgłoszonych przez Panią/Pana uczniów i uczennice, którzy rozwiązali test. Liczba punktów, która uprawnia do wzięcia udziału w zawodach finałowych to 52. Gratulujemy tym, którym się to udało. Zawody finałowe odbędą się w drugiej połowie kwietnia. Niebawem prześlemy szczegółowe informacje na ten temat.
-
-Wyniki uzyskane przez Pani/Pana podopiecznych:
-
-{% for submission in submissions %}{{submission.first_name.strip}} {{submission.last_name.strip}}: {{submission.final_result}}
-{% endfor %}
-
-Informacje o wynikach zostały przesłane również uczestnikom i uczestniczkom. Prosimy upewnić się, że wszyscy otrzymali wiadomość. Jeśli jednak do nich nie dotarła, prosimy o podanie danych kontaktowych tych osób (imię i nazwisko, adres e-mail).
-
-W razie jakichkolwiek pytań prosimy o kontakt.
-
-Pozdrawiamy,
-Zespół Edukacji Medialnej
-fundacja Nowoczesna Polska
diff --git a/wtem/templates/wtem/thanks.html b/wtem/templates/wtem/thanks.html
deleted file mode 100644 (file)
index 65c9a14..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-{% extends 'base_super.html' %}
-
-{% block body %}
-
-<h1>Twoje rozwiązania zostały wysłane</h1>
-
-<p>Dziękujemy za udział w egzaminie dla Warszawskich Liderek Edukacji Medialnej.
-Twoja praca została wysłana i poprawnie przyjęta przez system.</p>
-
-<p>Jeśli chcesz zmienić którąś z odpowiedzi, do 30 października do godz. {{end_time|default:"24:00"}} możesz ponownie wysłać rozwiązanie zadań, korzystając z przypisanego Ci linku. W ocenie weźmiemy pod uwagę tylko ostatnie zgłoszenie. Pamiętaj, w zależności od zachowania Twojej przeglądarki, po powrocie do strony z zadaniami część zadań możesz być zmuszona rozwiązać ponownie.</p>
-
-<p>Zespół Edukacji Medialnej
-fundacja Nowoczesna Polska</p>
-
-{% endblock %}
\ No newline at end of file
diff --git a/wtem/templates/wtem/title.html b/wtem/templates/wtem/title.html
deleted file mode 100644 (file)
index 32860e3..0000000
+++ /dev/null
@@ -1 +0,0 @@
-Egzamin dla Warszawskich Liderek Edukacji Medialnej
\ No newline at end of file
diff --git a/wtem/templatetags/__init__.py b/wtem/templatetags/__init__.py
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/wtem/templatetags/wtem_csv.py b/wtem/templatetags/wtem_csv.py
deleted file mode 100644 (file)
index 028836c..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-# -*- coding: utf-8 -*-
-from django import template
-
-register = template.Library()
-
-
-@register.simple_tag
-def csv_header(exercise_id, submissionSet):
-    examiners = submissionSet.examiners_by_exercise.get(exercise_id, [])
-    examiners_string = ','.join(['zad %s - %s' % (exercise_id, user.username) for user in examiners])
-    toret = ',zad %s' % exercise_id
-    if examiners_string:
-        toret += ',' + examiners_string
-    return toret
-
-
-@register.simple_tag
-def csv_row_fragment(exercise_id, submission, submissionSet):
-    final_mark = submission.get_final_exercise_mark(exercise_id)
-    if final_mark is not None:
-        final_mark = ('%.2f' % final_mark).rstrip('0').rstrip('.')
-    toret = final_mark if final_mark else '-'
-    examiners = submissionSet.examiners_by_exercise.get(exercise_id, [])
-    marks_by_examiner = submission.get_exercise_marks_by_examiner(exercise_id)
-    for examiner in examiners:
-        mark = marks_by_examiner.get(str(examiner.id), None)
-        toret += ','
-        if mark is None:
-            toret += '"-"'
-        else:
-            toret += str(mark)
-    return toret
diff --git a/wtem/urls.py b/wtem/urls.py
deleted file mode 100644 (file)
index 3e96c2e..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-# -*- coding: utf-8 -*-
-from django.conf.urls import patterns, url
-from .views import form, form_during
-
-urlpatterns = patterns(
-    '',
-    url(r'^_test/(?P<key>.*)/$', form_during),
-    url(r'^(?P<key>.*)/$', form, name='wtem_form')
-)
diff --git a/wtem/views.py b/wtem/views.py
deleted file mode 100644 (file)
index 0696174..0000000
+++ /dev/null
@@ -1,70 +0,0 @@
-# -*- coding: utf-8 -*-
-import json
-from copy import deepcopy
-
-from django.conf import settings
-from django.http import HttpResponseForbidden
-from django.shortcuts import render
-from django.views.decorators.cache import never_cache
-from django.views.decorators.csrf import csrf_exempt
-
-from .forms import WTEMForm
-from .models import Submission, DEBUG_KEY, exercises
-
-WTEM_CONTEST_STAGE = getattr(settings, 'WTEM_CONTEST_STAGE', 'before')
-
-
-@csrf_exempt
-def form(request, key):
-    return globals()['form_' + WTEM_CONTEST_STAGE](request, key)
-
-
-def form_before(request, key):
-    try:
-        Submission.objects.get(key=key)
-    except Submission.DoesNotExist:
-        return render(request, 'wtem/key_not_found_before.html')
-    else:
-        return render(request, 'wtem/main_before.html')
-
-
-def form_after(request, key):
-    return render(request, 'wtem/main_after.html')
-
-
-@never_cache
-@csrf_exempt
-def form_during(request, key):
-
-    if WTEM_CONTEST_STAGE != 'during':
-        if request.META['REMOTE_ADDR'] not in getattr(settings, 'WTEM_CONTEST_IP_ALLOW', []):
-            return HttpResponseForbidden('Not allowed')
-
-    try:
-        submission = Submission.objects.get(key=key)
-    except Submission.DoesNotExist:
-        if settings.DEBUG and key == DEBUG_KEY:
-            submission = Submission.create(
-                first_name='Debug', last_name='Debug', email='debug@debug.com', key=DEBUG_KEY)
-        else:
-            return render(request, 'wtem/key_not_found.html')
-    exercises_with_answers = deepcopy(exercises)
-    if submission.answers:
-        answers = json.loads(submission.answers)
-    else:
-        answers = {}
-    for exercise in exercises_with_answers:
-        exercise['saved_answer'] = answers.get(str(exercise['id']), '')
-        if exercise['type'] == 'open' and exercise.get('fields'):
-            field_answers = {field['id']: field['text'] for field in exercise['saved_answer']}
-            for field in exercise['fields']:
-                field['saved_answer'] = field_answers.get(field['id'], '')
-    if request.method == 'GET':
-        return render(request, 'wtem/main.html', {'exercises': exercises_with_answers, 'end_time': submission.end_time})
-    elif request.method == 'POST':
-        form = WTEMForm(request.POST, request.FILES, instance=submission)
-        if form.is_valid():
-            form.save()
-            return render(request, 'wtem/thanks.html', dict(end_time=submission.end_time))
-        else:
-            raise Exception