From 5244508c405d31ded3fa8278621c49c0e889c1d4 Mon Sep 17 00:00:00 2001 From: tangtanglove Date: Wed, 18 Jan 2023 13:40:07 +0800 Subject: [PATCH] first commit --- .editorconfig | 22 + .gitignore | 30 + LICENSE.md | 1 + Makefile | 1 + README.md | 31 + cmd/quark/.keep | 0 examples/fiberadmin/.air.toml | 9 + examples/fiberadmin/main.go | 35 + examples/ginadmin/.air.toml | 9 + examples/hertzadmin/.air.toml | 9 + examples/hertzadmin/.gitignore | 37 + examples/hertzadmin/.hz | 3 + examples/hertzadmin/biz/handler/providers.go | 10 + .../hertzadmin/biz/handler/resources/demo.go | 37 + examples/hertzadmin/biz/router/register.go | 12 + examples/hertzadmin/main.go | 22 + examples/hertzadmin/router.go | 44 + examples/hertzadmin/router_gen.go | 16 + go.mod | 93 + go.sum | 279 ++ internal/aliyunsms/aliyunsms.go | 106 + internal/sioosms/sioosms.go | 74 + pkg/adapter/fiberadapter/fiberadapter.go | 94 + pkg/adapter/hertzadapter/hertzadapter.go | 160 + .../handler/admin/actions/change_account.go | 45 + .../handler/admin/actions/change_status.go | 72 + .../admin/actions/change_web_config.go | 51 + .../handler/admin/actions/create_drawer.go | 88 + pkg/app/handler/admin/actions/create_link.go | 37 + pkg/app/handler/admin/actions/create_modal.go | 88 + pkg/app/handler/admin/actions/delete.go | 64 + pkg/app/handler/admin/actions/detail_link.go | 37 + pkg/app/handler/admin/actions/disable.go | 59 + pkg/app/handler/admin/actions/edit_drawer.go | 87 + pkg/app/handler/admin/actions/edit_link.go | 37 + pkg/app/handler/admin/actions/edit_modal.go | 87 + pkg/app/handler/admin/actions/enable.go | 59 + pkg/app/handler/admin/actions/form_back.go | 29 + .../handler/admin/actions/form_extra_back.go | 29 + pkg/app/handler/admin/actions/form_reset.go | 29 + pkg/app/handler/admin/actions/form_submit.go | 32 + pkg/app/handler/admin/actions/import.go | 90 + pkg/app/handler/admin/actions/more_actions.go | 44 + .../handler/admin/actions/select_options.go | 35 + .../handler/admin/actions/sync_permission.go | 78 + pkg/app/handler/admin/dashboards/index.go | 35 + pkg/app/handler/admin/login/index.go | 108 + pkg/app/handler/admin/metrics/system_info.go | 42 + pkg/app/handler/admin/metrics/team_info.go | 33 + pkg/app/handler/admin/metrics/total_admin.go | 29 + pkg/app/handler/admin/metrics/total_file.go | 31 + pkg/app/handler/admin/metrics/total_log.go | 29 + .../handler/admin/metrics/total_picture.go | 29 + pkg/app/handler/admin/providers.go | 23 + pkg/app/handler/admin/resources/account.go | 148 + pkg/app/handler/admin/resources/action_log.go | 84 + pkg/app/handler/admin/resources/admin.go | 312 ++ pkg/app/handler/admin/resources/config.go | 139 + pkg/app/handler/admin/resources/file.go | 72 + pkg/app/handler/admin/resources/menu.go | 207 + pkg/app/handler/admin/resources/permission.go | 90 + pkg/app/handler/admin/resources/picture.go | 80 + pkg/app/handler/admin/resources/role.go | 222 + pkg/app/handler/admin/resources/web_config.go | 171 + .../handler/admin/searches/datetime_range.go | 31 + pkg/app/handler/admin/searches/input.go | 25 + pkg/app/handler/admin/searches/status.go | 41 + pkg/app/handler/mix/.keep | 0 pkg/app/install/install.go | 66 + pkg/app/middleware/middleware.go | 71 + pkg/app/model/action_log.go | 28 + pkg/app/model/admin.go | 134 + pkg/app/model/config.go | 66 + pkg/app/model/file.go | 143 + pkg/app/model/file_category.go | 11 + pkg/app/model/menu.go | 198 + pkg/app/model/permission.go | 63 + pkg/app/model/picture.go | 118 + pkg/app/model/picture_category.go | 11 + pkg/app/model/role.go | 73 + pkg/app/model/time.go | 52 + pkg/builder/actions/action.go | 633 +++ pkg/builder/actions/drawer.go | 37 + pkg/builder/actions/dropdown.go | 209 + pkg/builder/actions/link.go | 35 + pkg/builder/actions/modal.go | 37 + pkg/builder/adminfield.go | 894 ++++ pkg/builder/builder.go | 232 + pkg/builder/metrics/admin_descriptions.go | 14 + pkg/builder/metrics/admin_metrics.go | 6 + pkg/builder/metrics/admin_value.go | 24 + pkg/builder/request.go | 229 + pkg/builder/resource.go | 169 + pkg/builder/searches/date.go | 12 + pkg/builder/searches/date_range.go | 13 + pkg/builder/searches/datetime.go | 12 + pkg/builder/searches/datetime_range.go | 13 + pkg/builder/searches/search.go | 101 + pkg/builder/searches/select.go | 12 + .../template/admindashboard/admindashboard.go | 110 + pkg/builder/template/adminlogin/adminlogin.go | 174 + .../template/adminresource/handlers_action.go | 67 + .../template/adminresource/handlers_detail.go | 65 + .../template/adminresource/handlers_edit.go | 65 + .../adminresource/handlers_editable.go | 38 + .../template/adminresource/handlers_export.go | 269 ++ .../template/adminresource/handlers_import.go | 356 ++ .../adminresource/handlers_import_template.go | 240 + .../template/adminresource/handlers_index.go | 152 + .../template/adminresource/handlers_store.go | 114 + .../template/adminresource/handlers_update.go | 144 + .../adminresource/performs_queries.go | 204 + .../adminresource/performs_validation.go | 598 +++ .../adminresource/resolves_actions.go | 343 ++ .../template/adminresource/resolves_fields.go | 565 +++ .../adminresource/resolves_filters.go | 8 + .../adminresource/resolves_searches.go | 74 + .../template/adminresource/resource.go | 189 + .../template/adminresource/resource_create.go | 50 + .../template/adminresource/resource_detail.go | 71 + .../template/adminresource/resource_edit.go | 58 + .../template/adminresource/resource_form.go | 130 + .../template/adminresource/resource_index.go | 94 + pkg/builder/template/template.go | 125 + pkg/component/admin/action/action.go | 205 + pkg/component/admin/action/drawer.go | 177 + pkg/component/admin/action/modal.go | 148 + pkg/component/admin/card/card.go | 153 + pkg/component/admin/chart/chart.go | 21 + pkg/component/admin/chart/line.go | 114 + pkg/component/admin/component/element.go | 37 + .../admin/descriptions/descriptions.go | 118 + pkg/component/admin/descriptions/field.go | 33 + .../admin/descriptions/fields/text.go | 80 + pkg/component/admin/divider/divider.go | 89 + pkg/component/admin/dropdown/dropdown.go | 160 + pkg/component/admin/dropdown/item.go | 198 + pkg/component/admin/footer/footer.go | 44 + pkg/component/admin/form/fields/cascader.go | 43 + pkg/component/admin/form/fields/checkbox.go | 53 + pkg/component/admin/form/fields/date.go | 62 + pkg/component/admin/form/fields/date_range.go | 63 + pkg/component/admin/form/fields/datetime.go | 15 + .../admin/form/fields/datetime_range.go | 16 + pkg/component/admin/form/fields/display.go | 15 + pkg/component/admin/form/fields/editor.go | 33 + pkg/component/admin/form/fields/file.go | 55 + pkg/component/admin/form/fields/geofence.go | 90 + pkg/component/admin/form/fields/group.go | 33 + pkg/component/admin/form/fields/hidden.go | 15 + pkg/component/admin/form/fields/icon.go | 99 + pkg/component/admin/form/fields/id.go | 45 + pkg/component/admin/form/fields/image.go | 97 + pkg/component/admin/form/fields/item.go | 688 +++ pkg/component/admin/form/fields/list.go | 46 + pkg/component/admin/form/fields/map.go | 79 + pkg/component/admin/form/fields/month.go | 15 + pkg/component/admin/form/fields/number.go | 52 + pkg/component/admin/form/fields/password.go | 82 + pkg/component/admin/form/fields/quarter.go | 15 + pkg/component/admin/form/fields/radio.go | 45 + pkg/component/admin/form/fields/search.go | 69 + pkg/component/admin/form/fields/select.go | 70 + pkg/component/admin/form/fields/selects.go | 23 + pkg/component/admin/form/fields/switch.go | 61 + pkg/component/admin/form/fields/text.go | 80 + pkg/component/admin/form/fields/textarea.go | 52 + pkg/component/admin/form/fields/time.go | 24 + pkg/component/admin/form/fields/time_range.go | 25 + pkg/component/admin/form/fields/tree.go | 22 + pkg/component/admin/form/fields/week.go | 15 + pkg/component/admin/form/fields/year.go | 15 + pkg/component/admin/form/form.go | 370 ++ pkg/component/admin/grid/col.go | 138 + pkg/component/admin/grid/row.go | 79 + pkg/component/admin/layout/layout.go | 173 + pkg/component/admin/lists/lists.go | 191 + pkg/component/admin/lists/meta.go | 126 + pkg/component/admin/login/login.go | 94 + pkg/component/admin/menu/divider.go | 23 + pkg/component/admin/menu/item.go | 216 + pkg/component/admin/menu/item_group.go | 33 + pkg/component/admin/menu/menu.go | 131 + pkg/component/admin/menu/sub_menu.go | 65 + pkg/component/admin/page/page.go | 44 + .../admin/pagecontainer/pagecontainer.go | 121 + .../admin/pagecontainer/pageheader.go | 100 + pkg/component/admin/space/space.go | 103 + pkg/component/admin/statistic/statistic.go | 90 + pkg/component/admin/table/column.go | 313 ++ pkg/component/admin/table/search.go | 263 ++ pkg/component/admin/table/search_item.go | 292 ++ pkg/component/admin/table/table.go | 312 ++ pkg/component/admin/table/tool_bar.go | 147 + pkg/component/admin/tabs/tab_pane.go | 38 + pkg/component/admin/tabs/tabs.go | 98 + pkg/component/admin/tpl/tpl.go | 30 + pkg/component/admin/view/view.go | 30 + pkg/component/mix/.keep | 0 pkg/dal/db/init.go | 16 + pkg/dal/init.go | 17 + pkg/dal/redis/init.go | 19 + pkg/github/github.go | 142 + pkg/hash/hash.go | 30 + pkg/lister/lister.go | 60 + pkg/msg/msg.go | 28 + pkg/rand/rand.go | 59 + scripts/README.md | 11 + scripts/start_service.sh | 44 + scripts/stop_service.sh | 21 + website/admin/apps/app.html | 9 + website/admin/config.json | 9 + website/admin/default.png | Bin 0 -> 6230 bytes website/admin/favicon.ico | Bin 0 -> 4286 bytes website/admin/index.html | 204 + .../admin/tinymce/icons/default/icons.min.js | 1 + website/admin/tinymce/langs/readme.md | 3 + website/admin/tinymce/langs/zh_CN.js | 1 + website/admin/tinymce/license.txt | 504 +++ .../tinymce/plugins/advlist/plugin.min.js | 1 + .../tinymce/plugins/anchor/plugin.min.js | 1 + .../tinymce/plugins/autolink/plugin.min.js | 1 + .../tinymce/plugins/autoresize/plugin.min.js | 1 + .../tinymce/plugins/autosave/plugin.min.js | 1 + .../tinymce/plugins/bbcode/plugin.min.js | 1 + .../tinymce/plugins/charmap/plugin.min.js | 1 + .../admin/tinymce/plugins/code/plugin.min.js | 1 + .../tinymce/plugins/codesample/plugin.min.js | 1 + .../tinymce/plugins/colorpicker/plugin.min.js | 1 + .../tinymce/plugins/contextmenu/plugin.min.js | 1 + .../plugins/directionality/plugin.min.js | 1 + .../plugins/emoticons/js/emojiimages.js | 1 + .../plugins/emoticons/js/emojiimages.min.js | 1 + .../tinymce/plugins/emoticons/js/emojis.js | 1 + .../plugins/emoticons/js/emojis.min.js | 1 + .../tinymce/plugins/emoticons/plugin.min.js | 1 + .../plugins/formatpainter/plugin.min.js | 1 + .../tinymce/plugins/fullpage/plugin.min.js | 1 + .../tinymce/plugins/fullscreen/plugin.min.js | 1 + .../admin/tinymce/plugins/help/plugin.min.js | 1 + .../admin/tinymce/plugins/hr/plugin.min.js | 1 + .../admin/tinymce/plugins/image/plugin.min.js | 1 + .../tinymce/plugins/imagetools/plugin.min.js | 1 + .../tinymce/plugins/importcss/plugin.min.js | 1 + .../admin/tinymce/plugins/indent2em/plugin.js | 1 + .../tinymce/plugins/indent2em/plugin.min.js | 1 + .../plugins/insertdatetime/plugin.min.js | 1 + .../plugins/legacyoutput/plugin.min.js | 1 + .../admin/tinymce/plugins/link/plugin.min.js | 1 + .../admin/tinymce/plugins/lists/plugin.min.js | 1 + .../admin/tinymce/plugins/media/plugin.min.js | 1 + .../plugins/multipleimage/plugin.min.js | 1 + .../tinymce/plugins/nonbreaking/plugin.min.js | 1 + .../tinymce/plugins/noneditable/plugin.min.js | 1 + .../tinymce/plugins/pagebreak/plugin.min.js | 1 + .../admin/tinymce/plugins/paste/plugin.min.js | 1 + .../tinymce/plugins/preview/plugin.min.js | 1 + .../admin/tinymce/plugins/print/plugin.min.js | 1 + .../tinymce/plugins/quickbars/plugin.min.js | 1 + .../admin/tinymce/plugins/save/plugin.min.js | 1 + .../plugins/searchreplace/plugin.min.js | 1 + .../plugins/spellchecker/plugin.min.js | 1 + .../tinymce/plugins/tabfocus/plugin.min.js | 1 + .../admin/tinymce/plugins/table/plugin.min.js | 1 + .../tinymce/plugins/template/plugin.min.js | 1 + .../tinymce/plugins/textcolor/plugin.min.js | 1 + .../tinymce/plugins/textpattern/plugin.min.js | 1 + .../admin/tinymce/plugins/toc/plugin.min.js | 1 + .../plugins/visualblocks/plugin.min.js | 1 + .../tinymce/plugins/visualchars/plugin.min.js | 1 + .../tinymce/plugins/wordcount/plugin.min.js | 1 + .../skins/content/dark/content.min.css | 1 + .../skins/content/default/content.min.css | 1 + .../skins/content/document/content.min.css | 1 + .../skins/content/writer/content.min.css | 1 + .../ui/oxide-dark/content.inline.min.css | 1 + .../skins/ui/oxide-dark/content.min.css | 1 + .../ui/oxide-dark/content.mobile.min.css | 1 + .../ui/oxide-dark/fonts/tinymce-mobile.woff | Bin 0 -> 4624 bytes .../tinymce/skins/ui/oxide-dark/skin.min.css | 1 + .../skins/ui/oxide-dark/skin.mobile.min.css | 1 + .../ui/oxide-dark/skin.shadowdom.min.css | 1 + .../skins/ui/oxide/content.inline.min.css | 1 + .../tinymce/skins/ui/oxide/content.min.css | 1 + .../skins/ui/oxide/content.mobile.min.css | 1 + .../skins/ui/oxide/fonts/tinymce-mobile.woff | Bin 0 -> 4624 bytes .../admin/tinymce/skins/ui/oxide/skin.min.css | 1 + .../skins/ui/oxide/skin.mobile.min.css | 1 + .../skins/ui/oxide/skin.shadowdom.min.css | 1 + .../admin/tinymce/themes/mobile/theme.min.js | 1 + .../admin/tinymce/themes/silver/theme.min.js | 1 + website/admin/tinymce/tinymce.d.ts | 3938 +++++++++++++++++ website/admin/tinymce/tinymce.min.js | 1 + website/admin/umi.css | 12 + website/admin/umi.js | 1 + website/favicon.ico | 0 website/robots.txt | 2 + 297 files changed, 24922 insertions(+) create mode 100644 .editorconfig create mode 100644 .gitignore create mode 100644 LICENSE.md create mode 100644 Makefile create mode 100644 README.md create mode 100644 cmd/quark/.keep create mode 100644 examples/fiberadmin/.air.toml create mode 100644 examples/fiberadmin/main.go create mode 100644 examples/ginadmin/.air.toml create mode 100644 examples/hertzadmin/.air.toml create mode 100644 examples/hertzadmin/.gitignore create mode 100644 examples/hertzadmin/.hz create mode 100644 examples/hertzadmin/biz/handler/providers.go create mode 100644 examples/hertzadmin/biz/handler/resources/demo.go create mode 100644 examples/hertzadmin/biz/router/register.go create mode 100644 examples/hertzadmin/main.go create mode 100644 examples/hertzadmin/router.go create mode 100644 examples/hertzadmin/router_gen.go create mode 100644 go.mod create mode 100644 go.sum create mode 100644 internal/aliyunsms/aliyunsms.go create mode 100644 internal/sioosms/sioosms.go create mode 100644 pkg/adapter/fiberadapter/fiberadapter.go create mode 100644 pkg/adapter/hertzadapter/hertzadapter.go create mode 100644 pkg/app/handler/admin/actions/change_account.go create mode 100644 pkg/app/handler/admin/actions/change_status.go create mode 100644 pkg/app/handler/admin/actions/change_web_config.go create mode 100644 pkg/app/handler/admin/actions/create_drawer.go create mode 100644 pkg/app/handler/admin/actions/create_link.go create mode 100644 pkg/app/handler/admin/actions/create_modal.go create mode 100644 pkg/app/handler/admin/actions/delete.go create mode 100644 pkg/app/handler/admin/actions/detail_link.go create mode 100644 pkg/app/handler/admin/actions/disable.go create mode 100644 pkg/app/handler/admin/actions/edit_drawer.go create mode 100644 pkg/app/handler/admin/actions/edit_link.go create mode 100644 pkg/app/handler/admin/actions/edit_modal.go create mode 100644 pkg/app/handler/admin/actions/enable.go create mode 100644 pkg/app/handler/admin/actions/form_back.go create mode 100644 pkg/app/handler/admin/actions/form_extra_back.go create mode 100644 pkg/app/handler/admin/actions/form_reset.go create mode 100644 pkg/app/handler/admin/actions/form_submit.go create mode 100644 pkg/app/handler/admin/actions/import.go create mode 100644 pkg/app/handler/admin/actions/more_actions.go create mode 100644 pkg/app/handler/admin/actions/select_options.go create mode 100644 pkg/app/handler/admin/actions/sync_permission.go create mode 100644 pkg/app/handler/admin/dashboards/index.go create mode 100644 pkg/app/handler/admin/login/index.go create mode 100644 pkg/app/handler/admin/metrics/system_info.go create mode 100644 pkg/app/handler/admin/metrics/team_info.go create mode 100644 pkg/app/handler/admin/metrics/total_admin.go create mode 100644 pkg/app/handler/admin/metrics/total_file.go create mode 100644 pkg/app/handler/admin/metrics/total_log.go create mode 100644 pkg/app/handler/admin/metrics/total_picture.go create mode 100644 pkg/app/handler/admin/providers.go create mode 100644 pkg/app/handler/admin/resources/account.go create mode 100644 pkg/app/handler/admin/resources/action_log.go create mode 100644 pkg/app/handler/admin/resources/admin.go create mode 100644 pkg/app/handler/admin/resources/config.go create mode 100644 pkg/app/handler/admin/resources/file.go create mode 100644 pkg/app/handler/admin/resources/menu.go create mode 100644 pkg/app/handler/admin/resources/permission.go create mode 100644 pkg/app/handler/admin/resources/picture.go create mode 100644 pkg/app/handler/admin/resources/role.go create mode 100644 pkg/app/handler/admin/resources/web_config.go create mode 100644 pkg/app/handler/admin/searches/datetime_range.go create mode 100644 pkg/app/handler/admin/searches/input.go create mode 100644 pkg/app/handler/admin/searches/status.go create mode 100644 pkg/app/handler/mix/.keep create mode 100644 pkg/app/install/install.go create mode 100644 pkg/app/middleware/middleware.go create mode 100644 pkg/app/model/action_log.go create mode 100644 pkg/app/model/admin.go create mode 100644 pkg/app/model/config.go create mode 100644 pkg/app/model/file.go create mode 100644 pkg/app/model/file_category.go create mode 100644 pkg/app/model/menu.go create mode 100644 pkg/app/model/permission.go create mode 100644 pkg/app/model/picture.go create mode 100644 pkg/app/model/picture_category.go create mode 100644 pkg/app/model/role.go create mode 100644 pkg/app/model/time.go create mode 100644 pkg/builder/actions/action.go create mode 100644 pkg/builder/actions/drawer.go create mode 100644 pkg/builder/actions/dropdown.go create mode 100644 pkg/builder/actions/link.go create mode 100644 pkg/builder/actions/modal.go create mode 100644 pkg/builder/adminfield.go create mode 100644 pkg/builder/builder.go create mode 100644 pkg/builder/metrics/admin_descriptions.go create mode 100644 pkg/builder/metrics/admin_metrics.go create mode 100644 pkg/builder/metrics/admin_value.go create mode 100644 pkg/builder/request.go create mode 100644 pkg/builder/resource.go create mode 100644 pkg/builder/searches/date.go create mode 100644 pkg/builder/searches/date_range.go create mode 100644 pkg/builder/searches/datetime.go create mode 100644 pkg/builder/searches/datetime_range.go create mode 100644 pkg/builder/searches/search.go create mode 100644 pkg/builder/searches/select.go create mode 100644 pkg/builder/template/admindashboard/admindashboard.go create mode 100644 pkg/builder/template/adminlogin/adminlogin.go create mode 100644 pkg/builder/template/adminresource/handlers_action.go create mode 100644 pkg/builder/template/adminresource/handlers_detail.go create mode 100644 pkg/builder/template/adminresource/handlers_edit.go create mode 100644 pkg/builder/template/adminresource/handlers_editable.go create mode 100644 pkg/builder/template/adminresource/handlers_export.go create mode 100644 pkg/builder/template/adminresource/handlers_import.go create mode 100644 pkg/builder/template/adminresource/handlers_import_template.go create mode 100644 pkg/builder/template/adminresource/handlers_index.go create mode 100644 pkg/builder/template/adminresource/handlers_store.go create mode 100644 pkg/builder/template/adminresource/handlers_update.go create mode 100644 pkg/builder/template/adminresource/performs_queries.go create mode 100644 pkg/builder/template/adminresource/performs_validation.go create mode 100644 pkg/builder/template/adminresource/resolves_actions.go create mode 100644 pkg/builder/template/adminresource/resolves_fields.go create mode 100644 pkg/builder/template/adminresource/resolves_filters.go create mode 100644 pkg/builder/template/adminresource/resolves_searches.go create mode 100644 pkg/builder/template/adminresource/resource.go create mode 100644 pkg/builder/template/adminresource/resource_create.go create mode 100644 pkg/builder/template/adminresource/resource_detail.go create mode 100644 pkg/builder/template/adminresource/resource_edit.go create mode 100644 pkg/builder/template/adminresource/resource_form.go create mode 100644 pkg/builder/template/adminresource/resource_index.go create mode 100644 pkg/builder/template/template.go create mode 100644 pkg/component/admin/action/action.go create mode 100644 pkg/component/admin/action/drawer.go create mode 100644 pkg/component/admin/action/modal.go create mode 100644 pkg/component/admin/card/card.go create mode 100644 pkg/component/admin/chart/chart.go create mode 100644 pkg/component/admin/chart/line.go create mode 100644 pkg/component/admin/component/element.go create mode 100644 pkg/component/admin/descriptions/descriptions.go create mode 100644 pkg/component/admin/descriptions/field.go create mode 100644 pkg/component/admin/descriptions/fields/text.go create mode 100644 pkg/component/admin/divider/divider.go create mode 100644 pkg/component/admin/dropdown/dropdown.go create mode 100644 pkg/component/admin/dropdown/item.go create mode 100644 pkg/component/admin/footer/footer.go create mode 100644 pkg/component/admin/form/fields/cascader.go create mode 100644 pkg/component/admin/form/fields/checkbox.go create mode 100644 pkg/component/admin/form/fields/date.go create mode 100644 pkg/component/admin/form/fields/date_range.go create mode 100644 pkg/component/admin/form/fields/datetime.go create mode 100644 pkg/component/admin/form/fields/datetime_range.go create mode 100644 pkg/component/admin/form/fields/display.go create mode 100644 pkg/component/admin/form/fields/editor.go create mode 100644 pkg/component/admin/form/fields/file.go create mode 100644 pkg/component/admin/form/fields/geofence.go create mode 100644 pkg/component/admin/form/fields/group.go create mode 100644 pkg/component/admin/form/fields/hidden.go create mode 100644 pkg/component/admin/form/fields/icon.go create mode 100644 pkg/component/admin/form/fields/id.go create mode 100644 pkg/component/admin/form/fields/image.go create mode 100644 pkg/component/admin/form/fields/item.go create mode 100644 pkg/component/admin/form/fields/list.go create mode 100644 pkg/component/admin/form/fields/map.go create mode 100644 pkg/component/admin/form/fields/month.go create mode 100644 pkg/component/admin/form/fields/number.go create mode 100644 pkg/component/admin/form/fields/password.go create mode 100644 pkg/component/admin/form/fields/quarter.go create mode 100644 pkg/component/admin/form/fields/radio.go create mode 100644 pkg/component/admin/form/fields/search.go create mode 100644 pkg/component/admin/form/fields/select.go create mode 100644 pkg/component/admin/form/fields/selects.go create mode 100644 pkg/component/admin/form/fields/switch.go create mode 100644 pkg/component/admin/form/fields/text.go create mode 100644 pkg/component/admin/form/fields/textarea.go create mode 100644 pkg/component/admin/form/fields/time.go create mode 100644 pkg/component/admin/form/fields/time_range.go create mode 100644 pkg/component/admin/form/fields/tree.go create mode 100644 pkg/component/admin/form/fields/week.go create mode 100644 pkg/component/admin/form/fields/year.go create mode 100644 pkg/component/admin/form/form.go create mode 100644 pkg/component/admin/grid/col.go create mode 100644 pkg/component/admin/grid/row.go create mode 100644 pkg/component/admin/layout/layout.go create mode 100644 pkg/component/admin/lists/lists.go create mode 100644 pkg/component/admin/lists/meta.go create mode 100644 pkg/component/admin/login/login.go create mode 100644 pkg/component/admin/menu/divider.go create mode 100644 pkg/component/admin/menu/item.go create mode 100644 pkg/component/admin/menu/item_group.go create mode 100644 pkg/component/admin/menu/menu.go create mode 100644 pkg/component/admin/menu/sub_menu.go create mode 100644 pkg/component/admin/page/page.go create mode 100644 pkg/component/admin/pagecontainer/pagecontainer.go create mode 100644 pkg/component/admin/pagecontainer/pageheader.go create mode 100644 pkg/component/admin/space/space.go create mode 100644 pkg/component/admin/statistic/statistic.go create mode 100644 pkg/component/admin/table/column.go create mode 100644 pkg/component/admin/table/search.go create mode 100644 pkg/component/admin/table/search_item.go create mode 100644 pkg/component/admin/table/table.go create mode 100644 pkg/component/admin/table/tool_bar.go create mode 100644 pkg/component/admin/tabs/tab_pane.go create mode 100644 pkg/component/admin/tabs/tabs.go create mode 100644 pkg/component/admin/tpl/tpl.go create mode 100644 pkg/component/admin/view/view.go create mode 100644 pkg/component/mix/.keep create mode 100644 pkg/dal/db/init.go create mode 100644 pkg/dal/init.go create mode 100644 pkg/dal/redis/init.go create mode 100644 pkg/github/github.go create mode 100644 pkg/hash/hash.go create mode 100644 pkg/lister/lister.go create mode 100644 pkg/msg/msg.go create mode 100644 pkg/rand/rand.go create mode 100644 scripts/README.md create mode 100644 scripts/start_service.sh create mode 100644 scripts/stop_service.sh create mode 100644 website/admin/apps/app.html create mode 100644 website/admin/config.json create mode 100644 website/admin/default.png create mode 100644 website/admin/favicon.ico create mode 100644 website/admin/index.html create mode 100644 website/admin/tinymce/icons/default/icons.min.js create mode 100644 website/admin/tinymce/langs/readme.md create mode 100644 website/admin/tinymce/langs/zh_CN.js create mode 100644 website/admin/tinymce/license.txt create mode 100644 website/admin/tinymce/plugins/advlist/plugin.min.js create mode 100644 website/admin/tinymce/plugins/anchor/plugin.min.js create mode 100644 website/admin/tinymce/plugins/autolink/plugin.min.js create mode 100644 website/admin/tinymce/plugins/autoresize/plugin.min.js create mode 100644 website/admin/tinymce/plugins/autosave/plugin.min.js create mode 100644 website/admin/tinymce/plugins/bbcode/plugin.min.js create mode 100644 website/admin/tinymce/plugins/charmap/plugin.min.js create mode 100644 website/admin/tinymce/plugins/code/plugin.min.js create mode 100644 website/admin/tinymce/plugins/codesample/plugin.min.js create mode 100644 website/admin/tinymce/plugins/colorpicker/plugin.min.js create mode 100644 website/admin/tinymce/plugins/contextmenu/plugin.min.js create mode 100644 website/admin/tinymce/plugins/directionality/plugin.min.js create mode 100644 website/admin/tinymce/plugins/emoticons/js/emojiimages.js create mode 100644 website/admin/tinymce/plugins/emoticons/js/emojiimages.min.js create mode 100644 website/admin/tinymce/plugins/emoticons/js/emojis.js create mode 100644 website/admin/tinymce/plugins/emoticons/js/emojis.min.js create mode 100644 website/admin/tinymce/plugins/emoticons/plugin.min.js create mode 100644 website/admin/tinymce/plugins/formatpainter/plugin.min.js create mode 100644 website/admin/tinymce/plugins/fullpage/plugin.min.js create mode 100644 website/admin/tinymce/plugins/fullscreen/plugin.min.js create mode 100644 website/admin/tinymce/plugins/help/plugin.min.js create mode 100644 website/admin/tinymce/plugins/hr/plugin.min.js create mode 100644 website/admin/tinymce/plugins/image/plugin.min.js create mode 100644 website/admin/tinymce/plugins/imagetools/plugin.min.js create mode 100644 website/admin/tinymce/plugins/importcss/plugin.min.js create mode 100644 website/admin/tinymce/plugins/indent2em/plugin.js create mode 100644 website/admin/tinymce/plugins/indent2em/plugin.min.js create mode 100644 website/admin/tinymce/plugins/insertdatetime/plugin.min.js create mode 100644 website/admin/tinymce/plugins/legacyoutput/plugin.min.js create mode 100644 website/admin/tinymce/plugins/link/plugin.min.js create mode 100644 website/admin/tinymce/plugins/lists/plugin.min.js create mode 100644 website/admin/tinymce/plugins/media/plugin.min.js create mode 100644 website/admin/tinymce/plugins/multipleimage/plugin.min.js create mode 100644 website/admin/tinymce/plugins/nonbreaking/plugin.min.js create mode 100644 website/admin/tinymce/plugins/noneditable/plugin.min.js create mode 100644 website/admin/tinymce/plugins/pagebreak/plugin.min.js create mode 100644 website/admin/tinymce/plugins/paste/plugin.min.js create mode 100644 website/admin/tinymce/plugins/preview/plugin.min.js create mode 100644 website/admin/tinymce/plugins/print/plugin.min.js create mode 100644 website/admin/tinymce/plugins/quickbars/plugin.min.js create mode 100644 website/admin/tinymce/plugins/save/plugin.min.js create mode 100644 website/admin/tinymce/plugins/searchreplace/plugin.min.js create mode 100644 website/admin/tinymce/plugins/spellchecker/plugin.min.js create mode 100644 website/admin/tinymce/plugins/tabfocus/plugin.min.js create mode 100644 website/admin/tinymce/plugins/table/plugin.min.js create mode 100644 website/admin/tinymce/plugins/template/plugin.min.js create mode 100644 website/admin/tinymce/plugins/textcolor/plugin.min.js create mode 100644 website/admin/tinymce/plugins/textpattern/plugin.min.js create mode 100644 website/admin/tinymce/plugins/toc/plugin.min.js create mode 100644 website/admin/tinymce/plugins/visualblocks/plugin.min.js create mode 100644 website/admin/tinymce/plugins/visualchars/plugin.min.js create mode 100644 website/admin/tinymce/plugins/wordcount/plugin.min.js create mode 100644 website/admin/tinymce/skins/content/dark/content.min.css create mode 100644 website/admin/tinymce/skins/content/default/content.min.css create mode 100644 website/admin/tinymce/skins/content/document/content.min.css create mode 100644 website/admin/tinymce/skins/content/writer/content.min.css create mode 100644 website/admin/tinymce/skins/ui/oxide-dark/content.inline.min.css create mode 100644 website/admin/tinymce/skins/ui/oxide-dark/content.min.css create mode 100644 website/admin/tinymce/skins/ui/oxide-dark/content.mobile.min.css create mode 100644 website/admin/tinymce/skins/ui/oxide-dark/fonts/tinymce-mobile.woff create mode 100644 website/admin/tinymce/skins/ui/oxide-dark/skin.min.css create mode 100644 website/admin/tinymce/skins/ui/oxide-dark/skin.mobile.min.css create mode 100644 website/admin/tinymce/skins/ui/oxide-dark/skin.shadowdom.min.css create mode 100644 website/admin/tinymce/skins/ui/oxide/content.inline.min.css create mode 100644 website/admin/tinymce/skins/ui/oxide/content.min.css create mode 100644 website/admin/tinymce/skins/ui/oxide/content.mobile.min.css create mode 100644 website/admin/tinymce/skins/ui/oxide/fonts/tinymce-mobile.woff create mode 100644 website/admin/tinymce/skins/ui/oxide/skin.min.css create mode 100644 website/admin/tinymce/skins/ui/oxide/skin.mobile.min.css create mode 100644 website/admin/tinymce/skins/ui/oxide/skin.shadowdom.min.css create mode 100644 website/admin/tinymce/themes/mobile/theme.min.js create mode 100644 website/admin/tinymce/themes/silver/theme.min.js create mode 100644 website/admin/tinymce/tinymce.d.ts create mode 100644 website/admin/tinymce/tinymce.min.js create mode 100644 website/admin/umi.css create mode 100644 website/admin/umi.js create mode 100644 website/favicon.ico create mode 100644 website/robots.txt diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..e90e11a --- /dev/null +++ b/.editorconfig @@ -0,0 +1,22 @@ +root = true + +[*] +charset = utf-8 +end_of_line = lf +insert_final_newline = true +trim_trailing_whitespace = true + +[{*.go,Makefile,.gitmodules,go.mod,go.sum}] +indent_style = tab + +[*.md] +indent_style = tab +trim_trailing_whitespace = false + +[*.{yml,yaml,json}] +indent_style = space +indent_size = 2 + +[*.{js,jsx,ts,tsx,css,less,sass,scss,vue,py}] +indent_style = space +indent_size = 4 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..0dc288a --- /dev/null +++ b/.gitignore @@ -0,0 +1,30 @@ +# Mac OS X files +.DS_Store + +# Binaries for programs and plugins +*.exe +*.exe~ +*.dll +*.so +*.dylib + +# Test binary, build with `go test -c` +*.test + +# Output of the go coverage tool, specifically when used with LiteIDE +*.out + +# Project-local glide cache, RE: https://github.com/Masterminds/glide/issues/736 +.glide/ + +# Dependency directories (remove the comment below to include it) +vendor/ + +# Air tool tmp file +tmp/ + +# Install lock file +install.lock + +# examples web site static files +examples/*/website/ \ No newline at end of file diff --git a/LICENSE.md b/LICENSE.md new file mode 100644 index 0000000..cced8d8 --- /dev/null +++ b/LICENSE.md @@ -0,0 +1 @@ +Hacker license! diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..76a4e8e --- /dev/null +++ b/Makefile @@ -0,0 +1 @@ +# note: call scripts from /scripts \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..e64cc7e --- /dev/null +++ b/README.md @@ -0,0 +1,31 @@ +## 介绍 +QuarkGO 是一个基于golang的低代码工具;它提供的丰富组件,能帮助您使用很少的代码就能搭建出功能完善的应用系统。 + +## 系统特性 + +**内置功能** +* 管理员管理 +* 用户管理 +* 权限系统 +* 菜单管理 +* 系统配置 +* 操作日志 +* 附件管理 + +**内置组件** +* Layout组件 +* Container组件 +* Card组件 +* Table组件 +* Form组件 +* Show组件 +* TabForm组件 +* ... + +## 技术支持 +为了避免打扰作者日常工作,你可以在Github上提交 [Issues](https://github.com/quarkcms/quark-go/issues) + +相关教程,你可以查看 [在线文档](http://www.quarkcms.com/quark-go/) + +## License +QuarkGo is licensed under The MIT License (MIT). \ No newline at end of file diff --git a/cmd/quark/.keep b/cmd/quark/.keep new file mode 100644 index 0000000..e69de29 diff --git a/examples/fiberadmin/.air.toml b/examples/fiberadmin/.air.toml new file mode 100644 index 0000000..a3d347c --- /dev/null +++ b/examples/fiberadmin/.air.toml @@ -0,0 +1,9 @@ +# Config file for [Air](https://github.com/cosmtrek/air) in TOML format + +# Working directory +# . or absolute path, please note that the directories following must be under root. +root = "." +tmp_dir = "tmp" + +[build] +exclude_dir = ["assets", "tmp", "vendor", "website"] \ No newline at end of file diff --git a/examples/fiberadmin/main.go b/examples/fiberadmin/main.go new file mode 100644 index 0000000..87de32c --- /dev/null +++ b/examples/fiberadmin/main.go @@ -0,0 +1,35 @@ +package main + +import ( + "github.com/gofiber/fiber/v2" + "github.com/quarkcms/quark-go/pkg/adapter/fiberadapter" + "github.com/quarkcms/quark-go/pkg/app/handler/admin" + "github.com/quarkcms/quark-go/pkg/builder" + "gorm.io/driver/mysql" + "gorm.io/gorm" +) + +func main() { + app := fiber.New() + + // 数据库配置信息 + dsn := "root:Bc5HQFJc4bLjZCcC@tcp(127.0.0.1:3306)/quarkgo?charset=utf8&parseTime=True&loc=Local" + + // 配置资源 + config := &builder.Config{ + AppKey: "123456", + Providers: admin.Providers, + DBConfig: &builder.DBConfig{ + Dialector: mysql.Open(dsn), + Opts: &gorm.Config{}, + }, + } + + // 创建对象 + b := builder.New(config) + + // 适配fiber + fiberadapter.Adapter(b, app) + + app.Listen(":3000") +} diff --git a/examples/ginadmin/.air.toml b/examples/ginadmin/.air.toml new file mode 100644 index 0000000..a3d347c --- /dev/null +++ b/examples/ginadmin/.air.toml @@ -0,0 +1,9 @@ +# Config file for [Air](https://github.com/cosmtrek/air) in TOML format + +# Working directory +# . or absolute path, please note that the directories following must be under root. +root = "." +tmp_dir = "tmp" + +[build] +exclude_dir = ["assets", "tmp", "vendor", "website"] \ No newline at end of file diff --git a/examples/hertzadmin/.air.toml b/examples/hertzadmin/.air.toml new file mode 100644 index 0000000..a3d347c --- /dev/null +++ b/examples/hertzadmin/.air.toml @@ -0,0 +1,9 @@ +# Config file for [Air](https://github.com/cosmtrek/air) in TOML format + +# Working directory +# . or absolute path, please note that the directories following must be under root. +root = "." +tmp_dir = "tmp" + +[build] +exclude_dir = ["assets", "tmp", "vendor", "website"] \ No newline at end of file diff --git a/examples/hertzadmin/.gitignore b/examples/hertzadmin/.gitignore new file mode 100644 index 0000000..101ea87 --- /dev/null +++ b/examples/hertzadmin/.gitignore @@ -0,0 +1,37 @@ +*.o +*.a +*.so +_obj +_test +*.[568vq] +[568vq].out +*.cgo1.go +*.cgo2.c +_cgo_defun.c +_cgo_gotypes.go +_cgo_export.* +_testmain.go +*.exe +*.exe~ +*.test +*.prof +*.rar +*.zip +*.gz +*.psd +*.bmd +*.cfg +*.pptx +*.log +*nohup.out +*settings.pyc +*.sublime-project +*.sublime-workspace +!.gitkeep +.DS_Store +/.idea +/.vscode +/output +*.local.yml +dumped_hertz_remote_config.json + \ No newline at end of file diff --git a/examples/hertzadmin/.hz b/examples/hertzadmin/.hz new file mode 100644 index 0000000..e2a7ec0 --- /dev/null +++ b/examples/hertzadmin/.hz @@ -0,0 +1,3 @@ +// Code generated by hz. DO NOT EDIT. + +hz version: v0.4.0 \ No newline at end of file diff --git a/examples/hertzadmin/biz/handler/providers.go b/examples/hertzadmin/biz/handler/providers.go new file mode 100644 index 0000000..46b58da --- /dev/null +++ b/examples/hertzadmin/biz/handler/providers.go @@ -0,0 +1,10 @@ +package handler + +import ( + "github.com/quarkcms/quark-go/examples/hertzadmin/biz/handler/resources" +) + +// 注册服务 +var Providers = []interface{}{ + &resources.Demo{}, +} diff --git a/examples/hertzadmin/biz/handler/resources/demo.go b/examples/hertzadmin/biz/handler/resources/demo.go new file mode 100644 index 0000000..c672b6d --- /dev/null +++ b/examples/hertzadmin/biz/handler/resources/demo.go @@ -0,0 +1,37 @@ +package resources + +import ( + "github.com/quarkcms/quark-go/pkg/builder" + "github.com/quarkcms/quark-go/pkg/builder/template/adminresource" +) + +type Demo struct { + adminresource.Template +} + +// 初始化 +func (p *Demo) Init() interface{} { + + // 初始化模板 + p.TemplateInit() + + return p +} + +// 字段 +func (p *Demo) Fields(request *builder.Request) []interface{} { + + return []interface{}{} +} + +// 搜索 +func (p *Demo) Searches(request *builder.Request) []interface{} { + + return []interface{}{} +} + +// 行为 +func (p *Demo) Actions(request *builder.Request) []interface{} { + + return []interface{}{} +} diff --git a/examples/hertzadmin/biz/router/register.go b/examples/hertzadmin/biz/router/register.go new file mode 100644 index 0000000..70316d6 --- /dev/null +++ b/examples/hertzadmin/biz/router/register.go @@ -0,0 +1,12 @@ +// Code generated by hertz generator. DO NOT EDIT. + +package router + +import ( + "github.com/cloudwego/hertz/pkg/app/server" +) + +// GeneratedRegister registers routers generated by IDL. +func GeneratedRegister(r *server.Hertz) { + //INSERT_POINT: DO NOT DELETE THIS LINE! +} diff --git a/examples/hertzadmin/main.go b/examples/hertzadmin/main.go new file mode 100644 index 0000000..12b376f --- /dev/null +++ b/examples/hertzadmin/main.go @@ -0,0 +1,22 @@ +// Code generated by hertz generator. + +package main + +import ( + "github.com/cloudwego/hertz/pkg/app" + "github.com/cloudwego/hertz/pkg/app/server" +) + +func main() { + h := server.Default(server.WithHostPorts(":3000")) + + // 静态文件目录 + fs := &app.FS{Root: "/website", IndexNames: []string{"index.html"}} + h.StaticFS("/", fs) + + // 注册路由 + register(h) + + // 启动服务 + h.Spin() +} diff --git a/examples/hertzadmin/router.go b/examples/hertzadmin/router.go new file mode 100644 index 0000000..0d2bc93 --- /dev/null +++ b/examples/hertzadmin/router.go @@ -0,0 +1,44 @@ +// Code generated by hertz generator. + +package main + +import ( + "github.com/cloudwego/hertz/pkg/app/server" + "github.com/quarkcms/quark-go/examples/hertzadmin/biz/handler" + "github.com/quarkcms/quark-go/pkg/adapter/hertzadapter" + "github.com/quarkcms/quark-go/pkg/app/handler/admin" + "github.com/quarkcms/quark-go/pkg/app/install" + "github.com/quarkcms/quark-go/pkg/app/middleware" + "github.com/quarkcms/quark-go/pkg/builder" + "gorm.io/driver/mysql" + "gorm.io/gorm" +) + +// customizeRegister registers customize routers. +func customizedRegister(r *server.Hertz) { + + // 数据库配置信息 + dsn := "root:Bc5HQFJc4bLjZCcC@tcp(127.0.0.1:3306)/quarkgo?charset=utf8&parseTime=True&loc=Local" + + // 配置资源 + config := &builder.Config{ + AppKey: "123456", + Providers: append(admin.Providers, handler.Providers...), + DBConfig: &builder.DBConfig{ + Dialector: mysql.Open(dsn), + Opts: &gorm.Config{}, + }, + } + + // 创建对象 + b := builder.New(config) + + // 初始化安装 + b.Use(install.Handle) + + // 中间件 + b.Use(middleware.Handle) + + // 适配hertz + hertzadapter.Adapter(b, r) +} diff --git a/examples/hertzadmin/router_gen.go b/examples/hertzadmin/router_gen.go new file mode 100644 index 0000000..d810765 --- /dev/null +++ b/examples/hertzadmin/router_gen.go @@ -0,0 +1,16 @@ +// Code generated by hertz generator. DO NOT EDIT. + +package main + +import ( + "github.com/cloudwego/hertz/pkg/app/server" + router "github.com/quarkcms/quark-go/examples/hertzadmin/biz/router" +) + +// register registers all routers. +func register(r *server.Hertz) { + + router.GeneratedRegister(r) + + customizedRegister(r) +} diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..0ba50b0 --- /dev/null +++ b/go.mod @@ -0,0 +1,93 @@ +module github.com/quarkcms/quark-go + +go 1.18 + +require ( + github.com/alibabacloud-go/darabonba-openapi v0.2.1 + github.com/alibabacloud-go/dysmsapi-20170525/v2 v2.0.18 + github.com/alibabacloud-go/tea v1.1.20 + github.com/alibabacloud-go/tea-utils v1.4.5 + github.com/go-basic/uuid v1.0.0 + github.com/gofiber/fiber/v2 v2.41.0 + github.com/parnurzeal/gorequest v0.2.16 +) + +require ( + github.com/andybalholm/brotli v1.0.4 // indirect + github.com/bytedance/go-tagexpr/v2 v2.9.2 // indirect + github.com/bytedance/gopkg v0.0.0-20220531084716-665b4f21126f // indirect + github.com/bytedance/sonic v1.5.0 // indirect + github.com/cespare/xxhash/v2 v2.1.2 // indirect + github.com/chenzhuoyu/base64x v0.0.0-20211019084208-fb5309c8db06 // indirect + github.com/cloudwego/netpoll v0.3.1 // indirect + github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect + github.com/fsnotify/fsnotify v1.5.4 // indirect + github.com/go-ole/go-ole v1.2.6 // indirect + github.com/go-sql-driver/mysql v1.7.0 // indirect + github.com/golang/protobuf v1.5.2 // indirect + github.com/henrylee2cn/ameda v1.4.10 // indirect + github.com/henrylee2cn/goutil v0.0.0-20210127050712-89660552f6f8 // indirect + github.com/jinzhu/inflection v1.0.0 // indirect + github.com/jinzhu/now v1.1.5 // indirect + github.com/klauspost/compress v1.15.9 // indirect + github.com/klauspost/cpuid/v2 v2.1.0 // indirect + github.com/mattn/go-colorable v0.1.13 // indirect + github.com/mattn/go-isatty v0.0.17 // indirect + github.com/mattn/go-runewidth v0.0.14 // indirect + github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect + github.com/nyaruka/phonenumbers v1.0.55 // indirect + github.com/richardlehane/mscfb v1.0.4 // indirect + github.com/richardlehane/msoleps v1.0.3 // indirect + github.com/rivo/uniseg v0.2.0 // indirect + github.com/tidwall/gjson v1.13.0 // indirect + github.com/tidwall/match v1.1.1 // indirect + github.com/tidwall/pretty v1.2.0 // indirect + github.com/tklauser/go-sysconf v0.3.11 // indirect + github.com/tklauser/numcpus v0.6.0 // indirect + github.com/twitchyliquid64/golang-asm v0.15.1 // indirect + github.com/valyala/bytebufferpool v1.0.0 // indirect + github.com/valyala/fasthttp v1.43.0 // indirect + github.com/valyala/tcplisten v1.0.0 // indirect + github.com/xuri/efp v0.0.0-20220603152613-6918739fd470 // indirect + github.com/xuri/nfp v0.0.0-20220409054826-5e722a1d9e22 // indirect + github.com/yusufpapurcu/wmi v1.2.2 // indirect + golang.org/x/arch v0.0.0-20220722155209-00200b7164a7 // indirect + golang.org/x/sys v0.4.0 // indirect + golang.org/x/text v0.6.0 // indirect + golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect + google.golang.org/protobuf v1.28.1 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect +) + +require ( + github.com/alibabacloud-go/alibabacloud-gateway-spi v0.0.4 // indirect + github.com/alibabacloud-go/debug v0.0.0-20190504072949-9472017b5c68 // indirect + github.com/alibabacloud-go/endpoint-util v1.1.0 // indirect + github.com/alibabacloud-go/openapi-util v0.0.11 // indirect + github.com/alibabacloud-go/tea-xml v1.1.2 // indirect + github.com/aliyun/credentials-go v1.1.2 // indirect + github.com/clbanning/mxj/v2 v2.5.6 // indirect + github.com/cloudwego/hertz v0.4.2 + github.com/dchest/captcha v1.0.0 + github.com/derekstavis/go-qs v0.0.0-20180720192143-9eef69e6c4e7 + github.com/elazarl/goproxy v0.0.0-20221015165544-a0805db90819 // indirect + github.com/go-redis/redis/v8 v8.11.5 + github.com/gobeam/stringy v0.0.5 + github.com/golang-jwt/jwt/v4 v4.4.3 + github.com/jinzhu/copier v0.3.5 + github.com/json-iterator/go v1.1.12 // indirect + github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 // indirect + github.com/modern-go/reflect2 v1.0.2 // indirect + github.com/pkg/errors v0.9.1 // indirect + github.com/shirou/gopsutil v3.21.11+incompatible + github.com/tjfoc/gmsm v1.3.2 // indirect + github.com/xuri/excelize/v2 v2.6.1 + golang.org/x/crypto v0.5.0 + golang.org/x/net v0.5.0 // indirect + gopkg.in/ini.v1 v1.56.0 // indirect + gorm.io/driver/mysql v1.4.5 + gorm.io/gorm v1.24.3 + moul.io/http2curl v1.0.0 // indirect +) + +replace github.com/apache/thrift => github.com/apache/thrift v0.13.0 diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..141832c --- /dev/null +++ b/go.sum @@ -0,0 +1,279 @@ +github.com/alibabacloud-go/alibabacloud-gateway-spi v0.0.4 h1:iC9YFYKDGEy3n/FtqJnOkZsene9olVspKmkX5A2YBEo= +github.com/alibabacloud-go/alibabacloud-gateway-spi v0.0.4/go.mod h1:sCavSAvdzOjul4cEqeVtvlSaSScfNsTQ+46HwlTL1hc= +github.com/alibabacloud-go/darabonba-openapi v0.1.18/go.mod h1:PB4HffMhJVmAgNKNq3wYbTUlFvPgxJpTzd1F5pTuUsc= +github.com/alibabacloud-go/darabonba-openapi v0.2.1 h1:WyzxxKvhdVDlwpAMOHgAiCJ+NXa6g5ZWPFEzaK/ewwY= +github.com/alibabacloud-go/darabonba-openapi v0.2.1/go.mod h1:zXOqLbpIqq543oioL9IuuZYOQgHQ5B8/n5OPrnko8aY= +github.com/alibabacloud-go/darabonba-string v1.0.0/go.mod h1:93cTfV3vuPhhEwGGpKKqhVW4jLe7tDpo3LUM0i0g6mA= +github.com/alibabacloud-go/debug v0.0.0-20190504072949-9472017b5c68 h1:NqugFkGxx1TXSh/pBcU00Y6bljgDPaFdh5MUSeJ7e50= +github.com/alibabacloud-go/debug v0.0.0-20190504072949-9472017b5c68/go.mod h1:6pb/Qy8c+lqua8cFpEy7g39NRRqOWc3rOwAy8m5Y2BY= +github.com/alibabacloud-go/dysmsapi-20170525/v2 v2.0.18 h1:hfZA4cgIl6frNdsRmAyj8sn9J1bihQpYbzIVv2T/+Cs= +github.com/alibabacloud-go/dysmsapi-20170525/v2 v2.0.18/go.mod h1:di54xjBFHvKiQQo7st3TUmiMy0ywne5TOHup786Rhes= +github.com/alibabacloud-go/endpoint-util v1.1.0 h1:r/4D3VSw888XGaeNpP994zDUaxdgTSHBbVfZlzf6b5Q= +github.com/alibabacloud-go/endpoint-util v1.1.0/go.mod h1:O5FuCALmCKs2Ff7JFJMudHs0I5EBgecXXxZRyswlEjE= +github.com/alibabacloud-go/openapi-util v0.0.11 h1:iYnqOPR5hyEEnNZmebGyRMkkEJRWUEjDiiaOHZ5aNhA= +github.com/alibabacloud-go/openapi-util v0.0.11/go.mod h1:sQuElr4ywwFRlCCberQwKRFhRzIyG4QTP/P4y1CJ6Ws= +github.com/alibabacloud-go/tea v1.1.0/go.mod h1:IkGyUSX4Ba1V+k4pCtJUc6jDpZLFph9QMy2VUPTwukg= +github.com/alibabacloud-go/tea v1.1.7/go.mod h1:/tmnEaQMyb4Ky1/5D+SE1BAsa5zj/KeGOFfwYm3N/p4= +github.com/alibabacloud-go/tea v1.1.8/go.mod h1:/tmnEaQMyb4Ky1/5D+SE1BAsa5zj/KeGOFfwYm3N/p4= +github.com/alibabacloud-go/tea v1.1.11/go.mod h1:/tmnEaQMyb4Ky1/5D+SE1BAsa5zj/KeGOFfwYm3N/p4= +github.com/alibabacloud-go/tea v1.1.17/go.mod h1:nXxjm6CIFkBhwW4FQkNrolwbfon8Svy6cujmKFUq98A= +github.com/alibabacloud-go/tea v1.1.19/go.mod h1:nXxjm6CIFkBhwW4FQkNrolwbfon8Svy6cujmKFUq98A= +github.com/alibabacloud-go/tea v1.1.20 h1:wFK4xEbvGYMtzTyHhIju9D7ecWxvSUdoLO6y4vDLFik= +github.com/alibabacloud-go/tea v1.1.20/go.mod h1:nXxjm6CIFkBhwW4FQkNrolwbfon8Svy6cujmKFUq98A= +github.com/alibabacloud-go/tea-utils v1.3.1/go.mod h1:EI/o33aBfj3hETm4RLiAxF/ThQdSngxrpF8rKUDJjPE= +github.com/alibabacloud-go/tea-utils v1.4.3/go.mod h1:KNcT0oXlZZxOXINnZBs6YvgOd5aYp9U67G+E3R8fcQw= +github.com/alibabacloud-go/tea-utils v1.4.5 h1:h0/6Xd2f3bPE4XHTvkpjwxowIwRCJAJOqY6Eq8f3zfA= +github.com/alibabacloud-go/tea-utils v1.4.5/go.mod h1:KNcT0oXlZZxOXINnZBs6YvgOd5aYp9U67G+E3R8fcQw= +github.com/alibabacloud-go/tea-xml v1.1.2 h1:oLxa7JUXm2EDFzMg+7oRsYc+kutgCVwm+bZlhhmvW5M= +github.com/alibabacloud-go/tea-xml v1.1.2/go.mod h1:Rq08vgCcCAjHyRi/M7xlHKUykZCEtyBy9+DPF6GgEu8= +github.com/aliyun/credentials-go v1.1.2 h1:qU1vwGIBb3UJ8BwunHDRFtAhS6jnQLnde/yk0+Ih2GY= +github.com/aliyun/credentials-go v1.1.2/go.mod h1:ozcZaMR5kLM7pwtCMEpVmQ242suV6qTJya2bDq4X1Tw= +github.com/andybalholm/brotli v1.0.4 h1:V7DdXeJtZscaqfNuAdSRuRFzuiKlHSC/Zh3zl9qY3JY= +github.com/andybalholm/brotli v1.0.4/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig= +github.com/bytedance/go-tagexpr/v2 v2.9.2 h1:QySJaAIQgOEDQBLS3x9BxOWrnhqu5sQ+f6HaZIxD39I= +github.com/bytedance/go-tagexpr/v2 v2.9.2/go.mod h1:5qsx05dYOiUXOUgnQ7w3Oz8BYs2qtM/bJokdLb79wRM= +github.com/bytedance/gopkg v0.0.0-20220413063733-65bf48ffb3a7/go.mod h1:2ZlV9BaUH4+NXIBF0aMdKKAnHTzqH+iMU4KUjAbL23Q= +github.com/bytedance/gopkg v0.0.0-20220531084716-665b4f21126f h1:2YCF3cgO6XCub0HIsLrA8ZGhmAPGZfOeSaGjT6Kx4Mc= +github.com/bytedance/gopkg v0.0.0-20220531084716-665b4f21126f/go.mod h1:2ZlV9BaUH4+NXIBF0aMdKKAnHTzqH+iMU4KUjAbL23Q= +github.com/bytedance/sonic v1.5.0 h1:XWdTi8bwPgxIML+eNV1IwNuTROK6EUrQ65ey8yd6fRQ= +github.com/bytedance/sonic v1.5.0/go.mod h1:ED5hyg4y6t3/9Ku1R6dU/4KyJ48DZ4jPhfY1O2AihPM= +github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE= +github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/chenzhuoyu/base64x v0.0.0-20211019084208-fb5309c8db06 h1:1sDoSuDPWzhkdzNVxCxtIaKiAe96ESVPv8coGwc1gZ4= +github.com/chenzhuoyu/base64x v0.0.0-20211019084208-fb5309c8db06/go.mod h1:DH46F32mSOjUmXrMHnKwZdA8wcEefY7UVqBKYGjpdQY= +github.com/clbanning/mxj/v2 v2.5.5/go.mod h1:hNiWqW14h+kc+MdF9C6/YoRfjEJoR3ou6tn/Qo+ve2s= +github.com/clbanning/mxj/v2 v2.5.6 h1:Jm4VaCI/+Ug5Q57IzEoZbwx4iQFA6wkXv72juUSeK+g= +github.com/clbanning/mxj/v2 v2.5.6/go.mod h1:hNiWqW14h+kc+MdF9C6/YoRfjEJoR3ou6tn/Qo+ve2s= +github.com/cloudwego/hertz v0.4.2 h1:Ntfs5MdPoKeFSbyStU2drM4CizOkEfYWsB9s1Q3taPY= +github.com/cloudwego/hertz v0.4.2/go.mod h1:K1U0RlU07CDeBINfHNbafH/3j9uSgIW8otbjUys3OPY= +github.com/cloudwego/netpoll v0.3.1 h1:xByoORmCLIyKZ8gS+da06WDo3j+jvmhaqS2KeKejtBk= +github.com/cloudwego/netpoll v0.3.1/go.mod h1:1T2WVuQ+MQw6h6DpE45MohSvDTKdy2DlzCx2KsnPI4E= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/dchest/captcha v1.0.0 h1:vw+bm/qMFvTgcjQlYVTuQBJkarm5R0YSsDKhm1HZI2o= +github.com/dchest/captcha v1.0.0/go.mod h1:7zoElIawLp7GUMLcj54K9kbw+jEyvz2K0FDdRRYhvWo= +github.com/derekstavis/go-qs v0.0.0-20180720192143-9eef69e6c4e7 h1:zmAiXR9h1TCVN/0yCMRYQNE91dNRORpSzMFiqfTTPOs= +github.com/derekstavis/go-qs v0.0.0-20180720192143-9eef69e6c4e7/go.mod h1:Vgz4nKcG6+B7QcALsWZpmhyQTLSl7nwFGKSrbq2LxEo= +github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78= +github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc= +github.com/elazarl/goproxy v0.0.0-20221015165544-a0805db90819 h1:RIB4cRk+lBqKK3Oy0r2gRX4ui7tuhiZq2SuTtTCi0/0= +github.com/elazarl/goproxy v0.0.0-20221015165544-a0805db90819/go.mod h1:Ro8st/ElPeALwNFlcTpWmkr6IoMFfkjXAvTHpevnDsM= +github.com/elazarl/goproxy/ext v0.0.0-20190711103511-473e67f1d7d2/go.mod h1:gNh8nYJoAm43RfaxurUnxr+N1PwuFV3ZMl/efxlIlY8= +github.com/fsnotify/fsnotify v1.5.4 h1:jRbGcIw6P2Meqdwuo0H1p6JVLbL5DHKAKlYndzMwVZI= +github.com/fsnotify/fsnotify v1.5.4/go.mod h1:OVB6XrOHzAwXMpEM7uPOzcehqUV2UqJxmVXmkdnm1bU= +github.com/go-basic/uuid v1.0.0 h1:Faqtetcr8uwOzR2qp8RSpkahQiv4+BnJhrpuXPOo63M= +github.com/go-basic/uuid v1.0.0/go.mod h1:yVtVnsXcmaLc9F4Zw7hTV7R0+vtuQw00mdXi+F6tqco= +github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY= +github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= +github.com/go-redis/redis/v8 v8.11.5 h1:AcZZR7igkdvfVmQTPnu9WE37LRrO/YrBH5zWyjDC0oI= +github.com/go-redis/redis/v8 v8.11.5/go.mod h1:gREzHqY1hg6oD9ngVRbLStwAWKhA0FEgq8Jd4h5lpwo= +github.com/go-sql-driver/mysql v1.7.0 h1:ueSltNNllEqE3qcWBTD0iQd3IpL/6U+mJxLkazJ7YPc= +github.com/go-sql-driver/mysql v1.7.0/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI= +github.com/gobeam/stringy v0.0.5 h1:TvxQGSAqr/qF0SBVxa8Q67WWIo7bCWS0bM101WOd52g= +github.com/gobeam/stringy v0.0.5/go.mod h1:W3620X9dJHf2FSZF5fRnWekHcHQjwmCz8ZQ2d1qloqE= +github.com/gofiber/fiber/v2 v2.41.0 h1:YhNoUS/OTjEz+/WLYuQ01xI7RXgKEFnGBKMagAu5f0M= +github.com/gofiber/fiber/v2 v2.41.0/go.mod h1:RdebcCuCRFp4W6hr3968/XxwJVg0K+jr9/Ae0PFzZ0Q= +github.com/golang-jwt/jwt/v4 v4.4.3 h1:Hxl6lhQFj4AnOX6MLrsCb/+7tCj7DxP7VA+2rDIq5AU= +github.com/golang-jwt/jwt/v4 v4.4.3/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= +github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= +github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU= +github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= +github.com/gopherjs/gopherjs v0.0.0-20200217142428-fce0ec30dd00 h1:l5lAOZEym3oK3SQ2HBHWsJUfbNBiTXJDeW2QDxw9AQ0= +github.com/gopherjs/gopherjs v0.0.0-20200217142428-fce0ec30dd00/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= +github.com/henrylee2cn/ameda v1.4.8/go.mod h1:liZulR8DgHxdK+MEwvZIylGnmcjzQ6N6f2PlWe7nEO4= +github.com/henrylee2cn/ameda v1.4.10 h1:JdvI2Ekq7tapdPsuhrc4CaFiqw6QXFvZIULWJgQyCAk= +github.com/henrylee2cn/ameda v1.4.10/go.mod h1:liZulR8DgHxdK+MEwvZIylGnmcjzQ6N6f2PlWe7nEO4= +github.com/henrylee2cn/goutil v0.0.0-20210127050712-89660552f6f8 h1:yE9ULgp02BhYIrO6sdV/FPe0xQM6fNHkVQW2IAymfM0= +github.com/henrylee2cn/goutil v0.0.0-20210127050712-89660552f6f8/go.mod h1:Nhe/DM3671a5udlv2AdV2ni/MZzgfv2qrPL5nIi3EGQ= +github.com/jinzhu/copier v0.3.5 h1:GlvfUwHk62RokgqVNvYsku0TATCF7bAHVwEXoBh3iJg= +github.com/jinzhu/copier v0.3.5/go.mod h1:DfbEm0FYsaqBcKcFuvmOZb218JkPGtvSHsKg8S8hyyg= +github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E= +github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc= +github.com/jinzhu/now v1.1.4/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= +github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ= +github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= +github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= +github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= +github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo= +github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= +github.com/klauspost/compress v1.15.9 h1:wKRjX6JRtDdrE9qwa4b/Cip7ACOshUI4smpCQanqjSY= +github.com/klauspost/compress v1.15.9/go.mod h1:PhcZ0MbTNciWF3rruxRgKxI5NkcHHrHUDtV4Yw2GlzU= +github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= +github.com/klauspost/cpuid/v2 v2.1.0 h1:eyi1Ad2aNJMW95zcSbmGg7Cg6cq3ADwLpMAP96d8rF0= +github.com/klauspost/cpuid/v2 v2.1.0/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8tyFgg4nqhuY= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= +github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= +github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/mattn/go-isatty v0.0.17 h1:BTarxUcIeDqL27Mc+vyvdWYSL28zpIhv3RoTdsLMPng= +github.com/mattn/go-isatty v0.0.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/mattn/go-runewidth v0.0.14 h1:+xnbZSEeDbOIg5/mE6JF0w6n9duR1l3/WmbinWVwUuU= +github.com/mattn/go-runewidth v0.0.14/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= +github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 h1:ZqeYNhU3OHLH3mGKHDcjJRFFRrJa6eAM5H+CtDdOsPc= +github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= +github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= +github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 h1:RWengNIwukTxcDr9M+97sNutRR1RKhG96O6jWumTTnw= +github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8= +github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= +github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= +github.com/nyaruka/phonenumbers v1.0.55 h1:bj0nTO88Y68KeUQ/n3Lo2KgK7lM1hF7L9NFuwcCl3yg= +github.com/nyaruka/phonenumbers v1.0.55/go.mod h1:sDaTZ/KPX5f8qyV9qN+hIm+4ZBARJrupC6LuhshJq1U= +github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= +github.com/onsi/gomega v1.18.1 h1:M1GfJqGRrBrrGGsbxzV5dqM2U2ApXefZCQpkukxYRLE= +github.com/parnurzeal/gorequest v0.2.16 h1:T/5x+/4BT+nj+3eSknXmCTnEVGSzFzPGdpqmUVVZXHQ= +github.com/parnurzeal/gorequest v0.2.16/go.mod h1:3Kh2QUMJoqw3icWAecsyzkpY7UzRfDhbRdTjtNwNiUE= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/richardlehane/mscfb v1.0.4 h1:WULscsljNPConisD5hR0+OyZjwK46Pfyr6mPu5ZawpM= +github.com/richardlehane/mscfb v1.0.4/go.mod h1:YzVpcZg9czvAuhk9T+a3avCpcFPMUWm7gK3DypaEsUk= +github.com/richardlehane/msoleps v1.0.1/go.mod h1:BWev5JBpU9Ko2WAgmZEuiz4/u3ZYTKbjLycmwiWUfWg= +github.com/richardlehane/msoleps v1.0.3 h1:aznSZzrwYRl3rLKRT3gUk9am7T/mLNSnJINvN0AQoVM= +github.com/richardlehane/msoleps v1.0.3/go.mod h1:BWev5JBpU9Ko2WAgmZEuiz4/u3ZYTKbjLycmwiWUfWg= +github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY= +github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= +github.com/rogpeppe/go-charset v0.0.0-20180617210344-2471d30d28b4/go.mod h1:qgYeAmZ5ZIpBWTGllZSQnw97Dj+woV0toclVaRGI8pc= +github.com/shirou/gopsutil v3.21.11+incompatible h1:+1+c1VGhc88SSonWP6foOcLhvnKlUeu/erjjvaPEYiI= +github.com/shirou/gopsutil v3.21.11+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= +github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= +github.com/smartystreets/assertions v1.1.0 h1:MkTeG1DMwsrdH7QtLXy5W+fUxWq+vmb6cLmyJ7aRtF0= +github.com/smartystreets/assertions v1.1.0/go.mod h1:tcbTF8ujkAEcZ8TElKY+i30BzYlVhC/LOxJk7iOWnoo= +github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s= +github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/tidwall/gjson v1.9.3/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= +github.com/tidwall/gjson v1.13.0 h1:3TFY9yxOQShrvmjdM76K+jc66zJeT6D3/VFFYCGQf7M= +github.com/tidwall/gjson v1.13.0/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= +github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA= +github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM= +github.com/tidwall/pretty v1.2.0 h1:RWIZEg2iJ8/g6fDDYzMpobmaoGh5OLl4AXtGUGPcqCs= +github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= +github.com/tjfoc/gmsm v1.3.2 h1:7JVkAn5bvUJ7HtU08iW6UiD+UTmJTIToHCfeFzkcCxM= +github.com/tjfoc/gmsm v1.3.2/go.mod h1:HaUcFuY0auTiaHB9MHFGCPx5IaLhTUd2atbCFBQXn9w= +github.com/tklauser/go-sysconf v0.3.11 h1:89WgdJhk5SNwJfu+GKyYveZ4IaJ7xAkecBo+KdJV0CM= +github.com/tklauser/go-sysconf v0.3.11/go.mod h1:GqXfhXY3kiPa0nAXPDIQIWzJbMCB7AmcWpGR8lSZfqI= +github.com/tklauser/numcpus v0.6.0 h1:kebhY2Qt+3U6RNK7UqpYNA+tJ23IBEGKkB7JQBfDYms= +github.com/tklauser/numcpus v0.6.0/go.mod h1:FEZLMke0lhOUG6w2JadTzp0a+Nl8PF/GFkQ5UVIcaL4= +github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI= +github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08= +github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= +github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= +github.com/valyala/fasthttp v1.43.0 h1:Gy4sb32C98fbzVWZlTM1oTMdLWGyvxR03VhM6cBIU4g= +github.com/valyala/fasthttp v1.43.0/go.mod h1:f6VbjjoI3z1NDOZOv17o6RvtRSWxC77seBFc2uWtgiY= +github.com/valyala/tcplisten v1.0.0 h1:rBHj/Xf+E1tRGZyWIWwJDiRY0zc1Js+CV5DqwacVSA8= +github.com/valyala/tcplisten v1.0.0/go.mod h1:T0xQ8SeCZGxckz9qRXTfG43PvQ/mcWh7FwZEA7Ioqkc= +github.com/xuri/efp v0.0.0-20220603152613-6918739fd470 h1:6932x8ltq1w4utjmfMPVj09jdMlkY0aiA6+Skbtl3/c= +github.com/xuri/efp v0.0.0-20220603152613-6918739fd470/go.mod h1:ybY/Jr0T0GTCnYjKqmdwxyxn2BQf2RcQIIvex5QldPI= +github.com/xuri/excelize/v2 v2.6.1 h1:ICBdtw803rmhLN3zfvyEGH3cwSmZv+kde7LhTDT659k= +github.com/xuri/excelize/v2 v2.6.1/go.mod h1:tL+0m6DNwSXj/sILHbQTYsLi9IF4TW59H2EF3Yrx1AU= +github.com/xuri/nfp v0.0.0-20220409054826-5e722a1d9e22 h1:OAmKAfT06//esDdpi/DZ8Qsdt4+M5+ltca05dA5bG2M= +github.com/xuri/nfp v0.0.0-20220409054826-5e722a1d9e22/go.mod h1:WwHg+CVyzlv/TX9xqBFXEZAuxOPxn2k1GNHwG41IIUQ= +github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.1.30/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yusufpapurcu/wmi v1.2.2 h1:KBNDSne4vP5mbSWnJbO+51IMOXJB67QiYCSBrubbPRg= +github.com/yusufpapurcu/wmi v1.2.2/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= +golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8= +golang.org/x/arch v0.0.0-20220722155209-00200b7164a7 h1:VBQqJMNMRfQsWSiCTLgz9XjAfWlgnJAPv8nsp1HF8Tw= +golang.org/x/arch v0.0.0-20220722155209-00200b7164a7/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20191219195013-becbf705a915/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20200510223506-06a226fb4e37/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20220214200702-86341886e292/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/crypto v0.0.0-20220817201139-bc19a97f63c8/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/crypto v0.5.0 h1:U/0M97KRkSFvyD/3FSmdP5W5swImpNgle/EHFhOsQPE= +golang.org/x/crypto v0.5.0/go.mod h1:NK/OQwhpMQP3MwtdjgLlYHnH9ebylxKWv3e0fK+mkQU= +golang.org/x/image v0.0.0-20220413100746-70e8d0d3baa9 h1:LRtI4W37N+KFebI/qV0OFiLUv4GLOWeEW5hn/KEJvxE= +golang.org/x/image v0.0.0-20220413100746-70e8d0d3baa9/go.mod h1:023OzeP/+EPmXeapQh35lcL3II3LrY8Ic+EFFKVhULM= +golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20220812174116-3211cb980234/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= +golang.org/x/net v0.0.0-20220906165146-f3363e06e74c/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= +golang.org/x/net v0.5.0 h1:GyT4nK/YDHSqa1c4753ouYCDajOYKTja9Xb/OHtgvSw= +golang.org/x/net v0.5.0/go.mod h1:DivGGAXEgPSlEBzxGzZI+ZLohi+xUj054jfeKui00ws= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200509044756-6aff5f38e54f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220110181412-a018aaa089fe/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.4.0 h1:Zr2JFtRQNX3BCZ8YtxRE9hNJYC8J6I1MVbMg6owUp18= +golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.6.0 h1:3XmdazWV+ubf7QgHSTWeykHOci5oeekaGJBLkrkaw4k= +golang.org/x/text v0.6.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20200509030707-2212a7e161a5/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= +google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w= +google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/ini.v1 v1.56.0 h1:DPMeDvGTM54DXbPkVIZsp19fp/I2K7zwA/itHYHKo8Y= +gopkg.in/ini.v1 v1.56.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gorm.io/driver/mysql v1.4.5 h1:u1lytId4+o9dDaNcPCFzNv7h6wvmc92UjNk3z8enSBU= +gorm.io/driver/mysql v1.4.5/go.mod h1:SxzItlnT1cb6e1e4ZRpgJN2VYtcqJgqnHxWr4wsP8oc= +gorm.io/gorm v1.23.8/go.mod h1:l2lP/RyAtc1ynaTjFksBde/O8v9oOGIApu2/xRitmZk= +gorm.io/gorm v1.24.3 h1:WL2ifUmzR/SLp85CSURAfybcHnGZ+yLSGSxgYXlFBHg= +gorm.io/gorm v1.24.3/go.mod h1:DVrVomtaYTbqs7gB/x2uVvqnXzv0nqjB396B8cG4dBA= +moul.io/http2curl v1.0.0 h1:6XwpyZOYsgZJrU8exnG87ncVkU1FVCcTRpwzOkTDUi8= +moul.io/http2curl v1.0.0/go.mod h1:f6cULg+e4Md/oW1cYmwW4IWQOVl2lGbmCNGOHvzX2kE= +rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4= diff --git a/internal/aliyunsms/aliyunsms.go b/internal/aliyunsms/aliyunsms.go new file mode 100644 index 0000000..198e3f0 --- /dev/null +++ b/internal/aliyunsms/aliyunsms.go @@ -0,0 +1,106 @@ +package aliyunsms + +import ( + "regexp" + + openapi "github.com/alibabacloud-go/darabonba-openapi/client" + dysmsapi20170525 "github.com/alibabacloud-go/dysmsapi-20170525/v2/client" + util "github.com/alibabacloud-go/tea-utils/service" + "github.com/alibabacloud-go/tea/tea" +) + +// 配置 +type Config struct { + AccessKeyId string + AccessKeySecret string + SignName string + TemplateCode string +} + +// 结构体 +type App struct { + Config *Config +} + +// 初始化 +func New(config *Config) *App { + + return &App{ + Config: config, + } +} + +// 发送短信 +func (p *App) SendSms(phone string, code string) (bool, string) { + + // 匹配规则 + regRuler := "^1[345789]{1}\\d{9}$" + + // 正则调用规则 + reg := regexp.MustCompile(regRuler) + + // 返回 MatchString 是否匹配 + if !reg.MatchString(phone) { + return false, "手机号格式错误!" + } + + client, _err := Client(tea.String(p.Config.AccessKeyId), tea.String(p.Config.AccessKeySecret)) + if _err != nil { + return false, _err.Error() + } + + sendSmsRequest := &dysmsapi20170525.SendSmsRequest{ + PhoneNumbers: tea.String(phone), + SignName: tea.String(p.Config.SignName), + TemplateCode: tea.String(p.Config.TemplateCode), + TemplateParam: tea.String("{\"code\":\"" + code + "\"}"), + } + runtime := &util.RuntimeOptions{} + tryErr := func() (_e error) { + defer func() { + if r := tea.Recover(recover()); r != nil { + _e = r + } + }() + // 复制代码运行请自行打印 API 的返回值 + _, _err = client.SendSmsWithOptions(sendSmsRequest, runtime) + if _err != nil { + return _err + } + + return nil + }() + + if tryErr != nil { + var error = &tea.SDKError{} + if _t, ok := tryErr.(*tea.SDKError); ok { + error = _t + } else { + error.Message = tea.String(tryErr.Error()) + } + // 如有需要,请打印 error + util.AssertAsString(error.Message) + } + + if _err != nil { + return false, _err.Error() + } + + return true, "" +} + +// 使用AK&SK初始化账号Client +func Client(accessKeyId *string, accessKeySecret *string) (_result *dysmsapi20170525.Client, _err error) { + config := &openapi.Config{ + // 您的 AccessKey ID + AccessKeyId: accessKeyId, + // 您的 AccessKey Secret + AccessKeySecret: accessKeySecret, + } + // 访问的域名 + config.Endpoint = tea.String("dysmsapi.aliyuncs.com") + _result = &dysmsapi20170525.Client{} + _result, _err = dysmsapi20170525.NewClient(config) + + return _result, _err +} diff --git a/internal/sioosms/sioosms.go b/internal/sioosms/sioosms.go new file mode 100644 index 0000000..739f3ea --- /dev/null +++ b/internal/sioosms/sioosms.go @@ -0,0 +1,74 @@ +package aliyunsms + +import ( + "crypto/md5" + "encoding/json" + "fmt" + "regexp" + + "github.com/parnurzeal/gorequest" +) + +// 配置 +type Config struct { + Uid string + Password string +} + +// 结构体 +type App struct { + Config *Config +} + +// 初始化 +func New(config *Config) *App { + + return &App{ + Config: config, + } +} + +// 发送短信 +func (p *App) SendSms(phone string, content string) (bool, string) { + // 匹配规则 + regRuler := "^1[345789]{1}\\d{9}$" + + // 正则调用规则 + reg := regexp.MustCompile(regRuler) + + // 返回 MatchString 是否匹配 + if !reg.MatchString(phone) { + return false, "手机号格式错误!" + } + + uid := p.Config.Uid + password := p.Config.Password + + if uid == "" || password == "" { + return false, "接口配置错误!" + } + + md5Byte := md5.Sum([]byte(password)) + md5Password := fmt.Sprintf("%x", md5Byte) + + // 接口url + url := "https://submit.10690221.com/send/ordinarykv?uid=" + uid + "&password=" + md5Password + "&mobile=" + phone + "&msg=" + content + + request := gorequest.New() + _, body, _ := request.Get(url).End() + + type Data struct { + Msg string + Code int + MsgId string + } + + var data Data + json.Unmarshal([]byte(body), &data) + + if data.Code == 0 { + return true, "发送成功" + } else { + return true, data.Msg + } +} diff --git a/pkg/adapter/fiberadapter/fiberadapter.go b/pkg/adapter/fiberadapter/fiberadapter.go new file mode 100644 index 0000000..5764719 --- /dev/null +++ b/pkg/adapter/fiberadapter/fiberadapter.go @@ -0,0 +1,94 @@ +package fiberadapter + +import ( + "bytes" + + "github.com/gofiber/fiber/v2" + "github.com/quarkcms/quark-go/pkg/builder" + "github.com/quarkcms/quark-go/pkg/msg" +) + +const COMPONENT_RESPONSE = "component" // 组件类型响应 +const ACTION_RESPONSE = "action" // 行为类型响应 +const FILE_RESPONSE = "file" // 文件类型响应 + +// 将gofiber框架的Ctx转换为builder框架Request +func RequestAdapter(ctx *fiber.Ctx) (*builder.Request, error) { + + return &builder.Request{ + IPString: ctx.IP(), + HeaderString: ctx.Request().Header.String(), + MethodString: string(ctx.Method()), + FullPathString: ctx.Route().Path, + HostString: string(ctx.Hostname()), + PathString: string(ctx.Path()), + QueryString: string(ctx.Context().QueryArgs().QueryString()), + BodyBuffer: ctx.Body(), + }, nil +} + +// 适配gofiber框架响应 +func ResponseAdapter(r *builder.Resource, responseType string, ctx *fiber.Ctx) error { + var responseError error + + result, err := r.Run() + if err != nil { + return ctx.JSON(msg.Error(err.Error(), "")) + } + + switch responseType { + case "component": + return ctx.JSON(result) + case "action": + return ctx.JSON(msg.Success("操作成功", "", result)) + case "file": + return ctx.SendStream(bytes.NewReader(result.([]byte))) + } + + return responseError +} + +// 适配gofiber框架路由 +func RouteAdapter(b *builder.Resource, responseType string, ctx *fiber.Ctx) error { + + // 适配请求 + request, err := RequestAdapter(ctx) + if err != nil { + return ctx.JSON(msg.Error(err.Error(), "")) + } + + // 适配响应 + resource := b.TransformRequest(request) + return ResponseAdapter(resource, responseType, ctx) +} + +// 适配gofiber框架 +func Adapter(b *builder.Resource, app *fiber.App) { + + // 后台路由组 + rg := app.Group("/api/admin") + + // 登录 + rg.Get("/login/:resource/index", func(ctx *fiber.Ctx) error { + return RouteAdapter(b, COMPONENT_RESPONSE, ctx) + }) + rg.Post("/login/:resource/handle", func(ctx *fiber.Ctx) error { + return RouteAdapter(b, ACTION_RESPONSE, ctx) + }) + rg.Get("/login/:resource/captchaId", func(ctx *fiber.Ctx) error { + return RouteAdapter(b, ACTION_RESPONSE, ctx) + }) + rg.Get("/login/:resource/captcha/:id", func(ctx *fiber.Ctx) error { + return RouteAdapter(b, FILE_RESPONSE, ctx) + }) + + // 仪表盘 + rg.Get("/dashboard/:resource/index", func(ctx *fiber.Ctx) error { + return RouteAdapter(b, COMPONENT_RESPONSE, ctx) + }) + + // 增删改查 + rg.Get("/:resource/index", func(ctx *fiber.Ctx) error { + return RouteAdapter(b, COMPONENT_RESPONSE, ctx) + }) +} diff --git a/pkg/adapter/hertzadapter/hertzadapter.go b/pkg/adapter/hertzadapter/hertzadapter.go new file mode 100644 index 0000000..8e0ea74 --- /dev/null +++ b/pkg/adapter/hertzadapter/hertzadapter.go @@ -0,0 +1,160 @@ +package hertzadapter + +import ( + "context" + "time" + + "github.com/cloudwego/hertz/pkg/app" + "github.com/cloudwego/hertz/pkg/app/server" + "github.com/quarkcms/quark-go/pkg/builder" + "github.com/quarkcms/quark-go/pkg/msg" +) + +const JSON_RESPONSE = "json" // json类型响应 +const IMAGE_RESPONSE = "image" // 图片类型响应 +const EXCEL_RESPONSE = "excel" // Excel文件类型响应 + +// 将hertz框架的RequestContext转发到builder的Request +func RequestAdapter(ctx *app.RequestContext) (*builder.Request, error) { + body, err := ctx.Body() + if err != nil { + return nil, err + } + + return &builder.Request{ + IPString: ctx.ClientIP(), + HeaderString: string(ctx.Request.Header.Header()), + MethodString: string(ctx.Method()), + FullPathString: ctx.FullPath(), + HostString: string(ctx.Host()), + PathString: string(ctx.Path()), + QueryString: string(ctx.Request.QueryString()), + BodyBuffer: body, + }, nil +} + +// 适配hertz框架响应 +func ResponseAdapter(r *builder.Resource, responseType string, ctx *app.RequestContext) { + result, err := r.Run() + if err != nil { + ctx.JSON(200, msg.Error(err.Error(), "")) + return + } + + switch responseType { + case JSON_RESPONSE: + ctx.JSON(200, result) + case IMAGE_RESPONSE: + ctx.Write(result.([]byte)) + } +} + +// 适配hertz框架路由 +func RouteAdapter(b *builder.Resource, responseType string, ctx *app.RequestContext) { + body, err := ctx.Body() + if err != nil { + ctx.JSON(200, msg.Error(err.Error(), "")) + return + } + + // 将hertz框架请求转换为builder框架请求 + request := &builder.Request{ + IPString: ctx.ClientIP(), + HeaderString: string(ctx.Request.Header.Header()), + MethodString: string(ctx.Method()), + FullPathString: ctx.FullPath(), + HostString: string(ctx.Host()), + PathString: string(ctx.Path()), + QueryString: string(ctx.Request.QueryString()), + BodyBuffer: body, + } + + // 转换Request对象 + result, err := b.TransformRequest(request).Run() + if err != nil { + ctx.JSON(200, msg.Error(err.Error(), "")) + return + } + + // 响应结果 + switch responseType { + case JSON_RESPONSE: + ctx.JSON(200, result) + case IMAGE_RESPONSE: + ctx.Write(result.([]byte)) + case EXCEL_RESPONSE: + ctx.Response.Header.Set("Content-Disposition", "attachment; filename=data_"+time.Now().Format("20060102150405")+".xlsx") + ctx.Response.Header.Set("Content-Type", "application/octet-stream") + ctx.Write(result.([]byte)) + } +} + +// 适配hertz框架 +func Adapter(b *builder.Resource, r *server.Hertz) { + + // 后台路由组 + rg := r.Group("/api/admin") + + // 登录 + rg.GET("/login/:resource/index", func(c context.Context, ctx *app.RequestContext) { + RouteAdapter(b, JSON_RESPONSE, ctx) + }) + rg.POST("/login/:resource/handle", func(c context.Context, ctx *app.RequestContext) { + RouteAdapter(b, JSON_RESPONSE, ctx) + }) + rg.GET("/login/:resource/captchaId", func(c context.Context, ctx *app.RequestContext) { + RouteAdapter(b, JSON_RESPONSE, ctx) + }) + rg.GET("/login/:resource/captcha/:id", func(c context.Context, ctx *app.RequestContext) { + RouteAdapter(b, IMAGE_RESPONSE, ctx) + }) + rg.GET("/logout/:resource/handle", func(c context.Context, ctx *app.RequestContext) { + RouteAdapter(b, JSON_RESPONSE, ctx) + }) + + // 仪表盘 + rg.GET("/dashboard/:resource/index", func(c context.Context, ctx *app.RequestContext) { + RouteAdapter(b, JSON_RESPONSE, ctx) + }) + + // 增删改查 + rg.GET("/:resource/index", func(c context.Context, ctx *app.RequestContext) { + RouteAdapter(b, JSON_RESPONSE, ctx) + }) + rg.GET("/:resource/editable", func(c context.Context, ctx *app.RequestContext) { + RouteAdapter(b, JSON_RESPONSE, ctx) + }) + rg.Any("/:resource/action/:uriKey", func(c context.Context, ctx *app.RequestContext) { + RouteAdapter(b, JSON_RESPONSE, ctx) + }) + rg.GET("/:resource/create", func(c context.Context, ctx *app.RequestContext) { + RouteAdapter(b, JSON_RESPONSE, ctx) + }) + rg.POST("/:resource/store", func(c context.Context, ctx *app.RequestContext) { + RouteAdapter(b, JSON_RESPONSE, ctx) + }) + rg.GET("/:resource/edit", func(c context.Context, ctx *app.RequestContext) { + RouteAdapter(b, JSON_RESPONSE, ctx) + }) + rg.GET("/:resource/edit/values", func(c context.Context, ctx *app.RequestContext) { + RouteAdapter(b, JSON_RESPONSE, ctx) + }) + rg.POST("/:resource/save", func(c context.Context, ctx *app.RequestContext) { + RouteAdapter(b, JSON_RESPONSE, ctx) + }) + rg.GET("/:resource/detail", func(c context.Context, ctx *app.RequestContext) { + RouteAdapter(b, JSON_RESPONSE, ctx) + }) + rg.GET("/:resource/export", func(c context.Context, ctx *app.RequestContext) { + RouteAdapter(b, EXCEL_RESPONSE, ctx) + }) + rg.Any("/:resource/import", func(c context.Context, ctx *app.RequestContext) { + RouteAdapter(b, JSON_RESPONSE, ctx) + }) + rg.GET("/:resource/import/template", func(c context.Context, ctx *app.RequestContext) { + RouteAdapter(b, EXCEL_RESPONSE, ctx) + }) + rg.GET("/:resource/:uriKey/form", func(c context.Context, ctx *app.RequestContext) { + RouteAdapter(b, JSON_RESPONSE, ctx) + }) +} diff --git a/pkg/app/handler/admin/actions/change_account.go b/pkg/app/handler/admin/actions/change_account.go new file mode 100644 index 0000000..29a5ef9 --- /dev/null +++ b/pkg/app/handler/admin/actions/change_account.go @@ -0,0 +1,45 @@ +package actions + +import ( + "encoding/json" + + models "github.com/quarkcms/quark-go/pkg/app/model" + "github.com/quarkcms/quark-go/pkg/builder" + "github.com/quarkcms/quark-go/pkg/builder/actions" + "github.com/quarkcms/quark-go/pkg/hash" + "github.com/quarkcms/quark-go/pkg/msg" + "gorm.io/gorm" +) + +type ChangeAccount struct { + actions.Action +} + +// 执行行为句柄 +func (p *ChangeAccount) Handle(request *builder.Request, model *gorm.DB) interface{} { + data := map[string]interface{}{} + json.Unmarshal(request.Body(), &data) + if data["avatar"] != "" { + data["avatar"], _ = json.Marshal(data["avatar"]) + } else { + data["avatar"] = nil + } + + // 加密密码 + if data["password"] != nil { + data["password"] = hash.Make(data["password"].(string)) + } + + // 获取登录管理员信息 + adminInfo, err := (&models.Admin{}).GetAuthUser(request.Token()) + if err != nil { + return msg.Error(err.Error(), "") + } + + err = model.Where("id", adminInfo.Id).Updates(data).Error + if err != nil { + return msg.Error(err.Error(), "") + } + + return msg.Success("操作成功", "", "") +} diff --git a/pkg/app/handler/admin/actions/change_status.go b/pkg/app/handler/admin/actions/change_status.go new file mode 100644 index 0000000..a1a0a28 --- /dev/null +++ b/pkg/app/handler/admin/actions/change_status.go @@ -0,0 +1,72 @@ +package actions + +import ( + "github.com/quarkcms/quark-go/pkg/builder" + "github.com/quarkcms/quark-go/pkg/builder/actions" + "github.com/quarkcms/quark-go/pkg/msg" + "gorm.io/gorm" +) + +type ChangeStatus struct { + actions.Action +} + +// 初始化 +func (p *ChangeStatus) Init() *ChangeStatus { + // 初始化父结构 + p.ParentInit() + + // 行为名称,当行为在表格行展示时,支持js表达式 + p.Name = "<%= (status==1 ? '禁用' : '启用') %>" + + // 设置按钮类型,primary | ghost | dashed | link | text | default + p.Type = "link" + + // 设置按钮大小,large | middle | small | default + p.Size = "small" + + // 执行成功后刷新的组件 + p.Reload = "table" + + // 设置展示位置 + p.SetOnlyOnIndexTableRow(true) + + // 当行为在表格行展示时,支持js表达式 + p.WithConfirm("确定要<%= (status==1 ? '禁用' : '启用') %>数据吗?", "", "pop") + + return p +} + +/** + * 行为接口接收的参数,当行为在表格行展示的时候,可以配置当前行的任意字段 + * + * @return array + */ +func (p *ChangeStatus) GetApiParams() []string { + return []string{ + "id", + "status", + } +} + +// 执行行为句柄 +func (p *ChangeStatus) Handle(request *builder.Request, model *gorm.DB) interface{} { + status := request.Query("status") + if status == "" { + return msg.Error("参数错误!", "") + } + + var fieldStatus int + if status == "1" { + fieldStatus = 0 + } else { + fieldStatus = 1 + } + + err := model.Update("status", fieldStatus).Error + if err != nil { + return msg.Error(err.Error(), "") + } + + return msg.Success("操作成功", "", "") +} diff --git a/pkg/app/handler/admin/actions/change_web_config.go b/pkg/app/handler/admin/actions/change_web_config.go new file mode 100644 index 0000000..f0d3f6b --- /dev/null +++ b/pkg/app/handler/admin/actions/change_web_config.go @@ -0,0 +1,51 @@ +package actions + +import ( + "encoding/json" + + models "github.com/quarkcms/quark-go/pkg/app/model" + "github.com/quarkcms/quark-go/pkg/builder" + "github.com/quarkcms/quark-go/pkg/builder/actions" + "github.com/quarkcms/quark-go/pkg/dal/db" + "github.com/quarkcms/quark-go/pkg/msg" + "gorm.io/gorm" +) + +type ChangeWebConfig struct { + actions.Action +} + +// 执行行为句柄 +func (p *ChangeWebConfig) Handle(request *builder.Request, model *gorm.DB) interface{} { + data := map[string]interface{}{} + json.Unmarshal(request.Body(), &data) + result := true + + for k, v := range data { + config := map[string]interface{}{} + db.Client.Model(&models.Config{}).Where("name =?", k).First(&config) + if getValue, ok := v.([]interface{}); ok { + v, _ = json.Marshal(getValue) + } + if getValue, ok := v.([]map[string]interface{}); ok { + v, _ = json.Marshal(getValue) + } + if getValue, ok := v.(map[string]interface{}); ok { + v, _ = json.Marshal(getValue) + } + updateResult := db.Client.Model(&models.Config{}).Where("name", k).Update("value", v) + if updateResult.Error != nil { + result = false + } + } + + if !result { + return msg.Error("操作失败,请重试!", "") + } + + // 刷新网站配置 + (&models.Config{}).Refresh() + + // 返回成功 + return msg.Success("操作成功", "", "") +} diff --git a/pkg/app/handler/admin/actions/create_drawer.go b/pkg/app/handler/admin/actions/create_drawer.go new file mode 100644 index 0000000..83e3f88 --- /dev/null +++ b/pkg/app/handler/admin/actions/create_drawer.go @@ -0,0 +1,88 @@ +package actions + +import ( + "github.com/quarkcms/quark-go/pkg/builder" + "github.com/quarkcms/quark-go/pkg/builder/actions" + "github.com/quarkcms/quark-go/pkg/component/admin/action" + "github.com/quarkcms/quark-go/pkg/component/admin/form" +) + +type CreateDrawer struct { + actions.Drawer +} + +// 初始化 +func (p *CreateDrawer) Init(name string) *CreateDrawer { + // 初始化父结构 + p.ParentInit() + + // 类型 + p.Type = "primary" + + // 图标 + p.Icon = "plus-circle" + + // 文字 + p.Name = "创建" + name + + // 执行成功后刷新的组件 + p.Reload = "table" + + // 关闭时销毁 Drawer 里的子元素 + p.DestroyOnClose = true + + // 设置展示位置 + p.SetOnlyOnIndex(true) + + return p +} + +// 内容 +func (p *CreateDrawer) GetBody(request *builder.Request, resourceInstance interface{}) interface{} { + + api := resourceInstance.(interface { + CreationApi(*builder.Request, interface{}) string + }).CreationApi(request, resourceInstance) + + fields := resourceInstance.(interface { + CreationFieldsWithinComponents(*builder.Request, interface{}) interface{} + }).CreationFieldsWithinComponents(request, resourceInstance) + + // 断言BeforeCreating方法,获取初始数据 + data := resourceInstance.(interface { + BeforeCreating(*builder.Request) map[string]interface{} + }).BeforeCreating(request) + + return (&form.Component{}). + Init(). + SetKey("createDrawerForm", false). + SetApi(api). + SetBody(fields). + SetInitialValues(data). + SetLabelCol(map[string]interface{}{ + "span": 6, + }). + SetWrapperCol(map[string]interface{}{ + "span": 18, + }) +} + +// 弹窗行为 +func (p *CreateDrawer) GetActions(request *builder.Request, resourceInstance interface{}) []interface{} { + + return []interface{}{ + (&action.Component{}). + Init(). + SetLabel("取消"). + SetActionType("cancel"), + + (&action.Component{}). + Init(). + SetLabel("提交"). + SetWithLoading(true). + SetReload("table"). + SetActionType("submit"). + SetType("primary", false). + SetSubmitForm("createDrawerForm"), + } +} diff --git a/pkg/app/handler/admin/actions/create_link.go b/pkg/app/handler/admin/actions/create_link.go new file mode 100644 index 0000000..3332c43 --- /dev/null +++ b/pkg/app/handler/admin/actions/create_link.go @@ -0,0 +1,37 @@ +package actions + +import ( + "strings" + + "github.com/quarkcms/quark-go/pkg/builder" + "github.com/quarkcms/quark-go/pkg/builder/actions" +) + +type CreateLink struct { + actions.Link +} + +// 初始化 +func (p *CreateLink) Init(name string) *CreateLink { + // 初始化父结构 + p.ParentInit() + + // 类型 + p.Type = "primary" + + // 图标 + p.Icon = "plus-circle" + + // 文字 + p.Name = "创建" + name + + // 设置展示位置 + p.SetOnlyOnIndex(true) + + return p +} + +// 跳转链接 +func (p *CreateLink) GetHref(request *builder.Request) string { + return "#/index?api=" + strings.Replace(request.Path(), "/index", "/create", -1) +} diff --git a/pkg/app/handler/admin/actions/create_modal.go b/pkg/app/handler/admin/actions/create_modal.go new file mode 100644 index 0000000..1b407fd --- /dev/null +++ b/pkg/app/handler/admin/actions/create_modal.go @@ -0,0 +1,88 @@ +package actions + +import ( + "github.com/quarkcms/quark-go/pkg/builder" + "github.com/quarkcms/quark-go/pkg/builder/actions" + "github.com/quarkcms/quark-go/pkg/component/admin/action" + "github.com/quarkcms/quark-go/pkg/component/admin/form" +) + +type CreateModal struct { + actions.Modal +} + +// 初始化 +func (p *CreateModal) Init(name string) *CreateModal { + // 初始化父结构 + p.ParentInit() + + // 类型 + p.Type = "primary" + + // 图标 + p.Icon = "plus-circle" + + // 文字 + p.Name = "创建" + name + + // 关闭时销毁 Modal 里的子元素 + p.DestroyOnClose = true + + // 执行成功后刷新的组件 + p.Reload = "table" + + // 设置展示位置 + p.SetOnlyOnIndex(true) + + return p +} + +// 内容 +func (p *CreateModal) GetBody(request *builder.Request, resourceInstance interface{}) interface{} { + + api := resourceInstance.(interface { + CreationApi(*builder.Request, interface{}) string + }).CreationApi(request, resourceInstance) + + fields := resourceInstance.(interface { + CreationFieldsWithinComponents(*builder.Request, interface{}) interface{} + }).CreationFieldsWithinComponents(request, resourceInstance) + + // 断言BeforeCreating方法,获取初始数据 + data := resourceInstance.(interface { + BeforeCreating(*builder.Request) map[string]interface{} + }).BeforeCreating(request) + + return (&form.Component{}). + Init(). + SetKey("createModalForm", false). + SetApi(api). + SetBody(fields). + SetInitialValues(data). + SetLabelCol(map[string]interface{}{ + "span": 6, + }). + SetWrapperCol(map[string]interface{}{ + "span": 18, + }) +} + +// 弹窗行为 +func (p *CreateModal) GetActions(request *builder.Request, resourceInstance interface{}) []interface{} { + + return []interface{}{ + (&action.Component{}). + Init(). + SetLabel("取消"). + SetActionType("cancel"), + + (&action.Component{}). + Init(). + SetLabel("提交"). + SetWithLoading(true). + SetReload("table"). + SetActionType("submit"). + SetType("primary", false). + SetSubmitForm("createModalForm"), + } +} diff --git a/pkg/app/handler/admin/actions/delete.go b/pkg/app/handler/admin/actions/delete.go new file mode 100644 index 0000000..7435d39 --- /dev/null +++ b/pkg/app/handler/admin/actions/delete.go @@ -0,0 +1,64 @@ +package actions + +import ( + "github.com/quarkcms/quark-go/pkg/builder" + "github.com/quarkcms/quark-go/pkg/builder/actions" + "github.com/quarkcms/quark-go/pkg/msg" + "gorm.io/gorm" +) + +type Delete struct { + actions.Action +} + +// 初始化 +func (p *Delete) Init(name string) *Delete { + // 初始化父结构 + p.ParentInit() + + // 行为名称,当行为在表格行展示时,支持js表达式 + p.Name = name + + // 设置按钮类型,primary | ghost | dashed | link | text | default + p.Type = "link" + + // 设置按钮大小,large | middle | small | default + p.Size = "small" + + // 执行成功后刷新的组件 + p.Reload = "table" + + // 当行为在表格行展示时,支持js表达式 + p.WithConfirm("确定要删除吗?", "删除后数据将无法恢复,请谨慎操作!", "modal") + + if name == "删除" { + p.SetOnlyOnIndexTableRow(true) + } + + if name == "批量删除" { + p.SetOnlyOnIndexTableAlert(true) + } + + return p +} + +/** + * 行为接口接收的参数,当行为在表格行展示的时候,可以配置当前行的任意字段 + * + * @return array + */ +func (p *Delete) GetApiParams() []string { + return []string{ + "id", + } +} + +// 执行行为句柄 +func (p *Delete) Handle(request *builder.Request, model *gorm.DB) interface{} { + err := model.Delete("").Error + if err != nil { + return msg.Error(err.Error(), "") + } + + return msg.Success("操作成功", "", "") +} diff --git a/pkg/app/handler/admin/actions/detail_link.go b/pkg/app/handler/admin/actions/detail_link.go new file mode 100644 index 0000000..69af37f --- /dev/null +++ b/pkg/app/handler/admin/actions/detail_link.go @@ -0,0 +1,37 @@ +package actions + +import ( + "strings" + + "github.com/quarkcms/quark-go/pkg/builder" + "github.com/quarkcms/quark-go/pkg/builder/actions" +) + +type DetailLink struct { + actions.Link +} + +// 初始化 +func (p *DetailLink) Init(name string) *DetailLink { + // 初始化父结构 + p.ParentInit() + + // 设置按钮类型,primary | ghost | dashed | link | text | default + p.Type = "link" + + // 设置按钮大小,large | middle | small | default + p.Size = "small" + + // 文字 + p.Name = name + + // 设置展示位置 + p.SetOnlyOnIndexTableRow(true) + + return p +} + +// 跳转链接 +func (p *DetailLink) GetHref(request *builder.Request) string { + return "#/index?api=" + strings.Replace(request.Path(), "/index", "/detail&id=${id}", -1) +} diff --git a/pkg/app/handler/admin/actions/disable.go b/pkg/app/handler/admin/actions/disable.go new file mode 100644 index 0000000..ef62ad7 --- /dev/null +++ b/pkg/app/handler/admin/actions/disable.go @@ -0,0 +1,59 @@ +package actions + +import ( + "github.com/quarkcms/quark-go/pkg/builder" + "github.com/quarkcms/quark-go/pkg/builder/actions" + "github.com/quarkcms/quark-go/pkg/msg" + "gorm.io/gorm" +) + +type Disable struct { + actions.Action +} + +// 初始化 +func (p *Disable) Init(name string) *Disable { + // 初始化父结构 + p.ParentInit() + + // 行为名称,当行为在表格行展示时,支持js表达式 + p.Name = name + + // 设置按钮类型,primary | ghost | dashed | link | text | default + p.Type = "link" + + // 设置按钮大小,large | middle | small | default + p.Size = "small" + + // 执行成功后刷新的组件 + p.Reload = "table" + + // 设置展示位置 + p.SetOnlyOnIndexTableAlert(true) + + // 当行为在表格行展示时,支持js表达式 + p.WithConfirm("确定要禁用吗?", "禁用后数据将无法使用,请谨慎操作!", "modal") + + return p +} + +/** + * 行为接口接收的参数,当行为在表格行展示的时候,可以配置当前行的任意字段 + * + * @return array + */ +func (p *Disable) GetApiParams() []string { + return []string{ + "id", + } +} + +// 执行行为句柄 +func (p *Disable) Handle(request *builder.Request, model *gorm.DB) interface{} { + err := model.Update("status", 0).Error + if err != nil { + return msg.Error(err.Error(), "") + } + + return msg.Success("操作成功", "", "") +} diff --git a/pkg/app/handler/admin/actions/edit_drawer.go b/pkg/app/handler/admin/actions/edit_drawer.go new file mode 100644 index 0000000..e54d59e --- /dev/null +++ b/pkg/app/handler/admin/actions/edit_drawer.go @@ -0,0 +1,87 @@ +package actions + +import ( + "github.com/quarkcms/quark-go/pkg/builder" + "github.com/quarkcms/quark-go/pkg/builder/actions" + "github.com/quarkcms/quark-go/pkg/component/admin/action" + "github.com/quarkcms/quark-go/pkg/component/admin/form" +) + +type EditDrawer struct { + actions.Drawer +} + +// 初始化 +func (p *EditDrawer) Init(name string) *EditDrawer { + // 初始化父结构 + p.ParentInit() + + // 类型 + p.Type = "link" + + // 设置按钮大小,large | middle | small | default + p.Size = "small" + + // 文字 + p.Name = name + + // 关闭时销毁 Drawer 里的子元素 + p.DestroyOnClose = true + + // 执行成功后刷新的组件 + p.Reload = "table" + + // 设置展示位置 + p.SetOnlyOnIndexTableRow(true) + + return p +} + +// 内容 +func (p *EditDrawer) GetBody(request *builder.Request, resourceInstance interface{}) interface{} { + + api := resourceInstance.(interface { + UpdateApi(*builder.Request, interface{}) string + }).UpdateApi(request, resourceInstance) + + initApi := resourceInstance.(interface { + EditValueApi(*builder.Request) string + }).EditValueApi(request) + + fields := resourceInstance.(interface { + UpdateFieldsWithinComponents(*builder.Request, interface{}) interface{} + }).UpdateFieldsWithinComponents(request, resourceInstance) + + return (&form.Component{}). + Init(). + SetKey("editDrawerForm", false). + SetApi(api). + SetInitApi(initApi). + SetBody(fields). + SetLabelCol(map[string]interface{}{ + "span": 6, + }). + SetWrapperCol(map[string]interface{}{ + "span": 18, + }) +} + +// 弹窗行为 +func (p *EditDrawer) GetActions(request *builder.Request, resourceInstance interface{}) []interface{} { + + return []interface{}{ + (&action.Component{}). + Init(). + SetLabel("取消"). + SetActionType("cancel"), + + (&action.Component{}). + Init(). + SetLabel("提交"). + SetWithLoading(true). + SetReload("table"). + SetActionType("submit"). + SetType("primary", false). + SetSubmitForm("editDrawerForm"), + } +} diff --git a/pkg/app/handler/admin/actions/edit_link.go b/pkg/app/handler/admin/actions/edit_link.go new file mode 100644 index 0000000..d681d06 --- /dev/null +++ b/pkg/app/handler/admin/actions/edit_link.go @@ -0,0 +1,37 @@ +package actions + +import ( + "strings" + + "github.com/quarkcms/quark-go/pkg/builder" + "github.com/quarkcms/quark-go/pkg/builder/actions" +) + +type EditLink struct { + actions.Link +} + +// 初始化 +func (p *EditLink) Init(name string) *EditLink { + // 初始化父结构 + p.ParentInit() + + // 设置按钮类型,primary | ghost | dashed | link | text | default + p.Type = "link" + + // 设置按钮大小,large | middle | small | default + p.Size = "small" + + // 文字 + p.Name = name + + // 设置展示位置 + p.SetOnlyOnIndexTableRow(true) + + return p +} + +// 跳转链接 +func (p *EditLink) GetHref(request *builder.Request) string { + return "#/index?api=" + strings.Replace(request.Path(), "/index", "/edit&id=${id}", -1) +} diff --git a/pkg/app/handler/admin/actions/edit_modal.go b/pkg/app/handler/admin/actions/edit_modal.go new file mode 100644 index 0000000..fed538c --- /dev/null +++ b/pkg/app/handler/admin/actions/edit_modal.go @@ -0,0 +1,87 @@ +package actions + +import ( + "github.com/quarkcms/quark-go/pkg/builder" + "github.com/quarkcms/quark-go/pkg/builder/actions" + "github.com/quarkcms/quark-go/pkg/component/admin/action" + "github.com/quarkcms/quark-go/pkg/component/admin/form" +) + +type EditModal struct { + actions.Modal +} + +// 初始化 +func (p *EditModal) Init(name string) *EditModal { + // 初始化父结构 + p.ParentInit() + + // 类型 + p.Type = "link" + + // 设置按钮大小,large | middle | small | default + p.Size = "small" + + // 文字 + p.Name = name + + // 关闭时销毁 Modal 里的子元素 + p.DestroyOnClose = true + + // 执行成功后刷新的组件 + p.Reload = "table" + + // 设置展示位置 + p.SetOnlyOnIndexTableRow(true) + + return p +} + +// 内容 +func (p *EditModal) GetBody(request *builder.Request, resourceInstance interface{}) interface{} { + + api := resourceInstance.(interface { + UpdateApi(*builder.Request, interface{}) string + }).UpdateApi(request, resourceInstance) + + initApi := resourceInstance.(interface { + EditValueApi(*builder.Request) string + }).EditValueApi(request) + + fields := resourceInstance.(interface { + UpdateFieldsWithinComponents(*builder.Request, interface{}) interface{} + }).UpdateFieldsWithinComponents(request, resourceInstance) + + return (&form.Component{}). + Init(). + SetKey("editModalForm", false). + SetApi(api). + SetInitApi(initApi). + SetBody(fields). + SetLabelCol(map[string]interface{}{ + "span": 6, + }). + SetWrapperCol(map[string]interface{}{ + "span": 18, + }) +} + +// 弹窗行为 +func (p *EditModal) GetActions(request *builder.Request, resourceInstance interface{}) []interface{} { + + return []interface{}{ + (&action.Component{}). + Init(). + SetLabel("取消"). + SetActionType("cancel"), + + (&action.Component{}). + Init(). + SetLabel("提交"). + SetWithLoading(true). + SetReload("table"). + SetActionType("submit"). + SetType("primary", false). + SetSubmitForm("editModalForm"), + } +} diff --git a/pkg/app/handler/admin/actions/enable.go b/pkg/app/handler/admin/actions/enable.go new file mode 100644 index 0000000..dca40e7 --- /dev/null +++ b/pkg/app/handler/admin/actions/enable.go @@ -0,0 +1,59 @@ +package actions + +import ( + "github.com/quarkcms/quark-go/pkg/builder" + "github.com/quarkcms/quark-go/pkg/builder/actions" + "github.com/quarkcms/quark-go/pkg/msg" + "gorm.io/gorm" +) + +type Enable struct { + actions.Action +} + +// 初始化 +func (p *Enable) Init(name string) *Enable { + // 初始化父结构 + p.ParentInit() + + // 行为名称,当行为在表格行展示时,支持js表达式 + p.Name = name + + // 设置按钮类型,primary | ghost | dashed | link | text | default + p.Type = "link" + + // 设置按钮大小,large | middle | small | default + p.Size = "small" + + // 执行成功后刷新的组件 + p.Reload = "table" + + // 设置展示位置 + p.SetOnlyOnIndexTableAlert(true) + + // 当行为在表格行展示时,支持js表达式 + p.WithConfirm("确定要启用吗?", "启用后数据将正常使用!", "modal") + + return p +} + +/** + * 行为接口接收的参数,当行为在表格行展示的时候,可以配置当前行的任意字段 + * + * @return array + */ +func (p *Enable) GetApiParams() []string { + return []string{ + "id", + } +} + +// 执行行为句柄 +func (p *Enable) Handle(request *builder.Request, model *gorm.DB) interface{} { + err := model.Update("status", 1).Error + if err != nil { + return msg.Error(err.Error(), "") + } + + return msg.Success("操作成功", "", "") +} diff --git a/pkg/app/handler/admin/actions/form_back.go b/pkg/app/handler/admin/actions/form_back.go new file mode 100644 index 0000000..fb4a6eb --- /dev/null +++ b/pkg/app/handler/admin/actions/form_back.go @@ -0,0 +1,29 @@ +package actions + +import ( + "github.com/quarkcms/quark-go/pkg/builder/actions" +) + +type FormBack struct { + actions.Action +} + +// 初始化 +func (p *FormBack) Init() *FormBack { + // 初始化父结构 + p.ParentInit() + + // 类型 + p.Type = "default" + + // 文字 + p.Name = "返回上一页" + + // 行为类型 + p.ActionType = "back" + + // 设置展示位置 + p.SetShowOnForm().SetShowOnDetail() + + return p +} diff --git a/pkg/app/handler/admin/actions/form_extra_back.go b/pkg/app/handler/admin/actions/form_extra_back.go new file mode 100644 index 0000000..4b7062e --- /dev/null +++ b/pkg/app/handler/admin/actions/form_extra_back.go @@ -0,0 +1,29 @@ +package actions + +import ( + "github.com/quarkcms/quark-go/pkg/builder/actions" +) + +type FormExtraBack struct { + actions.Action +} + +// 初始化 +func (p *FormExtraBack) Init() *FormExtraBack { + // 初始化父结构 + p.ParentInit() + + // 类型 + p.Type = "link" + + // 文字 + p.Name = "返回上一页" + + // 行为类型 + p.ActionType = "back" + + // 设置展示位置 + p.SetShowOnFormExtra().SetShowOnDetailExtra() + + return p +} diff --git a/pkg/app/handler/admin/actions/form_reset.go b/pkg/app/handler/admin/actions/form_reset.go new file mode 100644 index 0000000..424f30c --- /dev/null +++ b/pkg/app/handler/admin/actions/form_reset.go @@ -0,0 +1,29 @@ +package actions + +import ( + "github.com/quarkcms/quark-go/pkg/builder/actions" +) + +type FormReset struct { + actions.Action +} + +// 初始化 +func (p *FormReset) Init() *FormReset { + // 初始化父结构 + p.ParentInit() + + // 类型 + p.Type = "default" + + // 文字 + p.Name = "重置" + + // 行为类型 + p.ActionType = "reset" + + // 设置展示位置 + p.SetShowOnForm() + + return p +} diff --git a/pkg/app/handler/admin/actions/form_submit.go b/pkg/app/handler/admin/actions/form_submit.go new file mode 100644 index 0000000..a490351 --- /dev/null +++ b/pkg/app/handler/admin/actions/form_submit.go @@ -0,0 +1,32 @@ +package actions + +import ( + "github.com/quarkcms/quark-go/pkg/builder/actions" +) + +type FormSubmit struct { + actions.Action +} + +// 初始化 +func (p *FormSubmit) Init() *FormSubmit { + // 初始化父结构 + p.ParentInit() + + // 类型 + p.Type = "primary" + + // 文字 + p.Name = "提交" + + // 行为类型 + p.ActionType = "submit" + + // 是否具有loading,当action 的作用类型为ajax,submit时有效 + p.WithLoading = true + + // 设置展示位置 + p.SetOnlyOnForm(true) + + return p +} diff --git a/pkg/app/handler/admin/actions/import.go b/pkg/app/handler/admin/actions/import.go new file mode 100644 index 0000000..8d45cce --- /dev/null +++ b/pkg/app/handler/admin/actions/import.go @@ -0,0 +1,90 @@ +package actions + +import ( + "github.com/quarkcms/quark-go/pkg/builder" + "github.com/quarkcms/quark-go/pkg/builder/actions" + "github.com/quarkcms/quark-go/pkg/component/admin/action" + "github.com/quarkcms/quark-go/pkg/component/admin/form" + "github.com/quarkcms/quark-go/pkg/component/admin/space" + "github.com/quarkcms/quark-go/pkg/component/admin/tpl" +) + +type Import struct { + actions.Modal +} + +// 初始化 +func (p *Import) Init() *Import { + // 初始化父结构 + p.ParentInit() + + // 文字 + p.Name = "导入数据" + + // 设置展示位置 + p.SetOnlyOnIndex(true) + + return p +} + +// 内容 +func (p *Import) GetBody(request *builder.Request, resourceInstance interface{}) interface{} { + api := "admin/" + request.Param("resource") + "/import" + getTpl := (&tpl.Component{}). + Init(). + SetBody("模板文件: 下载模板"). + SetStyle(map[string]interface{}{ + "marginLeft": "50px", + }) + + fields := []interface{}{ + (&space.Component{}). + Init(). + SetBody(getTpl). + SetDirection("vertical"). + SetSize("middle"). + SetStyle(map[string]interface{}{ + "marginBottom": "20px", + }), + (&builder.AdminField{}). + File("fileId", "导入文件"). + SetLimitNum(1). + SetLimitType([]string{ + "application/vnd.ms-excel", + "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", + }). + SetHelp("请上传xls格式的文件"), + } + + return (&form.Component{}). + Init(). + SetKey("importModalForm", false). + SetApi(api). + SetBody(fields). + SetLabelCol(map[string]interface{}{ + "span": 6, + }). + SetWrapperCol(map[string]interface{}{ + "span": 18, + }) +} + +// 弹窗行为 +func (p *Import) GetActions(request *builder.Request, resourceInstance interface{}) []interface{} { + + return []interface{}{ + (&action.Component{}). + Init(). + SetLabel("取消"). + SetActionType("cancel"), + + (&action.Component{}). + Init(). + SetLabel("提交"). + SetWithLoading(true). + SetReload("table"). + SetActionType("submit"). + SetType("primary", false). + SetSubmitForm("importModalForm"), + } +} diff --git a/pkg/app/handler/admin/actions/more_actions.go b/pkg/app/handler/admin/actions/more_actions.go new file mode 100644 index 0000000..dd1228e --- /dev/null +++ b/pkg/app/handler/admin/actions/more_actions.go @@ -0,0 +1,44 @@ +package actions + +import ( + "github.com/quarkcms/quark-go/pkg/builder/actions" +) + +type MoreActions struct { + actions.Dropdown +} + +// 初始化 +func (p *MoreActions) Init(name string) *MoreActions { + + // 初始化父结构 + p.ParentInit() + + // 下拉框箭头是否显示 + p.Arrow = true + + // 菜单弹出位置:bottomLeft bottomCenter bottomRight topLeft topCenter topRight + p.Placement = "bottomLeft" + + // 触发下拉的行为, 移动端不支持 hover,Array + p.Trigger = []string{"hover"} + + // 下拉根元素的样式 + p.OverlayStyle = map[string]interface{}{ + "zIndex": 999, + } + + // 设置按钮类型,primary | ghost | dashed | link | text | default + p.Type = "link" + + // 设置按钮大小,large | middle | small | default + p.Size = "small" + + // 文字 + p.Name = name + + // 设置展示位置 + p.SetOnlyOnIndexTableRow(true) + + return p +} diff --git a/pkg/app/handler/admin/actions/select_options.go b/pkg/app/handler/admin/actions/select_options.go new file mode 100644 index 0000000..f471529 --- /dev/null +++ b/pkg/app/handler/admin/actions/select_options.go @@ -0,0 +1,35 @@ +package actions + +import ( + "github.com/quarkcms/quark-go/pkg/builder" + "github.com/quarkcms/quark-go/pkg/builder/actions" + "github.com/quarkcms/quark-go/pkg/msg" + "gorm.io/gorm" +) + +type SelectOptions struct { + actions.Action +} + +// 执行行为句柄 +func (p *SelectOptions) Handle(request *builder.Request, model *gorm.DB) interface{} { + resource := request.Param("resource") + search := request.Query("search") + lists := []map[string]interface{}{} + results := []map[string]interface{}{} + + switch resource { + case "Some Field": + model.Where("Some Field = ?", search).Find(&lists) + for _, v := range lists { + item := map[string]interface{}{ + "label": v["name"], + "value": v["id"], + } + + results = append(results, item) + } + } + + return msg.Success("操作成功", "", results) +} diff --git a/pkg/app/handler/admin/actions/sync_permission.go b/pkg/app/handler/admin/actions/sync_permission.go new file mode 100644 index 0000000..79aafd4 --- /dev/null +++ b/pkg/app/handler/admin/actions/sync_permission.go @@ -0,0 +1,78 @@ +package actions + +import ( + models "github.com/quarkcms/quark-go/pkg/app/model" + "github.com/quarkcms/quark-go/pkg/builder" + "github.com/quarkcms/quark-go/pkg/builder/actions" + "github.com/quarkcms/quark-go/pkg/dal/db" + "github.com/quarkcms/quark-go/pkg/msg" + "gorm.io/gorm" +) + +type SyncPermission struct { + actions.Action +} + +// 初始化 +func (p *SyncPermission) Init() *SyncPermission { + // 初始化父结构 + p.ParentInit() + + // 行为名称 + p.Name = "同步权限" + + // 执行成功后刷新的组件 + p.Reload = "table" + + // 是否具有loading,当action 的作用类型为ajax,submit时有效 + p.WithLoading = true + + // 设置展示位置 + p.SetOnlyOnIndex(true) + + // 行为类型 + p.ActionType = "ajax" + + return p +} + +// 执行行为句柄 +func (p *SyncPermission) Handle(request *builder.Request, model *gorm.DB) interface{} { + // 获取当前权限 + permissions := builder.GetRoutes() + data := []models.Permission{} + + var names []string + db.Client.Model(&models.Permission{}).Pluck("name", &names) + for _, v := range permissions { + has := false + for _, nv := range names { + if nv == v { + has = true + } + } + if has == false { + permission := models.Permission{ + MenuId: 0, + Name: v, + GuardName: "admin", + } + data = append(data, permission) + } + } + if len(data) == 0 { + return msg.Error("暂无新增权限!", "") + } + + err := model.Create(data).Error + if err != nil { + return msg.Error(err.Error(), "") + } + + err = db.Client.Model(&models.Permission{}).Where("name NOT IN ?", permissions).Delete("").Error + if err != nil { + return msg.Error(err.Error(), "") + } + + return msg.Success("操作成功", "", "") +} diff --git a/pkg/app/handler/admin/dashboards/index.go b/pkg/app/handler/admin/dashboards/index.go new file mode 100644 index 0000000..7460c45 --- /dev/null +++ b/pkg/app/handler/admin/dashboards/index.go @@ -0,0 +1,35 @@ +package dashboards + +import ( + "github.com/quarkcms/quark-go/pkg/app/handler/admin/metrics" + "github.com/quarkcms/quark-go/pkg/builder" + "github.com/quarkcms/quark-go/pkg/builder/template/admindashboard" +) + +type Index struct { + admindashboard.Template +} + +// 初始化 +func (p *Index) Init() interface{} { + + // 初始化模板 + p.TemplateInit() + + p.Title = "仪表盘" + + return p +} + +// 内容 +func (p *Index) Cards(request *builder.Request) interface{} { + + return []any{ + &metrics.TotalAdmin{}, + &metrics.TotalLog{}, + &metrics.TotalPicture{}, + &metrics.TotalFile{}, + &metrics.SystemInfo{}, + &metrics.TeamInfo{}, + } +} diff --git a/pkg/app/handler/admin/login/index.go b/pkg/app/handler/admin/login/index.go new file mode 100644 index 0000000..48f665c --- /dev/null +++ b/pkg/app/handler/admin/login/index.go @@ -0,0 +1,108 @@ +package login + +import ( + "bytes" + + "github.com/dchest/captcha" + "github.com/golang-jwt/jwt/v4" + "github.com/quarkcms/quark-go/pkg/app/model" + "github.com/quarkcms/quark-go/pkg/builder" + "github.com/quarkcms/quark-go/pkg/builder/template/adminlogin" + "github.com/quarkcms/quark-go/pkg/hash" + "github.com/quarkcms/quark-go/pkg/msg" +) + +type Index struct { + adminlogin.Template +} + +type LoginRequest struct { + Username string `json:"username" form:"username"` + Password string `json:"password" form:"password"` + CaptchaId string `json:"captchaId" form:"captchaId"` + Captcha string `json:"captcha" form:"captcha"` +} + +// 初始化 +func (p *Index) Init() interface{} { + // 初始化模板 + p.TemplateInit() + + // 登录页面Logo + p.Logo = false + + // 登录页面标题 + p.Title = "QuarkGo" + + // 登录页面描述 + p.Description = "信息丰富的世界里,唯一稀缺的就是人类的注意力" + + // 登录后跳转地址 + p.Redirect = "/index?api=/api/admin/dashboard/index/index" + + return p +} + +// 验证码ID +func (p *Index) CaptchaId(request *builder.Request, resource *builder.Resource, templateInstance interface{}) interface{} { + + return msg.Success("获取成功", "", map[string]string{ + "captchaId": captcha.NewLen(4), + }) +} + +// 生成验证码 +func (p *Index) Captcha(request *builder.Request, resource *builder.Resource, templateInstance interface{}) interface{} { + id := request.Param("id") + writer := bytes.Buffer{} + captcha.WriteImage(&writer, id, 110, 38) + + return writer.Bytes() +} + +// 登录方法 +func (p *Index) Handle(request *builder.Request, resource *builder.Resource, templateInstance interface{}) interface{} { + loginRequest := &LoginRequest{} + if err := request.BodyParser(loginRequest); err != nil { + return msg.Error(err.Error(), "") + } + if loginRequest.CaptchaId == "" || loginRequest.Captcha == "" { + return msg.Error("验证码不能为空", "") + } + + verifyResult := captcha.VerifyString(loginRequest.CaptchaId, loginRequest.Captcha) + if !verifyResult { + return msg.Error("验证码错误", "") + } + captcha.Reload(loginRequest.CaptchaId) + + if loginRequest.Username == "" || loginRequest.Password == "" { + return msg.Error("用户名或密码不能为空", "") + } + + adminInfo, err := (&model.Admin{}).GetInfoByUsername(loginRequest.Username) + if err != nil { + return msg.Error(err.Error(), "") + } + + // 检验账号和密码 + if !hash.Check(adminInfo.Password, loginRequest.Password) { + return msg.Error("用户名或密码错误", "") + } + + config := builder.GetConfig() + token := jwt.NewWithClaims(jwt.SigningMethodHS256, (&model.Admin{}).GetClaims(adminInfo)) + + // 获取token字符串 + tokenString, err := token.SignedString([]byte(config.AppKey)) + + return msg.Success("获取成功", "", map[string]string{ + "token": tokenString, + }) +} + +// 退出方法 +func (p *Index) Logout(request *builder.Request, resource *builder.Resource, templateInstance interface{}) interface{} { + + return msg.Success("退出成功", "", "") +} diff --git a/pkg/app/handler/admin/metrics/system_info.go b/pkg/app/handler/admin/metrics/system_info.go new file mode 100644 index 0000000..7ffbe0e --- /dev/null +++ b/pkg/app/handler/admin/metrics/system_info.go @@ -0,0 +1,42 @@ +package metrics + +import ( + "fmt" + "runtime" + "strconv" + "time" + + "github.com/quarkcms/quark-go/pkg/builder/metrics" + "github.com/quarkcms/quark-go/pkg/component/admin/descriptions" + "github.com/shirou/gopsutil/cpu" + "github.com/shirou/gopsutil/mem" +) + +type SystemInfo struct { + metrics.AdminDescriptions +} + +// 初始化 +func (p *SystemInfo) Init() *SystemInfo { + p.Title = "系统信息" + p.Col = 12 + + return p +} + +// 计算数值 +func (p *SystemInfo) Calculate() *descriptions.Component { + + field := &descriptions.Field{} + memory, _ := mem.VirtualMemory() + cpuPercent, _ := cpu.Percent(time.Second, false) + + return p.Init().Result([]interface{}{ + field.Text("系统版本").SetValue("1.0.0"), + field.Text("Fiber版本").SetValue("1.0.0"), + field.Text("Golang版本").SetValue(runtime.Version()), + field.Text("服务器操作系统").SetValue(runtime.GOOS + " " + runtime.GOARCH), + field.Text("内存信息").SetValue(strconv.FormatUint(memory.Total/(1024*1024), 10) + "MB / " + fmt.Sprintf("%.0f", memory.UsedPercent) + "%"), + field.Text("CPU使用率").SetValue(fmt.Sprintf("%.0f", cpuPercent[0]) + "%"), + }) +} diff --git a/pkg/app/handler/admin/metrics/team_info.go b/pkg/app/handler/admin/metrics/team_info.go new file mode 100644 index 0000000..0b37063 --- /dev/null +++ b/pkg/app/handler/admin/metrics/team_info.go @@ -0,0 +1,33 @@ +package metrics + +import ( + "github.com/quarkcms/quark-go/pkg/builder/metrics" + "github.com/quarkcms/quark-go/pkg/component/admin/descriptions" +) + +type TeamInfo struct { + metrics.AdminDescriptions +} + +// 初始化 +func (p *TeamInfo) Init() *TeamInfo { + p.Title = "团队信息" + p.Col = 12 + + return p +} + +// 计算数值 +func (p *TeamInfo) Calculate() *descriptions.Component { + + field := &descriptions.Field{} + + return p.Init().Result([]interface{}{ + field.Text("作者").SetValue("tangtanglove"), + field.Text("联系方式").SetValue("dai_hang_love@126.com"), + field.Text("官方网址").SetValue("www.quarkcms.com"), + field.Text("文档地址").SetValue("查看文档"), + field.Text("BUG反馈").SetValue("提交BUG"), + field.Text("代码仓储").SetValue("Github"), + }) +} diff --git a/pkg/app/handler/admin/metrics/total_admin.go b/pkg/app/handler/admin/metrics/total_admin.go new file mode 100644 index 0000000..2030ae3 --- /dev/null +++ b/pkg/app/handler/admin/metrics/total_admin.go @@ -0,0 +1,29 @@ +package metrics + +import ( + "github.com/quarkcms/quark-go/pkg/app/model" + "github.com/quarkcms/quark-go/pkg/builder/metrics" + "github.com/quarkcms/quark-go/pkg/component/admin/statistic" + "github.com/quarkcms/quark-go/pkg/dal/db" +) + +type TotalAdmin struct { + metrics.AdminValue +} + +// 初始化 +func (p *TotalAdmin) Init() *TotalAdmin { + p.Title = "管理员数量" + p.Col = 6 + + return p +} + +// 计算数值 +func (p *TotalAdmin) Calculate() *statistic.Component { + + return p. + Init(). + Count(db.Client.Model(&model.Admin{})). + SetValueStyle(map[string]string{"color": "#3f8600"}) +} diff --git a/pkg/app/handler/admin/metrics/total_file.go b/pkg/app/handler/admin/metrics/total_file.go new file mode 100644 index 0000000..f3df4d8 --- /dev/null +++ b/pkg/app/handler/admin/metrics/total_file.go @@ -0,0 +1,31 @@ +package metrics + +import ( + "github.com/quarkcms/quark-go/pkg/app/model" + "github.com/quarkcms/quark-go/pkg/builder/metrics" + "github.com/quarkcms/quark-go/pkg/component/admin/statistic" + "github.com/quarkcms/quark-go/pkg/dal/db" +) + +type TotalFile struct { + metrics.AdminValue +} + +// 初始化 + +// 初始化 +func (p *TotalFile) Init() *TotalFile { + p.Title = "文件数量" + p.Col = 6 + + return p +} + +// 计算数值 +func (p *TotalFile) Calculate() *statistic.Component { + + return p. + Init(). + Count(db.Client.Model(&model.File{})). + SetValueStyle(map[string]string{"color": "#cf1322"}) +} diff --git a/pkg/app/handler/admin/metrics/total_log.go b/pkg/app/handler/admin/metrics/total_log.go new file mode 100644 index 0000000..5954284 --- /dev/null +++ b/pkg/app/handler/admin/metrics/total_log.go @@ -0,0 +1,29 @@ +package metrics + +import ( + "github.com/quarkcms/quark-go/pkg/app/model" + "github.com/quarkcms/quark-go/pkg/builder/metrics" + "github.com/quarkcms/quark-go/pkg/component/admin/statistic" + "github.com/quarkcms/quark-go/pkg/dal/db" +) + +type TotalLog struct { + metrics.AdminValue +} + +// 初始化 +func (p *TotalLog) Init() *TotalLog { + p.Title = "日志数量" + p.Col = 6 + + return p +} + +// 计算数值 +func (p *TotalLog) Calculate() *statistic.Component { + + return p. + Init(). + Count(db.Client.Model(&model.ActionLog{})). + SetValueStyle(map[string]string{"color": "#999999"}) +} diff --git a/pkg/app/handler/admin/metrics/total_picture.go b/pkg/app/handler/admin/metrics/total_picture.go new file mode 100644 index 0000000..ef02d52 --- /dev/null +++ b/pkg/app/handler/admin/metrics/total_picture.go @@ -0,0 +1,29 @@ +package metrics + +import ( + "github.com/quarkcms/quark-go/pkg/app/model" + "github.com/quarkcms/quark-go/pkg/builder/metrics" + "github.com/quarkcms/quark-go/pkg/component/admin/statistic" + "github.com/quarkcms/quark-go/pkg/dal/db" +) + +type TotalPicture struct { + metrics.AdminValue +} + +// 初始化 +func (p *TotalPicture) Init() *TotalPicture { + p.Title = "图片数量" + p.Col = 6 + + return p +} + +// 计算数值 +func (p *TotalPicture) Calculate() *statistic.Component { + + return p. + Init(). + Count(db.Client.Model(&model.Picture{})). + SetValueStyle(map[string]string{"color": "#cf1322"}) +} diff --git a/pkg/app/handler/admin/providers.go b/pkg/app/handler/admin/providers.go new file mode 100644 index 0000000..bd65ea9 --- /dev/null +++ b/pkg/app/handler/admin/providers.go @@ -0,0 +1,23 @@ +package admin + +import ( + "github.com/quarkcms/quark-go/pkg/app/handler/admin/dashboards" + "github.com/quarkcms/quark-go/pkg/app/handler/admin/login" + "github.com/quarkcms/quark-go/pkg/app/handler/admin/resources" +) + +// 注册服务 +var Providers = []interface{}{ + &login.Index{}, + &dashboards.Index{}, + &resources.Admin{}, + &resources.Role{}, + &resources.Permission{}, + &resources.Menu{}, + &resources.ActionLog{}, + &resources.Config{}, + &resources.File{}, + &resources.Picture{}, + &resources.WebConfig{}, + &resources.Account{}, +} diff --git a/pkg/app/handler/admin/resources/account.go b/pkg/app/handler/admin/resources/account.go new file mode 100644 index 0000000..b731c4e --- /dev/null +++ b/pkg/app/handler/admin/resources/account.go @@ -0,0 +1,148 @@ +package resources + +import ( + "github.com/quarkcms/quark-go/pkg/app/handler/admin/actions" + "github.com/quarkcms/quark-go/pkg/app/model" + "github.com/quarkcms/quark-go/pkg/builder" + "github.com/quarkcms/quark-go/pkg/builder/template/adminresource" + "github.com/quarkcms/quark-go/pkg/dal/db" +) + +type Account struct { + adminresource.Template +} + +// 初始化 +func (p *Account) Init() interface{} { + + // 初始化模板 + p.TemplateInit() + + // 标题 + p.Title = "个人设置" + + // 模型 + p.Model = &model.Admin{} + + return p +} + +// 表单接口 +func (p *Account) FormApi(request *builder.Request) string { + + return "admin/account/action/change-account" +} + +// 字段 +func (p *Account) Fields(request *builder.Request) []interface{} { + field := &builder.AdminField{} + + return []interface{}{ + + field.Image("avatar", "头像").OnlyOnForms(), + + field.Text("nickname", "昵称"). + SetEditable(true). + SetRules( + []string{ + "required", + }, + map[string]string{ + "required": "昵称必须填写", + }, + ), + + field.Text("email", "邮箱"). + SetRules( + []string{ + "required", + }, + map[string]string{ + "required": "邮箱必须填写", + }, + ). + SetCreationRules( + []string{ + "unique:admins,email", + }, + map[string]string{ + "unique": "邮箱已存在", + }, + ). + SetUpdateRules( + []string{ + "unique:admins,email,{id}", + }, + map[string]string{ + "unique": "邮箱已存在", + }, + ), + + field.Text("phone", "手机号"). + SetRules( + []string{ + "required", + }, + map[string]string{ + "required": "手机号必须填写", + }, + ). + SetCreationRules( + []string{ + "unique:admins,phone", + }, + map[string]string{ + "unique": "手机号已存在", + }, + ). + SetUpdateRules( + []string{ + "unique:admins,phone,{id}", + }, + map[string]string{ + "unique": "手机号已存在", + }, + ), + + field.Radio("sex", "性别"). + SetOptions(map[interface{}]interface{}{ + 1: "男", + 2: "女", + }).SetDefault(1), + + field.Password("password", "密码"). + SetCreationRules( + []string{ + "required", + }, + map[string]string{ + "required": "密码必须填写", + }, + ).OnlyOnForms(), + } +} + +// 行为 +func (p *Account) Actions(request *builder.Request) []interface{} { + return []interface{}{ + (&actions.ChangeAccount{}), + (&actions.FormSubmit{}).Init(), + (&actions.FormReset{}).Init(), + (&actions.FormBack{}).Init(), + (&actions.FormExtraBack{}).Init(), + } +} + +// 创建页面显示前回调 +func (p *Account) BeforeCreating(request *builder.Request) map[string]interface{} { + data := map[string]interface{}{} + adminInfo, _ := (&model.Admin{}).GetAuthUser(request.Token()) + db.Client. + Model(p.Model). + Where("id = ?", adminInfo.Id). + First(&data) + + delete(data, "password") + + return data +} diff --git a/pkg/app/handler/admin/resources/action_log.go b/pkg/app/handler/admin/resources/action_log.go new file mode 100644 index 0000000..ffe9b27 --- /dev/null +++ b/pkg/app/handler/admin/resources/action_log.go @@ -0,0 +1,84 @@ +package resources + +import ( + "time" + + "github.com/quarkcms/quark-go/pkg/app/handler/admin/actions" + "github.com/quarkcms/quark-go/pkg/app/handler/admin/searches" + "github.com/quarkcms/quark-go/pkg/app/model" + "github.com/quarkcms/quark-go/pkg/builder" + "github.com/quarkcms/quark-go/pkg/builder/template/adminresource" + "github.com/quarkcms/quark-go/pkg/component/admin/table" + "gorm.io/gorm" +) + +type ActionLog struct { + adminresource.Template +} + +// 初始化 +func (p *ActionLog) Init() interface{} { + + // 初始化模板 + p.TemplateInit() + + // 标题 + p.Title = "操作日志" + + // 模型 + p.Model = &model.ActionLog{} + + // 分页 + p.PerPage = 10 + + p.WithExport = true + + return p +} + +// 列表查询 +func (p *ActionLog) Query(request *builder.Request, query *gorm.DB) *gorm.DB { + + return query. + Select("action_logs.*,admins.username"). + Joins("left join admins on admins.id = action_logs.object_id"). + Where("type = ?", "admin") +} + +// 字段 +func (p *ActionLog) Fields(request *builder.Request) []interface{} { + field := &builder.AdminField{} + + return []interface{}{ + field.ID("id", "ID"), + field.Text("username", "用户"), + field.Text("url", "行为"). + SetColumn(func(column *table.Column) *table.Column { + return column.SetEllipsis(true) + }), + field.Text("ip", "IP"), + field.Datetime("created_at", "发生时间", func() interface{} { + if p.Field["created_at"] == nil { + return p.Field["created_at"] + } + + return p.Field["created_at"].(time.Time).Format("2006-01-02 15:04:05") + }), + } +} + +// 搜索 +func (p *ActionLog) Searches(request *builder.Request) []interface{} { + return []interface{}{ + (&searches.Input{}).Init("url", "行为"), + (&searches.Input{}).Init("ip", "IP"), + } +} + +// 行为 +func (p *ActionLog) Actions(request *builder.Request) []interface{} { + return []interface{}{ + (&actions.Delete{}).Init("批量删除"), + (&actions.Delete{}).Init("删除"), + } +} diff --git a/pkg/app/handler/admin/resources/admin.go b/pkg/app/handler/admin/resources/admin.go new file mode 100644 index 0000000..9f178cd --- /dev/null +++ b/pkg/app/handler/admin/resources/admin.go @@ -0,0 +1,312 @@ +package resources + +import ( + "encoding/json" + "strconv" + "strings" + "time" + + "github.com/quarkcms/quark-go/pkg/app/handler/admin/actions" + "github.com/quarkcms/quark-go/pkg/app/handler/admin/searches" + "github.com/quarkcms/quark-go/pkg/app/model" + models "github.com/quarkcms/quark-go/pkg/app/model" + "github.com/quarkcms/quark-go/pkg/builder" + "github.com/quarkcms/quark-go/pkg/builder/template/adminresource" + "github.com/quarkcms/quark-go/pkg/component/admin/table" + "github.com/quarkcms/quark-go/pkg/dal/db" + "github.com/quarkcms/quark-go/pkg/hash" + "github.com/quarkcms/quark-go/pkg/msg" + "gorm.io/gorm" +) + +type Admin struct { + adminresource.Template +} + +// 初始化 +func (p *Admin) Init() interface{} { + + // 初始化模板 + p.TemplateInit() + + // 标题 + p.Title = "管理员" + + // 模型 + p.Model = &model.Admin{} + + // 分页 + p.PerPage = 10 + + p.WithExport = true + + return p +} + +// 字段 +func (p *Admin) Fields(request *builder.Request) []interface{} { + + field := &builder.AdminField{} + + // 角色列表 + roles, _ := (&model.Role{}).List() + + return []interface{}{ + field.ID("id", "ID"), + + field.Image("avatar", "头像").OnlyOnForms(), + + field.Text("username", "用户名", func() interface{} { + + return "" + p.Field["username"].(string) + "" + }). + SetRules( + []string{ + "required", + "min:6", + "max:20", + }, + map[string]string{ + "required": "用户名必须填写", + "min": "用户名不能少于6个字符", + "max": "用户名不能超过20个字符", + }, + ). + SetCreationRules( + []string{ + "unique:admins,username", + }, + map[string]string{ + "unique": "用户名已存在", + }, + ). + SetUpdateRules( + []string{ + "unique:admins,username,{id}", + }, + map[string]string{ + "unique": "用户名已存在", + }, + ), + + field.Checkbox("role_ids", "角色"). + SetOptions(roles). + OnlyOnForms(), + + field.Text("nickname", "昵称"). + SetEditable(true). + SetRules( + []string{ + "required", + }, + map[string]string{ + "required": "昵称必须填写", + }, + ), + + field.Text("email", "邮箱"). + SetRules( + []string{ + "required", + }, + map[string]string{ + "required": "邮箱必须填写", + }, + ). + SetCreationRules( + []string{ + "unique:admins,email", + }, + map[string]string{ + "unique": "邮箱已存在", + }, + ). + SetUpdateRules( + []string{ + "unique:admins,email,{id}", + }, + map[string]string{ + "unique": "邮箱已存在", + }, + ), + + field.Text("phone", "手机号"). + SetRules( + []string{ + "required", + }, + map[string]string{ + "required": "手机号必须填写", + }, + ). + SetCreationRules( + []string{ + "unique:admins,phone", + }, + map[string]string{ + "unique": "手机号已存在", + }, + ). + SetUpdateRules( + []string{ + "unique:admins,phone,{id}", + }, + map[string]string{ + "unique": "手机号已存在", + }, + ), + + field.Radio("sex", "性别"). + SetOptions(map[interface{}]interface{}{ + 1: "男", + 2: "女", + }).SetDefault(1). + SetColumn(func(column *table.Column) *table.Column { + return column.SetFilters(true) + }), + + field.Password("password", "密码"). + SetCreationRules( + []string{ + "required", + }, + map[string]string{ + "required": "密码必须填写", + }, + ).OnlyOnForms(), + + field.Datetime("last_login_time", "最后登录时间", func() interface{} { + if p.Field["last_login_time"] == nil { + return p.Field["last_login_time"] + } + + return p.Field["last_login_time"].(time.Time).Format("2006-01-02 15:04:05") + }).OnlyOnIndex(), + + field.Switch("status", "状态"). + SetTrueValue("正常"). + SetFalseValue("禁用"). + SetEditable(true). + SetDefault(true), + } +} + +// 搜索 +func (p *Admin) Searches(request *builder.Request) []interface{} { + + return []interface{}{ + (&searches.Input{}).Init("username", "用户名"), + (&searches.Input{}).Init("nickname", "昵称"), + (&searches.Status{}).Init(), + (&searches.DateTimeRange{}).Init("last_login_time", "登录时间"), + } +} + +// 行为 +func (p *Admin) Actions(request *builder.Request) []interface{} { + + return []interface{}{ + (&actions.Import{}).Init(), + (&actions.CreateLink{}).Init(p.Title), + (&actions.Delete{}).Init("批量删除"), + (&actions.Disable{}).Init("批量禁用"), + (&actions.Enable{}).Init("批量启用"), + (&actions.DetailLink{}).Init("详情"), + (&actions.MoreActions{}).Init("更多").SetActions([]interface{}{ + (&actions.EditLink{}).Init("编辑"), + (&actions.Delete{}).Init("删除"), + }), + (&actions.FormSubmit{}).Init(), + (&actions.FormReset{}).Init(), + (&actions.FormBack{}).Init(), + (&actions.FormExtraBack{}).Init(), + } +} + +// 编辑页面显示前回调 +func (p *Admin) BeforeEditing(request *builder.Request, data map[string]interface{}) map[string]interface{} { + delete(data, "password") + + roleIds := []int{} + db.Client. + Model(&model.ModelHasRole{}). + Where("model_id = ?", data["id"]). + Where("model_type = ?", "admin"). + Pluck("role_id", &roleIds) + + data["role_ids"] = roleIds + + return data +} + +// 保存数据前回调 +func (p *Admin) BeforeSaving(request *builder.Request, submitData map[string]interface{}) (map[string]interface{}, error) { + + // 加密密码 + if submitData["password"] != nil { + submitData["password"] = hash.Make(submitData["password"].(string)) + } + + // 暂时清理role_ids + delete(submitData, "role_ids") + + return submitData, nil +} + +// 保存后回调 +func (p *Admin) AfterSaved(request *builder.Request, model *gorm.DB) interface{} { + data := map[string]interface{}{} + json.Unmarshal(request.Body(), &data) + if data["role_ids"] == nil { + if model.Error != nil { + return msg.Error(model.Error.Error(), "") + } + + return msg.Success("操作成功!", strings.Replace("/index?api="+adminresource.IndexRoute, ":resource", request.Param("resource"), -1), "") + } + + var result *gorm.DB + if request.IsCreating() { + last := map[string]interface{}{} + model.Order("id desc").First(&last) // hack + roleData := []map[string]interface{}{} + for _, v := range data["role_ids"].([]interface{}) { + item := map[string]interface{}{ + "role_id": v, + "model_type": "admin", + "model_id": last["id"], + } + roleData = append(roleData, item) + } + if len(roleData) > 0 { + // 同步角色 + result = db.Client.Model(&models.ModelHasRole{}).Create(roleData) + } + } else { + + // 同步角色 + id := data["id"].(float64) + roleData := []map[string]interface{}{} + + // 先清空用户对应的角色 + db.Client.Model(&models.ModelHasRole{}).Where("model_id = ?", id).Where("model_type = ?", "admin").Delete("") + for _, v := range data["role_ids"].([]interface{}) { + item := map[string]interface{}{ + "role_id": v, + "model_type": "admin", + "model_id": int(id), + } + roleData = append(roleData, item) + } + if len(roleData) > 0 { + // 同步角色 + result = db.Client.Model(&models.ModelHasRole{}).Create(roleData) + } + } + + if result.Error != nil { + return msg.Error(result.Error.Error(), "") + } + + return msg.Success("操作成功!", strings.Replace("/index?api="+adminresource.IndexRoute, ":resource", request.Param("resource"), -1), "") +} diff --git a/pkg/app/handler/admin/resources/config.go b/pkg/app/handler/admin/resources/config.go new file mode 100644 index 0000000..9154acd --- /dev/null +++ b/pkg/app/handler/admin/resources/config.go @@ -0,0 +1,139 @@ +package resources + +import ( + "github.com/quarkcms/quark-go/pkg/app/handler/admin/actions" + "github.com/quarkcms/quark-go/pkg/app/handler/admin/searches" + "github.com/quarkcms/quark-go/pkg/app/model" + "github.com/quarkcms/quark-go/pkg/builder" + "github.com/quarkcms/quark-go/pkg/builder/template/adminresource" +) + +type Config struct { + adminresource.Template +} + +// 初始化 +func (p *Config) Init() interface{} { + + // 初始化模板 + p.TemplateInit() + + // 标题 + p.Title = "配置" + + // 模型 + p.Model = &model.Config{} + + // 分页 + p.PerPage = 10 + + return p +} + +// 字段 +func (p *Config) Fields(request *builder.Request) []interface{} { + field := &builder.AdminField{} + + return []interface{}{ + field.ID("id", "ID"), + + field.Text("title", "标题"). + SetRules( + []string{ + "required", + }, + map[string]string{ + "required": "标题必须填写", + }, + ), + + field.Text("name", "名称"). + SetEditable(true). + SetRules( + []string{ + "required", + }, + map[string]string{ + "required": "名称必须填写", + }, + ). + SetCreationRules( + []string{ + "unique:configs,name", + }, + map[string]string{ + "unique": "名称已存在", + }, + ). + SetUpdateRules( + []string{ + "unique:configs,name,{id}", + }, + map[string]string{ + "unique": "名称已存在", + }, + ), + + field.Radio("type", "表单类型"). + SetOptions(map[interface{}]interface{}{ + "text": "输入框", + "textarea": "文本域", + "picture": "图片", + "file": "文件", + "switch": "开关", + }). + SetDefault("text"). + OnlyOnForms(), + + field.Text("sort", "排序"). + SetEditable(true). + SetDefault(0). + SetHelp("值越小越靠前"). + OnlyOnForms(), + + field.Text("group_name", "分组名称"). + SetRules( + []string{ + "required", + }, + map[string]string{ + "required": "分组名称必须填写", + }, + ).OnlyOnForms(), + + field.Text("remark", "备注"). + OnlyOnForms(), + + field.Switch("status", "状态"). + SetTrueValue("正常"). + SetFalseValue("禁用"). + SetEditable(true). + SetDefault(true), + } +} + +// 搜索 +func (p *Config) Searches(request *builder.Request) []interface{} { + return []interface{}{ + (&searches.Input{}).Init("title", "标题"), + (&searches.Input{}).Init("name", "名称"), + (&searches.Status{}).Init(), + } +} + +// 行为 +func (p *Config) Actions(request *builder.Request) []interface{} { + return []interface{}{ + (&actions.CreateDrawer{}).Init(p.Title), + (&actions.Delete{}).Init("批量删除"), + (&actions.Disable{}).Init("批量禁用"), + (&actions.Enable{}).Init("批量启用"), + (&actions.ChangeStatus{}).Init(), + (&actions.EditDrawer{}).Init("编辑"), + (&actions.Delete{}).Init("删除"), + (&actions.FormSubmit{}).Init(), + (&actions.FormReset{}).Init(), + (&actions.FormBack{}).Init(), + (&actions.FormExtraBack{}).Init(), + } +} diff --git a/pkg/app/handler/admin/resources/file.go b/pkg/app/handler/admin/resources/file.go new file mode 100644 index 0000000..9c2a062 --- /dev/null +++ b/pkg/app/handler/admin/resources/file.go @@ -0,0 +1,72 @@ +package resources + +import ( + "time" + + "github.com/quarkcms/quark-go/pkg/app/handler/admin/actions" + "github.com/quarkcms/quark-go/pkg/app/handler/admin/searches" + "github.com/quarkcms/quark-go/pkg/app/model" + "github.com/quarkcms/quark-go/pkg/builder" + "github.com/quarkcms/quark-go/pkg/builder/template/adminresource" + "github.com/quarkcms/quark-go/pkg/component/admin/table" +) + +type File struct { + adminresource.Template +} + +// 初始化 +func (p *File) Init() interface{} { + + // 初始化模板 + p.TemplateInit() + + // 标题 + p.Title = "文件" + + // 模型 + p.Model = &model.File{} + + // 分页 + p.PerPage = 10 + + return p +} + +// 字段 +func (p *File) Fields(request *builder.Request) []interface{} { + field := &builder.AdminField{} + + return []interface{}{ + field.ID("id", "ID"), + field.Text("name", "名称"), + field.Text("size", "大小"). + SetColumn(func(column *table.Column) *table.Column { + return column.SetSorter(true) + }), + field.Text("ext", "扩展名"), + field.Datetime("created_at", "上传时间", func() interface{} { + if p.Field["created_at"] == nil { + return p.Field["created_at"] + } + + return p.Field["created_at"].(time.Time).Format("2006-01-02 15:04:05") + }), + } +} + +// 搜索 +func (p *File) Searches(request *builder.Request) []interface{} { + return []interface{}{ + (&searches.Input{}).Init("name", "名称"), + (&searches.DateTimeRange{}).Init("created_at", "上传时间"), + } +} + +// 行为 +func (p *File) Actions(request *builder.Request) []interface{} { + return []interface{}{ + (&actions.Delete{}).Init("批量删除"), + (&actions.Delete{}).Init("删除"), + } +} diff --git a/pkg/app/handler/admin/resources/menu.go b/pkg/app/handler/admin/resources/menu.go new file mode 100644 index 0000000..7b55a47 --- /dev/null +++ b/pkg/app/handler/admin/resources/menu.go @@ -0,0 +1,207 @@ +package resources + +import ( + "encoding/json" + "strings" + + "github.com/quarkcms/quark-go/pkg/app/handler/admin/actions" + "github.com/quarkcms/quark-go/pkg/app/handler/admin/searches" + models "github.com/quarkcms/quark-go/pkg/app/model" + "github.com/quarkcms/quark-go/pkg/builder" + "github.com/quarkcms/quark-go/pkg/builder/template/adminresource" + "github.com/quarkcms/quark-go/pkg/dal/db" + "github.com/quarkcms/quark-go/pkg/lister" + "github.com/quarkcms/quark-go/pkg/msg" + "gorm.io/gorm" +) + +type Menu struct { + adminresource.Template +} + +// 初始化 +func (p *Menu) Init() interface{} { + + // 初始化模板 + p.TemplateInit() + + // 标题 + p.Title = "菜单" + + // 模型 + p.Model = &models.Menu{} + + // 分页 + p.PerPage = false + + // 默认排序 + p.IndexOrder = "sort asc" + + return p +} + +// 字段 +func (p *Menu) Fields(request *builder.Request) []interface{} { + field := &builder.AdminField{} + + // 权限列表 + permissions, _ := (&models.Permission{}).List() + + // 菜单列表 + menus, _ := (&models.Menu{}).OrderedList() + + return []interface{}{ + field.Hidden("id", "ID"), // 列表读取且不展示的字段 + + field.Hidden("pid", "PID").OnlyOnIndex(), // 列表读取且不展示的字段 + + field.Text("name", "名称"). + SetRules( + []string{ + "required", + }, + map[string]string{ + "required": "名称必须填写", + }, + ), + + field.Text("guard_name", "GuardName"). + SetDefault("admin"). + OnlyOnForms(), + + field.Icon("icon", "图标").OnlyOnForms(), + + field.Radio("type", "渲染组件"). + SetOptions(map[interface{}]interface{}{ + "default": "无组件", + "engine": "引擎组件", + }).SetDefault("engine"), + + field.Text("path", "路由"). + SetEditable(true). + SetHelp("前端路由或后端api"), + + field.Select("pid", "父节点"). + SetOptions(menus). + SetDefault(0). + OnlyOnForms(), + + field.Number("sort", "排序"). + SetEditable(true). + SetDefault(0), + + field.Select("permission_ids", "绑定权限"). + SetMode("tags"). + SetOptions(permissions). + OnlyOnForms(), + + field.Switch("status", "状态"). + SetTrueValue("正常"). + SetFalseValue("禁用"). + SetEditable(true). + SetDefault(true), + } +} + +// 搜索 +func (p *Menu) Searches(request *builder.Request) []interface{} { + return []interface{}{ + (&searches.Input{}).Init("name", "名称"), + (&searches.Input{}).Init("path", "路由"), + (&searches.Status{}).Init(), + } +} + +// 行为 +func (p *Menu) Actions(request *builder.Request) []interface{} { + return []interface{}{ + (&actions.CreateDrawer{}).Init(p.Title), + (&actions.Delete{}).Init("批量删除"), + (&actions.Disable{}).Init("批量禁用"), + (&actions.Enable{}).Init("批量启用"), + (&actions.ChangeStatus{}).Init(), + (&actions.EditDrawer{}).Init("编辑"), + (&actions.Delete{}).Init("删除"), + (&actions.FormSubmit{}).Init(), + (&actions.FormReset{}).Init(), + (&actions.FormBack{}).Init(), + (&actions.FormExtraBack{}).Init(), + } +} + +// 列表页面显示前回调 +func (p *Menu) BeforeIndexShowing(request *builder.Request, list []map[string]interface{}) []interface{} { + data := request.AllQuerys() + if search, ok := data["search"].(map[string]interface{}); ok == true && search != nil { + result := []interface{}{} + for _, v := range list { + result = append(result, v) + } + + return result + } + + // 转换成树形表格 + tree, _ := lister.ListToTree(list, "id", "pid", "children", 0) + + return tree +} + +// 编辑页面显示前回调 +func (p *Menu) BeforeEditing(request *builder.Request, data map[string]interface{}) map[string]interface{} { + id := request.Query("id", "") + + if id != "" { + menus := []int{} + + db.Client. + Model(&models.Permission{}). + Where("menu_id = ?", id). + Pluck("id", &menus) + + data["permission_ids"] = menus + } + + return data +} + +// 保存数据前回调 +func (p *Menu) BeforeSaving(request *builder.Request, submitData map[string]interface{}) interface{} { + + // 暂时清理permission_ids + delete(submitData, "permission_ids") + + return submitData +} + +// 保存后回调 +func (p *Menu) AfterSaved(request *builder.Request, model *gorm.DB) interface{} { + var result *gorm.DB + data := map[string]interface{}{} + json.Unmarshal(request.Body(), &data) + id := 0 + if request.IsCreating() { + last := map[string]interface{}{} + result = model.Order("id desc").First(&last) // 获取最后一条记录的id + id = last["id"].(int) + } else { + id = int(data["id"].(float64)) + result = db.Client. + Model(&models.Permission{}). + Where("menu_id = ?", id). + Update("menu_id", 0) + } + + if data["permission_ids"] != nil { + result = db.Client. + Model(&models.Permission{}). + Where("id In ?", data["permission_ids"]). + Update("menu_id", id) + } + + if result.Error != nil { + return msg.Error(result.Error.Error(), "") + } + + return msg.Success("操作成功!", strings.Replace("/index?api="+adminresource.IndexRoute, ":resource", request.Param("resource"), -1), "") +} diff --git a/pkg/app/handler/admin/resources/permission.go b/pkg/app/handler/admin/resources/permission.go new file mode 100644 index 0000000..ff729b9 --- /dev/null +++ b/pkg/app/handler/admin/resources/permission.go @@ -0,0 +1,90 @@ +package resources + +import ( + "time" + + "github.com/quarkcms/quark-go/pkg/app/handler/admin/actions" + "github.com/quarkcms/quark-go/pkg/app/handler/admin/searches" + "github.com/quarkcms/quark-go/pkg/app/model" + "github.com/quarkcms/quark-go/pkg/builder" + "github.com/quarkcms/quark-go/pkg/builder/template/adminresource" +) + +type Permission struct { + adminresource.Template +} + +// 初始化 +func (p *Permission) Init() interface{} { + + // 初始化模板 + p.TemplateInit() + + // 标题 + p.Title = "权限" + + // 模型 + p.Model = &model.Permission{} + + // 分页 + p.PerPage = 10 + + return p +} + +// 字段 +func (p *Permission) Fields(request *builder.Request) []interface{} { + field := &builder.AdminField{} + + return []interface{}{ + field.ID("id", "ID"), + + field.Text("name", "名称"). + SetRules( + []string{ + "required", + }, + map[string]string{ + "required": "名称必须填写", + }, + ), + + field.Text("guard_name", "GuardName").SetDefault("admin"), + field.Datetime("created_at", "创建时间", func() interface{} { + if p.Field["created_at"] == nil { + return p.Field["created_at"] + } + + return p.Field["created_at"].(time.Time).Format("2006-01-02 15:04:05") + }).OnlyOnIndex(), + field.Datetime("updated_at", "更新时间", func() interface{} { + if p.Field["updated_at"] == nil { + return p.Field["updated_at"] + } + + return p.Field["updated_at"].(time.Time).Format("2006-01-02 15:04:05") + }).OnlyOnIndex(), + } +} + +// 搜索 +func (p *Permission) Searches(request *builder.Request) []interface{} { + return []interface{}{ + (&searches.Input{}).Init("name", "名称"), + } +} + +// 行为 +func (p *Permission) Actions(request *builder.Request) []interface{} { + return []interface{}{ + (&actions.SyncPermission{}).Init(), + (&actions.CreateModal{}).Init(p.Title), + (&actions.Delete{}).Init("批量删除"), + (&actions.EditModal{}).Init("编辑"), + (&actions.Delete{}).Init("删除"), + (&actions.FormSubmit{}).Init(), + (&actions.FormReset{}).Init(), + (&actions.FormBack{}).Init(), + (&actions.FormExtraBack{}).Init(), + } +} diff --git a/pkg/app/handler/admin/resources/picture.go b/pkg/app/handler/admin/resources/picture.go new file mode 100644 index 0000000..a91b240 --- /dev/null +++ b/pkg/app/handler/admin/resources/picture.go @@ -0,0 +1,80 @@ +package resources + +import ( + "time" + + "github.com/quarkcms/quark-go/pkg/app/handler/admin/actions" + "github.com/quarkcms/quark-go/pkg/app/handler/admin/searches" + "github.com/quarkcms/quark-go/pkg/app/model" + "github.com/quarkcms/quark-go/pkg/builder" + "github.com/quarkcms/quark-go/pkg/builder/template/adminresource" + "github.com/quarkcms/quark-go/pkg/component/admin/table" +) + +type Picture struct { + adminresource.Template +} + +// 初始化 +func (p *Picture) Init() interface{} { + + // 初始化模板 + p.TemplateInit() + + // 标题 + p.Title = "图片" + + // 模型 + p.Model = &model.Picture{} + + // 分页 + p.PerPage = 10 + + return p +} + +// 字段 +func (p *Picture) Fields(request *builder.Request) []interface{} { + field := &builder.AdminField{} + + return []interface{}{ + field.ID("id", "ID"), + field.Text("path", "显示", func() interface{} { + + return "" + }), + field.Text("name", "名称").SetColumn(func(column *table.Column) *table.Column { + return column.SetEllipsis(true) + }), + field.Text("size", "大小"). + SetColumn(func(column *table.Column) *table.Column { + return column.SetSorter(true) + }), + field.Text("width", "宽度"), + field.Text("height", "高度"), + field.Text("ext", "扩展名"), + field.Datetime("created_at", "上传时间", func() interface{} { + if p.Field["created_at"] == nil { + return p.Field["created_at"] + } + + return p.Field["created_at"].(time.Time).Format("2006-01-02 15:04:05") + }), + } +} + +// 搜索 +func (p *Picture) Searches(request *builder.Request) []interface{} { + return []interface{}{ + (&searches.Input{}).Init("name", "名称"), + (&searches.DateTimeRange{}).Init("created_at", "上传时间"), + } +} + +// 行为 +func (p *Picture) Actions(request *builder.Request) []interface{} { + return []interface{}{ + (&actions.Delete{}).Init("批量删除"), + (&actions.Delete{}).Init("删除"), + } +} diff --git a/pkg/app/handler/admin/resources/role.go b/pkg/app/handler/admin/resources/role.go new file mode 100644 index 0000000..51534dc --- /dev/null +++ b/pkg/app/handler/admin/resources/role.go @@ -0,0 +1,222 @@ +package resources + +import ( + "encoding/json" + "errors" + "time" + + "github.com/quarkcms/quark-go/pkg/app/handler/admin/actions" + "github.com/quarkcms/quark-go/pkg/app/handler/admin/searches" + models "github.com/quarkcms/quark-go/pkg/app/model" + "github.com/quarkcms/quark-go/pkg/builder" + "github.com/quarkcms/quark-go/pkg/builder/template/adminresource" + "github.com/quarkcms/quark-go/pkg/dal/db" + "gorm.io/gorm" +) + +type Role struct { + adminresource.Template +} + +// 初始化 +func (p *Role) Init() interface{} { + + // 初始化模板 + p.TemplateInit() + + // 标题 + p.Title = "角色" + + // 模型 + p.Model = &models.Role{} + + // 分页 + p.PerPage = 10 + + return p +} + +// 字段 +func (p *Role) Fields(request *builder.Request) []interface{} { + field := &builder.AdminField{} + treeData, _ := (&models.Menu{}).Tree() + + return []interface{}{ + field.ID("id", "ID"), + + field.Text("name", "名称"). + SetRules( + []string{ + "required", + }, + map[string]string{ + "required": "名称必须填写", + }, + ), + + field.Text("guard_name", "GuardName").SetDefault("admin"), + field.Tree("menu_ids", "权限").SetData(treeData).OnlyOnForms(), + field.Datetime("created_at", "创建时间", func() interface{} { + if p.Field["created_at"] == nil { + return p.Field["created_at"] + } + + return p.Field["created_at"].(time.Time).Format("2006-01-02 15:04:05") + }).OnlyOnIndex(), + field.Datetime("updated_at", "更新时间", func() interface{} { + if p.Field["updated_at"] == nil { + return p.Field["updated_at"] + } + + return p.Field["updated_at"].(time.Time).Format("2006-01-02 15:04:05") + }).OnlyOnIndex(), + } +} + +// 搜索 +func (p *Role) Searches(request *builder.Request) []interface{} { + return []interface{}{ + (&searches.Input{}).Init("name", "名称"), + } +} + +// 行为 +func (p *Role) Actions(request *builder.Request) []interface{} { + return []interface{}{ + (&actions.CreateLink{}).Init(p.Title), + (&actions.Delete{}).Init("批量删除"), + (&actions.EditLink{}).Init("编辑"), + (&actions.Delete{}).Init("删除"), + (&actions.FormSubmit{}).Init(), + (&actions.FormReset{}).Init(), + (&actions.FormBack{}).Init(), + (&actions.FormExtraBack{}).Init(), + } +} + +// 编辑页面显示前回调 +func (p *Role) BeforeEditing(request *builder.Request, data map[string]interface{}) map[string]interface{} { + id := request.Query("id", "") + menus := []map[string]interface{}{} + + db.Client.Model(&models.Menu{}).Find(&menus) + + checkedMenus := []int{} + for _, v := range menus { + var permissionIds []int + db.Client. + Model(&models.Permission{}). + Where("menu_id", v["id"]). + Pluck("id", &permissionIds) + + if len(permissionIds) > 0 { + roleHasPermission := map[string]interface{}{} + db.Client. + Model(&models.RoleHasPermission{}). + Where("permission_id IN ?", permissionIds). + Where("role_id", id). + First(&roleHasPermission) + + if len(roleHasPermission) > 0 { + checkedMenus = append(checkedMenus, v["id"].(int)) + } + } + } + + data["menu_ids"] = checkedMenus + + return data +} + +// 保存数据前回调 +func (p *Role) BeforeSaving(request *builder.Request, submitData map[string]interface{}) interface{} { + + // 根据菜单id获取所有权限 + var permissionIds []int + db.Client. + Model(&models.Permission{}). + Where("menu_id IN ?", submitData["menu_ids"]). + Pluck("id", &permissionIds) + + if len(permissionIds) == 0 { + return errors.New("获取的权限为空,请在菜单管理中绑定权限") + } + + delete(submitData, "menu_ids") + + return submitData +} + +// 保存后回调 +func (p *Role) AfterSaved(request *builder.Request, model *gorm.DB) interface{} { + data := map[string]interface{}{} + json.Unmarshal(request.Body(), &data) + + // 根据菜单id获取所有权限 + var permissionIds []int + db.Client. + Model(&models.Permission{}). + Where("menu_id IN ?", data["menu_ids"]). + Pluck("id", &permissionIds) + + if len(permissionIds) == 0 { + return errors.New("获取的权限为空,请先在菜单管理中绑定权限") + } + + var result interface{} + + if request.IsCreating() { + lastRole := map[string]interface{}{} + model.Order("id desc").First(&lastRole) // hack + + // 同步权限 + result = p.syncPermissions(lastRole["id"].(int), permissionIds) + } else { + + // 同步权限 + id := data["id"].(float64) + result = p.syncPermissions(int(id), permissionIds) + } + + return result +} + +// 保存后回调 +func (p *Role) syncPermissions(roleId int, permissionIds []int) *gorm.DB { + permissionIds = p.arrayFilter(permissionIds) + + // 先清空此角色的权限 + db.Client.Model(&models.RoleHasPermission{}).Where("role_id", roleId).Delete("") + + data := []map[string]interface{}{} + for _, v := range permissionIds { + permission := map[string]interface{}{ + "role_id": roleId, + "permission_id": v, + } + data = append(data, permission) + } + + return db.Client.Model(&models.RoleHasPermission{}).Create(data) +} + +// 数组去重 +func (p *Role) arrayFilter(list []int) []int { + var x []int = []int{} + for _, i := range list { + if len(x) == 0 { + x = append(x, i) + } else { + for k, v := range x { + if i == v { + break + } + if k == len(x)-1 { + x = append(x, i) + } + } + } + } + + return x +} diff --git a/pkg/app/handler/admin/resources/web_config.go b/pkg/app/handler/admin/resources/web_config.go new file mode 100644 index 0000000..19595d1 --- /dev/null +++ b/pkg/app/handler/admin/resources/web_config.go @@ -0,0 +1,171 @@ +package resources + +import ( + "encoding/json" + "strings" + + "github.com/quarkcms/quark-go/pkg/app/handler/admin/actions" + models "github.com/quarkcms/quark-go/pkg/app/model" + "github.com/quarkcms/quark-go/pkg/builder" + "github.com/quarkcms/quark-go/pkg/builder/template/adminresource" + "github.com/quarkcms/quark-go/pkg/component/admin/tabs" + "github.com/quarkcms/quark-go/pkg/dal/db" +) + +type WebConfig struct { + adminresource.Template +} + +// 初始化 +func (p *WebConfig) Init() interface{} { + + // 初始化模板 + p.TemplateInit() + + // 标题 + p.Title = "网站配置" + + // 模型 + p.Model = &models.Config{} + + return p +} + +// 表单接口 +func (p *WebConfig) FormApi(request *builder.Request) string { + + return "admin/webConfig/action/change-web-config" +} + +// 字段 +func (p *WebConfig) Fields(request *builder.Request) []interface{} { + field := &builder.AdminField{} + groupNames := []string{} + + db.Client.Model(p.Model).Where("status = ?", 1).Distinct("group_name").Pluck("group_name", &groupNames) + + tabPanes := []interface{}{} + for _, groupName := range groupNames { + configs := []map[string]interface{}{} + db.Client. + Model(p.Model). + Where("status = ?", 1). + Where("group_name = ?", groupName). + Order("sort asc"). + Find(&configs) + + fields := []interface{}{} + + for _, config := range configs { + + remark, ok := config["remark"].(string) + + if ok == false { + remark = "" + } + + switch config["type"] { + case "text": + getField := field. + Text(config["name"], config["title"]).SetExtra(remark) + + fields = append(fields, getField) + + case "textarea": + getField := field. + TextArea(config["name"], config["title"]).SetExtra(remark) + + fields = append(fields, getField) + + case "file": + getField := field. + File(config["name"], config["title"]). + SetButton("上传" + config["title"].(string)). + SetExtra(remark) + + fields = append(fields, getField) + + case "picture": + getField := field. + Image(config["name"], config["title"]). + SetButton("上传" + config["title"].(string)). + SetExtra(remark) + + fields = append(fields, getField) + + case "switch": + getField := field. + Switch(config["name"].(string), config["title"].(string)). + SetTrueValue("正常"). + SetFalseValue("禁用"). + SetExtra(remark) + + fields = append(fields, getField) + } + } + + tabPane := (&tabs.TabPane{}). + Init(). + SetTitle(groupName). + SetBody(fields) + + tabPanes = append(tabPanes, tabPane) + } + + return tabPanes +} + +// 行为 +func (p *WebConfig) Actions(request *builder.Request) []interface{} { + return []interface{}{ + (&actions.ChangeWebConfig{}), + (&actions.FormSubmit{}).Init(), + (&actions.FormReset{}).Init(), + (&actions.FormBack{}).Init(), + (&actions.FormExtraBack{}).Init(), + } +} + +// 创建页面显示前回调 +func (p *WebConfig) BeforeCreating(request *builder.Request) map[string]interface{} { + configs := []map[string]interface{}{} + data := map[string]interface{}{} + + db.Client. + Model(p.Model). + Where("status = ?", 1). + Find(&configs) + + for _, config := range configs { + data[config["name"].(string)] = config["value"] + + if config["type"] == "switch" { + if config["value"] != "0" { + data[config["name"].(string)] = true + } else { + data[config["name"].(string)] = false + } + } + + if config["type"] == "picture" || config["type"] == "file" { + + // json字符串 + if strings.Contains(config["value"].(string), "{") { + var jsonData interface{} + json.Unmarshal([]byte(config["value"].(string)), &jsonData) + + // 如果为map + if mapData, ok := jsonData.(map[string]interface{}); ok { + data[config["name"].(string)] = mapData + } + + // 如果为数组,返回第一个key的path + if arrayData, ok := jsonData.([]map[string]interface{}); ok { + data[config["name"].(string)] = arrayData + } + } + } + } + + return data +} diff --git a/pkg/app/handler/admin/searches/datetime_range.go b/pkg/app/handler/admin/searches/datetime_range.go new file mode 100644 index 0000000..cc5ed48 --- /dev/null +++ b/pkg/app/handler/admin/searches/datetime_range.go @@ -0,0 +1,31 @@ +package searches + +import ( + "github.com/quarkcms/quark-go/pkg/builder" + "github.com/quarkcms/quark-go/pkg/builder/searches" + "gorm.io/gorm" +) + +type DateTimeRange struct { + searches.DatetimeRange +} + +// 初始化 +func (p *DateTimeRange) Init(column string, name string) *DateTimeRange { + p.ParentInit() + p.Column = column + p.Name = name + + return p +} + +// 执行查询 +func (p *DateTimeRange) Apply(request *builder.Request, query *gorm.DB, value interface{}) *gorm.DB { + values, ok := value.(map[string]interface{}) + + if ok == false { + return query + } + + return query.Where(p.Column+" BETWEEN ? AND ?", values["0"], values["1"]) +} diff --git a/pkg/app/handler/admin/searches/input.go b/pkg/app/handler/admin/searches/input.go new file mode 100644 index 0000000..83a09bc --- /dev/null +++ b/pkg/app/handler/admin/searches/input.go @@ -0,0 +1,25 @@ +package searches + +import ( + "github.com/quarkcms/quark-go/pkg/builder" + "github.com/quarkcms/quark-go/pkg/builder/searches" + "gorm.io/gorm" +) + +type Input struct { + searches.Search +} + +// 初始化 +func (p *Input) Init(column string, name string) *Input { + p.ParentInit() + p.Column = column + p.Name = name + + return p +} + +// 执行查询 +func (p *Input) Apply(request *builder.Request, query *gorm.DB, value interface{}) *gorm.DB { + return query.Where(p.Column+" LIKE ?", "%"+value.(string)+"%") +} diff --git a/pkg/app/handler/admin/searches/status.go b/pkg/app/handler/admin/searches/status.go new file mode 100644 index 0000000..f7dfed5 --- /dev/null +++ b/pkg/app/handler/admin/searches/status.go @@ -0,0 +1,41 @@ +package searches + +import ( + "github.com/quarkcms/quark-go/pkg/builder" + "github.com/quarkcms/quark-go/pkg/builder/searches" + "gorm.io/gorm" +) + +type Status struct { + searches.Select +} + +// 初始化 +func (p *Status) Init() *Status { + p.ParentInit() + p.Name = "状态" + + return p +} + +// 执行查询 +func (p *Status) Apply(request *builder.Request, query *gorm.DB, value interface{}) *gorm.DB { + + var status int + + if value.(string) == "on" { + status = 1 + } else { + status = 0 + } + + return query.Where("status = ?", status) +} + +// 属性 +func (p *Status) Options(request *builder.Request) map[interface{}]interface{} { + return map[interface{}]interface{}{ + "on": "正常", + "off": "禁用", + } +} diff --git a/pkg/app/handler/mix/.keep b/pkg/app/handler/mix/.keep new file mode 100644 index 0000000..e69de29 diff --git a/pkg/app/install/install.go b/pkg/app/install/install.go new file mode 100644 index 0000000..d7ad785 --- /dev/null +++ b/pkg/app/install/install.go @@ -0,0 +1,66 @@ +package install + +import ( + "os" + + "github.com/quarkcms/quark-go/pkg/app/model" + "github.com/quarkcms/quark-go/pkg/builder" + "github.com/quarkcms/quark-go/pkg/dal/db" +) + +// 判断路径是否存在 +func PathExist(path string) bool { + _, err := os.Stat(path) //os.Stat获取文件信息 + if err != nil { + if os.IsExist(err) { + return true + } + return false + } + + return true +} + +// 执行安装操作 +func Handle(request *builder.Request) error { + + // 如果锁定文件存在则不执行安装步骤 + if PathExist("install.lock") { + return nil + } + + // 迁移数据 + db.Client.AutoMigrate( + &model.ActionLog{}, + &model.Admin{}, + &model.Config{}, + &model.Menu{}, + &model.File{}, + &model.FileCategory{}, + &model.Picture{}, + &model.PictureCategory{}, + &model.Permission{}, + &model.Role{}, + &model.ModelHasRole{}, + &model.RoleHasPermission{}, + &model.ModelHasPermission{}, + ) + + // 如果超级管理员不存在,初始化数据库数据 + adminInfo, err := (&model.Admin{}).GetInfoById(1) + if err != nil && err.Error() != "record not found" { + panic(err) + } + if adminInfo.Id == 0 { + // 数据填充 + (&model.Admin{}).Seeder() + (&model.Config{}).Seeder() + (&model.Menu{}).Seeder() + } + + // 创建锁定文件 + file, _ := os.Create("install.lock") + file.Close() + + return nil +} diff --git a/pkg/app/middleware/middleware.go b/pkg/app/middleware/middleware.go new file mode 100644 index 0000000..65a88cf --- /dev/null +++ b/pkg/app/middleware/middleware.go @@ -0,0 +1,71 @@ +package middleware + +import ( + "errors" + + "github.com/quarkcms/quark-go/pkg/app/handler/admin/login" + "github.com/quarkcms/quark-go/pkg/app/model" + "github.com/quarkcms/quark-go/pkg/builder" +) + +// 中间件 +func Handle(request *builder.Request) error { + loginIndex := (&login.Index{}).Init() + + // 获取登录模板定义的路由 + loginIndexRoutes := loginIndex.(interface { + GetRoutes() []*builder.Route + }).GetRoutes() + + inLoginRoute := false + for _, v := range loginIndexRoutes { + if v.Path == request.FullPath() { + inLoginRoute = true + } + } + + // 排除登录路由 + if inLoginRoute { + return nil + } + + // 获取登录管理员信息 + adminInfo, err := (&model.Admin{}).GetAuthUser(request.Token()) + if err != nil { + return err + } + + guardName := adminInfo.GuardName + if guardName != "admin" { + return errors.New("401 Unauthozied") + } + + // 管理员id + if adminInfo.Id != 1 { + permissions, err := (&model.Permission{}).GetListByAdminId(adminInfo.Id) + if err != nil { + return errors.New("403 Forbidden") + } + + hasPermission := false + for _, v := range permissions { + if "/"+v.Name == request.Path() { + hasPermission = true + } + } + + if !hasPermission { + return errors.New("403 Forbidden") + } + } + + // 记录操作日志 + (&model.ActionLog{}).InsertGetId(&model.ActionLog{ + ObjectId: adminInfo.Id, + Url: request.Path(), + Ip: request.IP(), + Type: "admin", + }) + + return nil +} diff --git a/pkg/app/model/action_log.go b/pkg/app/model/action_log.go new file mode 100644 index 0000000..3211986 --- /dev/null +++ b/pkg/app/model/action_log.go @@ -0,0 +1,28 @@ +package model + +import ( + "time" + + "github.com/quarkcms/quark-go/pkg/dal/db" +) + +// 字段 +type ActionLog struct { + Id int `json:"id" gorm:"autoIncrement"` + ObjectId int `json:"object_id" gorm:"size:11;not null"` + Username string `json:"username" gorm:"<-:false"` + Url string `json:"url" gorm:"size:500;not null"` + Remark string `json:"remark" gorm:"size:255;not null"` + Ip string `json:"ip" gorm:"size:100;not null"` + Type string `json:"type" gorm:"size:100;not null"` + Status int `json:"status" gorm:"size:1;not null;default:1"` + CreatedAt time.Time `json:"created_at"` + UpdatedAt time.Time `json:"updated_at"` +} + +// 插入数据 +func (model *ActionLog) InsertGetId(data *ActionLog) (id int, Error error) { + err := db.Client.Create(data).Error + + return data.Id, err +} diff --git a/pkg/app/model/admin.go b/pkg/app/model/admin.go new file mode 100644 index 0000000..61c21e5 --- /dev/null +++ b/pkg/app/model/admin.go @@ -0,0 +1,134 @@ +package model + +import ( + "errors" + "time" + + "github.com/golang-jwt/jwt/v4" + "github.com/quarkcms/quark-go/pkg/builder" + "github.com/quarkcms/quark-go/pkg/dal/db" + "github.com/quarkcms/quark-go/pkg/hash" + "gorm.io/gorm" +) + +// 字段 +type Admin struct { + Id int `json:"id" gorm:"autoIncrement"` + Username string `json:"username" gorm:"size:20;index:admins_username_unique,unique;not null"` + Nickname string `json:"nickname" gorm:"size:200;not null"` + Sex int `json:"sex" gorm:"size:4;not null;default:1"` + Email string `json:"email" gorm:"size:50;index:admins_email_unique,unique;not null"` + Phone string `json:"phone" gorm:"size:11;index:admins_phone_unique,unique;not null"` + Password string `json:"password" gorm:"size:255;not null"` + Avatar string `json:"avatar" gorm:"size:1000"` + LastLoginIp string `json:"last_login_ip" gorm:"size:255"` + LastLoginTime time.Time `json:"last_login_time"` + Status int `json:"status" gorm:"size:1;not null;default:1"` + CreatedAt time.Time `json:"created_at"` + UpdatedAt time.Time `json:"updated_at"` + DeletedAt gorm.DeletedAt `json:"deleted_at"` +} + +// 管理员JWT结构体 +type AdminClaims struct { + Id int `json:"id"` + Username string `json:"username"` + Nickname string `json:"nickname"` + Sex int `json:"sex"` + Email string `json:"email"` + Phone string `json:"phone"` + Avatar string `json:"avatar"` + GuardName string `json:"guard_name"` + jwt.RegisteredClaims +} + +// 管理员Seeder +func (model *Admin) Seeder() { + seeders := []Admin{ + {Username: "administrator", Nickname: "超级管理员", Email: "admin@yourweb.com", Phone: "10086", Password: hash.Make("123456"), Sex: 1, Status: 1}, + } + + db.Client.Create(&seeders) +} + +// 获取管理员JWT信息 +func (model *Admin) GetClaims(adminInfo *Admin) (adminClaims *AdminClaims) { + adminClaims = &AdminClaims{ + adminInfo.Id, + adminInfo.Username, + adminInfo.Nickname, + adminInfo.Sex, + adminInfo.Email, + adminInfo.Phone, + adminInfo.Avatar, + "admin", + jwt.RegisteredClaims{ + ExpiresAt: jwt.NewNumericDate(time.Now().Add(24 * time.Hour)), // 过期时间,默认24小时 + IssuedAt: jwt.NewNumericDate(time.Now()), // 颁发时间 + NotBefore: jwt.NewNumericDate(time.Now()), // 不早于时间 + Issuer: "QuarkGo", // 颁发人 + Subject: "Admin Token", // 主题信息 + }, + } + + return adminClaims +} + +// 获取当前认证的用户信息,默认参数为tokenString +func (model *Admin) GetAuthUser(authValue interface{}) (adminClaims *AdminClaims, Error error) { + config := builder.GetConfig() + token, err := jwt.ParseWithClaims(authValue.(string), &AdminClaims{}, func(token *jwt.Token) (interface{}, error) { + return []byte(config.AppKey), nil + }) + if err != nil { + if ve, ok := err.(*jwt.ValidationError); ok { + if ve.Errors&jwt.ValidationErrorMalformed != 0 { + return nil, errors.New("token格式错误") + } else if ve.Errors&jwt.ValidationErrorExpired != 0 { + return nil, errors.New("token已过期") + } else if ve.Errors&jwt.ValidationErrorNotValidYet != 0 { + return nil, errors.New("token未生效") + } else { + return nil, err + } + } + } + + if claims, ok := token.Claims.(*AdminClaims); ok && token.Valid { + return claims, nil + } + + return nil, errors.New("token不可用") +} + +// 通过ID获取管理员信息 +func (model *Admin) GetInfoById(id interface{}) (admin *Admin, Error error) { + err := db.Client.Where("status = ?", 1).Where("id = ?", id).First(&admin).Error + + return admin, err +} + +// 通过用户名获取管理员信息 +func (model *Admin) GetInfoByUsername(username string) (admin *Admin, Error error) { + err := db.Client.Where("status = ?", 1).Where("username = ?", username).First(&admin).Error + + return admin, err +} + +// 通过ID获取管理员拥有的菜单列表 +func (model *Admin) GetMenuListById(id interface{}) (menuList interface{}, Error error) { + + return (&Menu{}).GetListByAdminId(id.(int)) +} + +// 更新最后一次登录数据 +func (model *Admin) UpdateLastLogin(uid int, lastLoginIp string, lastLoginTime time.Time) error { + data := Admin{ + LastLoginIp: lastLoginIp, + LastLoginTime: lastLoginTime, + } + + return db.Client. + Where("id = ?", uid). + Updates(&data).Error +} diff --git a/pkg/app/model/config.go b/pkg/app/model/config.go new file mode 100644 index 0000000..e37c0c3 --- /dev/null +++ b/pkg/app/model/config.go @@ -0,0 +1,66 @@ +package model + +import ( + "time" + + "github.com/quarkcms/quark-go/pkg/dal/db" +) + +// 字段 +type Config struct { + Id int `json:"id" gorm:"autoIncrement"` + Title string `json:"title" gorm:"size:255;not null"` + Type string `json:"type" gorm:"size:20;not null"` + Name string `json:"name" gorm:"size:255;not null"` + Sort int `json:"sort" gorm:"size:11;default:0"` + GroupName string `json:"group_name" gorm:"size:255;not null"` + Value string `json:"value" gorm:"size:2000"` + Remark string `json:"remark" gorm:"size:100;not null"` + Status int `json:"status" gorm:"size:1;not null;default:1"` + CreatedAt time.Time `json:"created_at"` + UpdatedAt time.Time `json:"updated_at"` +} + +// 存储配置 +var webConfig = make(map[string]string) + +// 配置表 +func (model *Config) Seeder() { + seeders := []Config{ + {Title: "网站名称", Type: "text", Name: "WEB_SITE_NAME", Sort: 0, GroupName: "基本", Value: "QuarkCMS", Remark: "", Status: 1}, + {Title: "关键字", Type: "text", Name: "WEB_SITE_KEYWORDS", Sort: 0, GroupName: "基本", Value: "QuarkCMS", Remark: "", Status: 1}, + {Title: "描述", Type: "textarea", Name: "WEB_SITE_DESCRIPTION", Sort: 0, GroupName: "基本", Value: "QuarkCMS", Remark: "", Status: 1}, + {Title: "Logo", Type: "picture", Name: "WEB_SITE_LOGO", Sort: 0, GroupName: "基本", Value: "", Remark: "", Status: 1}, + {Title: "统计代码", Type: "textarea", Name: "WEB_SITE_SCRIPT", Sort: 0, GroupName: "基本", Value: "", Remark: "", Status: 1}, + {Title: "网站域名", Type: "text", Name: "WEB_SITE_DOMAIN", Sort: 0, GroupName: "基本", Value: "", Remark: "", Status: 1}, + {Title: "网站版权", Type: "text", Name: "WEB_SITE_COPYRIGHT", Sort: 0, GroupName: "基本", Value: "© Company 2018", Remark: "", Status: 1}, + {Title: "开启SSL", Type: "switch", Name: "SSL_OPEN", Sort: 0, GroupName: "基本", Value: "0", Remark: "", Status: 1}, + {Title: "开启网站", Type: "switch", Name: "WEB_SITE_OPEN", Sort: 0, GroupName: "基本", Value: "1", Remark: "", Status: 1}, + {Title: "KeyID", Type: "text", Name: "OSS_ACCESS_KEY_ID", Sort: 0, GroupName: "阿里云存储", Value: "", Remark: "你的AccessKeyID", Status: 1}, + {Title: "KeySecret", Type: "text", Name: "OSS_ACCESS_KEY_SECRET", Sort: 0, GroupName: "阿里云存储", Value: "", Remark: "你的AccessKeySecret", Status: 1}, + {Title: "EndPoint", Type: "text", Name: "OSS_ENDPOINT", Sort: 0, GroupName: "阿里云存储", Value: "", Remark: "地域节点", Status: 1}, + {Title: "Bucket域名", Type: "text", Name: "OSS_BUCKET", Sort: 0, GroupName: "阿里云存储", Value: "", Remark: "", Status: 1}, + {Title: "自定义域名", Type: "text", Name: "OSS_MYDOMAIN", Sort: 0, GroupName: "阿里云存储", Value: "", Remark: "例如:oss.web.com", Status: 1}, + {Title: "开启云存储", Type: "switch", Name: "OSS_OPEN", Sort: 0, GroupName: "阿里云存储", Value: "0", Remark: "", Status: 1}, + } + + db.Client.Create(&seeders) +} + +// 刷新配置 +func (model *Config) Refresh() { + configs := []Config{} + db.Client.Where("status", 1).Find(&configs) + for _, config := range configs { + webConfig[config.Name] = config.Value + } +} + +// 获取配置信息 +func (model *Config) GetValue(key string) string { + if len(webConfig) == 0 { + model.Refresh() + } + + return webConfig[key] +} diff --git a/pkg/app/model/file.go b/pkg/app/model/file.go new file mode 100644 index 0000000..9ebf24c --- /dev/null +++ b/pkg/app/model/file.go @@ -0,0 +1,143 @@ +package model + +import ( + "encoding/json" + "errors" + "fmt" + "strings" + "time" + + "github.com/quarkcms/quark-go/pkg/dal/db" + "github.com/xuri/excelize/v2" +) + +// 字段 +type File struct { + Id int `json:"id" gorm:"autoIncrement"` + ObjType string `json:"obj_type" gorm:"size:255"` + ObjId int `json:"obj_id" gorm:"size:11;default:0"` + FileCategoryId int `json:"file_category_id" gorm:"size:11;default:0"` + Sort int `json:"sort" gorm:"size:11;default:0"` + Name string `json:"name" gorm:"size:255;not null"` + Size string `json:"size" gorm:"size:20;default:0"` + Ext string `json:"ext" gorm:"size:255"` + Path string `json:"path" gorm:"size:255;not null"` + Md5 string `json:"md5" gorm:"size:255;not null"` + Status int `json:"status" gorm:"size:1;not null;default:1"` + CreatedAt time.Time `json:"created_at"` + UpdatedAt time.Time `json:"updated_at"` +} + +// 插入数据并返回ID +func (model *File) InsertGetId(data *File) (id int, Error error) { + err := db.Client.Create(&data).Error + + return data.Id, err +} + +// 获取文件路径 +func (model *File) GetPath(id interface{}) string { + http, path := "", "" + webSiteDomain := (&Config{}).GetValue("WEB_SITE_DOMAIN") + WebConfig := (&Config{}).GetValue("SSL_OPEN") + if webSiteDomain != "" { + if WebConfig == "1" { + http = "https://" + } else { + http = "http://" + } + } + + if getId, ok := id.(string); ok { + if strings.Contains(getId, "//") && !strings.Contains(getId, "{") { + return getId + } + if strings.Contains(getId, "./") && !strings.Contains(getId, "{") { + // 如果设置域名,则加上域名前缀 + return http + webSiteDomain + strings.Replace(getId, "./storage/app/public", "/storage", -1) + } + // json字符串 + if strings.Contains(getId, "{") { + var jsonData interface{} + json.Unmarshal([]byte(getId), &jsonData) + // 如果为map + if mapData, ok := jsonData.(map[string]interface{}); ok { + path = mapData["path"].(string) + } + // 如果为数组,返回第一个key的path + if arrayData, ok := jsonData.([]map[string]interface{}); ok { + path = arrayData[0]["path"].(string) + } + } + + if strings.Contains(path, "//") { + return path + } + if strings.Contains(path, "./") { + path = strings.Replace(path, "./storage/app/public", "/storage", -1) + } + if path != "" { + // 如果设置域名,则加上域名前缀 + return http + webSiteDomain + path + } + } + + file := &File{} + db.Client.Where("id", id).Where("status", 1).First(&file) + if file.Id != 0 { + path = file.Path + if strings.Contains(path, "//") { + return path + } + if strings.Contains(path, "./") { + path = strings.Replace(path, "./storage/app/public", "/storage", -1) + } + if path != "" { + // 如果设置域名,则加上域名前缀 + return http + webSiteDomain + path + } + } + + return "" +} + +// 获取Excel文件数据 +func (model *File) GetExcelData(fileId int) (data [][]interface{}, Error error) { + filePath := "" + file := &File{} + err := db.Client.Where("id", fileId).Where("status", 1).First(&file).Error + if err != nil { + return data, err + } + if file.Id != 0 { + filePath = file.Path + } + if filePath == "" { + return data, errors.New("参数错误!") + } + + f, err := excelize.OpenFile(filePath) + if err != nil { + return data, err + } + defer func() { + if err := f.Close(); err != nil { + fmt.Println(err) + } + }() + + rows, err := f.GetRows("Sheet1") + if err != nil { + return data, err + } + + for _, row := range rows { + getRows := []interface{}{} + for _, colCell := range row { + getRows = append(getRows, colCell) + } + data = append(data, getRows) + } + + return data, err +} diff --git a/pkg/app/model/file_category.go b/pkg/app/model/file_category.go new file mode 100644 index 0000000..c61a100 --- /dev/null +++ b/pkg/app/model/file_category.go @@ -0,0 +1,11 @@ +package model + +// 字段 +type FileCategory struct { + Id int `json:"id" gorm:"autoIncrement"` + ObjType string `json:"obj_type" gorm:"size:100"` + ObjId int `json:"obj_id" gorm:"size:11;default:0"` + Title string `json:"title" gorm:"size:255;not null"` + Sort int `json:"sort" gorm:"size:11;default:0"` + Description string `json:"description" gorm:"size:255"` +} diff --git a/pkg/app/model/menu.go b/pkg/app/model/menu.go new file mode 100644 index 0000000..0610664 --- /dev/null +++ b/pkg/app/model/menu.go @@ -0,0 +1,198 @@ +package model + +import ( + "strings" + "time" + + "github.com/go-basic/uuid" + "github.com/quarkcms/quark-go/pkg/dal/db" + "github.com/quarkcms/quark-go/pkg/lister" +) + +// 字段 +type Menu struct { + Key string `json:"key" gorm:"<-:false"` + Id int `json:"id" gorm:"autoIncrement"` + Name string `json:"name" gorm:"size:100;not null"` + GuardName string `json:"group_name" gorm:"size:100;not null"` + Icon string `json:"icon" gorm:"size:100;"` + Type string `json:"type" gorm:"size:100;not null"` + Pid int `json:"pid" gorm:"size:11;default:0"` + Sort int `json:"sort" gorm:"size:11;default:0"` + Path string `json:"path" gorm:"size:255"` + Show int `json:"show" gorm:"size:1;not null;default:1"` + Status int `json:"status" gorm:"size:1;not null;default:1"` + Locale string `json:"locale" gorm:"<-:false"` + HideInMenu bool `json:"hide_in_menu" gorm:"<-:false"` + CreatedAt time.Time `json:"created_at"` + UpdatedAt time.Time `json:"updated_at"` +} + +// 菜单表 +func (p *Menu) Seeder() { + seeders := []Menu{ + {Id: 1, Name: "控制台", GuardName: "admin", Icon: "icon-home", Type: "default", Pid: 0, Sort: 0, Path: "/dashboard", Show: 1, Status: 1}, + {Id: 2, Name: "主页", GuardName: "admin", Icon: "", Type: "engine", Pid: 1, Sort: 0, Path: "/api/admin/dashboard/index/index", Show: 1, Status: 1}, + {Id: 3, Name: "管理员", GuardName: "admin", Icon: "icon-admin", Type: "default", Pid: 0, Sort: 0, Path: "/admin", Show: 1, Status: 1}, + {Id: 4, Name: "管理员列表", GuardName: "admin", Icon: "", Type: "engine", Pid: 3, Sort: 0, Path: "/api/admin/admin/index", Show: 1, Status: 1}, + {Id: 5, Name: "权限列表", GuardName: "admin", Icon: "", Type: "engine", Pid: 3, Sort: 0, Path: "/api/admin/permission/index", Show: 1, Status: 1}, + {Id: 6, Name: "角色列表", GuardName: "admin", Icon: "", Type: "engine", Pid: 3, Sort: 0, Path: "/api/admin/role/index", Show: 1, Status: 1}, + {Id: 7, Name: "系统配置", GuardName: "admin", Icon: "icon-setting", Type: "default", Pid: 0, Sort: 0, Path: "/system", Show: 1, Status: 1}, + {Id: 8, Name: "设置管理", GuardName: "admin", Icon: "", Type: "default", Pid: 7, Sort: 0, Path: "/system/config", Show: 1, Status: 1}, + {Id: 9, Name: "网站设置", GuardName: "admin", Icon: "", Type: "engine", Pid: 8, Sort: 0, Path: "/api/admin/webConfig/setting/form", Show: 1, Status: 1}, + {Id: 10, Name: "配置管理", GuardName: "admin", Icon: "", Type: "engine", Pid: 8, Sort: 0, Path: "/api/admin/config/index", Show: 1, Status: 1}, + {Id: 11, Name: "菜单管理", GuardName: "admin", Icon: "", Type: "engine", Pid: 7, Sort: 0, Path: "/api/admin/menu/index", Show: 1, Status: 1}, + {Id: 12, Name: "操作日志", GuardName: "admin", Icon: "", Type: "engine", Pid: 7, Sort: 0, Path: "/api/admin/actionLog/index", Show: 1, Status: 1}, + {Id: 13, Name: "附件空间", GuardName: "admin", Icon: "icon-attachment", Type: "default", Pid: 0, Sort: 0, Path: "/attachment", Show: 1, Status: 1}, + {Id: 14, Name: "文件管理", GuardName: "admin", Icon: "", Type: "engine", Pid: 13, Sort: 0, Path: "/api/admin/file/index", Show: 1, Status: 1}, + {Id: 15, Name: "图片管理", GuardName: "admin", Icon: "", Type: "engine", Pid: 13, Sort: 0, Path: "/api/admin/picture/index", Show: 1, Status: 1}, + {Id: 16, Name: "我的账号", GuardName: "admin", Icon: "icon-user", Type: "default", Pid: 0, Sort: 0, Path: "/account", Show: 1, Status: 1}, + {Id: 17, Name: "个人设置", GuardName: "admin", Icon: "", Type: "engine", Pid: 16, Sort: 0, Path: "/api/admin/account/setting/form", Show: 1, Status: 1}, + } + + db.Client.Create(&seeders) +} + +// 获取菜单的有序列表 +func (model *Menu) OrderedList() (list []map[string]interface{}, Error error) { + var menus []map[string]interface{} + err := db.Client. + Model(&model). + Where("guard_name = ?", "admin"). + Order("sort asc,id asc"). + Find(&menus).Error + if err != nil { + return list, err + } + + menuTrees, err := lister.ListToTree(menus, "id", "pid", "children", 0) + if err != nil { + return list, err + } + + menuTreeList, err := lister.TreeToOrderedList(menuTrees, 0, "name", "children") + if err != nil { + return list, err + } + + list = append(list, map[string]interface{}{ + "label": "根节点", + "value": 0, + }) + for _, v := range menuTreeList { + option := map[string]interface{}{ + "label": v.((map[string]interface{}))["name"], + "value": v.(map[string]interface{})["id"], + } + list = append(list, option) + } + + return list, nil +} + +// 获取菜单的tree +func (model *Menu) Tree() (list []interface{}, Error error) { + menus := []Menu{} + err := db.Client.Where("status = ?", 1).Select("name", "id", "pid").Find(&menus).Error + if err != nil { + return list, err + } + + menuList := []map[string]interface{}{} + for _, v := range menus { + item := map[string]interface{}{ + "key": v.Id, + "pid": v.Pid, + "title": v.Name, + } + menuList = append(menuList, item) + } + + return lister.ListToTree(menuList, "key", "pid", "children", 0) +} + +// 通过管理员ID权限菜单 +func (model *Menu) GetListByAdminId(adminId int) (menuList interface{}, Error error) { + menus := []Menu{} + var menuKey int + + if adminId == 1 { + db.Client.Where("status = ?", 1).Where("guard_name", "admin").Order("sort asc").Find(&menus) + } else { + var menuIds []int + permissions, err := (&Permission{}).GetListByAdminId(adminId) + if err != nil { + return menuList, err + } + + if permissions != nil { + for key, v := range permissions { + menuIds[key] = v.MenuId + } + } + + var pids1 []int + // 三级查询列表 + db.Client. + Where("status = ?", 1). + Where("id in (?)", menuIds). + Where("pid <> ?", 0). + Order("sort asc"). + Find(&menus) + for key, v := range menus { + if v.Pid != 0 { + pids1[key] = v.Pid + } + menuKey = key + } + + var pids2 []int + menu2 := []Menu{} + // 二级查询列表 + db.Client. + Where("status = ?", 1). + Where("id in (?)", pids1). + Where("pid <> ?", 0). + Order("sort asc"). + Find(&menu2) + for key, v := range menu2 { + if v.Pid != 0 { + pids2[key] = v.Pid + } + menuKey = menuKey + key + menus[menuKey] = v + } + + menu3 := []Menu{} + // 一级查询列表 + db.Client. + Where("status = ?", 1). + Where("id in (?)", pids2). + Where("pid", 0). + Order("sort asc"). + Find(&menu3) + for key, v := range menu3 { + menuKey = menuKey + key + menus[menuKey] = v + } + } + + for k, v := range menus { + v.Key = uuid.New() + v.Locale = "menu" + strings.Replace(v.Path, "/", ".", -1) + + if v.Show == 1 { + v.HideInMenu = false + } else { + v.HideInMenu = true + } + + if v.Type == "engine" { + v.Path = "/index?api=" + v.Path + } + + menus[k] = v + } + + return lister.ListToTree(menus, "id", "pid", "routes", 0) +} diff --git a/pkg/app/model/permission.go b/pkg/app/model/permission.go new file mode 100644 index 0000000..8e7ac12 --- /dev/null +++ b/pkg/app/model/permission.go @@ -0,0 +1,63 @@ +package model + +import ( + "time" + + "github.com/quarkcms/quark-go/pkg/dal/db" +) + +// 权限 +type Permission struct { + Id int `json:"id" gorm:"autoIncrement"` + MenuId int `json:"menu_id" gorm:"size:11;default:0"` + Name string `json:"name" gorm:"size:100;not null"` + GuardName string `json:"guard_name" gorm:"size:100"` + CreatedAt time.Time `json:"created_at"` + UpdatedAt time.Time `json:"updated_at"` +} + +// 获取列表 +func (model *Permission) List() (list []map[string]interface{}, Error error) { + permissions := []Permission{} + err := db.Client.Find(&permissions).Error + if err != nil { + return list, err + } + + for _, v := range permissions { + option := map[string]interface{}{ + "label": v.Name, + "value": v.Id, + } + + list = append(list, option) + } + + return list, nil +} + +// 通过权限id集合获取权限列表 +func (model *Permission) GetListByIds(permissionIds []int) (permissions []Permission, Error error) { + err := db.Client.Where("id in (?)", &permissionIds).Find(&permissions).Error + + return permissions, err +} + +// 通过管理员ID获取权限列表 +func (model *Permission) GetListByAdminId(id int) (permissions []Permission, Error error) { + + // 管理员拥有的角色id集合 + roleIds, err := (&ModelHasRole{}).GetRoleIdsByAdminId(id) + if err != nil { + return permissions, nil + } + + // 角色拥有的权限id集合 + permissionIds, err := (&RoleHasPermission{}).GetPermissionIdsByRoleIds(roleIds) + if err != nil { + return permissions, err + } + + // 角色权限列表 + return (&Permission{}).GetListByIds(permissionIds) +} diff --git a/pkg/app/model/picture.go b/pkg/app/model/picture.go new file mode 100644 index 0000000..4157946 --- /dev/null +++ b/pkg/app/model/picture.go @@ -0,0 +1,118 @@ +package model + +import ( + "encoding/json" + "strconv" + "strings" + "time" + + "github.com/quarkcms/quark-go/pkg/dal/db" +) + +// 字段 +type Picture struct { + Id int `json:"id" gorm:"autoIncrement"` + ObjType string `json:"obj_type" gorm:"size:255"` + ObjId int `json:"obj_id" gorm:"size:11;default:0"` + PictureCategoryId int `json:"picture_category_id" gorm:"size:11;default:0"` + Sort int `json:"sort" gorm:"size:11;default:0"` + Name string `json:"name" gorm:"size:255;not null"` + Size string `json:"size" gorm:"size:20;default:0"` + Width int `json:"width" gorm:"size:11;default:0"` + Height int `json:"height" gorm:"size:11;default:0"` + Ext string `json:"ext" gorm:"size:255"` + Path string `json:"path" gorm:"size:255;not null"` + Md5 string `json:"md5" gorm:"size:255;not null"` + Status int `json:"status" gorm:"size:1;not null;default:1"` + CreatedAt time.Time `json:"created_at"` + UpdatedAt time.Time `json:"updated_at"` +} + +// 插入数据并返回ID +func (model *Picture) InsertGetId(data map[string]interface{}) (id int, Error error) { + size := strconv.FormatInt(data["size"].(int64), 10) + picture := Picture{ + ObjType: data["obj_type"].(string), + ObjId: data["obj_id"].(int), + Name: data["name"].(string), + Size: size, + Md5: data["md5"].(string), + Path: data["path"].(string), + Width: data["width"].(int), + Height: data["height"].(int), + Ext: data["ext"].(string), + Status: 1, + } + err := db.Client.Create(&picture).Error + if err != nil { + return id, err + } + + return picture.Id, nil +} + +// 获取图片路径 +func (model *Picture) GetPath(id interface{}) string { + http, path := "", "" + webSiteDomain := (&Config{}).GetValue("WEB_SITE_DOMAIN") + WebConfig := (&Config{}).GetValue("SSL_OPEN") + if webSiteDomain != "" { + if WebConfig == "1" { + http = "https://" + } else { + http = "http://" + } + } + + if getId, ok := id.(string); ok { + if strings.Contains(getId, "//") && !strings.Contains(getId, "{") { + return getId + } + if strings.Contains(getId, "./") && !strings.Contains(getId, "{") { + // 如果设置域名,则加上域名前缀 + return http + webSiteDomain + strings.Replace(getId, "./storage/app/public", "/storage", -1) + } + + // json字符串 + if strings.Contains(getId, "{") { + var jsonData interface{} + json.Unmarshal([]byte(getId), &jsonData) + if mapData, ok := jsonData.(map[string]interface{}); ok { + path = mapData["url"].(string) + } + + // 如果为数组,返回第一个key的path + if arrayData, ok := jsonData.([]map[string]interface{}); ok { + path = arrayData[0]["url"].(string) + } + } + if strings.Contains(path, "//") { + return path + } + if strings.Contains(path, "./") { + path = strings.Replace(path, "./storage/app/public", "/storage", -1) + } + if path != "" { + // 如果设置域名,则加上域名前缀 + return http + webSiteDomain + path + } + } + + picture := &Picture{} + db.Client.Where("id", id).Where("status", 1).First(&picture) + if picture.Id != 0 { + path = picture.Path + if strings.Contains(path, "//") { + return path + } + if strings.Contains(path, "./") { + path = strings.Replace(path, "./storage/app/public", "/storage", -1) + } + } + if path != "" { + // 如果设置域名,则加上域名前缀 + return http + webSiteDomain + path + } + + return http + webSiteDomain + "/admin/default.png" +} diff --git a/pkg/app/model/picture_category.go b/pkg/app/model/picture_category.go new file mode 100644 index 0000000..121c7bf --- /dev/null +++ b/pkg/app/model/picture_category.go @@ -0,0 +1,11 @@ +package model + +// 字段 +type PictureCategory struct { + Id int `json:"id" gorm:"autoIncrement"` + ObjType string `json:"obj_type" gorm:"size:100"` + ObjId int `json:"obj_id" gorm:"size:11;default:0"` + Title string `json:"title" gorm:"size:255;not null"` + Sort int `json:"sort" gorm:"size:11;default:0"` + Description string `json:"description" gorm:"size:255"` +} diff --git a/pkg/app/model/role.go b/pkg/app/model/role.go new file mode 100644 index 0000000..4d0c2d5 --- /dev/null +++ b/pkg/app/model/role.go @@ -0,0 +1,73 @@ +package model + +import ( + "time" + + "github.com/quarkcms/quark-go/pkg/dal/db" +) + +// 角色 +type Role struct { + Id int `json:"id" gorm:"autoIncrement"` + Name string `json:"name" gorm:"size:255;not null"` + GuardName string `json:"guard_name" gorm:"size:100;not null"` + CreatedAt time.Time `json:"created_at"` + UpdatedAt time.Time `json:"updated_at"` +} + +// 模型角色关联表 +type ModelHasRole struct { + RoleId int `json:"role_id" gorm:"index:model_has_roles_model_id_model_type_index"` + ModelType string `json:"model_type" gorm:"size:255;not null"` + ModelId int `json:"model_id" gorm:"index:model_has_roles_model_id_model_type_index"` +} + +// 角色权限关联表 +type RoleHasPermission struct { + PermissionId int `json:"permission_id" gorm:"size:11;not null"` + RoleId int `json:"role_id" gorm:"index:role_has_permissions_role_id_foreign"` +} + +// 模型权限关联表 +type ModelHasPermission struct { + PermissionId int `json:"permission_id" gorm:"index:model_has_permissions_model_id_model_type_index"` + ModelType string `json:"model_type" gorm:"size:255;not null"` + ModelId int `json:"model_id" gorm:"index:model_has_permissions_model_id_model_type_index"` +} + +// 获取角色列表 +func (model *Role) List() (list map[interface{}]interface{}, Error error) { + roles := []Role{} + err := db.Client.Find(&roles).Error + if err != nil { + return list, err + } + + for _, v := range roles { + list[v.Id] = v.Name + } + + return list, nil +} + +// 通过管理员ID获取角色相关 +func (model *ModelHasRole) GetListByAdminId(id int) (modelHasRole *ModelHasRole, Error error) { + err := db.Client.Where("model_id", id).Where("model_type", "admin").First(&modelHasRole).Error + + return modelHasRole, err +} + +// 通过管理员ID获取角色id集合 +func (model *ModelHasRole) GetRoleIdsByAdminId(id int) (roleIds []int, Error error) { + err := db.Client.Model(model).Where("model_id", id).Where("model_type", "admin").Pluck("id", &roleIds).Error + + return roleIds, err +} + +// 通过角色id集合获取权限id集合 +func (model *RoleHasPermission) GetPermissionIdsByRoleIds(roleIds []int) (permissionIds []int, Error error) { + // 角色权限id + err := db.Client.Model(model).Where("role_id in (?)", roleIds).Pluck("id", &permissionIds).Error + + return permissionIds, err +} diff --git a/pkg/app/model/time.go b/pkg/app/model/time.go new file mode 100644 index 0000000..6063703 --- /dev/null +++ b/pkg/app/model/time.go @@ -0,0 +1,52 @@ +package model + +import ( + "database/sql/driver" + "errors" + "fmt" + "strings" + "time" +) + +//自定义时间 +type Time time.Time + +func (t *Time) UnmarshalJSON(data []byte) error { + if string(data) == "null" { + return nil + } + var err error + //前端接收的时间字符串 + str := string(data) + //去除接收的str收尾多余的" + timeStr := strings.Trim(str, "\"") + t1, err := time.Parse("2006-01-02 15:04:05", timeStr) + *t = Time(t1) + return err +} + +func (t Time) MarshalJSON() ([]byte, error) { + formatted := fmt.Sprintf("\"%v\"", time.Time(t).Format("2006-01-02 15:04:05")) + return []byte(formatted), nil +} + +func (t Time) Value() (driver.Value, error) { + // Time 转换成 time.Time 类型 + tTime := time.Time(t) + return tTime.Format("2006-01-02 15:04:05"), nil +} + +func (t *Time) Scan(v interface{}) error { + switch vt := v.(type) { + case time.Time: + // 字符串转成 time.Time 类型 + *t = Time(vt) + case string: + // 字符串转成 time.Time 类型 + getTime, _ := time.Parse("2006-01-02 15:04:05", vt) + *t = Time(getTime) + default: + return errors.New("类型处理错误") + } + return nil +} diff --git a/pkg/builder/actions/action.go b/pkg/builder/actions/action.go new file mode 100644 index 0000000..0d1fb9e --- /dev/null +++ b/pkg/builder/actions/action.go @@ -0,0 +1,633 @@ +package actions + +import ( + "reflect" + "strings" + + "github.com/gobeam/stringy" + "github.com/quarkcms/quark-go/pkg/builder" +) + +type Action struct { + Name string `json:"name"` + Reload string `json:"reload"` + ActionType string `json:"actionType"` + SubmitForm string `json:"submitForm"` + Icon string `json:"icon"` + Type string `json:"type"` + Size string `json:"size"` + WithLoading bool `json:"withLoading"` + Fields interface{} `json:"fields"` + ConfirmTitle string `json:"confirmTitle"` + ConfirmText string `json:"confirmText"` + ConfirmType string `json:"confirmType"` + OnlyOnIndex bool `json:"onlyOnIndex"` + OnlyOnForm bool `json:"onlyOnForm"` + OnlyOnDetail bool `json:"onlyOnDetail"` + ShowOnIndex bool `json:"showOnIndex"` + ShowOnIndexTableRow bool `json:"showOnIndexTableRow"` + ShowOnIndexTableAlert bool `json:"showOnIndexTableAlert"` + ShowOnForm bool `json:"showOnForm"` + ShowOnFormExtra bool `json:"showOnFormExtra"` + ShowOnDetail bool `json:"showOnDetail"` + ShowOnDetailExtra bool `json:"showOnDetailExtra"` +} + +// 初始化 +func (p *Action) ParentInit() interface{} { + p.ActionType = "ajax" + + return p +} + +/** + * 行为key + * + * @return string + */ +func (p *Action) GetUriKey(action interface{}) string { + uriKey := reflect.TypeOf(action).String() + uriKey = strings.Replace(uriKey, "*actions.", "", -1) + uriKey = stringy.New(uriKey).KebabCase("?", "").ToLower() + + return uriKey +} + +/** + * 获取名称 + * + * @return string + */ +func (p *Action) GetName() string { + return p.Name +} + +/** + * 执行成功后刷新的组件 + * + * @return string + */ +func (p *Action) GetReload() string { + return p.Reload +} + +/** + * 行为接口接收的参数,当行为在表格行展示的时候,可以配置当前行的任意字段 + * + * @return array + */ +func (p *Action) GetApiParams() []string { + return []string{} +} + +/** + * 执行行为的接口 + * + * @return string + */ +func (p *Action) GetApi(request *builder.Request) string { + + return "" +} + +/** + * 【必填】这是 action 最核心的配置,来指定该 action 的作用类型,支持:ajax、link、url、drawer、dialog、confirm、cancel、prev、next、copy、close。 + * + * @return string + */ +func (p *Action) GetActionType() string { + return p.ActionType +} + +/** + * 当action 的作用类型为submit的时候,可以指定提交哪个表格,submitForm为提交表单的key值,为空时提交当前表单 + * + * @return string + */ +func (p *Action) GetSubmitForm() string { + return p.SubmitForm +} + +/** + * 设置按钮类型,primary | ghost | dashed | link | text | default + * + * @return string + */ +func (p *Action) GetType() string { + return p.Type +} + +/** + * 设置按钮大小,large | middle | small | default + * + * @return string + */ +func (p *Action) GetSize() string { + return p.Size +} + +/** + * 是否具有loading,当action 的作用类型为ajax,submit时有效 + * + * @return bool + */ +func (p *Action) GetWithLoading() bool { + return p.WithLoading +} + +/** + * 设置按钮的图标组件 + * + * @return string + */ +func (p *Action) GetIcon() string { + return p.Icon +} + +/** + * 行为表单字段 + * + * @return mixed + */ +func (p *Action) GetFields() interface{} { + return p.Fields +} + +/** + * 确认标题 + * + * @return mixed + */ +func (p *Action) GetConfirmTitle() string { + return p.ConfirmTitle +} + +/** + * 确认文字 + * + * @return mixed + */ +func (p *Action) GetConfirmText() string { + return p.ConfirmText +} + +/** + * 确认类型 + * + * @return mixed + */ +func (p *Action) GetConfirmType() string { + return p.ConfirmType +} + +/** + * 设置行为前的确认操作 + * + * @param string title + * @param string text + * @param string confirmType + * @return p + */ +func (p *Action) WithConfirm(title string, text string, confirmType string) *Action { + + p.ConfirmTitle = title + p.ConfirmText = text + p.ConfirmType = confirmType + + return p +} + +/** + * 只在列表页展示 + * + * @param bool value + * @return p + */ +func (p *Action) SetOnlyOnIndex(value bool) *Action { + p.OnlyOnIndex = value + p.ShowOnIndex = value + p.ShowOnDetail = !value + p.ShowOnIndexTableRow = !value + p.ShowOnIndexTableAlert = !value + p.ShowOnForm = !value + p.ShowOnFormExtra = !value + p.ShowOnDetail = !value + p.ShowOnDetailExtra = !value + + return p +} + +/** + * 除了列表页外展示 + * + * @return p + */ +func (p *Action) SetExceptOnIndex() *Action { + p.ShowOnDetail = true + p.ShowOnIndexTableRow = true + p.ShowOnIndexTableAlert = true + p.ShowOnForm = true + p.ShowOnFormExtra = true + p.ShowOnDetail = true + p.ShowOnDetailExtra = true + p.ShowOnIndex = false + + return p +} + +/** + * 只在表单页展示 + * + * @param bool value + * @return p + */ +func (p *Action) SetOnlyOnForm(value bool) *Action { + p.ShowOnForm = value + p.ShowOnIndexTableAlert = !value + p.ShowOnIndex = !value + p.ShowOnDetail = !value + p.ShowOnIndexTableRow = !value + p.ShowOnFormExtra = !value + p.ShowOnDetail = !value + p.ShowOnDetailExtra = !value + + return p +} + +/** + * 除了表单页外展示 + * + * @return p + */ +func (p *Action) SetExceptOnForm() *Action { + p.ShowOnIndexTableAlert = true + p.ShowOnIndex = true + p.ShowOnDetail = true + p.ShowOnIndexTableRow = true + p.ShowOnForm = false + p.ShowOnFormExtra = true + p.ShowOnDetail = true + p.ShowOnDetailExtra = true + + return p +} + +/** + * 只在表单页右上角自定义区域展示 + * + * @param bool value + * @return p + */ +func (p *Action) SetOnlyOnFormExtra(value bool) *Action { + p.ShowOnForm = !value + p.ShowOnIndexTableAlert = !value + p.ShowOnIndex = !value + p.ShowOnDetail = !value + p.ShowOnIndexTableRow = !value + p.ShowOnFormExtra = value + p.ShowOnDetail = !value + p.ShowOnDetailExtra = !value + + return p +} + +/** + * 除了表单页右上角自定义区域外展示 + * + * @return p + */ +func (p *Action) SetExceptOnFormExtra() *Action { + p.ShowOnIndexTableAlert = true + p.ShowOnIndex = true + p.ShowOnDetail = true + p.ShowOnIndexTableRow = true + p.ShowOnForm = true + p.ShowOnFormExtra = false + p.ShowOnDetail = true + p.ShowOnDetailExtra = true + + return p +} + +/** + * 只在详情页展示 + * + * @param bool value + * @return p + */ +func (p *Action) SetOnlyOnDetail(value bool) *Action { + p.OnlyOnDetail = value + p.ShowOnDetail = value + p.ShowOnIndex = !value + p.ShowOnIndexTableRow = !value + p.ShowOnIndexTableAlert = !value + p.ShowOnForm = !value + p.ShowOnFormExtra = !value + p.ShowOnDetailExtra = !value + + return p +} + +/** + * 除了详情页外展示 + * + * @return p + */ +func (p *Action) SetExceptOnDetail() *Action { + p.ShowOnIndex = true + p.ShowOnDetail = false + p.ShowOnIndexTableRow = true + p.ShowOnIndexTableAlert = true + p.ShowOnForm = true + p.ShowOnFormExtra = true + p.ShowOnDetailExtra = true + + return p +} + +/** + * 只在详情页右上角自定义区域展示 + * + * @param bool value + * @return p + */ +func (p *Action) SetOnlyOnDetailExtra(value bool) *Action { + p.ShowOnForm = !value + p.ShowOnIndexTableAlert = !value + p.ShowOnIndex = !value + p.ShowOnDetail = !value + p.ShowOnIndexTableRow = !value + p.ShowOnFormExtra = !value + p.ShowOnDetail = !value + p.ShowOnDetailExtra = value + + return p +} + +/** + * 除了详情页右上角自定义区域外展示 + * + * @return p + */ +func (p *Action) SetExceptOnDetailExtra() *Action { + p.ShowOnIndexTableAlert = true + p.ShowOnIndex = true + p.ShowOnDetail = true + p.ShowOnIndexTableRow = true + p.ShowOnForm = true + p.ShowOnFormExtra = true + p.ShowOnDetail = true + p.ShowOnDetailExtra = false + + return p +} + +/** + * 在表格行内展示 + * + * @param bool value + * @return p + */ +func (p *Action) SetOnlyOnIndexTableRow(value bool) *Action { + p.ShowOnIndexTableRow = value + p.ShowOnIndex = !value + p.ShowOnDetail = !value + p.ShowOnIndexTableAlert = !value + p.ShowOnForm = !value + p.ShowOnFormExtra = !value + p.ShowOnDetail = !value + p.ShowOnDetailExtra = !value + + return p +} + +/** + * 除了表格行内外展示 + * + * @return p + */ +func (p *Action) SetExceptOnIndexTableRow() *Action { + p.ShowOnIndexTableRow = false + p.ShowOnIndex = true + p.ShowOnDetail = true + p.ShowOnIndexTableAlert = true + p.ShowOnForm = true + p.ShowOnFormExtra = true + p.ShowOnDetail = true + p.ShowOnDetailExtra = true + + return p +} + +/** + * 在表格多选弹出层展示 + * + * @param bool value + * @return p + */ +func (p *Action) SetOnlyOnIndexTableAlert(value bool) *Action { + p.ShowOnIndexTableAlert = value + p.ShowOnIndex = !value + p.ShowOnDetail = !value + p.ShowOnIndexTableRow = !value + p.ShowOnForm = !value + p.ShowOnFormExtra = !value + p.ShowOnDetail = !value + p.ShowOnDetailExtra = !value + + return p +} + +/** + * 除了表格多选弹出层外展示 + * + * @return p + */ +func (p *Action) SetExceptOnIndexTableAlert() *Action { + p.ShowOnIndexTableAlert = false + p.ShowOnIndex = true + p.ShowOnDetail = true + p.ShowOnIndexTableRow = true + p.ShowOnForm = true + p.ShowOnFormExtra = true + p.ShowOnDetail = true + p.ShowOnDetailExtra = true + + return p +} + +/** + * 在列表页展示 + * + * @return p + */ +func (p *Action) SetShowOnIndex() *Action { + p.ShowOnIndex = true + + return p +} + +/** + * 在表单页展示 + * + * @return p + */ +func (p *Action) SetShowOnForm() *Action { + p.ShowOnForm = true + + return p +} + +/** + * 在表单页右上角自定义区域展示 + * + * @return p + */ +func (p *Action) SetShowOnFormExtra() *Action { + p.ShowOnFormExtra = true + + return p +} + +/** + * 在详情页展示 + * + * @return p + */ +func (p *Action) SetShowOnDetail() *Action { + p.ShowOnDetail = true + + return p +} + +/** + * 在详情页右上角自定义区域展示 + * + * @return p + */ +func (p *Action) SetShowOnDetailExtra() *Action { + p.ShowOnDetailExtra = true + + return p +} + +/** + * 在表格行内展示 + * + * @return p + */ +func (p *Action) SetShowOnIndexTableRow() *Action { + p.ShowOnIndexTableRow = true + + return p +} + +/** + * 在多选弹出层展示 + * + * @return p + */ +func (p *Action) SetShowOnIndexTableAlert() *Action { + p.ShowOnIndexTableAlert = true + + return p +} + +/** + * 判断是否在列表页展示 + * + * @return bool + */ +func (p *Action) ShownOnIndex() bool { + if p.OnlyOnIndex == true { + return true + } + + if p.OnlyOnDetail { + return false + } + + if p.OnlyOnForm { + return false + } + + return p.ShowOnIndex +} + +/** + * 判断是否在表单页展示 + * + * @return bool + */ +func (p *Action) ShownOnForm() bool { + if p.OnlyOnForm == true { + return true + } + + if p.OnlyOnDetail { + return false + } + + if p.OnlyOnIndex { + return false + } + + return p.ShowOnForm +} + +/** + * 判断是否在详情页展示 + * + * @return bool + */ +func (p *Action) ShownOnDetail() bool { + if p.OnlyOnDetail { + return true + } + + if p.OnlyOnIndex { + return false + } + + if p.OnlyOnForm { + return false + } + + return p.ShowOnDetail +} + +/** + * 判断是否在表格行内展示 + * + * @return bool + */ +func (p *Action) ShownOnIndexTableRow() bool { + return p.ShowOnIndexTableRow +} + +/** + * 判断是否在多选弹出层展示 + * + * @return bool + */ +func (p *Action) ShownOnIndexTableAlert() bool { + return p.ShowOnIndexTableAlert +} + +/** + * 判断是否在表单页右上角自定义区域展示 + * + * @return bool + */ +func (p *Action) ShownOnFormExtra() bool { + return p.ShowOnFormExtra +} + +/** + * 判断是否在详情页右上角自定义区域展示 + * + * @return bool + */ +func (p *Action) ShownOnDetailExtra() bool { + return p.ShowOnDetailExtra +} diff --git a/pkg/builder/actions/drawer.go b/pkg/builder/actions/drawer.go new file mode 100644 index 0000000..fae045b --- /dev/null +++ b/pkg/builder/actions/drawer.go @@ -0,0 +1,37 @@ +package actions + +import "github.com/quarkcms/quark-go/pkg/builder" + +type Drawer struct { + Action + Width int `json:"width"` + DestroyOnClose bool `json:"destroyOnClose"` +} + +// 初始化 +func (p *Drawer) ParentInit() interface{} { + p.ActionType = "drawer" + p.Width = 520 + + return p +} + +// 宽度 +func (p *Drawer) GetWidth() int { + return p.Width +} + +// 关闭时销毁 Modal 里的子元素 +func (p *Drawer) GetDestroyOnClose() bool { + return p.DestroyOnClose +} + +// 内容 +func (p *Drawer) GetBody(request *builder.Request, resourceInstance interface{}) interface{} { + return nil +} + +// 弹窗行为 +func (p *Drawer) GetActions(request *builder.Request, resourceInstance interface{}) []interface{} { + return []interface{}{} +} diff --git a/pkg/builder/actions/dropdown.go b/pkg/builder/actions/dropdown.go new file mode 100644 index 0000000..0320011 --- /dev/null +++ b/pkg/builder/actions/dropdown.go @@ -0,0 +1,209 @@ +package actions + +import ( + "strings" + + "github.com/quarkcms/quark-go/pkg/builder" + "github.com/quarkcms/quark-go/pkg/component/admin/action" + "github.com/quarkcms/quark-go/pkg/component/admin/menu" +) + +type Dropdown struct { + Action + Arrow bool `json:"arrow"` + Placement string `json:"placement"` + Trigger []string `json:"trigger"` + OverlayStyle map[string]interface{} `json:"overlayStyle"` + Actions []interface{} `json:"actions"` +} + +// 初始化 +func (p *Dropdown) ParentInit() interface{} { + p.ActionType = "dropdown" + p.Placement = "bottomLeft" + p.Trigger = append(p.Trigger, "hover") + + return p +} + +// 是否显示箭头图标 +func (p *Dropdown) GetArrow() bool { + return p.Arrow +} + +// 菜单弹出位置:bottomLeft bottomCenter bottomRight topLeft topCenter topRight +func (p *Dropdown) GetPlacement() string { + return p.Placement +} + +// 触发下拉的行为, 移动端不支持 hover,Array +func (p *Dropdown) GetTrigger() []string { + return p.Trigger +} + +// 下拉根元素的样式 +func (p *Dropdown) GetOverlayStyle() map[string]interface{} { + return p.OverlayStyle +} + +// 菜单 +func (p *Dropdown) GetOverlay(request *builder.Request, templateInstance interface{}) interface{} { + actions := p.GetActions() + items := []interface{}{} + + for _, v := range actions { + action := p.buildAction(request, v, templateInstance) + items = append(items, action) + } + + return (&menu.Component{}).Init().SetItems(items) +} + +//创建行为组件 +func (p *Dropdown) buildAction(request *builder.Request, item interface{}, templateInstance interface{}) interface{} { + name := item.(interface{ GetName() string }).GetName() + withLoading := item.(interface{ GetWithLoading() bool }).GetWithLoading() + reload := item.(interface{ GetReload() string }).GetReload() + + // uri唯一标识 + uriKey := item.(interface { + GetUriKey(interface{}) string + }).GetUriKey(item) + + // 获取api + api := item.(interface { + GetApi(*builder.Request) string + }).GetApi(request) + + // 获取api替换参数 + params := item.(interface { + GetApiParams() []string + }).GetApiParams() + + if api == "" { + api = p.buildActionApi(request, params, uriKey) + } + + actionType := item.(interface{ GetActionType() string }).GetActionType() + buttonType := item.(interface{ GetType() string }).GetType() + size := item.(interface{ GetSize() string }).GetSize() + icon := item.(interface{ GetIcon() string }).GetIcon() + confirmTitle := item.(interface{ GetConfirmTitle() string }).GetConfirmTitle() + confirmText := item.(interface{ GetConfirmText() string }).GetConfirmText() + confirmType := item.(interface{ GetConfirmType() string }).GetConfirmType() + + getAction := (&menu.Item{}).Init(). + Init(). + SetLabel(name). + SetWithLoading(withLoading). + SetReload(reload). + SetApi(api). + SetActionType(actionType). + SetType(buttonType, false). + SetSize(size) + + if icon != "" { + getAction = getAction. + SetIcon(icon) + } + + switch actionType { + case "link": + href := item.(interface { + GetHref(request *builder.Request) string + }).GetHref(request) + target := item.(interface { + GetTarget(request *builder.Request) string + }).GetTarget(request) + + getAction = getAction. + SetLink(href, target). + SetStyle(map[string]interface{}{ + "color": "#1890ff", + }) + case "modal": + formWidth := item.(interface { + GetWidth() int + }).GetWidth() + + formDestroyOnClose := item.(interface { + GetDestroyOnClose() bool + }).GetDestroyOnClose() + + formBody := item.(interface { + GetBody(request *builder.Request, templateInstance interface{}) interface{} + }).GetBody(request, templateInstance) + + formActions := item.(interface { + GetActions(request *builder.Request, templateInstance interface{}) []interface{} + }).GetActions(request, templateInstance) + + getAction = getAction.SetModal(func(modal *action.Modal) interface{} { + return modal. + SetTitle(name). + SetWidth(formWidth). + SetBody(formBody). + SetActions(formActions). + SetDestroyOnClose(formDestroyOnClose) + }) + case "drawer": + formWidth := item.(interface { + GetWidth() int + }).GetWidth() + + formDestroyOnClose := item.(interface { + GetDestroyOnClose() bool + }).GetDestroyOnClose() + + formBody := item.(interface { + GetBody(request *builder.Request, templateInstance interface{}) interface{} + }).GetBody(request, templateInstance) + + formActions := item.(interface { + GetActions(request *builder.Request, templateInstance interface{}) []interface{} + }).GetActions(request, templateInstance) + + getAction = getAction.SetDrawer(func(drawer *action.Drawer) interface{} { + return drawer. + SetTitle(name). + SetWidth(formWidth). + SetBody(formBody). + SetActions(formActions). + SetDestroyOnClose(formDestroyOnClose) + }) + } + + if confirmTitle != "" { + getAction = getAction. + SetWithConfirm(confirmTitle, confirmText, confirmType) + } + + return getAction +} + +// 下拉菜单行为 +func (p *Dropdown) SetActions(actions []interface{}) *Dropdown { + p.Actions = actions + + return p +} + +// 获取下拉菜单行为 +func (p *Dropdown) GetActions() []interface{} { + return p.Actions +} + +//创建行为接口 +func (p *Dropdown) buildActionApi(request *builder.Request, params []string, uriKey string) string { + paramsUri := "" + for _, v := range params { + paramsUri = paramsUri + v + "=${" + v + "}&" + } + + api := strings.Replace(request.Path(), "/index", "/action/"+uriKey, -1) + if paramsUri != "" { + api = api + "?" + paramsUri + } + + return api +} diff --git a/pkg/builder/actions/link.go b/pkg/builder/actions/link.go new file mode 100644 index 0000000..236b7a3 --- /dev/null +++ b/pkg/builder/actions/link.go @@ -0,0 +1,35 @@ +package actions + +import "github.com/quarkcms/quark-go/pkg/builder" + +type Link struct { + Action + Href string `json:"href"` + Target string `json:"target"` +} + +// 初始化 +func (p *Link) ParentInit() interface{} { + p.ActionType = "link" + p.Target = "_self" + + return p +} + +/** + * 获取跳转链接 + * + * @return string + */ +func (p *Link) GetHref(request *builder.Request) string { + return p.Href +} + +/** + * 相当于 a 链接的 target 属性,href 存在时生效 + * + * @return string + */ +func (p *Link) GetTarget(request *builder.Request) string { + return p.Target +} diff --git a/pkg/builder/actions/modal.go b/pkg/builder/actions/modal.go new file mode 100644 index 0000000..292472c --- /dev/null +++ b/pkg/builder/actions/modal.go @@ -0,0 +1,37 @@ +package actions + +import "github.com/quarkcms/quark-go/pkg/builder" + +type Modal struct { + Action + Width int `json:"width"` + DestroyOnClose bool `json:"destroyOnClose"` +} + +// 初始化 +func (p *Modal) ParentInit() interface{} { + p.ActionType = "modal" + p.Width = 520 + + return p +} + +// 宽度 +func (p *Modal) GetWidth() int { + return p.Width +} + +// 关闭时销毁 Modal 里的子元素 +func (p *Modal) GetDestroyOnClose() bool { + return p.DestroyOnClose +} + +// 内容 +func (p *Modal) GetBody(request *builder.Request, templateInstance interface{}) interface{} { + return nil +} + +// 弹窗行为 +func (p *Modal) GetActions(request *builder.Request, templateInstance interface{}) []interface{} { + return []interface{}{} +} diff --git a/pkg/builder/adminfield.go b/pkg/builder/adminfield.go new file mode 100644 index 0000000..bb2bb58 --- /dev/null +++ b/pkg/builder/adminfield.go @@ -0,0 +1,894 @@ +package builder + +import ( + "reflect" + + "github.com/quarkcms/quark-go/pkg/component/admin/form/fields" +) + +// 后台字段组件 +type AdminField struct{} + +// ID组件 +func (p *AdminField) ID(params ...interface{}) *fields.ID { + field := (&fields.ID{}).Init() + + if len(params) >= 2 { + + field.SetName(params[0].(string)).SetLabel(params[1].(string)) + if len(params) == 3 { + + // 判断是否为闭包函数 + closure, ok := params[2].(func() interface{}) + if ok { + field.SetCallback(closure) + } + } + } else { + field.SetName(params[0].(string)).SetLabel(params[0].(string)) + } + + return field +} + +// Hidden组件 +func (p *AdminField) Hidden(params ...interface{}) *fields.Hidden { + field := (&fields.Hidden{}).Init() + + if len(params) >= 2 { + + field.SetName(params[0].(string)).SetLabel(params[1].(string)) + if len(params) == 3 { + + // 判断是否为闭包函数 + closure, ok := params[2].(func() interface{}) + if ok { + field.SetCallback(closure) + } + } + } else { + field.SetName(params[0].(string)).SetLabel(params[0].(string)) + } + + return field +} + +// 输入框组件 +func (p *AdminField) Text(params ...interface{}) *fields.Text { + field := (&fields.Text{}).Init() + + placeholder := reflect. + ValueOf(field). + Elem(). + FieldByName("Placeholder").String() + + if len(params) >= 2 { + + if placeholder == "" { + field.SetPlaceholder("请输入" + params[1].(string)) + } + + field.SetName(params[0].(string)).SetLabel(params[1].(string)) + if len(params) == 3 { + + // 判断是否为闭包函数 + closure, ok := params[2].(func() interface{}) + if ok { + field.SetCallback(closure) + } + } + } else { + if placeholder == "" { + field.SetPlaceholder("请输入" + params[1].(string)) + } + + field.SetName(params[0].(string)).SetLabel(params[0].(string)) + } + + return field +} + +// 文本域组件 +func (p *AdminField) TextArea(params ...interface{}) *fields.TextArea { + field := (&fields.TextArea{}).Init() + + placeholder := reflect. + ValueOf(field). + Elem(). + FieldByName("Placeholder").String() + + if len(params) >= 2 { + + if placeholder == "" { + field.SetPlaceholder("请输入" + params[1].(string)) + } + + field.SetName(params[0].(string)).SetLabel(params[1].(string)) + if len(params) == 3 { + + // 判断是否为闭包函数 + closure, ok := params[2].(func() interface{}) + if ok { + field.SetCallback(closure) + } + } + } else { + if placeholder == "" { + field.SetPlaceholder("请输入" + params[1].(string)) + } + + field.SetName(params[0].(string)).SetLabel(params[0].(string)) + } + + return field +} + +// 密码框组件 +func (p *AdminField) Password(params ...interface{}) *fields.Password { + field := (&fields.Password{}).Init() + + placeholder := reflect. + ValueOf(field). + Elem(). + FieldByName("Placeholder").String() + + if len(params) >= 2 { + + if placeholder == "" { + field.SetPlaceholder("请输入" + params[1].(string)) + } + + field.SetName(params[0].(string)).SetLabel(params[1].(string)) + if len(params) == 3 { + + // 判断是否为闭包函数 + closure, ok := params[2].(func() interface{}) + if ok { + field.SetCallback(closure) + } + } + } else { + if placeholder == "" { + field.SetPlaceholder("请输入" + params[1].(string)) + } + + field.SetName(params[0].(string)).SetLabel(params[0].(string)) + } + + return field +} + +// 单选组件 +func (p *AdminField) Radio(params ...string) *fields.Radio { + field := &fields.Radio{} + + if len(params) == 2 { + field.Init().SetName(params[0]).SetLabel(params[1]) + } else { + field.Init().SetName(params[0]).SetLabel(params[0]) + } + + return field +} + +// 多选组件 +func (p *AdminField) Checkbox(params ...string) *fields.Checkbox { + field := &fields.Checkbox{} + + if len(params) == 2 { + field.Init().SetName(params[0]).SetLabel(params[1]) + } else { + field.Init().SetName(params[0]).SetLabel(params[0]) + } + + return field +} + +// 日期组件 +func (p *AdminField) Date(params ...interface{}) *fields.Date { + field := &fields.Date{} + + placeholder := reflect. + ValueOf(field). + Elem(). + FieldByName("Placeholder").String() + + if len(params) >= 2 { + + if placeholder == "" { + field.Init().SetPlaceholder("请选择") + } + + field.SetName(params[0].(string)).SetLabel(params[1].(string)) + if len(params) == 3 { + + // 判断是否为闭包函数 + closure, ok := params[2].(func() interface{}) + if ok { + field.SetCallback(closure) + } + } + } else { + if placeholder == "" { + field.Init().SetPlaceholder("请选择") + } + + field.SetName(params[0].(string)).SetLabel(params[0].(string)) + } + + return field +} + +// 日期范围组件 +func (p *AdminField) DateRange(params ...interface{}) *fields.DateRange { + field := &fields.DateRange{} + + placeholder := reflect. + ValueOf(field). + Elem(). + FieldByName("Placeholder").String() + + if len(params) >= 2 { + + if placeholder == "" { + field.Init().SetPlaceholder("请选择") + } + + field.SetName(params[0].(string)).SetLabel(params[1].(string)) + if len(params) == 3 { + + // 判断是否为闭包函数 + closure, ok := params[2].(func() interface{}) + if ok { + field.SetCallback(closure) + } + } + } else { + if placeholder == "" { + field.Init().SetPlaceholder("请选择") + } + + field.SetName(params[0].(string)).SetLabel(params[0].(string)) + } + + return field +} + +// 日期时间组件 +func (p *AdminField) Datetime(params ...interface{}) *fields.Datetime { + field := &fields.Datetime{} + + placeholder := reflect. + ValueOf(field). + Elem(). + FieldByName("Placeholder").String() + + if len(params) >= 2 { + + if placeholder == "" { + field.Init().SetPlaceholder("请选择") + } + + field.SetName(params[0].(string)).SetLabel(params[1].(string)) + if len(params) == 3 { + + // 判断是否为闭包函数 + closure, ok := params[2].(func() interface{}) + if ok { + field.SetCallback(closure) + } + } + } else { + if placeholder == "" { + field.Init().SetPlaceholder("请选择") + } + + field.SetName(params[0].(string)).SetLabel(params[0].(string)) + } + + return field +} + +// 日期时间范围组件 +func (p *AdminField) DatetimeRange(params ...interface{}) *fields.DatetimeRange { + field := &fields.DatetimeRange{} + + placeholder := reflect. + ValueOf(field). + Elem(). + FieldByName("Placeholder").String() + + if len(params) >= 2 { + + if placeholder == "" { + field.Init().SetPlaceholder("请选择") + } + + field.SetName(params[0].(string)).SetLabel(params[1].(string)) + if len(params) == 3 { + + // 判断是否为闭包函数 + closure, ok := params[2].(func() interface{}) + if ok { + field.SetCallback(closure) + } + } + } else { + if placeholder == "" { + field.Init().SetPlaceholder("请选择") + } + + field.SetName(params[0].(string)).SetLabel(params[0].(string)) + } + + return field +} + +// 开关组件 +func (p *AdminField) Switch(params ...string) *fields.Switch { + field := &fields.Switch{} + + if len(params) == 2 { + field.Init().SetName(params[0]).SetLabel(params[1]) + } else { + field.Init().SetName(params[0]).SetLabel(params[0]) + } + + return field +} + +// 树形组件 +func (p *AdminField) Tree(params ...interface{}) *fields.Tree { + field := (&fields.Tree{}).Init() + + placeholder := reflect. + ValueOf(field). + Elem(). + FieldByName("Placeholder").String() + + if len(params) >= 2 { + + if placeholder == "" { + field.SetPlaceholder("请选择" + params[1].(string)) + } + + field.SetName(params[0].(string)).SetLabel(params[1].(string)) + if len(params) == 3 { + + // 判断是否为闭包函数 + closure, ok := params[2].(func() interface{}) + if ok { + field.SetCallback(closure) + } + } + } else { + if placeholder == "" { + field.SetPlaceholder("请选择" + params[1].(string)) + } + + field.SetName(params[0].(string)).SetLabel(params[0].(string)) + } + + return field +} + +// 图标组件 +func (p *AdminField) Icon(params ...interface{}) *fields.Icon { + field := (&fields.Icon{}).Init() + + placeholder := reflect. + ValueOf(field). + Elem(). + FieldByName("Placeholder").String() + + if len(params) >= 2 { + + if placeholder == "" { + field.SetPlaceholder("请选择" + params[1].(string)) + } + + field.SetName(params[0].(string)).SetLabel(params[1].(string)) + if len(params) == 3 { + + // 判断是否为闭包函数 + closure, ok := params[2].(func() interface{}) + if ok { + field.SetCallback(closure) + } + } + } else { + if placeholder == "" { + field.SetPlaceholder("请选择" + params[1].(string)) + } + + field.SetName(params[0].(string)).SetLabel(params[0].(string)) + } + + return field +} + +// 下拉框组件 +func (p *AdminField) Select(params ...interface{}) *fields.Select { + field := (&fields.Select{}).Init() + + placeholder := reflect. + ValueOf(field). + Elem(). + FieldByName("Placeholder").String() + + if len(params) >= 2 { + + if placeholder == "" { + field.SetPlaceholder("请选择" + params[1].(string)) + } + + field.SetName(params[0].(string)).SetLabel(params[1].(string)) + if len(params) == 3 { + + // 判断是否为闭包函数 + closure, ok := params[2].(func() interface{}) + if ok { + field.SetCallback(closure) + } + } + } else { + if placeholder == "" { + field.SetPlaceholder("请选择" + params[1].(string)) + } + + field.SetName(params[0].(string)).SetLabel(params[0].(string)) + } + + return field +} + +// 级联菜单组件 +func (p *AdminField) Cascader(params ...interface{}) *fields.Select { + field := (&fields.Select{}).Init() + + if len(params) >= 2 { + field.SetName(params[0].(string)).SetLabel(params[1].(string)) + if len(params) == 3 { + + // 判断是否为闭包函数 + closure, ok := params[2].(func() interface{}) + if ok { + field.SetCallback(closure) + } + } + } else { + field.SetName(params[0].(string)).SetLabel(params[0].(string)) + } + + return field +} + +// 图片组件 +func (p *AdminField) Image(params ...interface{}) *fields.Image { + field := (&fields.Image{}).Init() + + if len(params) >= 2 { + + field.SetName(params[0].(string)).SetLabel(params[1].(string)) + if len(params) == 3 { + + // 判断是否为闭包函数 + closure, ok := params[2].(func() interface{}) + if ok { + field.SetCallback(closure) + } + } + } else { + + field.SetName(params[0].(string)).SetLabel(params[0].(string)) + } + + return field +} + +// 文件组件 +func (p *AdminField) File(params ...interface{}) *fields.File { + field := (&fields.File{}).Init() + + if len(params) >= 2 { + + field.SetName(params[0].(string)).SetLabel(params[1].(string)) + if len(params) == 3 { + + // 判断是否为闭包函数 + closure, ok := params[2].(func() interface{}) + if ok { + field.SetCallback(closure) + } + } + } else { + + field.SetName(params[0].(string)).SetLabel(params[0].(string)) + } + + return field +} + +// 文本展示组件 +func (p *AdminField) Display(label string) *fields.Display { + field := (&fields.Display{}).Init() + field.SetLabel(label) + + return field +} + +// 编辑器组件 +func (p *AdminField) Editor(params ...interface{}) *fields.Editor { + field := (&fields.Editor{}).Init() + + if len(params) >= 2 { + field.SetName(params[0].(string)).SetLabel(params[1].(string)) + if len(params) == 3 { + + // 判断是否为闭包函数 + closure, ok := params[2].(func() interface{}) + if ok { + field.SetCallback(closure) + } + } + } else { + field.SetName(params[0].(string)).SetLabel(params[0].(string)) + } + + return field +} + +// 分组组件 +func (p *AdminField) Group(label string, items []interface{}) *fields.Group { + field := (&fields.Group{}).Init() + + field.SetBody(items).SetLabel(label) + + return field +} + +// List组件 +func (p *AdminField) List(params ...interface{}) *fields.List { + field := (&fields.List{}).Init() + + if len(params) >= 2 { + + field.SetName(params[0].(string)).SetLabel(params[1].(string)) + if len(params) == 3 { + + // 判断是否为闭包函数 + closure, ok := params[2].(func() interface{}) + if ok { + field.SetCallback(closure) + } + } + } else { + + field.SetName(params[0].(string)).SetLabel(params[0].(string)) + } + + return field +} + +// 地图组件 +func (p *AdminField) Map(params ...interface{}) *fields.Map { + field := (&fields.Map{}).Init() + + if len(params) >= 2 { + + field.SetName(params[0].(string)).SetLabel(params[1].(string)) + if len(params) == 3 { + + // 判断是否为闭包函数 + closure, ok := params[2].(func() interface{}) + if ok { + field.SetCallback(closure) + } + } + } else { + + field.SetName(params[0].(string)).SetLabel(params[0].(string)) + } + + return field +} + +// 地图围栏组件 +func (p *AdminField) Geofence(params ...interface{}) *fields.Geofence { + field := (&fields.Geofence{}).Init() + + if len(params) >= 2 { + + field.SetName(params[0].(string)).SetLabel(params[1].(string)) + if len(params) == 3 { + + // 判断是否为闭包函数 + closure, ok := params[2].(func() interface{}) + if ok { + field.SetCallback(closure) + } + } + } else { + + field.SetName(params[0].(string)).SetLabel(params[0].(string)) + } + + return field +} + +// 日期-月组件 +func (p *AdminField) Month(params ...interface{}) *fields.Month { + field := &fields.Month{} + + placeholder := reflect. + ValueOf(field). + Elem(). + FieldByName("Placeholder").String() + + if len(params) >= 2 { + + if placeholder == "" { + field.Init().SetPlaceholder("请选择") + } + + field.SetName(params[0].(string)).SetLabel(params[1].(string)) + if len(params) == 3 { + + // 判断是否为闭包函数 + closure, ok := params[2].(func() interface{}) + if ok { + field.SetCallback(closure) + } + } + } else { + if placeholder == "" { + field.Init().SetPlaceholder("请选择") + } + + field.SetName(params[0].(string)).SetLabel(params[0].(string)) + } + + return field +} + +// 数组输入框组件 +func (p *AdminField) Number(params ...interface{}) *fields.Number { + field := (&fields.Number{}).Init() + + placeholder := reflect. + ValueOf(field). + Elem(). + FieldByName("Placeholder").String() + + if len(params) >= 2 { + + if placeholder == "" { + field.SetPlaceholder("请输入" + params[1].(string)) + } + + field.SetName(params[0].(string)).SetLabel(params[1].(string)) + if len(params) == 3 { + + // 判断是否为闭包函数 + closure, ok := params[2].(func() interface{}) + if ok { + field.SetCallback(closure) + } + } + } else { + if placeholder == "" { + field.SetPlaceholder("请输入" + params[1].(string)) + } + + field.SetName(params[0].(string)).SetLabel(params[0].(string)) + } + + return field +} + +// 日期-季度组件 +func (p *AdminField) Quarter(params ...interface{}) *fields.Quarter { + field := &fields.Quarter{} + + placeholder := reflect. + ValueOf(field). + Elem(). + FieldByName("Placeholder").String() + + if len(params) >= 2 { + + if placeholder == "" { + field.Init().SetPlaceholder("请选择") + } + + field.SetName(params[0].(string)).SetLabel(params[1].(string)) + if len(params) == 3 { + + // 判断是否为闭包函数 + closure, ok := params[2].(func() interface{}) + if ok { + field.SetCallback(closure) + } + } + } else { + if placeholder == "" { + field.Init().SetPlaceholder("请选择") + } + + field.SetName(params[0].(string)).SetLabel(params[0].(string)) + } + + return field +} + +// 搜索组件 +func (p *AdminField) Search(params ...interface{}) *fields.Search { + field := (&fields.Search{}).Init() + + if len(params) >= 2 { + + field.SetName(params[0].(string)).SetLabel(params[1].(string)) + if len(params) == 3 { + + // 判断是否为闭包函数 + closure, ok := params[2].(func() interface{}) + if ok { + field.SetCallback(closure) + } + } + } else { + + field.SetName(params[0].(string)).SetLabel(params[0].(string)) + } + + return field +} + +// 时间范围组件 +func (p *AdminField) TimeRange(params ...interface{}) *fields.TimeRange { + field := &fields.TimeRange{} + + placeholder := reflect. + ValueOf(field). + Elem(). + FieldByName("Placeholder").String() + + if len(params) >= 2 { + + if placeholder == "" { + field.Init().SetPlaceholder("请选择") + } + + field.SetName(params[0].(string)).SetLabel(params[1].(string)) + if len(params) == 3 { + + // 判断是否为闭包函数 + closure, ok := params[2].(func() interface{}) + if ok { + field.SetCallback(closure) + } + } + } else { + if placeholder == "" { + field.Init().SetPlaceholder("请选择") + } + + field.SetName(params[0].(string)).SetLabel(params[0].(string)) + } + + return field +} + +// 时间组件 +func (p *AdminField) Time(params ...interface{}) *fields.Time { + field := &fields.Time{} + + placeholder := reflect. + ValueOf(field). + Elem(). + FieldByName("Placeholder").String() + + if len(params) >= 2 { + + if placeholder == "" { + field.Init().SetPlaceholder("请选择") + } + + field.SetName(params[0].(string)).SetLabel(params[1].(string)) + if len(params) == 3 { + + // 判断是否为闭包函数 + closure, ok := params[2].(func() interface{}) + if ok { + field.SetCallback(closure) + } + } + } else { + if placeholder == "" { + field.Init().SetPlaceholder("请选择") + } + + field.SetName(params[0].(string)).SetLabel(params[0].(string)) + } + + return field +} + +// 周组件 +func (p *AdminField) Week(params ...interface{}) *fields.Week { + field := &fields.Week{} + + placeholder := reflect. + ValueOf(field). + Elem(). + FieldByName("Placeholder").String() + + if len(params) >= 2 { + + if placeholder == "" { + field.Init().SetPlaceholder("请选择") + } + + field.SetName(params[0].(string)).SetLabel(params[1].(string)) + if len(params) == 3 { + + // 判断是否为闭包函数 + closure, ok := params[2].(func() interface{}) + if ok { + field.SetCallback(closure) + } + } + } else { + if placeholder == "" { + field.Init().SetPlaceholder("请选择") + } + + field.SetName(params[0].(string)).SetLabel(params[0].(string)) + } + + return field +} + +// 年组件 +func (p *AdminField) Year(params ...interface{}) *fields.Year { + field := &fields.Year{} + + placeholder := reflect. + ValueOf(field). + Elem(). + FieldByName("Placeholder").String() + + if len(params) >= 2 { + + if placeholder == "" { + field.Init().SetPlaceholder("请选择") + } + + field.SetName(params[0].(string)).SetLabel(params[1].(string)) + if len(params) == 3 { + + // 判断是否为闭包函数 + closure, ok := params[2].(func() interface{}) + if ok { + field.SetCallback(closure) + } + } + } else { + if placeholder == "" { + field.Init().SetPlaceholder("请选择") + } + + field.SetName(params[0].(string)).SetLabel(params[0].(string)) + } + + return field +} + +// Select组合组件 +func (p *AdminField) Selects(body interface{}) *fields.Selects { + field := &fields.Selects{} + + field.Init().SetBody(body) + + return field +} diff --git a/pkg/builder/builder.go b/pkg/builder/builder.go new file mode 100644 index 0000000..e42e1bb --- /dev/null +++ b/pkg/builder/builder.go @@ -0,0 +1,232 @@ +package builder + +import ( + "reflect" + "strings" + "time" + + "github.com/jinzhu/copier" + "github.com/quarkcms/quark-go/pkg/dal" + "github.com/quarkcms/quark-go/pkg/github" + "gorm.io/gorm" +) + +// 静态文件URL +const RespositoryURL = "https://github.com/quarkcms/quark-go/tree/2.0/website/" + +type DBConfig struct { + Dialector gorm.Dialector + Opts gorm.Option +} + +type Config struct { + AppKey string // 应用加密Key,用于JWT认证 + AppName string // 应用名称 + DBConfig *DBConfig // 数据库配置 + StaticPath string // 静态文件目录 + Providers []interface{} // 服务列表 + AdminLayout *AdminLayout // 后台布局 + Routes []string // 路由列表 +} + +// 全局配置 +var AppConfig *Config + +// 初始化对象 +func New(config *Config) *Resource { + + // 初始化数据库 + if config.DBConfig != nil { + dal.InitDB(config.DBConfig.Dialector, config.DBConfig.Opts) + } + + // 初始化配置 + SetConfig(config) + + // 定义结构体 + resource := &Resource{ + Providers: AppConfig.Providers, + } + + // 下载静态文件 + github.Download(RespositoryURL, config.StaticPath) + + // 调用初始化方法 + return resource +} + +// 转换Request对象 +func (p *Resource) TransformRequest(request *Request) *Resource { + requestInstance := request.Init() + + // 定义结构体 + resource := &Resource{ + Providers: p.Providers, + UseHandlers: p.UseHandlers, + Request: requestInstance, + } + + // 初始化路由列表 + p.InitRoutes() + + // 调用初始化方法 + return resource +} + +// 初始化路由列表 +func (p *Resource) InitRoutes() { + if AppConfig.Routes != nil { + return + } + + var routes []string + for _, provider := range AppConfig.Providers { + + // 初始化 + getTemplateInstance := provider.(interface { + Init() interface{} + }).Init() + + // 获取模板定义的路由 + templateInstanceRoutes := getTemplateInstance.(interface { + GetRoutes() []*Route + }).GetRoutes() + + for _, v := range templateInstanceRoutes { + providerName := reflect.TypeOf(provider).String() + getNames := strings.Split(providerName, ".") + structName := getNames[len(getNames)-1] + + if strings.Contains(v.Path, ":resource") { + path := strings.Replace(v.Path, ":resource", strings.ToLower(structName), -1) + //处理行为 + if strings.Contains(path, ":uriKey") { + actions := getTemplateInstance.(interface { + Actions(request *Request) []interface{} + }).Actions(p.Request) + + for _, av := range actions { + + // uri唯一标识 + uriKey := av.(interface { + GetUriKey(interface{}) string + }).GetUriKey(av) + + actionType := av.(interface{ GetActionType() string }).GetActionType() + if actionType == "dropdown" { + dropdownActions := av.(interface{ GetActions() []interface{} }).GetActions() + for _, dropdownAction := range dropdownActions { + uriKey := dropdownAction.(interface { + GetUriKey(interface{}) string + }).GetUriKey(dropdownAction) // uri唯一标识 + + path = strings.Replace(path, ":uriKey", uriKey, -1) + } + } else { + path = strings.Replace(path, ":uriKey", uriKey, -1) + } + } + } + + routes = append(routes, path) + } + } + } + + AppConfig.Routes = routes +} + +// 获取后台默认布局 +func getDefaultAdminLayout(adminLayout *AdminLayout) *AdminLayout { + defalutAdminLayout := &AdminLayout{ + "QuarkGo", + false, + []map[string]interface{}{ + { + "component": "icon", + "icon": "icon-question-circle", + "tooltip": "使用文档", + "href": "https://www.quarkcms.com/", + "target": "_blank", + "style": map[string]interface{}{ + "color": "#000", + }, + }, + }, + "side", + false, + "dark", + "Fluid", + "dark", + "#1890ff", + true, + true, + "//at.alicdn.com/t/font_1615691_3pgkh5uyob.js", + "zh-CN", + 208, + time.Now().Format("2006") + " QuarkGo", + []map[string]interface{}{ + { + "title": "Quark", + "href": "http://www.quarkcms.com/", + }, + { + "title": "爱小圈", + "href": "http://www.ixiaoquan.com", + }, + { + "title": "Github", + "href": "https://github.com/quarkcms", + }, + }, + } + + // 设置布局 + copier.CopyWithOption(defalutAdminLayout, adminLayout, copier.Option{IgnoreEmpty: true}) + + return defalutAdminLayout +} + +// 设置配置 +func SetConfig(config *Config) { + + // 初始化后台布局 + config.AdminLayout = getDefaultAdminLayout(config.AdminLayout) + + // 赋给全局变量 + AppConfig = config +} + +// 获取当前配置 +func GetConfig() *Config { + + return AppConfig +} + +// 获取当前AdminLayout配置 +func GetAdminLayoutConfig() *AdminLayout { + + return AppConfig.AdminLayout +} + +// 获取路由列表 +func GetRoutes() []string { + + return AppConfig.Routes +} + +// 通用调用方法 +func (p *Resource) Use(args interface{}) *Resource { + argsName := reflect.TypeOf(args).String() + + switch argsName { + case "*builder.AdminLayout": + AppConfig.AdminLayout = getDefaultAdminLayout(args.(*AdminLayout)) + case "func(*builder.Request) error": + p.UseHandlers = append(p.UseHandlers, args.(func(request *Request) error)) + default: + panic(argsName + " arguments was not found") + } + + return p +} diff --git a/pkg/builder/metrics/admin_descriptions.go b/pkg/builder/metrics/admin_descriptions.go new file mode 100644 index 0000000..cb2647b --- /dev/null +++ b/pkg/builder/metrics/admin_descriptions.go @@ -0,0 +1,14 @@ +package metrics + +import ( + "github.com/quarkcms/quark-go/pkg/component/admin/descriptions" +) + +type AdminDescriptions struct { + AdminMetrics +} + +// 包含组件的结果 +func (p *AdminDescriptions) Result(value interface{}) *descriptions.Component { + return (&descriptions.Component{}).Init().SetTitle(p.Title).SetItems(value) +} diff --git a/pkg/builder/metrics/admin_metrics.go b/pkg/builder/metrics/admin_metrics.go new file mode 100644 index 0000000..172fe5d --- /dev/null +++ b/pkg/builder/metrics/admin_metrics.go @@ -0,0 +1,6 @@ +package metrics + +type AdminMetrics struct { + Title string + Col int +} diff --git a/pkg/builder/metrics/admin_value.go b/pkg/builder/metrics/admin_value.go new file mode 100644 index 0000000..6473553 --- /dev/null +++ b/pkg/builder/metrics/admin_value.go @@ -0,0 +1,24 @@ +package metrics + +import ( + "github.com/quarkcms/quark-go/pkg/component/admin/statistic" + "gorm.io/gorm" +) + +type AdminValue struct { + AdminMetrics + Precision int +} + +// 记录条数 +func (p *AdminValue) Count(DB *gorm.DB) *statistic.Component { + var count int64 + DB.Count(&count) + + return p.Result(count) +} + +// 包含组件的结果 +func (p *AdminValue) Result(value int64) *statistic.Component { + return (&statistic.Component{}).Init().SetTitle(p.Title).SetValue(value) +} diff --git a/pkg/builder/request.go b/pkg/builder/request.go new file mode 100644 index 0000000..3d8ba18 --- /dev/null +++ b/pkg/builder/request.go @@ -0,0 +1,229 @@ +package builder + +import ( + "encoding/json" + "strings" + + "github.com/derekstavis/go-qs" + "github.com/gobeam/stringy" +) + +type Request struct { + IPString string `json:"IPString"` // 请求的ip地址 + HeaderString string `json:"headerString"` // 请求的Header字符串 + MethodString string `json:"methodString"` // 请求方法 + FullPathString string `json:"fullPathString"` // 路由 + HostString string `json:"hostString"` // 主机地址 + PathString string `json:"pathString"` // URL路径 + QueryString string `json:"queryString"` // 请求参数 + Headers map[string]string `json:"headers"` // 请求的Headers + Params map[string]string `json:"params"` // URL param + Querys map[string]interface{} `json:"querys"` // URL querys + BodyBuffer []byte `json:"bodyBuffer"` // 请求的Body数据 +} + +type ParamValue struct { + Key int + Value string +} + +// 初始化 +func (p *Request) Init() *Request { + p.parseParams() + p.parseHeaders() + p.parseQuerys() + + return p +} + +// Method return request method. +// +// Returned value is valid until returning from RequestHandler. +func (p *Request) Method() string { + return p.MethodString +} + +// FullPath returns a matched route full path. For not found routes +// returns an empty string. +// +// router.GET("/user/:id", func(c *hertz.RequestContext) { +// c.FullPath() == "/user/:id" // true +// }) +func (p *Request) FullPath() string { + return p.FullPathString +} + +// Host returns requested host. +// +// The host is valid until returning from RequestHandler. +func (p *Request) Host() string { + return p.HostString +} + +// Path returns requested path. +// +// The path is valid until returning from RequestHandler. +func (p *Request) Path() string { + return p.PathString +} + +// IP tries to parse the headers in [X-Real-Ip, X-Forwarded-For]. It calls RemoteIP() under the hood +func (p *Request) IP() string { + return p.IPString +} + +// OriginalURL returns url query data +func (p *Request) OriginalURL() string { + return p.QueryString +} + +// Body returns body data +func (p *Request) Body() []byte { + return p.BodyBuffer +} + +// Param returns the value of the URL param. +// It is a shortcut for c.Params.ByName(key) +func (p *Request) parseParams() { + params := map[string]string{} + fullPaths := strings.Split(p.FullPath(), "/") + paramValues := []*ParamValue{} + for k, v := range fullPaths { + if strings.Contains(v, ":") { + v = stringy.New(v).ReplaceFirst(":", "") + mapValue := &ParamValue{ + Key: k, + Value: v, + } + paramValues = append(paramValues, mapValue) + } + } + + paths := strings.Split(p.Path(), "/") + for _, v := range paramValues { + params[v.Value] = paths[v.Key] + } + + p.Params = params +} + +// Param returns the value of the URL param. +// It is a shortcut for c.Params.ByName(key) +// +// router.GET("/user/:id", func(c *hertz.RequestContext) { +// // a GET request to /user/john +// id := c.Param("id") // id == "john" +// }) +func (p *Request) Param(key string) string { + return p.Params[key] +} + +// Query returns the value of the URL Querys. +func (p *Request) parseQuerys() { + querys, err := qs.Unmarshal(p.QueryString) + if err == nil { + p.Querys = querys + } +} + +// Query returns the value of the URL query. +func (p *Request) Query(params ...interface{}) interface{} { + if len(params) == 2 { + if p.Querys[params[0].(string)] == nil { + return params[1] + } + } + + return p.Querys[params[0].(string)] +} + +// AllQuerys returns all query arguments from RequestURI. +func (p *Request) AllQuerys() map[string]interface{} { + return p.Querys +} + +// ResourceName returns the value of the URL Resource param. +// If request path is "/api/admin/login/index" and route is "/api/admin/login/:resource" +// +// resourceName := p.ResourceName() // resourceName = "index" +func (p *Request) ResourceName() string { + return p.Param("resource") +} + +// BodyParser binds the request body to a struct. +// It supports decoding the following content types based on the Content-Type header: +// application/json, application/xml, application/x-www-form-urlencoded, multipart/form-data +// If none of the content types above are matched, it will return a ErrUnprocessableEntity error +func (p *Request) BodyParser(out interface{}) error { + return json.Unmarshal(p.BodyBuffer, out) +} + +// 解析头部数据 +func (p *Request) parseHeaders() { + params := map[string]string{} + headers := strings.Split(p.HeaderString, "\r\n") + for _, v := range headers { + header := strings.Split(v, ": ") + if len(header) == 2 { + params[header[0]] = header[1] + } + } + + p.Headers = params +} + +// 获取请求头数据 +func (p *Request) Header(key string) string { + return p.Headers[key] +} + +// 获取Header中的token +func (p *Request) Token() string { + authorization := p.Header("Authorization") + authorizations := strings.Split(authorization, " ") + if len(authorizations) == 2 { + return authorizations[1] + } + + queryToken := p.Query("token", "") + if queryToken.(string) != "" { + return queryToken.(string) + } + + return "" +} + +// 判断当前页面是否为列表页面 todo +func (p *Request) IsIndex() bool { + uri := strings.Split(p.Path(), "/") + + return (uri[len(uri)-1] == "index") +} + +//判断当前页面是否为创建页面 +func (p *Request) IsCreating() bool { + uri := strings.Split(p.Path(), "/") + + return (uri[len(uri)-1] == "create") || (uri[len(uri)-1] == "store") +} + +// 判断当前页面是否为编辑页面 +func (p *Request) IsEditing() bool { + uri := strings.Split(p.Path(), "/") + + return (uri[len(uri)-1] == "edit") || (uri[len(uri)-1] == "update") +} + +// 判断当前页面是否为详情页面 +func (p *Request) IsDetail() bool { + uri := strings.Split(p.Path(), "/") + + return (uri[len(uri)-1] == "detail") +} + +// 判断当前页面是否为导出页面 +func (p *Request) isExport() bool { + uri := strings.Split(p.Path(), "/") + + return (uri[len(uri)-1] == "export") +} diff --git a/pkg/builder/resource.go b/pkg/builder/resource.go new file mode 100644 index 0000000..e55e028 --- /dev/null +++ b/pkg/builder/resource.go @@ -0,0 +1,169 @@ +package builder + +import ( + "errors" + "reflect" + "strings" +) + +type Route struct { + Path string + HandlerName string +} + +type AdminLayout struct { + Title string // layout 的左上角 的 title + Logo interface{} // layout 的左上角 的 logo + HeaderActions []map[string]interface{} // layout 的头部行为 + Layout string // layout 的菜单模式,side:右侧导航,top:顶部导航,mix:混合模式 + SplitMenus bool // layout 的菜单模式为mix时,是否自动分割菜单 + HeaderTheme string // layout 的菜单模式为mix时,顶部主题 'dark' | 'light' + ContentWidth string // layout 的内容模式,Fluid:定宽 1200px,Fixed:自适应 + NavTheme string // 导航的主题,'light' | 'dark' + PrimaryColor string // 主题色,"#1890ff" + FixedHeader bool // 是否固定 header 到顶部 + FixSiderbar bool // 是否固定导航 + IconfontUrl string // 使用 IconFont 的图标配置 + Locale string // 当前 layout 的语言设置,'zh-CN' | 'zh-TW' | 'en-US' + SiderWidth int // 侧边菜单宽度 + Copyright string // 网站版权 time.Now().Format("2006") + " QuarkGo" + Links []map[string]interface{} // 友情链接 +} + +type Resource struct { + Providers []interface{} // 服务列表 + Request *Request // 请求数据 + TemplateInstance interface{} // 资源模板实例 + UseHandlers []func(request *Request) error // 中间件方法 +} + +// 解析UseHandler方法 +func (p *Resource) UseHandlerParser() error { + var err error + + // 执行本资源的方法 + for _, Handler := range p.UseHandlers { + err = Handler(p.Request) + if err != nil { + return err + } + } + + return err +} + +// 解析路由方法 +func (p *Resource) RouteParser() (interface{}, error) { + var ( + result interface{} + err error + templateInstance interface{} + ) + + // 获取模板实例 + templateInstance, err = p.GetTemplateInstance() + if err != nil { + return nil, err + } + + // 设置模板实例 + p.SetTemplateInstance(templateInstance) + + // 执行挂载的方法 + templateInstanceRoutes := templateInstance.(interface { + GetRoutes() []*Route + }).GetRoutes() + + for _, v := range templateInstanceRoutes { + if v.Path == p.Request.FullPath() { + handlerResult := reflect. + ValueOf(templateInstance). + MethodByName(v.HandlerName). + Call([]reflect.Value{ + reflect.ValueOf(p.Request), + reflect.ValueOf(p), + reflect.ValueOf(templateInstance), + }) + + if len(handlerResult) == 1 { + result = handlerResult[0].Interface() + } + } + } + + return result, err +} + +// 替换路由中的资源参数 +// +// url := p.RouteToResourceUrl("/api/admin/login/:resource/captchaId") // url = "/api/admin/login/index/captchaId" +func (p *Resource) RouteToResourceUrl(route string) string { + resourceName := p.Request.ResourceName() + + return strings.ReplaceAll(route, ":resource", resourceName) +} + +// 根据路由判断是否为当前加载实例 +func (p *Resource) IsCurrentTemplateInstance(provider interface{}) bool { + providerName := reflect.TypeOf(provider).String() + getNames := strings.Split(providerName, ".") + structName := getNames[len(getNames)-1] + resourceName := p.Request.ResourceName() + + // fmt.Println(providerName) + // fmt.Println(resourceName) + + return strings.EqualFold(strings.ToLower(structName), strings.ToLower(resourceName)) +} + +// 获取当前模板实例 +func (p *Resource) GetTemplateInstance() (interface{}, error) { + var templateInstance interface{} + + for _, provider := range p.Providers { + + // 初始化 + getTemplateInstance := provider.(interface { + Init() interface{} + }).Init() + + // 获取模板定义的路由 + templateInstanceRoutes := getTemplateInstance.(interface { + GetRoutes() []*Route + }).GetRoutes() + + for _, v := range templateInstanceRoutes { + if v.Path == p.Request.FullPath() { + if p.IsCurrentTemplateInstance(provider) { + // 设置实例 + templateInstance = getTemplateInstance + } + } + } + } + + if templateInstance == nil { + return nil, errors.New("未获取到实例") + } + + return templateInstance, nil +} + +// 设置当前模板实例 +func (p *Resource) SetTemplateInstance(templateInstance interface{}) { + // 设置实例 + p.TemplateInstance = templateInstance +} + +// 处理执行 +func (p *Resource) Run() (interface{}, error) { + + // 解析UseHandler方法 + err := p.UseHandlerParser() + if err != nil { + return nil, err + } + + // 解析路由 + return p.RouteParser() +} diff --git a/pkg/builder/searches/date.go b/pkg/builder/searches/date.go new file mode 100644 index 0000000..4fb6af9 --- /dev/null +++ b/pkg/builder/searches/date.go @@ -0,0 +1,12 @@ +package searches + +type Date struct { + Search +} + +// 初始化 +func (p *Date) ParentInit() interface{} { + p.Component = "date" + + return p +} diff --git a/pkg/builder/searches/date_range.go b/pkg/builder/searches/date_range.go new file mode 100644 index 0000000..ec84404 --- /dev/null +++ b/pkg/builder/searches/date_range.go @@ -0,0 +1,13 @@ +package searches + +type DateRange struct { + Search +} + +// 初始化 +func (p *DateRange) ParentInit() interface{} { + p.Component = "date" + p.Operator = "between" + + return p +} diff --git a/pkg/builder/searches/datetime.go b/pkg/builder/searches/datetime.go new file mode 100644 index 0000000..8b7003d --- /dev/null +++ b/pkg/builder/searches/datetime.go @@ -0,0 +1,12 @@ +package searches + +type Datetime struct { + Search +} + +// 初始化 +func (p *Datetime) ParentInit() interface{} { + p.Component = "datetime" + + return p +} diff --git a/pkg/builder/searches/datetime_range.go b/pkg/builder/searches/datetime_range.go new file mode 100644 index 0000000..41f225f --- /dev/null +++ b/pkg/builder/searches/datetime_range.go @@ -0,0 +1,13 @@ +package searches + +type DatetimeRange struct { + Search +} + +// 初始化 +func (p *DatetimeRange) ParentInit() interface{} { + p.Component = "datetime" + p.Operator = "between" + + return p +} diff --git a/pkg/builder/searches/search.go b/pkg/builder/searches/search.go new file mode 100644 index 0000000..7dbd1b9 --- /dev/null +++ b/pkg/builder/searches/search.go @@ -0,0 +1,101 @@ +package searches + +import ( + "reflect" + "strings" + + "github.com/gobeam/stringy" + "github.com/quarkcms/quark-go/pkg/builder" + "gorm.io/gorm" +) + +type Search struct { + Column string `json:"column"` + Name string `json:"name"` + Component string `json:"component"` + Operator string `json:"operator"` + Api string `json:"api"` +} + +// 初始化 +func (p *Search) ParentInit() interface{} { + p.Component = "input" + + return p +} + +/** + * 获取字段名 + * + * @return string + */ +func (p *Search) GetColumn(search interface{}) string { + + if p.Column == "" { + column := reflect.TypeOf(search).String() + column = strings.Replace(column, "*searches.", "", -1) + return stringy.New(column).ToLower() + } + + return p.Column +} + +/** + * 获取名称 + * + * @return string + */ +func (p *Search) GetName() string { + return p.Name +} + +/** + * 获取组件名称 + * + * @return string + */ +func (p *Search) GetComponent() string { + return p.Component +} + +/** + * 获取接口 + * + * @return string + */ +func (p *Search) GetApi() string { + return p.Api +} + +/** + * 获取操作符 + * + * @return string + */ +func (p *Search) GetOperator() string { + return p.Operator +} + +/** + * 默认值 + * + * @var string + */ +func (p *Search) GetDefault() interface{} { + return true +} + +// 执行查询 +func (p *Search) Apply(request *builder.Request, query *gorm.DB, value interface{}) *gorm.DB { + return query +} + +// 属性 +func (p *Search) Options(request *builder.Request) map[interface{}]interface{} { + return nil +} + +// 单向联动,返回数据类型:map[string]string{"field": "you_want_load_field","api": "admin/resource_name/action/select-options"} +func (p *Search) Load(request *builder.Request) map[string]string { + return nil +} diff --git a/pkg/builder/searches/select.go b/pkg/builder/searches/select.go new file mode 100644 index 0000000..464ee81 --- /dev/null +++ b/pkg/builder/searches/select.go @@ -0,0 +1,12 @@ +package searches + +type Select struct { + Search +} + +// 初始化 +func (p *Select) ParentInit() interface{} { + p.Component = "select" + + return p +} diff --git a/pkg/builder/template/admindashboard/admindashboard.go b/pkg/builder/template/admindashboard/admindashboard.go new file mode 100644 index 0000000..04a550c --- /dev/null +++ b/pkg/builder/template/admindashboard/admindashboard.go @@ -0,0 +1,110 @@ +package admindashboard + +import ( + "reflect" + + "github.com/quarkcms/quark-go/pkg/builder" + "github.com/quarkcms/quark-go/pkg/builder/template" + "github.com/quarkcms/quark-go/pkg/component/admin/card" + "github.com/quarkcms/quark-go/pkg/component/admin/descriptions" + "github.com/quarkcms/quark-go/pkg/component/admin/grid" + "github.com/quarkcms/quark-go/pkg/component/admin/statistic" + "github.com/quarkcms/quark-go/pkg/dal/db" + "github.com/quarkcms/quark-go/pkg/msg" +) + +// 后台登录模板 +type Template struct { + template.AdminTemplate + Title string // 标题 + SubTitle string // 子标题 +} + +// 初始化 +func (p *Template) Init() interface{} { + p.TemplateInit() + + return p +} + +// 初始化模板 +func (p *Template) TemplateInit() interface{} { + + // 初始化数据对象 + p.DB = db.Client + + // 清空路由 + p.Routes = nil + + // 注册路由 + p.AddRoute("/api/admin/dashboard/:resource/index", "Render") // 后台仪表盘路由 + + // 标题 + p.Title = "仪表盘" + + return p +} + +// 内容 +func (p *Template) Cards(request *builder.Request) interface{} { + return nil +} + +// 组件渲染 +func (p *Template) Render(request *builder.Request, resource *builder.Resource, templateInstance interface{}) interface{} { + cards := templateInstance.(interface { + Cards(*builder.Request) interface{} + }).Cards(request) + if cards == nil { + return msg.Error("请实现Cards内容", "") + } + + var cols []interface{} + var body []interface{} + var colNum int = 0 + for key, v := range cards.([]interface{}) { + + // 断言statistic组件类型 + statistic, ok := v.(interface{ Calculate() *statistic.Component }) + item := (&card.Component{}).Init() + if ok { + item = item.SetBody(statistic.Calculate()) + } else { + // 断言descriptions组件类型 + descriptions, ok := v.(interface { + Calculate() *descriptions.Component + }) + if ok { + item = item.SetBody(descriptions.Calculate()) + } + } + + col := reflect. + ValueOf(v). + Elem(). + FieldByName("Col").Int() + colInfo := (&grid.Col{}).Init().SetSpan(int(col)).SetBody(item) + cols = append(cols, colInfo) + colNum = colNum + int(col) + if colNum%24 == 0 { + row := (&grid.Row{}).Init().SetGutter(8).SetBody(cols) + if key != 1 { + row = row.SetStyle(map[string]interface{}{"marginTop": "20px"}) + } + body = append(body, row) + cols = nil + } + } + + if cols != nil { + row := (&grid.Row{}).Init().SetGutter(8).SetBody(cols) + if colNum > 24 { + row = row.SetStyle(map[string]interface{}{"marginTop": "20px"}) + } + body = append(body, row) + } + + return templateInstance.(interface { + PageComponentRender(request *builder.Request, templateInstance interface{}, body interface{}) interface{} + }).PageComponentRender(request, templateInstance, body) +} diff --git a/pkg/builder/template/adminlogin/adminlogin.go b/pkg/builder/template/adminlogin/adminlogin.go new file mode 100644 index 0000000..cdbac08 --- /dev/null +++ b/pkg/builder/template/adminlogin/adminlogin.go @@ -0,0 +1,174 @@ +package adminlogin + +import ( + "reflect" + "time" + + "github.com/quarkcms/quark-go/pkg/builder" + "github.com/quarkcms/quark-go/pkg/builder/template" + "github.com/quarkcms/quark-go/pkg/component/admin/login" + "github.com/quarkcms/quark-go/pkg/dal/db" + "github.com/quarkcms/quark-go/pkg/msg" +) + +// 后台登录模板 +type Template struct { + template.AdminTemplate + Api string // 登录接口 + Redirect string // 登录后跳转地址 + Logo interface{} // 登录页面Logo + Title string // 标题 + Description string // 描述 + Copyright string // 版权信息 + Links []map[string]interface{} // 友情链接 +} + +// 初始化 +func (p *Template) Init() interface{} { + p.TemplateInit() + + return p +} + +// 初始化模板 +func (p *Template) TemplateInit() interface{} { + + // 初始化数据对象 + p.DB = db.Client + + // 清空路由 + p.Routes = nil + + // 注册路由 + p.AddRoute("/api/admin/login/:resource/index", "Render") // 渲染登录页面路由 + p.AddRoute("/api/admin/login/:resource/handle", "Handle") // 后台登录执行路由 + p.AddRoute("/api/admin/login/:resource/captchaId", "CaptchaId") // 后台登录获取验证码ID路由 + p.AddRoute("/api/admin/login/:resource/captcha/:id", "Captcha") // 后台登录验证码路由 + p.AddRoute("/api/admin/logout/:resource/handle", "Logout") // 后台退出执行路由 + + // 标题 + p.Title = "QuarkGo" + + // 跳转地址 + p.Redirect = "/index?api=/api/admin/dashboard/index/index" + + // 描述 + p.Description = "信息丰富的世界里,唯一稀缺的就是人类的注意力" + + // 版权 + p.Copyright = time.Now().Format("2006") + " QuarkGo" + + // 友情链接 + p.Links = []map[string]interface{}{ + { + "title": "Quark", + "href": "http://www.quarkcms.com/", + }, + { + "title": "爱小圈", + "href": "http://www.ixiaoquan.com", + }, + { + "title": "Github", + "href": "https://github.com/quarkcms", + }, + } + + return p +} + +// 验证码ID +func (p *Template) CaptchaId(request *builder.Request, resource *builder.Resource, templateInstance interface{}) interface{} { + + return msg.Error("请实现创建验证码ID方法", "") +} + +// 生成验证码 +func (p *Template) Captcha(request *builder.Request, resource *builder.Resource, templateInstance interface{}) interface{} { + + return msg.Error("请实现生成验证码方法", "") +} + +// 登录方法 +func (p *Template) Handle(request *builder.Request, resource *builder.Resource, templateInstance interface{}) interface{} { + + return msg.Error("请实现登录方法", "") +} + +// 退出方法 +func (p *Template) Logout(request *builder.Request, resource *builder.Resource, templateInstance interface{}) interface{} { + + return msg.Error("请实现退出方法", "") +} + +// 组件渲染 +func (p *Template) Render(request *builder.Request, resource *builder.Resource, templateInstance interface{}) interface{} { + + // 默认登录接口 + defaultLoginApi := resource.RouteToResourceUrl("/api/admin/login/:resource/handle") + + // 登录接口 + loginApi := reflect. + ValueOf(templateInstance). + Elem(). + FieldByName("Api").String() + if loginApi != "" { + defaultLoginApi = loginApi + } + + // 登录后跳转地址 + redirect := reflect. + ValueOf(templateInstance). + Elem(). + FieldByName("Redirect").String() + + // Logo + logo := reflect. + ValueOf(templateInstance). + Elem(). + FieldByName("Logo").Interface() + + // 标题 + title := reflect. + ValueOf(templateInstance). + Elem(). + FieldByName("Title").String() + + // 描述 + description := reflect. + ValueOf(templateInstance). + Elem(). + FieldByName("Description").String() + + // 获取验证码ID链接 + captchaIdUrl := resource.RouteToResourceUrl("/api/admin/login/:resource/captchaId") + + // 验证码链接 + captchaUrl := resource.RouteToResourceUrl("/api/admin/login/:resource/captcha/:id") + + // 版权信息 + copyright := reflect. + ValueOf(templateInstance). + Elem(). + FieldByName("Copyright").String() + + // 友情链接 + links := reflect. + ValueOf(templateInstance). + Elem(). + FieldByName("Links").Interface() + + component := (&login.Component{}). + SetApi(defaultLoginApi). + SetRedirect(redirect). + SetLogo(logo). + SetTitle(title). + SetDescription(description). + SetCaptchaIdUrl(captchaIdUrl). + SetCaptchaUrl(captchaUrl). + SetCopyright(copyright). + SetLinks(links.([]map[string]interface{})). + JsonSerialize() + + return component +} diff --git a/pkg/builder/template/adminresource/handlers_action.go b/pkg/builder/template/adminresource/handlers_action.go new file mode 100644 index 0000000..07fc67a --- /dev/null +++ b/pkg/builder/template/adminresource/handlers_action.go @@ -0,0 +1,67 @@ +package adminresource + +import ( + "reflect" + "strings" + + "github.com/quarkcms/quark-go/pkg/builder" + "github.com/quarkcms/quark-go/pkg/dal/db" + "gorm.io/gorm" +) + +type ActionRequest struct{} + +// 执行行为 +func (p *ActionRequest) Handle(request *builder.Request, templateInstance interface{}) interface{} { + var result interface{} + modelInstance := reflect. + ValueOf(templateInstance). + Elem(). + FieldByName("Model").Interface() + model := db.Client.Model(&modelInstance) + + id := request.Query("id") + if id != "" { + if strings.Contains(id.(string), ",") { + model.Where("id IN ?", strings.Split(id.(string), ",")) + } else { + model.Where("id = ?", id) + } + } + + actions := templateInstance.(interface { + Actions(request *builder.Request) []interface{} + }).Actions(request) + + for _, v := range actions { + // uri唯一标识 + uriKey := v.(interface { + GetUriKey(interface{}) string + }).GetUriKey(v) + + actionType := v.(interface{ GetActionType() string }).GetActionType() + if actionType == "dropdown" { + dropdownActions := v.(interface{ GetActions() []interface{} }).GetActions() + for _, dropdownAction := range dropdownActions { + // uri唯一标识 + uriKey := dropdownAction.(interface { + GetUriKey(interface{}) string + }).GetUriKey(dropdownAction) + + if request.Param("uriKey") == uriKey { + result = dropdownAction.(interface { + Handle(*builder.Request, *gorm.DB) interface{} + }).Handle(request, model) + } + } + } else { + if request.Param("uriKey") == uriKey { + result = v.(interface { + Handle(*builder.Request, *gorm.DB) interface{} + }).Handle(request, model) + } + } + } + + return result +} diff --git a/pkg/builder/template/adminresource/handlers_detail.go b/pkg/builder/template/adminresource/handlers_detail.go new file mode 100644 index 0000000..f53c1cc --- /dev/null +++ b/pkg/builder/template/adminresource/handlers_detail.go @@ -0,0 +1,65 @@ +package adminresource + +import ( + "reflect" + + "github.com/quarkcms/quark-go/pkg/builder" + "github.com/quarkcms/quark-go/pkg/dal/db" + "github.com/quarkcms/quark-go/pkg/msg" +) + +type DetailRequest struct{} + +// 表单数据 +func (p *DetailRequest) FillData(request *builder.Request, templateInstance interface{}) map[string]interface{} { + result := map[string]interface{}{} + id := request.Query("id", "") + if id == "" { + return result + } + + modelInstance := reflect. + ValueOf(templateInstance). + Elem(). + FieldByName("Model").Interface() + model := db.Client.Model(&modelInstance) + model.Where("id = ?", id).First(&result) + + // 获取列表字段 + detailFields := templateInstance.(interface { + DetailFields(request *builder.Request, templateInstance interface{}) interface{} + }).DetailFields(request, templateInstance) + + // 给实例的Field属性赋值 + templateInstance.(interface { + SetField(fieldData map[string]interface{}) interface{} + }).SetField(result) + + fields := make(map[string]interface{}) + for _, field := range detailFields.([]interface{}) { + + // 字段名 + name := reflect. + ValueOf(field). + Elem(). + FieldByName("Name").String() + + if result[name] != nil { + fields[name] = result[name] + } + } + + return fields +} + +// 获取表单初始化数据 +func (p *DetailRequest) Values(request *builder.Request, templateInstance interface{}) interface{} { + data := p.FillData(request, templateInstance) + + // 断言BeforeEditing方法,获取初始数据 + data = templateInstance.(interface { + BeforeDetailShowing(*builder.Request, map[string]interface{}) map[string]interface{} + }).BeforeDetailShowing(request, data) + + return msg.Success("获取成功", "", data) +} diff --git a/pkg/builder/template/adminresource/handlers_edit.go b/pkg/builder/template/adminresource/handlers_edit.go new file mode 100644 index 0000000..c85e937 --- /dev/null +++ b/pkg/builder/template/adminresource/handlers_edit.go @@ -0,0 +1,65 @@ +package adminresource + +import ( + "reflect" + + "github.com/quarkcms/quark-go/pkg/builder" + "github.com/quarkcms/quark-go/pkg/dal/db" + "github.com/quarkcms/quark-go/pkg/msg" +) + +type EditRequest struct{} + +// 表单数据 +func (p *EditRequest) FillData(request *builder.Request, templateInstance interface{}) map[string]interface{} { + result := map[string]interface{}{} + id := request.Query("id", "") + if id == "" { + return result + } + + modelInstance := reflect. + ValueOf(templateInstance). + Elem(). + FieldByName("Model").Interface() + model := db.Client.Model(&modelInstance) + model.Where("id = ?", id).First(&result) + + // 获取列表字段 + updateFields := templateInstance.(interface { + UpdateFields(request *builder.Request, templateInstance interface{}) interface{} + }).UpdateFields(request, templateInstance) + + // 给实例的Field属性赋值 + templateInstance.(interface { + SetField(fieldData map[string]interface{}) interface{} + }).SetField(result) + + fields := make(map[string]interface{}) + for _, field := range updateFields.([]interface{}) { + + // 字段名 + name := reflect. + ValueOf(field). + Elem(). + FieldByName("Name").String() + + if result[name] != nil { + fields[name] = result[name] + } + } + + return fields +} + +// 获取表单初始化数据 +func (p *EditRequest) Values(request *builder.Request, templateInstance interface{}) interface{} { + data := p.FillData(request, templateInstance) + + // 断言BeforeEditing方法,获取初始数据 + data = templateInstance.(interface { + BeforeEditing(*builder.Request, map[string]interface{}) map[string]interface{} + }).BeforeEditing(request, data) + + return msg.Success("获取成功", "", data) +} diff --git a/pkg/builder/template/adminresource/handlers_editable.go b/pkg/builder/template/adminresource/handlers_editable.go new file mode 100644 index 0000000..88607eb --- /dev/null +++ b/pkg/builder/template/adminresource/handlers_editable.go @@ -0,0 +1,38 @@ +package adminresource + +import ( + "reflect" + + "github.com/quarkcms/quark-go/pkg/builder" + "github.com/quarkcms/quark-go/pkg/dal/db" + "github.com/quarkcms/quark-go/pkg/msg" +) + +type EditableRequest struct{} + +// 执行行为 +func (p *EditableRequest) Handle(request *builder.Request, templateInstance interface{}) interface{} { + modelInstance := reflect. + ValueOf(templateInstance). + Elem(). + FieldByName("Model").Interface() + model := db.Client.Model(&modelInstance) + + data := request.AllQuerys() + for k, v := range data { + if v == "true" { + v = 1 + } + if v == "false" { + v = 0 + } + data[k] = v + } + + err := model.Where("id = ?", data["id"]).Updates(data).Error + if err != nil { + msg.Error(err.Error(), "") + } + + return msg.Success("操作成功", "", "") +} diff --git a/pkg/builder/template/adminresource/handlers_export.go b/pkg/builder/template/adminresource/handlers_export.go new file mode 100644 index 0000000..c32a7ab --- /dev/null +++ b/pkg/builder/template/adminresource/handlers_export.go @@ -0,0 +1,269 @@ +package adminresource + +import ( + "encoding/json" + "reflect" + "strconv" + "strings" + + "github.com/quarkcms/quark-go/pkg/builder" + "github.com/quarkcms/quark-go/pkg/dal/db" + "github.com/xuri/excelize/v2" + "gorm.io/gorm" +) + +type ExportRequest struct{} + +// 执行行为 +func (p *ExportRequest) Handle(request *builder.Request, templateInstance interface{}) interface{} { + data := p.QueryData(request, templateInstance) + + // 获取列表字段 + fields := templateInstance.(interface { + ExportFields(request *builder.Request, templateInstance interface{}) interface{} + }).ExportFields(request, templateInstance) + + f := excelize.NewFile() + index := f.NewSheet("Sheet1") + rowData := map[string]interface{}{} + + var a = 'a' + for _, fieldValue := range fields.([]interface{}) { + Label := reflect. + ValueOf(fieldValue). + Elem(). + FieldByName("Label"). + String() + f.SetCellValue("Sheet1", string(a)+"1", Label) + a++ + } + + for dataKey, dataValue := range data.([]interface{}) { + var a = 'a' + for _, fieldValue := range fields.([]interface{}) { + + name := reflect. + ValueOf(fieldValue). + Elem(). + FieldByName("Name").String() + + component := reflect. + ValueOf(fieldValue). + Elem(). + FieldByName("Component").String() + + switch component { + case "inputNumberField": + rowData[name] = dataValue.(map[string]interface{})[name] + case "textField": + rowData[name] = dataValue.(map[string]interface{})[name] + case "selectField": + options := reflect. + ValueOf(fieldValue). + Elem(). + FieldByName("Options").Interface() + rowData[name] = p.getOptionValue(options, dataValue.(map[string]interface{})[name]) + case "cascaderField": + options := reflect. + ValueOf(fieldValue). + Elem(). + FieldByName("Options").Interface() + rowData[name] = p.getOptionValue(options, dataValue.(map[string]interface{})[name]) + case "checkboxField": + options := reflect. + ValueOf(fieldValue). + Elem(). + FieldByName("Options").Interface() + rowData[name] = p.getOptionValue(options, dataValue.(map[string]interface{})[name]) + case "radioField": + options := reflect. + ValueOf(fieldValue). + Elem(). + FieldByName("Options").Interface() + rowData[name] = p.getOptionValue(options, dataValue.(map[string]interface{})[name]) + case "switchField": + options := reflect. + ValueOf(fieldValue). + Elem(). + FieldByName("Options").Interface() + rowData[name] = p.getSwitchValue(options, dataValue.(map[string]interface{})[name].(int)) + default: + rowData[name] = dataValue.(map[string]interface{})[name] + } + + f.SetCellValue("Sheet1", string(a)+strconv.Itoa(dataKey+2), rowData[name]) + a++ + } + } + + f.SetActiveSheet(index) + buf, _ := f.WriteToBuffer() + + return buf.Bytes() +} + +// 获取属性值 +func (p *ExportRequest) getOptionValue(options interface{}, value interface{}) string { + result := "" + arr := []interface{}{} + + if value, ok := value.(string); ok { + if strings.Contains(value, "[") || strings.Contains(value, "{") { + json.Unmarshal([]byte(value), &arr) + } + } + + if len(arr) > 0 { + if getOptions, ok := options.([]interface{}); ok { + for _, option := range getOptions { + for _, v := range arr { + if v == option.(map[string]interface{})["value"] { + result = result + option.(map[string]interface{})["label"].(string) + } + } + } + } + if getOptions, ok := options.([]map[string]interface{}); ok { + for _, option := range getOptions { + for _, v := range arr { + if v == option["value"] { + result = result + option["label"].(string) + } + } + } + } + } else { + if getOptions, ok := options.([]interface{}); ok { + for _, option := range getOptions { + if value == option.(map[string]interface{})["value"] { + result = option.(map[string]interface{})["label"].(string) + } + } + } + if getOptions, ok := options.([]map[string]interface{}); ok { + for _, option := range getOptions { + if value == option["value"] { + result = option["label"].(string) + } + } + } + } + + return result +} + +// 获取开关组件值 +func (p *ExportRequest) getSwitchValue(options interface{}, value int) string { + if value == 1 { + return options.(map[string]interface{})["on"].(string) + } else { + return options.(map[string]interface{})["off"].(string) + } +} + +// 列表查询 +func (p *ExportRequest) QueryData(request *builder.Request, templateInstance interface{}) interface{} { + var lists []map[string]interface{} + modelInstance := reflect. + ValueOf(templateInstance). + Elem(). + FieldByName("Model").Interface() + model := db.Client.Model(&modelInstance) + + // 搜索项 + searches := templateInstance.(interface { + Searches(request *builder.Request) []interface{} + }).Searches(request) + + // 过滤项,预留 + filters := templateInstance.(interface { + Filters(request *builder.Request) []interface{} + }).Filters(request) + + query := templateInstance.(interface { + BuildExportQuery(request *builder.Request, templateInstance interface{}, query *gorm.DB, search []interface{}, filters []interface{}, columnFilters map[string]interface{}, orderings map[string]interface{}) *gorm.DB + }).BuildExportQuery(request, templateInstance, model, searches, filters, p.columnFilters(request), p.orderings(request)) + + query.Find(&lists) + + // 返回解析列表 + return p.performsList(request, templateInstance, lists) +} + +/** + * Get the column filters for the request. + * + * @return array + */ +func (p *ExportRequest) columnFilters(request *builder.Request) map[string]interface{} { + data := request.AllQuerys() + result, ok := data["filter"].(map[string]interface{}) + if ok == false { + return map[string]interface{}{} + } + + return result +} + +/** + * Get the orderings for the request. + * + * @return array + */ +func (p *ExportRequest) orderings(request *builder.Request) map[string]interface{} { + data := request.AllQuerys() + result, ok := data["sorter"].(map[string]interface{}) + if ok == false { + return map[string]interface{}{} + } + + return result +} + +// 处理列表 +func (p *ExportRequest) performsList(request *builder.Request, templateInstance interface{}, lists []map[string]interface{}) []interface{} { + result := []map[string]interface{}{} + + // 获取列表字段 + exportFields := templateInstance.(interface { + ExportFields(request *builder.Request, templateInstance interface{}) interface{} + }).ExportFields(request, templateInstance) + + // 解析字段回调函数 + for _, v := range lists { + + // 给实例的Field属性赋值 + templateInstance.(interface { + SetField(fieldData map[string]interface{}) interface{} + }).SetField(v) + + fields := make(map[string]interface{}) + for _, field := range exportFields.([]interface{}) { + + // 字段名 + name := reflect. + ValueOf(field). + Elem(). + FieldByName("Name").String() + + // 获取实例的回调函数 + callback := field.(interface{ GetCallback() interface{} }).GetCallback() + + if callback != nil { + getCallback := callback.(func() interface{}) + fields[name] = getCallback() + } else { + if v[name] != nil { + fields[name] = v[name] + } + } + } + + result = append(result, fields) + } + + // 回调处理列表字段值 + return templateInstance.(interface { + BeforeExporting(request *builder.Request, result []map[string]interface{}) []interface{} + }).BeforeExporting(request, result) +} diff --git a/pkg/builder/template/adminresource/handlers_import.go b/pkg/builder/template/adminresource/handlers_import.go new file mode 100644 index 0000000..fd2b7f0 --- /dev/null +++ b/pkg/builder/template/adminresource/handlers_import.go @@ -0,0 +1,356 @@ +package adminresource + +import ( + "encoding/json" + "os" + "reflect" + "strconv" + "strings" + + models "github.com/quarkcms/quark-go/pkg/app/model" + "github.com/quarkcms/quark-go/pkg/builder" + "github.com/quarkcms/quark-go/pkg/component/admin/space" + "github.com/quarkcms/quark-go/pkg/component/admin/tpl" + "github.com/quarkcms/quark-go/pkg/dal/db" + "github.com/quarkcms/quark-go/pkg/msg" + "github.com/quarkcms/quark-go/pkg/rand" + "github.com/xuri/excelize/v2" + "gorm.io/gorm" +) + +type ImportRequest struct{} + +// 执行行为 +func (p *ImportRequest) Handle(request *builder.Request, templateInstance interface{}) interface{} { + data := map[string]interface{}{} + json.Unmarshal(request.Body(), &data) + fileId := data["fileId"] + getFileId := 0 + + if value, ok := fileId.(map[string]interface{}); ok { + if value, ok := value["0"]; ok { + if value, ok := value.(map[string]interface{})["id"]; ok { + getFileId = int(value.(float64)) + } + } + } + + if getFileId == 0 { + return msg.Error("参数错误!", "") + } + + modelInstance := reflect. + ValueOf(templateInstance). + Elem(). + FieldByName("Model").Interface() + model := db.Client.Model(&modelInstance) + + importData, err := (&models.File{}).GetExcelData(getFileId) + if err != nil { + return msg.Error(err.Error(), "") + } + + // 表格头部 + importHead := importData[0] + + // 去除表格头部 + importData = importData[1:] + + // 导入前回调 + lists := templateInstance.(interface { + BeforeImporting(request *builder.Request, list [][]interface{}) [][]interface{} + }).BeforeImporting(request, importData) + + importResult := true + importTotalNum := len(lists) + importSuccessedNum := 0 + importFailedNum := 0 + importFailedData := [][]interface{}{} + + // 获取字段 + fields := templateInstance.(interface { + ImportFields(request *builder.Request, templateInstance interface{}) interface{} + }).ImportFields(request, templateInstance) + + for _, item := range lists { + + formValues := p.transformFormValues(fields, item) + + validator := templateInstance.(interface { + ValidatorForImport(request *builder.Request, templateInstance interface{}, data map[string]interface{}) error + }).ValidatorForImport(request, templateInstance, formValues) + + if validator != nil { + + importResult = false + importFailedNum = importFailedNum + 1 // 记录错误条数 + item = append(item, validator.Error()) // 记录错误信息 + + //记录错误数据 + importFailedData = append(importFailedData, item) + } + + submitData := templateInstance.(interface { + BeforeSaving(request *builder.Request, data map[string]interface{}) interface{} + }).BeforeSaving(request, formValues) // 保存前回调 + + if value, ok := submitData.(error); ok { + importResult = false + importFailedNum = importFailedNum + 1 // 记录错误条数 + item = append(item, value.Error()) // 记录错误信息 + + //记录错误数据 + importFailedData = append(importFailedData, item) + } + + data := p.getSubmitData( + fields, + submitData, + ) + + // 获取对象 + getModel := model.Create(data) + + if getModel.Error != nil { + importResult = false + importFailedNum = importFailedNum + 1 // 记录错误条数 + item = append(item, getModel.Error.Error()) // 记录错误信息 + + //记录错误数据 + importFailedData = append(importFailedData, item) + } else { + templateInstance.(interface { + AfterSaved(request *builder.Request, model *gorm.DB) interface{} + }).AfterSaved(request, getModel) + + importSuccessedNum = importSuccessedNum + 1 + } + } + + if importResult { + return msg.Success("操作成功!", strings.Replace("/index?api="+IndexRoute, ":resource", request.Param("resource"), -1), "") + } else { + importHead = append(importHead, "错误信息") + + f := excelize.NewFile() + // Create a new sheet. + index := f.NewSheet("Sheet1") + + //定义一个字符 变量a 是一个byte类型的 表示单个字符 + var a = 'a' + + //生成26个字符 + for i := 1; i <= len(importHead); i++ { + // 设置单元格的值 + f.SetCellValue("Sheet1", string(a)+"1", importHead[i-1]) + a++ + } + + for k, v := range importFailedData { + //定义一个字符 变量a 是一个byte类型的 表示单个字符 + var a = 'a' + + //生成26个字符 + for i := 1; i <= len(v); i++ { + // 设置单元格的值 + f.SetCellValue("Sheet1", string(a)+strconv.Itoa(k+2), v[i-1]) + a++ + } + } + + f.SetActiveSheet(index) + + filePath := "./storage/app/public/failImports/" + fileName := rand.MakeAlphanumeric(40) + ".xlsx" + + // 不存在路径,则创建 + if isExist(filePath) == false { + err := os.MkdirAll(filePath, 0666) + if err != nil { + return msg.Error(err.Error(), "") + } + } + + if err := f.SaveAs(filePath + fileName); err != nil { + return msg.Error(err.Error(), "") + } + + importTotalNumTpl := (&tpl.Component{}). + Init(). + SetBody("导入总量: " + strconv.Itoa(importTotalNum)) + + importSuccessedNumTpl := (&tpl.Component{}). + Init(). + SetBody("成功数量: " + strconv.Itoa(importSuccessedNum)) + + importFailedNumTpl := (&tpl.Component{}). + Init(). + SetBody("失败数量: " + strconv.Itoa(importFailedNum) + " 下载失败数据") + + component := (&space.Component{}). + Init(). + SetBody([]interface{}{ + importTotalNumTpl, + importSuccessedNumTpl, + importFailedNumTpl, + }). + SetDirection("vertical"). + SetSize("small"). + SetStyle(map[string]interface{}{ + "marginLeft": "50px", + "marginBottom": "20px", + }) + + return component + } +} + +// 将表格数据转换成表单数据 +func (p *ImportRequest) transformFormValues(fields interface{}, data []interface{}) map[string]interface{} { + result := make(map[string]interface{}) + + for k, v := range fields.([]interface{}) { + if data[k] != nil { + + name := reflect. + ValueOf(v). + Elem(). + FieldByName("Name").String() + + result[name] = data[k] + } + } + + return result +} + +// 获取提交表单的数据 +func (p *ImportRequest) getSubmitData(fields interface{}, submitData interface{}) interface{} { + + result := make(map[string]interface{}) + + for _, v := range fields.([]interface{}) { + + component := reflect. + ValueOf(v). + Elem(). + FieldByName("Component").String() + + name := reflect. + ValueOf(v). + Elem(). + FieldByName("Name").String() + + switch component { + case "inputNumberField": + result[name] = submitData.(map[string]interface{})[name] + case "textField": + result[name] = strings.Trim(submitData.(map[string]interface{})[name].(string), "\n") + case "selectField": + options := reflect. + ValueOf(v). + Elem(). + FieldByName("Options").Interface() + + result[name] = p.getOptionValue(options, submitData.(map[string]interface{})[name].(string)) + case "cascaderField": + options := reflect. + ValueOf(v). + Elem(). + FieldByName("Options").Interface() + + result[name] = p.getOptionValue(options, submitData.(map[string]interface{})[name].(string)) + case "checkboxField": + options := reflect. + ValueOf(v). + Elem(). + FieldByName("Options").Interface() + + result[name] = p.getOptionValue(options, submitData.(map[string]interface{})[name].(string)) + case "radioField": + options := reflect. + ValueOf(v). + Elem(). + FieldByName("Options").Interface() + + result[name] = p.getOptionValue(options, submitData.(map[string]interface{})[name].(string)) + case "switchField": + options := reflect. + ValueOf(v). + Elem(). + FieldByName("Options").Interface() + + result[name] = p.getSwitchValue(options, submitData.(map[string]interface{})[name].(string)) + default: + result[name] = submitData.(map[string]interface{})[name] + } + + if getValue, ok := result[name].([]interface{}); ok { + result[name], _ = json.Marshal(getValue) + } + + if getValue, ok := result[name].([]map[string]interface{}); ok { + result[name], _ = json.Marshal(getValue) + } + + if getValue, ok := result[name].(map[string]interface{}); ok { + result[name], _ = json.Marshal(getValue) + } + } + + return result +} + +// 获取属性值 +func (p *ImportRequest) getOptionValue(options interface{}, label string) interface{} { + var result1 []interface{} + var result2 interface{} + + labels1 := strings.Split(label, ",") + labels2 := strings.Split(label, ",") + + if len(labels1) > 1 || len(labels2) > 1 { + labels := []string{} + if len(labels1) > 1 { + labels = labels1 + } + + if len(labels2) > 1 { + labels = labels2 + } + + for _, v := range options.([]map[string]interface{}) { + for _, label := range labels { + if v["label"] == label { + result1 = append(result1, v["value"]) + } + } + } + } else { + for _, v := range options.([]map[string]interface{}) { + if v["label"] == label { + result2 = v["value"] + } + } + } + + if len(result1) > 0 { + return result1 + } + + return result2 +} + +// 获取开关组件值 +func (p *ImportRequest) getSwitchValue(options interface{}, label string) interface{} { + return (options.(map[string]interface{})["on"] == label) +} + +// if file or directory exits +func isExist(path string) bool { + _, err := os.Stat(path) + if os.IsNotExist(err) { + return false + } + return true +} diff --git a/pkg/builder/template/adminresource/handlers_import_template.go b/pkg/builder/template/adminresource/handlers_import_template.go new file mode 100644 index 0000000..995cc4a --- /dev/null +++ b/pkg/builder/template/adminresource/handlers_import_template.go @@ -0,0 +1,240 @@ +package adminresource + +import ( + "fmt" + "reflect" + "strings" + + "github.com/quarkcms/quark-go/pkg/builder" + "github.com/xuri/excelize/v2" +) + +type ImportTemplateRequest struct{} + +// 导入数据模板 +func (p *ImportTemplateRequest) Handle(request *builder.Request, templateInstance interface{}) interface{} { + + fields := templateInstance.(interface { + ImportFields(request *builder.Request, templateInstance interface{}) interface{} + }).ImportFields(request, templateInstance) + + exportTitles := []string{} + for _, v := range fields.([]interface{}) { + label := reflect. + ValueOf(v). + Elem(). + FieldByName("Label").String() + + exportTitles = append(exportTitles, label+p.getFieldRemark(v)) + } + + f := excelize.NewFile() + // 创建一个工作表 + index := f.NewSheet("Sheet1") + + //定义一个字符 变量a 是一个byte类型的 表示单个字符 + var a = 'a' + + //生成26个字符 + for i := 1; i <= len(exportTitles); i++ { + // 设置单元格的值 + f.SetCellValue("Sheet1", string(a)+"1", exportTitles[i-1]) + a++ + } + + // 设置工作簿的默认工作表 + f.SetActiveSheet(index) + buf, _ := f.WriteToBuffer() + + return buf.Bytes() +} + +// 导入字段提示信息 +func (p *ImportTemplateRequest) getFieldRemark(field interface{}) string { + remark := "" + + component := reflect. + ValueOf(field). + Elem(). + FieldByName("Component").String() + + switch component { + case "inputNumberField": + + } + + switch component { + case "inputNumberField": + remark = "数字格式" + + case "textField": + remark = "" + + case "selectField": + + options := reflect. + ValueOf(field). + Elem(). + FieldByName("Options").Interface() + + mode := reflect. + ValueOf(field). + Elem(). + FieldByName("Mode").String() + + fieldOptionLabel := p.getFieldOptionLabels(options) + + if mode != "" { + remark = "可多选:" + fieldOptionLabel + ";多值请用“,”分割" + } else { + remark = "可选:" + fieldOptionLabel + } + + case "cascaderField": + remark = "级联格式,例如:省,市,县" + + case "checkboxField": + options := reflect. + ValueOf(field). + Elem(). + FieldByName("Options").Interface() + + remark = "可多选项:" + p.getFieldOptionLabels(options) + ";多值请用“,”分割" + + case "radioField": + options := reflect. + ValueOf(field). + Elem(). + FieldByName("Options").Interface() + + remark = "可选项:" + p.getFieldOptionLabels(options) + + case "switchField": + options := reflect. + ValueOf(field). + Elem(). + FieldByName("Options").Interface() + + remark = "可选项:" + p.getSwitchLabels(options) + + case "dateField": + remark = "日期格式,例如:1987-02-15" + + case "datetimeField": + remark = "日期时间格式,例如:1987-02-15 20:00:00" + } + + rules := reflect. + ValueOf(field). + Elem(). + FieldByName("Rules").Interface() + + creationRules := reflect. + ValueOf(field). + Elem(). + FieldByName("CreationRules").Interface() + + items := []interface{}{} + + for _, v := range rules.([]string) { + items = append(items, v) + } + + for _, v := range creationRules.([]string) { + items = append(items, v) + } + + ruleMessage := p.getFieldRuleMessage(items) + + if ruleMessage != "" { + remark = remark + " 条件:" + ruleMessage + } + + if remark != "" { + remark = "(" + remark + ")" + } + + return remark +} + +// 导入字段的规则 +func (p *ImportTemplateRequest) getFieldRuleMessage(rules []interface{}) string { + var message []string + rule := "" + + for _, v := range rules { + var arr []string + + if strings.Contains(v.(string), ":") { + arr = strings.Split(v.(string), ":") + rule = arr[0] + } else { + rule = v.(string) + } + + switch rule { + + case "required": + // 必填 + message = append(message, "必填") + + case "min": + // 最小字符串数 + message = append(message, "大于"+arr[1]+"个字符") + + case "max": + // 最大字符串数 + message = append(message, "小于"+arr[1]+"个字符") + + case "email": + // 必须为邮箱 + message = append(message, "必须为邮箱格式") + + case "numeric": + // 必须为数字 + message = append(message, "必须为数字格式") + + case "url": + // 必须为url + message = append(message, "必须为链接格式") + + case "integer": + // 必须为整数 + message = append(message, "必须为整数格式") + + case "date": + // 必须为日期 + message = append(message, "必须为日期格式") + + case "boolean": + // 必须为布尔值 + message = append(message, "必须为布尔格式") + + case "unique": + // 必须为布尔值 + message = append(message, "不可重复") + } + } + + if len(message) > 0 { + return strings.Replace(strings.Trim(fmt.Sprint(message), "/"), " ", ",", -1) + } else { + return "" + } +} + +// 获取字段的可选值 +func (p *ImportTemplateRequest) getFieldOptionLabels(options interface{}) string { + result := []string{} + + for _, v := range options.([]map[string]interface{}) { + result = append(result, v["label"].(string)) + } + + return strings.Replace(strings.Trim(fmt.Sprint(result), "[]"), " ", ",", -1) +} + +// 获取开关组件值 +func (p *ImportTemplateRequest) getSwitchLabels(options interface{}) string { + return options.(map[string]interface{})["on"].(string) + "," + options.(map[string]interface{})["off"].(string) +} diff --git a/pkg/builder/template/adminresource/handlers_index.go b/pkg/builder/template/adminresource/handlers_index.go new file mode 100644 index 0000000..050815e --- /dev/null +++ b/pkg/builder/template/adminresource/handlers_index.go @@ -0,0 +1,152 @@ +package adminresource + +import ( + "reflect" + "strconv" + + "github.com/quarkcms/quark-go/pkg/builder" + "github.com/quarkcms/quark-go/pkg/dal/db" + "gorm.io/gorm" +) + +type IndexRequest struct{} + +// 列表查询 +func (p *IndexRequest) QueryData(request *builder.Request, templateInstance interface{}) interface{} { + var lists []map[string]interface{} + modelInstance := reflect. + ValueOf(templateInstance). + Elem(). + FieldByName("Model").Interface() + model := db.Client.Model(&modelInstance) + + // 搜索项 + searches := templateInstance.(interface { + Searches(request *builder.Request) []interface{} + }).Searches(request) + + // 过滤项,预留 + filters := templateInstance.(interface { + Filters(request *builder.Request) []interface{} + }).Filters(request) + + query := templateInstance.(interface { + BuildIndexQuery(request *builder.Request, templateInstance interface{}, query *gorm.DB, search []interface{}, filters []interface{}, columnFilters map[string]interface{}, orderings map[string]interface{}) *gorm.DB + }).BuildIndexQuery(request, templateInstance, model, searches, filters, p.columnFilters(request), p.orderings(request)) + + // 获取分页 + perPage := reflect. + ValueOf(templateInstance). + Elem(). + FieldByName("PerPage").Interface() + + // 不分页,直接返回lists + if reflect.TypeOf(perPage).String() != "int" { + query.Find(&lists) + + // 返回解析列表 + return p.performsList(request, templateInstance, lists) + } + + var total int64 + page := request.Query("page", "1") + pageSize := request.Query("pageSize", "10") + if pageSize != "" { + perPage, _ = strconv.Atoi(pageSize.(string)) + } + getPage, _ := strconv.Atoi(page.(string)) + + // 获取总数量 + query.Count(&total) + + // 获取列表 + query.Limit(perPage.(int)).Offset((getPage - 1) * perPage.(int)).Find(&lists) + + // 解析列表 + result := p.performsList(request, templateInstance, lists) + + return map[string]interface{}{ + "currentPage": getPage, + "perPage": perPage, + "total": total, + "items": result, + } +} + +/** + * Get the column filters for the request. + * + * @return array + */ +func (p *IndexRequest) columnFilters(request *builder.Request) map[string]interface{} { + data := request.AllQuerys() + result, ok := data["filter"].(map[string]interface{}) + if ok == false { + return map[string]interface{}{} + } + + return result +} + +/** + * Get the orderings for the request. + * + * @return array + */ +func (p *IndexRequest) orderings(request *builder.Request) map[string]interface{} { + data := request.AllQuerys() + result, ok := data["sorter"].(map[string]interface{}) + if ok == false { + return map[string]interface{}{} + } + + return result +} + +// 处理列表 +func (p *IndexRequest) performsList(request *builder.Request, templateInstance interface{}, lists []map[string]interface{}) []interface{} { + result := []map[string]interface{}{} + + // 获取列表字段 + indexFields := templateInstance.(interface { + IndexFields(request *builder.Request, templateInstance interface{}) interface{} + }).IndexFields(request, templateInstance) + + // 解析字段回调函数 + for _, v := range lists { + + // 给实例的Field属性赋值 + templateInstance.(interface { + SetField(fieldData map[string]interface{}) interface{} + }).SetField(v) + + fields := make(map[string]interface{}) + for _, field := range indexFields.([]interface{}) { + + // 字段名 + name := reflect. + ValueOf(field). + Elem(). + FieldByName("Name").String() + + // 获取实例的回调函数 + callback := field.(interface{ GetCallback() interface{} }).GetCallback() + + if callback != nil { + getCallback := callback.(func() interface{}) + fields[name] = getCallback() + } else { + if v[name] != nil { + fields[name] = v[name] + } + } + } + + result = append(result, fields) + } + + // 回调处理列表字段值 + return templateInstance.(interface { + BeforeIndexShowing(request *builder.Request, result []map[string]interface{}) []interface{} + }).BeforeIndexShowing(request, result) +} diff --git a/pkg/builder/template/adminresource/handlers_store.go b/pkg/builder/template/adminresource/handlers_store.go new file mode 100644 index 0000000..48aee97 --- /dev/null +++ b/pkg/builder/template/adminresource/handlers_store.go @@ -0,0 +1,114 @@ +package adminresource + +import ( + "encoding/json" + "reflect" + "time" + + "github.com/gobeam/stringy" + "github.com/quarkcms/quark-go/pkg/builder" + "github.com/quarkcms/quark-go/pkg/dal/db" + "github.com/quarkcms/quark-go/pkg/msg" + "gorm.io/gorm" +) + +type StoreRequest struct{} + +// 执行行为 +func (p *StoreRequest) Handle(request *builder.Request, templateInstance interface{}) interface{} { + modelInstance := reflect. + ValueOf(templateInstance). + Elem(). + FieldByName("Model").Interface() + model := db.Client.Model(&modelInstance) + + // 获取字段 + fields := templateInstance.(interface { + CreationFields(request *builder.Request, templateInstance interface{}) interface{} + }).CreationFields(request, templateInstance) + + data := map[string]interface{}{} + json.Unmarshal(request.Body(), &data) + data, err := templateInstance.(interface { + BeforeSaving(request *builder.Request, data map[string]interface{}) (map[string]interface{}, error) + }).BeforeSaving(request, data) + if err != nil { + msg.Error(err.Error(), "") + } + + validator := templateInstance.(interface { + ValidatorForCreation(request *builder.Request, templateInstance interface{}, data map[string]interface{}) error + }).ValidatorForCreation(request, templateInstance, data) + if validator != nil { + msg.Error(validator.Error(), "") + } + + for _, v := range fields.([]interface{}) { + + name := reflect. + ValueOf(v). + Elem(). + FieldByName("Name").String() + + formValue := data[name] + if getValue, ok := formValue.([]interface{}); ok { + formValue, _ = json.Marshal(getValue) + } + if getValue, ok := formValue.([]map[string]interface{}); ok { + formValue, _ = json.Marshal(getValue) + } + if getValue, ok := formValue.(map[string]interface{}); ok { + formValue, _ = json.Marshal(getValue) + } + if name != "" && formValue != nil { + fieldName := stringy.New(name).CamelCase("?", "") + reflectFieldName := reflect. + ValueOf(modelInstance). + Elem(). + FieldByName(fieldName) + var reflectValue reflect.Value + switch reflectFieldName.Type().String() { + case "int": + if value, ok := formValue.(bool); ok { + if value == true { + reflectValue = reflect.ValueOf(1) + } else { + reflectValue = reflect.ValueOf(0) + } + } + if value, ok := formValue.(float64); ok { + reflectValue = reflect.ValueOf(int(value)) + } + case "float64": + if value, ok := formValue.(float64); ok { + reflectValue = reflect.ValueOf(float64(value)) + } + case "float32": + if value, ok := formValue.(float64); ok { + reflectValue = reflect.ValueOf(float32(value)) + } + case "time.Time": + getTime, _ := time.ParseInLocation("2006-01-02 15:04:05", formValue.(string), time.Local) + reflectValue = reflect.ValueOf(getTime) + default: + reflectValue = reflect.ValueOf(formValue) + if reflect.ValueOf(formValue).Type().String() == "[]uint8" { + reflectValue = reflect.ValueOf(string(formValue.([]uint8))) + } + } + + if reflectFieldName.Type().String() != reflectValue.Type().String() { + return msg.Error("结构体类型与传参类型不一致!", "") + } + + reflectFieldName.Set(reflectValue) + } + } + + // 获取对象 + getModel := model.Create(modelInstance) + + return templateInstance.(interface { + AfterSaved(request *builder.Request, model *gorm.DB) interface{} + }).AfterSaved(request, getModel) +} diff --git a/pkg/builder/template/adminresource/handlers_update.go b/pkg/builder/template/adminresource/handlers_update.go new file mode 100644 index 0000000..6da41bc --- /dev/null +++ b/pkg/builder/template/adminresource/handlers_update.go @@ -0,0 +1,144 @@ +package adminresource + +import ( + "encoding/json" + "reflect" + "time" + + "github.com/gobeam/stringy" + "github.com/quarkcms/quark-go/pkg/builder" + "github.com/quarkcms/quark-go/pkg/dal/db" + "github.com/quarkcms/quark-go/pkg/msg" + "gorm.io/gorm" +) + +type UpdateRequest struct{} + +// 执行行为 +func (p *UpdateRequest) Handle(request *builder.Request, templateInstance interface{}) interface{} { + modelInstance := reflect. + ValueOf(templateInstance). + Elem(). + FieldByName("Model").Interface() + model := db.Client.Model(&modelInstance) + + // 获取字段 + fields := templateInstance.(interface { + UpdateFields(request *builder.Request, templateInstance interface{}) interface{} + }).UpdateFields(request, templateInstance) + + data := map[string]interface{}{} + json.Unmarshal(request.Body(), &data) + if data["id"] == "" { + return msg.Error("参数错误!", "") + } + + data, err := templateInstance.(interface { + BeforeSaving(request *builder.Request, data map[string]interface{}) (map[string]interface{}, error) + }).BeforeSaving(request, data) + if err != nil { + msg.Error(err.Error(), "") + } + + validator := templateInstance.(interface { + ValidatorForUpdate(request *builder.Request, templateInstance interface{}, data map[string]interface{}) error + }).ValidatorForUpdate(request, templateInstance, data) + if validator != nil { + return validator + } + + zeroValues := map[string]interface{}{} + for _, v := range fields.([]interface{}) { + + name := reflect. + ValueOf(v). + Elem(). + FieldByName("Name").String() + + formValue := data[name] + + if getValue, ok := formValue.([]interface{}); ok { + formValue, _ = json.Marshal(getValue) + } + + if getValue, ok := formValue.([]map[string]interface{}); ok { + formValue, _ = json.Marshal(getValue) + } + + if getValue, ok := formValue.(map[string]interface{}); ok { + formValue, _ = json.Marshal(getValue) + } + + if name != "" && formValue != nil { + fieldName := stringy.New(name).CamelCase("?", "") + + reflectFieldName := reflect. + ValueOf(modelInstance). + Elem(). + FieldByName(fieldName) + + var reflectValue reflect.Value + + switch reflectFieldName.Type().String() { + case "int": + if value, ok := formValue.(bool); ok { + if value == true { + reflectValue = reflect.ValueOf(1) + } else { + reflectValue = reflect.ValueOf(0) + zeroValues[fieldName] = 0 + } + } + + if value, ok := formValue.(float64); ok { + reflectValue = reflect.ValueOf(int(value)) + + // 因为gorm结构体不更新零值,使用map记录零值,单独更新 + if int(value) == 0 { + zeroValues[fieldName] = 0 + } + } + case "float64": + if value, ok := formValue.(float64); ok { + reflectValue = reflect.ValueOf(float64(value)) + + // 因为gorm结构体不更新零值,使用map记录零值,单独更新 + if int(value) == 0 { + zeroValues[fieldName] = 0 + } + } + case "float32": + if value, ok := formValue.(float64); ok { + reflectValue = reflect.ValueOf(float32(value)) + } + case "time.Time": + getTime, _ := time.ParseInLocation("2006-01-02 15:04:05", formValue.(string), time.Local) + reflectValue = reflect.ValueOf(getTime) + default: + reflectValue = reflect.ValueOf(formValue) + + if reflect.ValueOf(formValue).Type().String() == "[]uint8" { + reflectValue = reflect.ValueOf(string(formValue.([]uint8))) + } + } + + if reflectFieldName.Type().String() != reflectValue.Type().String() { + return msg.Error("结构体类型与传参类型不一致!", "") + } + + reflectFieldName.Set(reflectValue) + } + } + + // 获取对象 + getModel := model.Where("id = ?", data["id"]).Updates(modelInstance) + + // 因为gorm使用结构体,不更新零值,需要使用map更新零值 + if len(zeroValues) > 0 { + getModel = model.Where("id = ?", data["id"]).Updates(zeroValues) + } + + return templateInstance.(interface { + AfterSaved(request *builder.Request, model *gorm.DB) interface{} + }).AfterSaved(request, getModel) +} diff --git a/pkg/builder/template/adminresource/performs_queries.go b/pkg/builder/template/adminresource/performs_queries.go new file mode 100644 index 0000000..45a7c0c --- /dev/null +++ b/pkg/builder/template/adminresource/performs_queries.go @@ -0,0 +1,204 @@ +package adminresource + +import ( + "reflect" + + "github.com/quarkcms/quark-go/pkg/builder" + "gorm.io/gorm" + "gorm.io/gorm/clause" +) + +// 创建列表查询 +func (p *Template) BuildIndexQuery(request *builder.Request, templateInstance interface{}, query *gorm.DB, search []interface{}, filters []interface{}, columnFilters map[string]interface{}, orderings map[string]interface{}) *gorm.DB { + + // 初始化查询 + query = p.initializeQuery(request, templateInstance, query) + + // 执行列表查询,这里使用的是透传的实例 + query = templateInstance.(interface { + IndexQuery(*builder.Request, *gorm.DB) *gorm.DB + }).IndexQuery(request, query) + + // 执行搜索查询 + query = p.applySearch(request, query, search) + + // 执行过滤器查询 + query = p.applyFilters(query, filters) + + // 执行表格列上过滤器查询 + query = p.applyColumnFilters(query, columnFilters) + + // 获取默认排序 + defaultOrder := reflect. + ValueOf(templateInstance). + Elem(). + FieldByName("IndexOrder").String() + + if defaultOrder == "" { + defaultOrder = "id desc" + } + + // 执行排序查询 + query = p.applyOrderings(query, orderings, defaultOrder) + + return query +} + +// 创建详情页查询 +func (p *Template) BuildDetailQuery(request *builder.Request, templateInstance interface{}, query *gorm.DB) *gorm.DB { + // 初始化查询 + query = p.initializeQuery(request, templateInstance, query) + + // 执行列表查询,这里使用的是透传的实例 + query = templateInstance.(interface { + DetailQuery(*builder.Request, *gorm.DB) *gorm.DB + }).DetailQuery(request, query) + + return query +} + +// 创建导出查询 +func (p *Template) BuildExportQuery(request *builder.Request, templateInstance interface{}, query *gorm.DB, search []interface{}, filters []interface{}, columnFilters map[string]interface{}, orderings map[string]interface{}) *gorm.DB { + + // 初始化查询 + query = p.initializeQuery(request, templateInstance, query) + + // 执行列表查询,这里使用的是透传的实例 + query = templateInstance.(interface { + ExportQuery(*builder.Request, *gorm.DB) *gorm.DB + }).ExportQuery(request, query) + + // 执行搜索查询 + query = p.applySearch(request, query, search) + + // 执行过滤器查询 + query = p.applyFilters(query, filters) + + // 执行表格列上过滤器查询 + query = p.applyColumnFilters(query, columnFilters) + + // 获取默认排序 + defaultOrder := reflect. + ValueOf(templateInstance). + Elem(). + FieldByName("IndexOrder").String() + + if defaultOrder == "" { + defaultOrder = "id desc" + } + + // 执行排序查询 + query = p.applyOrderings(query, orderings, defaultOrder) + + return query +} + +// 初始化查询 +func (p *Template) initializeQuery(request *builder.Request, templateInstance interface{}, query *gorm.DB) *gorm.DB { + + return templateInstance.(interface { + Query(*builder.Request, *gorm.DB) *gorm.DB + }).Query(request, query) +} + +// 执行搜索表单查询 +func (p *Template) applySearch(request *builder.Request, query *gorm.DB, search []interface{}) *gorm.DB { + data := request.AllQuerys() + result, ok := data["search"].(map[string]interface{}) + if ok == false { + return query + } + + for _, v := range search { + + // 获取字段 + column := v.(interface { + GetColumn(search interface{}) string + }).GetColumn(v) // 字段名,支持数组 + + value := result[column] + + if value != nil { + query = v.(interface { + Apply(*builder.Request, *gorm.DB, interface{}) *gorm.DB + }).Apply(request, query, value) + } + } + + return query +} + +// 执行表格列上过滤器查询 +func (p *Template) applyColumnFilters(query *gorm.DB, filters map[string]interface{}) *gorm.DB { + + if len(filters) == 0 { + return query + } + + for k, v := range filters { + if v != "" { + + values := []string{} + for _, subValue := range v.(map[string]interface{}) { + values = append(values, subValue.(string)) + } + + query = query.Where(k+" IN ?", values) + } + } + + return query +} + +// 执行过滤器查询 +func (p *Template) applyFilters(query *gorm.DB, filters []interface{}) *gorm.DB { + // todo + return query +} + +// 执行排序查询 +func (p *Template) applyOrderings(query *gorm.DB, orderings map[string]interface{}, defaultOrder string) *gorm.DB { + + if len(orderings) == 0 { + return query.Order(defaultOrder) + } + + var order clause.OrderByColumn + + for key, v := range orderings { + + if v == "descend" { + order = clause.OrderByColumn{Column: clause.Column{Name: key}, Desc: true} + } else { + order = clause.OrderByColumn{Column: clause.Column{Name: key}, Desc: false} + } + + query = query.Order(order) + } + + return query +} + +// 全局查询 +func (p *Template) Query(request *builder.Request, query *gorm.DB) *gorm.DB { + + return query +} + +// 列表查询 +func (p *Template) IndexQuery(request *builder.Request, query *gorm.DB) *gorm.DB { + + return query +} + +// 详情查询 +func (p *Template) DetailQuery(request *builder.Request, query *gorm.DB) *gorm.DB { + + return query +} + +// 导出查询 +func (p *Template) ExportQuery(request *builder.Request, query *gorm.DB) *gorm.DB { + + return query +} diff --git a/pkg/builder/template/adminresource/performs_validation.go b/pkg/builder/template/adminresource/performs_validation.go new file mode 100644 index 0000000..d25704e --- /dev/null +++ b/pkg/builder/template/adminresource/performs_validation.go @@ -0,0 +1,598 @@ +package adminresource + +import ( + "encoding/json" + "errors" + "reflect" + "strconv" + "strings" + "unicode/utf8" + + "github.com/derekstavis/go-qs" + "github.com/quarkcms/quark-go/pkg/builder" + "github.com/quarkcms/quark-go/pkg/dal/db" +) + +// 创建请求的验证器 +func (p *Template) ValidatorForCreation(request *builder.Request, templateInstance interface{}, data map[string]interface{}) error { + rules, messages := p.RulesForCreation(request, templateInstance) + + validator := p.Validator(rules, messages, data) + + p.afterValidation(request, validator) + p.afterCreationValidation(request, validator) + + return validator +} + +// 验证规则 +func (p *Template) Validator(rules []interface{}, messages []interface{}, data map[string]interface{}) error { + var result error + + for _, rule := range rules { + for k, v := range rule.(map[string]interface{}) { + fieldValue := data[k] + for _, item := range v.([]interface{}) { + getItem, ok := item.(string) + if ok { + getItems := strings.Split(getItem, ":") + getOption := "" + if len(getItems) == 2 { + getItem = getItems[0] + getOption = getItems[1] + } + + switch getItem { + case "required": + if fieldValue == nil { + errMsg := p.getRuleMessage(messages, k+"."+getItem) + + if errMsg != "" { + result = errors.New(errMsg) + } + } + case "min": + strNum := utf8.RuneCountInString(fieldValue.(string)) + minOption, _ := strconv.Atoi(getOption) + + if strNum < minOption { + errMsg := p.getRuleMessage(messages, k+"."+getItem) + if errMsg != "" { + result = errors.New(errMsg) + } + } + case "max": + strNum := utf8.RuneCountInString(fieldValue.(string)) + maxOption, _ := strconv.Atoi(getOption) + + if strNum > maxOption { + errMsg := p.getRuleMessage(messages, k+"."+getItem) + if errMsg != "" { + result = errors.New(errMsg) + } + } + case "unique": + var ( + table string + field string + except string + count int + ) + + uniqueOptions := strings.Split(getOption, ",") + + if len(uniqueOptions) == 2 { + table = uniqueOptions[0] + field = uniqueOptions[1] + } + + if len(uniqueOptions) == 3 { + table = uniqueOptions[0] + field = uniqueOptions[1] + except = uniqueOptions[2] + } + + if except != "" { + db.Client.Raw("SELECT Count("+field+") FROM "+table+" WHERE id <> "+except+" AND "+field+" = ?", fieldValue).Scan(&count) + } else { + db.Client.Raw("SELECT Count("+field+") FROM "+table+" WHERE "+field+" = ?", fieldValue).Scan(&count) + } + + if count > 0 { + errMsg := p.getRuleMessage(messages, k+"."+getItem) + if errMsg != "" { + result = errors.New(errMsg) + } + } + } + } + } + } + } + + return result +} + +// 获取规则错误信息 +func (p *Template) getRuleMessage(messages []interface{}, key string) string { + msg := "" + + for _, v := range messages { + getMsg := v.(map[string]interface{})[key] + if getMsg != nil { + msg = getMsg.(string) + } + } + + return msg +} + +// 创建请求的验证规则 +func (p *Template) RulesForCreation(request *builder.Request, templateInstance interface{}) ([]interface{}, []interface{}) { + + fields := templateInstance.(interface { + CreationFieldsWithoutWhen(*builder.Request, interface{}) interface{} + }).CreationFieldsWithoutWhen(request, templateInstance) + + rules := []interface{}{} + ruleMessages := []interface{}{} + + for _, v := range fields.([]interface{}) { + getResult := p.getRulesForCreation(request, v) + + if len(getResult["rules"].(map[string]interface{})) > 0 { + rules = append(rules, getResult["rules"]) + } + + if len(getResult["messages"].(map[string]interface{})) > 0 { + ruleMessages = append(ruleMessages, getResult["messages"]) + } + + when := reflect. + ValueOf(v). + Elem(). + FieldByName("When").Interface() + + if when != nil { + whenItems := reflect. + ValueOf(when). + Elem(). + FieldByName("Items").Interface() + + if whenItems != nil { + for _, vi := range whenItems.([]map[string]interface{}) { + if p.needValidateWhenRules(request, vi) { + body := vi["body"] + if body != nil { + // 如果为数组 + getBody, ok := body.([]interface{}) + if ok { + for _, bv := range getBody { + whenItemResult := p.getRulesForCreation(request, bv) + + if len(whenItemResult["rules"].(map[string]interface{})) > 0 { + rules = append(rules, whenItemResult["rules"]) + } + + if len(whenItemResult["messages"].(map[string]interface{})) > 0 { + ruleMessages = append(ruleMessages, whenItemResult["messages"]) + } + } + } else { + whenItemResult := p.getRulesForCreation(request, getBody) + + if len(whenItemResult["rules"].(map[string]interface{})) > 0 { + rules = append(rules, whenItemResult["rules"]) + } + + if len(whenItemResult["messages"].(map[string]interface{})) > 0 { + ruleMessages = append(ruleMessages, whenItemResult["messages"]) + } + } + } + } + } + } + } + + } + + return rules, ruleMessages +} + +// 判断是否需要验证When组件里的规则 +func (p *Template) needValidateWhenRules(request *builder.Request, when map[string]interface{}) bool { + conditionName := when["condition_name"].(string) + conditionOption := when["condition_option"] + conditionOperator := when["condition_operator"].(string) + result := false + + data, error := qs.Unmarshal(request.OriginalURL()) + if error != nil { + return false + } + + value, ok := data[conditionName] + if !ok { + return false + } + + valueString, isString := value.(string) + if isString { + if valueString == "" { + return false + } + } + + switch conditionOperator { + case "=": + result = (value.(string) == conditionOption.(string)) + case ">": + result = (value.(string) > conditionOption.(string)) + case "<": + result = (value.(string) < conditionOption.(string)) + case "<=": + result = (value.(string) <= conditionOption.(string)) + case ">=": + result = (value.(string) >= conditionOption.(string)) + case "has": + _, isArray := value.([]string) + if isArray { + getJson, err := json.Marshal(value) + if err != nil { + result = strings.Contains(string(getJson), conditionOption.(string)) + } + } else { + result = strings.Contains(value.(string), conditionOption.(string)) + } + case "in": + conditionOptionArray, isArray := conditionOption.([]string) + if isArray { + for _, v := range conditionOptionArray { + if v == value.(string) { + result = true + } + } + } + default: + result = (value.(string) == conditionOption) + } + + return result +} + +// 获取创建请求资源规则 +func (p *Template) getRulesForCreation(request *builder.Request, field interface{}) map[string]interface{} { + getRules := map[string]interface{}{} + getRuleMessages := map[string]interface{}{} + + name := reflect. + ValueOf(field). + Elem(). + FieldByName("Name").String() + + rules := reflect. + ValueOf(field). + Elem(). + FieldByName("Rules").Interface() + + ruleMessages := reflect. + ValueOf(field). + Elem(). + FieldByName("RuleMessages").Interface() + + creationRules := reflect. + ValueOf(field). + Elem(). + FieldByName("CreationRules").Interface() + + creationRuleMessages := reflect. + ValueOf(field). + Elem(). + FieldByName("CreationRuleMessages").Interface() + + items := []interface{}{} + + for _, v := range p.formatRules(request, rules.([]string)) { + items = append(items, v) + } + + for key, v := range ruleMessages.(map[string]string) { + getRuleMessages[name+"."+key] = v + } + + for _, v := range p.formatRules(request, creationRules.([]string)) { + items = append(items, v) + } + + for key, v := range creationRuleMessages.(map[string]string) { + getRuleMessages[name+"."+key] = v + } + + if len(items) > 0 { + getRules[name] = items + } + + return map[string]interface{}{ + "rules": getRules, + "messages": getRuleMessages, + } +} + +// 更新请求的验证器 +func (p *Template) ValidatorForUpdate(request *builder.Request, templateInstance interface{}, data map[string]interface{}) error { + rules, messages := p.RulesForUpdate(request, templateInstance) + + validator := p.Validator(rules, messages, data) + + p.afterValidation(request, validator) + p.afterCreationValidation(request, validator) + + return validator +} + +// 更新请求的验证规则 +func (p *Template) RulesForUpdate(request *builder.Request, templateInstance interface{}) ([]interface{}, []interface{}) { + + fields := templateInstance.(interface { + UpdateFieldsWithoutWhen(*builder.Request, interface{}) interface{} + }).UpdateFieldsWithoutWhen(request, templateInstance) + + rules := []interface{}{} + ruleMessages := []interface{}{} + + for _, v := range fields.([]interface{}) { + getResult := p.getRulesForUpdate(request, v) + + if len(getResult["rules"].(map[string]interface{})) > 0 { + rules = append(rules, getResult["rules"]) + } + + if len(getResult["messages"].(map[string]interface{})) > 0 { + ruleMessages = append(ruleMessages, getResult["messages"]) + } + + when := reflect. + ValueOf(v). + Elem(). + FieldByName("When").Interface() + + if when != nil { + whenItems := reflect. + ValueOf(when). + Elem(). + FieldByName("Items").Interface() + + if whenItems != nil { + for _, vi := range whenItems.([]map[string]interface{}) { + if p.needValidateWhenRules(request, vi) { + body := vi["body"] + + if body != nil { + + // 如果为数组 + getBody, ok := body.([]interface{}) + if ok { + for _, bv := range getBody { + whenItemResult := p.getRulesForUpdate(request, bv) + + if len(whenItemResult["rules"].(map[string]interface{})) > 0 { + rules = append(rules, whenItemResult["rules"]) + } + + if len(whenItemResult["messages"].(map[string]interface{})) > 0 { + ruleMessages = append(ruleMessages, whenItemResult["messages"]) + } + } + } else { + whenItemResult := p.getRulesForUpdate(request, getBody) + + if len(whenItemResult["rules"].(map[string]interface{})) > 0 { + rules = append(rules, whenItemResult["rules"]) + } + + if len(whenItemResult["messages"].(map[string]interface{})) > 0 { + ruleMessages = append(ruleMessages, whenItemResult["messages"]) + } + } + } + } + } + } + } + + } + + return rules, ruleMessages +} + +// 获取更新请求资源规则 +func (p *Template) getRulesForUpdate(request *builder.Request, field interface{}) map[string]interface{} { + + getRules := map[string]interface{}{} + getRuleMessages := map[string]interface{}{} + + name := reflect. + ValueOf(field). + Elem(). + FieldByName("Name").String() + + rules := reflect. + ValueOf(field). + Elem(). + FieldByName("Rules").Interface() + + ruleMessages := reflect. + ValueOf(field). + Elem(). + FieldByName("RuleMessages").Interface() + + updateRules := reflect. + ValueOf(field). + Elem(). + FieldByName("UpdateRules").Interface() + + updateRuleMessages := reflect. + ValueOf(field). + Elem(). + FieldByName("UpdateRuleMessages").Interface() + + items := []interface{}{} + + for _, v := range p.formatRules(request, rules.([]string)) { + items = append(items, v) + } + + for key, v := range ruleMessages.(map[string]string) { + getRuleMessages[name+"."+key] = v + } + + for _, v := range p.formatRules(request, updateRules.([]string)) { + items = append(items, v) + } + + for key, v := range updateRuleMessages.(map[string]string) { + getRuleMessages[name+"."+key] = v + } + + if len(items) > 0 { + getRules[name] = items + } + + return map[string]interface{}{ + "rules": getRules, + "messages": getRuleMessages, + } +} + +// 导入请求的验证器 +func (p *Template) ValidatorForImport(request *builder.Request, templateInstance interface{}, data map[string]interface{}) error { + rules, messages := p.RulesForImport(request, templateInstance) + + validator := p.Validator(rules, messages, data) + + p.afterValidation(request, validator) + p.afterCreationValidation(request, validator) + + return validator +} + +// 创建请求的验证规则 +func (p *Template) RulesForImport(request *builder.Request, templateInstance interface{}) ([]interface{}, []interface{}) { + + fields := templateInstance.(interface { + ImportFieldsWithoutWhen(*builder.Request, interface{}) interface{} + }).ImportFieldsWithoutWhen(request, templateInstance) + + rules := []interface{}{} + ruleMessages := []interface{}{} + + for _, v := range fields.([]interface{}) { + getResult := p.getRulesForCreation(request, v) + + if len(getResult["rules"].(map[string]interface{})) > 0 { + rules = append(rules, getResult["rules"]) + } + + if len(getResult["messages"].(map[string]interface{})) > 0 { + ruleMessages = append(ruleMessages, getResult["messages"]) + } + + when := reflect. + ValueOf(v). + Elem(). + FieldByName("When").Interface() + + if when != nil { + whenItems := reflect. + ValueOf(when). + Elem(). + FieldByName("Items").Interface() + + if whenItems != nil { + for _, vi := range whenItems.([]map[string]interface{}) { + if p.needValidateWhenRules(request, vi) { + body := vi["body"] + + if body != nil { + + // 如果为数组 + getBody, ok := body.([]interface{}) + if ok { + for _, bv := range getBody { + whenItemResult := p.getRulesForCreation(request, bv) + + if len(whenItemResult["rules"].(map[string]interface{})) > 0 { + rules = append(rules, whenItemResult["rules"]) + } + + if len(whenItemResult["messages"].(map[string]interface{})) > 0 { + ruleMessages = append(ruleMessages, whenItemResult["messages"]) + } + } + } else { + whenItemResult := p.getRulesForCreation(request, getBody) + + if len(whenItemResult["rules"].(map[string]interface{})) > 0 { + rules = append(rules, whenItemResult["rules"]) + } + + if len(whenItemResult["messages"].(map[string]interface{})) > 0 { + ruleMessages = append(ruleMessages, whenItemResult["messages"]) + } + } + } + } + } + } + } + + } + + return rules, ruleMessages +} + +// 格式化规则 +func (p *Template) formatRules(request *builder.Request, rules []string) []string { + data := map[string]interface{}{} + json.Unmarshal(request.Body(), &data) + + formId := data["id"] + requestId := request.Query("id", "") + if requestId.(string) == "" && formId == nil { + return rules + } + + if requestId != "" { + for key, v := range rules { + rules[key] = strings.Replace(v, "{id}", requestId.(string), -1) + } + } else if formId != nil { + for key, v := range rules { + requestId = strconv.FormatFloat(formId.(float64), 'E', -1, 64) + rules[key] = strings.Replace(v, "{id}", requestId.(string), -1) + } + } + + return rules +} + +// 验证完成后回调 +func (p *Template) afterValidation(request *builder.Request, validator interface{}) { + // +} + +// 创建请求验证完成后回调 +func (p *Template) afterCreationValidation(request *builder.Request, validator interface{}) { + // +} + +// 更新请求验证完成后回调 +func (p *Template) afterUpdateValidation(request *builder.Request, validator interface{}) { + // +} + +// 创建请求验证完成后回调 +func (p *Template) afterImportValidation(request *builder.Request, validator interface{}) { + // +} diff --git a/pkg/builder/template/adminresource/resolves_actions.go b/pkg/builder/template/adminresource/resolves_actions.go new file mode 100644 index 0000000..abf68fe --- /dev/null +++ b/pkg/builder/template/adminresource/resolves_actions.go @@ -0,0 +1,343 @@ +package adminresource + +import ( + "strings" + + "github.com/quarkcms/quark-go/pkg/builder" + "github.com/quarkcms/quark-go/pkg/component/admin/action" + "github.com/quarkcms/quark-go/pkg/component/admin/dropdown" + "github.com/quarkcms/quark-go/pkg/component/admin/space" +) + +// 列表行为 +func (p *Template) IndexActions(request *builder.Request, templateInstance interface{}) interface{} { + actions := templateInstance.(interface { + Actions(request *builder.Request) []interface{} + }).Actions(request) + + var items []interface{} + for _, v := range actions { + shownOnIndex := v.(interface { + ShownOnIndex() bool + }).ShownOnIndex() + + if shownOnIndex { + getAction := p.buildAction(request, v, templateInstance) + items = append(items, getAction) + } + } + + return (&space.Component{}).Init().SetBody(items) +} + +//表格行内行为 +func (p *Template) IndexTableRowActions(request *builder.Request, templateInstance interface{}) interface{} { + actions := templateInstance.(interface { + Actions(request *builder.Request) []interface{} + }).Actions(request) + + var items []interface{} + for _, v := range actions { + shownOnIndexTableRow := v.(interface { + ShownOnIndexTableRow() bool + }).ShownOnIndexTableRow() + + if shownOnIndexTableRow { + getAction := p.buildAction(request, v, templateInstance) + items = append(items, getAction) + } + } + + return items +} + +//表格多选弹出层行为 +func (p *Template) IndexTableAlertActions(request *builder.Request, templateInstance interface{}) interface{} { + actions := templateInstance.(interface { + Actions(request *builder.Request) []interface{} + }).Actions(request) + + var items []interface{} + for _, v := range actions { + shownOnIndexTableAlert := v.(interface { + ShownOnIndexTableAlert() bool + }).ShownOnIndexTableAlert() + + if shownOnIndexTableAlert { + getAction := p.buildAction(request, v, templateInstance) + items = append(items, getAction) + } + } + + return items +} + +//表单页行为 +func (p *Template) FormActions(request *builder.Request, templateInstance interface{}) []interface{} { + actions := templateInstance.(interface { + Actions(request *builder.Request) []interface{} + }).Actions(request) + + var items []interface{} + for _, v := range actions { + shownOnForm := v.(interface { + ShownOnForm() bool + }).ShownOnForm() + + if shownOnForm { + getAction := p.buildAction(request, v, templateInstance) + items = append(items, getAction) + } + } + + return items +} + +//表单页右上角自定义区域行为 +func (p *Template) FormExtraActions(request *builder.Request, templateInstance interface{}) interface{} { + actions := templateInstance.(interface { + Actions(request *builder.Request) []interface{} + }).Actions(request) + + var items []interface{} + for _, v := range actions { + shownOnFormExtra := v.(interface { + ShownOnFormExtra() bool + }).ShownOnFormExtra() + + if shownOnFormExtra { + getAction := p.buildAction(request, v, templateInstance) + items = append(items, getAction) + } + } + + return items +} + +//详情页行为 +func (p *Template) DetailActions(request *builder.Request, templateInstance interface{}) []interface{} { + actions := templateInstance.(interface { + Actions(request *builder.Request) []interface{} + }).Actions(request) + + var items []interface{} + for _, v := range actions { + shownOnDetail := v.(interface { + ShownOnDetail() bool + }).ShownOnDetail() + + if shownOnDetail { + getAction := p.buildAction(request, v, templateInstance) + items = append(items, getAction) + } + } + + return items +} + +//详情页右上角自定义区域行为 +func (p *Template) DetailExtraActions(request *builder.Request, templateInstance interface{}) interface{} { + actions := templateInstance.(interface { + Actions(request *builder.Request) []interface{} + }).Actions(request) + + var items []interface{} + for _, v := range actions { + shownOnDetailExtra := v.(interface { + ShownOnDetailExtra() bool + }).ShownOnDetailExtra() + + if shownOnDetailExtra { + getAction := p.buildAction(request, v, templateInstance) + items = append(items, getAction) + } + } + + return items +} + +//创建行为组件 +func (p *Template) buildAction(request *builder.Request, item interface{}, templateInstance interface{}) interface{} { + name := item.(interface{ GetName() string }).GetName() + withLoading := item.(interface{ GetWithLoading() bool }).GetWithLoading() + reload := item.(interface{ GetReload() string }).GetReload() + + // uri唯一标识 + uriKey := item.(interface { + GetUriKey(interface{}) string + }).GetUriKey(item) + + // 获取api + api := item.(interface { + GetApi(request *builder.Request) string + }).GetApi(request) + + // 获取api替换参数 + params := item.(interface { + GetApiParams() []string + }).GetApiParams() + + if api == "" { + api = p.buildActionApi(request, params, uriKey) + } + + actionType := item.(interface{ GetActionType() string }).GetActionType() + buttonType := item.(interface{ GetType() string }).GetType() + size := item.(interface{ GetSize() string }).GetSize() + icon := item.(interface{ GetIcon() string }).GetIcon() + confirmTitle := item.(interface{ GetConfirmTitle() string }).GetConfirmTitle() + confirmText := item.(interface{ GetConfirmText() string }).GetConfirmText() + confirmType := item.(interface{ GetConfirmType() string }).GetConfirmType() + + if actionType == "dropdown" { + overlay := item.(interface { + GetOverlay(request *builder.Request, templateInstance interface{}) interface{} + }).GetOverlay(request, templateInstance) + + overlayStyle := item.(interface { + GetOverlayStyle() map[string]interface{} + }).GetOverlayStyle() + + placement := item.(interface { + GetPlacement() string + }).GetPlacement() + + trigger := item.(interface { + GetTrigger() []string + }).GetTrigger() + + arrow := item.(interface { + GetArrow() bool + }).GetArrow() + + getAction := (&dropdown.Component{}). + Init(). + SetLabel(name). + SetOverlay(overlay). + SetOverlayStyle(overlayStyle). + SetPlacement(placement). + SetTrigger(trigger). + SetArrow(arrow). + SetType(buttonType, false). + SetSize(size) + + if icon != "" { + getAction = getAction. + SetIcon(icon) + } + + return getAction + } + + getAction := (&action.Component{}). + Init(). + SetLabel(name). + SetWithLoading(withLoading). + SetReload(reload). + SetApi(api). + SetActionType(actionType). + SetType(buttonType, false). + SetSize(size) + + if icon != "" { + getAction = getAction. + SetIcon(icon) + } + + switch actionType { + case "link": + href := item.(interface { + GetHref(request *builder.Request) string + }).GetHref(request) + target := item.(interface { + GetTarget(request *builder.Request) string + }).GetTarget(request) + + getAction = getAction. + SetLink(href, target) + case "modal": + formWidth := item.(interface { + GetWidth() int + }).GetWidth() + + formDestroyOnClose := item.(interface { + GetDestroyOnClose() bool + }).GetDestroyOnClose() + + formBody := item.(interface { + GetBody(request *builder.Request, templateInstance interface{}) interface{} + }).GetBody(request, templateInstance) + + formActions := item.(interface { + GetActions(request *builder.Request, templateInstance interface{}) []interface{} + }).GetActions(request, templateInstance) + + getAction = getAction.SetModal(func(modal *action.Modal) interface{} { + return modal. + SetTitle(name). + SetWidth(formWidth). + SetBody(formBody). + SetActions(formActions). + SetDestroyOnClose(formDestroyOnClose) + }) + case "drawer": + formWidth := item.(interface { + GetWidth() int + }).GetWidth() + + formDestroyOnClose := item.(interface { + GetDestroyOnClose() bool + }).GetDestroyOnClose() + + formBody := item.(interface { + GetBody(request *builder.Request, templateInstance interface{}) interface{} + }).GetBody(request, templateInstance) + + formActions := item.(interface { + GetActions(request *builder.Request, templateInstance interface{}) []interface{} + }).GetActions(request, templateInstance) + + getAction = getAction.SetDrawer(func(drawer *action.Drawer) interface{} { + return drawer. + SetTitle(name). + SetWidth(formWidth). + SetBody(formBody). + SetActions(formActions). + SetDestroyOnClose(formDestroyOnClose) + }) + } + + if confirmTitle != "" { + getAction = getAction. + SetWithConfirm(confirmTitle, confirmText, confirmType) + } + + return getAction +} + +//创建行为接口 +func (p *Template) buildActionApi(request *builder.Request, params []string, uriKey string) string { + paramsUri := "" + + for _, v := range params { + paramsUri = paramsUri + v + "=${" + v + "}&" + } + + // 自动构建列表页接口 + api := strings.Replace(request.Path(), "/index", "/action/"+uriKey, -1) + + // 自动构建创建页接口 + api = strings.Replace(api, "/create", "/action/"+uriKey, -1) + + // 自动构建编辑页接口 + api = strings.Replace(api, "/edit", "/action/"+uriKey, -1) + + // 自动构建详情页接口 + api = strings.Replace(api, "/detail", "/action/"+uriKey, -1) + + if paramsUri != "" { + api = api + "?" + paramsUri + } + + return api +} diff --git a/pkg/builder/template/adminresource/resolves_fields.go b/pkg/builder/template/adminresource/resolves_fields.go new file mode 100644 index 0000000..3a69514 --- /dev/null +++ b/pkg/builder/template/adminresource/resolves_fields.go @@ -0,0 +1,565 @@ +package adminresource + +import ( + "reflect" + "strings" + + "github.com/quarkcms/quark-go/pkg/builder" + "github.com/quarkcms/quark-go/pkg/component/admin/descriptions" + "github.com/quarkcms/quark-go/pkg/component/admin/table" + "github.com/quarkcms/quark-go/pkg/component/admin/tabs" +) + +// 列表字段 +func (p *Template) IndexFields(request *builder.Request, templateInstance interface{}) interface{} { + fields := p.getFields(request, templateInstance) + var items []interface{} + for _, v := range fields.([]interface{}) { + if v, ok := v.(interface { + IsShownOnIndex() bool + }); ok { + isShownOnIndex := v.IsShownOnIndex() + + if isShownOnIndex { + items = append(items, v) + } + } + } + + return items +} + +// 表格列 +func (p *Template) IndexColumns(request *builder.Request, templateInstance interface{}) interface{} { + fields := p.IndexFields(request, templateInstance) + var columns []interface{} + for _, v := range fields.([]interface{}) { + isShownOnIndex := v.(interface { + IsShownOnIndex() bool + }).IsShownOnIndex() + if isShownOnIndex { + getColumn := p.fieldToColumn(request, v) + + if getColumn != nil { + columns = append(columns, getColumn) + } + } + } + + // 行内行为 + indexTableRowActions := templateInstance.(interface { + IndexTableRowActions(request *builder.Request, templateInstance interface{}) interface{} + }).IndexTableRowActions(request, templateInstance) + if len(indexTableRowActions.([]interface{})) > 0 { + column := (&table.Column{}). + Init(). + SetTitle("操作"). + SetAttribute("action"). + SetValueType("option"). + SetActions(indexTableRowActions). + SetFixed("right") + columns = append(columns, column) + } + + return columns +} + +// 将表单项转换为表格列 +func (p *Template) fieldToColumn(request *builder.Request, field interface{}) interface{} { + reflectElem := reflect. + ValueOf(field). + Elem() + + // 字段 + name := reflectElem. + FieldByName("Name"). + String() + + // 文字 + label := reflectElem. + FieldByName("Label"). + String() + + // 组件类型 + component := reflectElem. + FieldByName("Component"). + String() + + // 是否可编辑 + editable := reflectElem. + FieldByName("Editable"). + Bool() + + // 是否可编辑 + getColumn := reflectElem. + FieldByName("Column"). + Interface() + + column := getColumn.(*table.Column). + SetTitle(label). + SetAttribute(name) + + switch component { + case "idField": + // 是否显示在列表 + onIndexDisplayed := reflectElem. + FieldByName("OnIndexDisplayed"). + Bool() + if onIndexDisplayed { + column = column.SetValueType("text") + } else { + return nil + } + case "hiddenField": + return nil + case "textField": + column = column.SetValueType("text") + case "textAreaField": + column = column.SetValueType("text") + case "selectField": + valueEnum := field.(interface { + GetValueEnum() map[interface{}]interface{} + }).GetValueEnum() + column = column.SetValueType("select").SetValueEnum(valueEnum) + case "radioField": + valueEnum := field.(interface { + GetValueEnum() map[interface{}]interface{} + }).GetValueEnum() + column = column.SetValueType("radio").SetValueEnum(valueEnum) + case "switchField": + valueEnum := field.(interface { + GetSwitchValueEnum() map[interface{}]interface{} + }).GetSwitchValueEnum() + column = column.SetValueType("select").SetValueEnum(valueEnum) + case "imageField": + column = column.SetValueType("image") + default: + column = column.SetValueType(component) + } + + if editable { + // 可编辑,设置编辑 + options := reflectElem. + FieldByName("Options"). + Interface() + + // 可编辑api地址 + editableApi := strings.Replace(request.Path(), "/index", "/editable", -1) + + // 设置编辑项 + column = column.SetEditable(component, options, editableApi) + } + + return column +} + +// 创建页字段 +func (p *Template) CreationFields(request *builder.Request, templateInstance interface{}) interface{} { + fields := p.getFields(request, templateInstance) + var items []interface{} + for _, v := range fields.([]interface{}) { + isShownOnCreation := v.(interface { + IsShownOnCreation() bool + }).IsShownOnCreation() + + if isShownOnCreation { + items = append(items, v) + } + } + + return items + +} + +// 不包含When组件内字段的创建页字段 +func (p *Template) CreationFieldsWithoutWhen(request *builder.Request, templateInstance interface{}) interface{} { + fields := p.getFieldsWithoutWhen(request, templateInstance) + var items []interface{} + for _, v := range fields.([]interface{}) { + isShownOnCreation := v.(interface { + IsShownOnCreation() bool + }).IsShownOnCreation() + if isShownOnCreation { + items = append(items, v) + } + } + + return items +} + +// 包裹在组件内的创建页字段 +func (p *Template) CreationFieldsWithinComponents(request *builder.Request, templateInstance interface{}) interface{} { + fields := templateInstance.(interface { + Fields(request *builder.Request) []interface{} + }).Fields(request) + var items []interface{} + for _, v := range fields { + component := reflect. + ValueOf(v). + Elem(). + FieldByName("Component").String() + if component == "tabPane" { + body := reflect. + ValueOf(v). + Elem(). + FieldByName("Body").Interface() + var subItems []interface{} + for _, sv := range body.([]interface{}) { + isShownOnCreation := sv.(interface { + IsShownOnCreation() bool + }).IsShownOnCreation() + if isShownOnCreation { + sv.(interface { + BuildFrontendRules(string) interface{} + }).BuildFrontendRules(request.Path()) + subItems = append(subItems, sv) + } + } + v.(interface { + SetBody(interface{}) *tabs.TabPane + }).SetBody(subItems) + + items = append(items, v) + } else { + isShownOnCreation := v.(interface { + IsShownOnCreation() bool + }).IsShownOnCreation() + if isShownOnCreation { + v.(interface { + BuildFrontendRules(string) interface{} + }).BuildFrontendRules(request.Path()) + items = append(items, v) + } + } + } + + return items +} + +// 编辑页字段 +func (p *Template) UpdateFields(request *builder.Request, templateInstance interface{}) interface{} { + fields := p.getFields(request, templateInstance) + var items []interface{} + + for _, v := range fields.([]interface{}) { + isShownOnUpdate := v.(interface { + IsShownOnUpdate() bool + }).IsShownOnUpdate() + if isShownOnUpdate { + items = append(items, v) + } + } + + return items +} + +// 不包含When组件内字段的编辑页字段 +func (p *Template) UpdateFieldsWithoutWhen(request *builder.Request, templateInstance interface{}) interface{} { + fields := p.getFieldsWithoutWhen(request, templateInstance) + var items []interface{} + + for _, v := range fields.([]interface{}) { + isShownOnUpdate := v.(interface { + IsShownOnUpdate() bool + }).IsShownOnUpdate() + if isShownOnUpdate { + items = append(items, v) + } + } + + return items +} + +// 包裹在组件内的编辑页字段 +func (p *Template) UpdateFieldsWithinComponents(request *builder.Request, templateInstance interface{}) interface{} { + fields := templateInstance.(interface { + Fields(request *builder.Request) []interface{} + }).Fields(request) + var items []interface{} + + for _, v := range fields { + component := reflect. + ValueOf(v). + Elem(). + FieldByName("Component").String() + if component == "tabPane" { + body := reflect. + ValueOf(v). + Elem(). + FieldByName("Body").Interface() + var subItems []interface{} + for _, sv := range body.([]interface{}) { + isShownOnUpdate := sv.(interface { + IsShownOnUpdate() bool + }).IsShownOnUpdate() + if isShownOnUpdate { + sv.(interface { + BuildFrontendRules(string) interface{} + }).BuildFrontendRules(request.Path()) + subItems = append(subItems, sv) + } + } + v.(interface { + SetBody(interface{}) *tabs.TabPane + }).SetBody(subItems) + + items = append(items, v) + } else { + isShownOnUpdate := v.(interface { + IsShownOnUpdate() bool + }).IsShownOnUpdate() + if isShownOnUpdate { + v.(interface { + BuildFrontendRules(string) interface{} + }).BuildFrontendRules(request.Path()) + items = append(items, v) + } + } + } + + return items +} + +// 详情页字段 +func (p *Template) DetailFields(request *builder.Request, templateInstance interface{}) interface{} { + fields := p.getFields(request, templateInstance) + var items []interface{} + + for _, v := range fields.([]interface{}) { + isShownOnDetail := v.(interface { + IsShownOnDetail() bool + }).IsShownOnDetail() + if isShownOnDetail { + items = append(items, v) + } + } + + return items +} + +// 包裹在组件内的详情页字段 +func (p *Template) DetailFieldsWithinComponents(request *builder.Request, templateInstance interface{}, data map[string]interface{}) interface{} { + componentType := "description" + + fields := templateInstance.(interface { + Fields(request *builder.Request) []interface{} + }).Fields(request) + var items []interface{} + + for _, v := range fields { + + component := reflect. + ValueOf(v). + Elem(). + FieldByName("Component").String() + + if component == "tabPane" { + + body := reflect. + ValueOf(v). + Elem(). + FieldByName("Body").Interface() + + var subItems []interface{} + for _, sv := range body.([]interface{}) { + isShownOnDetail := sv.(interface { + IsShownOnDetail() bool + }).IsShownOnDetail() + + if isShownOnDetail { + getColumn := p.fieldToColumn(request, sv) + subItems = append(subItems, getColumn) + } + } + + descriptions := (&descriptions.Component{}).Init().SetStyle(map[string]interface{}{ + "padding": "24px", + }). + SetTitle(""). + SetColumn(2). + SetColumns(subItems). + SetDataSource(data). + SetActions(p.DetailActions(request, templateInstance)) + + v.(interface{ SetBody(interface{}) interface{} }).SetBody(descriptions) + items = append(items, v) + } else { + isShownOnDetail := v.(interface { + IsShownOnDetail() bool + }).IsShownOnDetail() + + if isShownOnDetail { + getColumn := p.fieldToColumn(request, v) + items = append(items, getColumn) + } + } + } + + if componentType == "description" { + return (&descriptions.Component{}). + Init(). + SetStyle(map[string]interface{}{ + "padding": "24px", + }). + SetTitle(""). + SetColumn(2). + SetColumns(items). + SetDataSource(data). + SetActions(p.DetailActions(request, templateInstance)) + } else { + return items + } +} + +// 导出字段 +func (p *Template) ExportFields(request *builder.Request, templateInstance interface{}) interface{} { + fields := p.getFields(request, templateInstance) + var items []interface{} + for _, v := range fields.([]interface{}) { + isShownOnExport := v.(interface { + IsShownOnExport() bool + }).IsShownOnExport() + if isShownOnExport { + items = append(items, v) + } + } + + return items +} + +// 导入字段 +func (p *Template) ImportFields(request *builder.Request, templateInstance interface{}) interface{} { + fields := p.getFields(request, templateInstance) + var items []interface{} + for _, v := range fields.([]interface{}) { + isShownOnImport := v.(interface { + IsShownOnImport() bool + }).IsShownOnImport() + if isShownOnImport { + items = append(items, v) + } + } + + return items +} + +// 不包含When组件内字段的导入字段 +func (p *Template) ImportFieldsWithoutWhen(request *builder.Request, templateInstance interface{}) interface{} { + fields := p.getFieldsWithoutWhen(request, templateInstance) + var items []interface{} + for _, v := range fields.([]interface{}) { + + isShownOnImport := v.(interface { + IsShownOnImport() bool + }).IsShownOnImport() + + if isShownOnImport { + items = append(items, v) + } + } + + return items +} + +// 获取字段 +func (p *Template) getFields(request *builder.Request, templateInstance interface{}) interface{} { + fields := templateInstance.(interface { + Fields(request *builder.Request) []interface{} + }).Fields(request) + + return p.findFields(fields, true) +} + +// 获取不包含When组件的字段 +func (p *Template) getFieldsWithoutWhen(request *builder.Request, templateInstance interface{}) interface{} { + + fields := templateInstance.(interface { + Fields(request *builder.Request) []interface{} + }).Fields(request) + + return p.findFields(fields, false) +} + +// 查找字段 +func (p *Template) findFields(fields interface{}, when bool) interface{} { + var items []interface{} + if fields, ok := fields.([]interface{}); ok { + for _, v := range fields { + hasBody := reflect. + ValueOf(v). + Elem(). + FieldByName("Body").IsValid() + if hasBody { + body := reflect. + ValueOf(v). + Elem(). + FieldByName("Body").Interface() + + getItems := p.findFields(body, true) + if getItems, ok := getItems.([]interface{}); ok { + if len(getItems) > 0 { + items = append(items, getItems...) + } + } + } else { + component := reflect. + ValueOf(v). + Elem(). + FieldByName("Component").String() + if strings.Contains(component, "Field") { + items = append(items, v) + if when { + whenFields := p.getWhenFields(v) + if len(whenFields) > 0 { + items = append(items, whenFields...) + } + } + } + } + } + } + + return items +} + +// 获取When组件中的字段 +func (p *Template) getWhenFields(item interface{}) []interface{} { + var items []interface{} + when := reflect. + ValueOf(item). + Elem(). + FieldByName("When").Interface() + if when == nil { + return items + } + + whenItems := reflect. + ValueOf(when). + Elem(). + FieldByName("Items").Interface() + if whenItems == nil { + return items + } + + whenItems, ok := whenItems.([]interface{}) + if ok { + for _, v := range whenItems.([]interface{}) { + body := reflect. + ValueOf(v). + Elem(). + FieldByName("Body").Interface() + if body != nil { + if body, ok := body.([]interface{}); ok { + if len(body) > 0 { + items = append(items, body...) + } + } + if body, ok := body.(interface{}); ok { + items = append(items, body) + } + } + } + } + + return items +} diff --git a/pkg/builder/template/adminresource/resolves_filters.go b/pkg/builder/template/adminresource/resolves_filters.go new file mode 100644 index 0000000..d631c79 --- /dev/null +++ b/pkg/builder/template/adminresource/resolves_filters.go @@ -0,0 +1,8 @@ +package adminresource + +import "github.com/quarkcms/quark-go/pkg/builder" + +//定义筛选表单 +func (p *Template) Filters(request *builder.Request) []interface{} { + return []interface{}{} +} diff --git a/pkg/builder/template/adminresource/resolves_searches.go b/pkg/builder/template/adminresource/resolves_searches.go new file mode 100644 index 0000000..d8ba2f1 --- /dev/null +++ b/pkg/builder/template/adminresource/resolves_searches.go @@ -0,0 +1,74 @@ +package adminresource + +import ( + "reflect" + "strings" + + "github.com/quarkcms/quark-go/pkg/builder" + "github.com/quarkcms/quark-go/pkg/component/admin/table" +) + +// 列表页搜索表单 +func (p *Template) IndexSearches(request *builder.Request, templateInstance interface{}) interface{} { + searches := templateInstance.(interface { + Searches(*builder.Request) []interface{} + }).Searches(request) + search := (&table.Search{}).Init() + + withExport := reflect. + ValueOf(templateInstance). + Elem(). + FieldByName("WithExport").Bool() + + if withExport { + search = search.SetShowExportButton(true).SetExportApi(strings.Replace(ExportRoute, ":resource", request.Param("resource"), -1)) + } + + for _, v := range searches { + component := v.(interface{ GetComponent() string }).GetComponent() // 获取组件名称 + name := v.(interface{ GetName() string }).GetName() // label 标签的文本 + column := v.(interface { + GetColumn(search interface{}) string + }).GetColumn(v) // 字段名,支持数组 + operator := v.(interface{ GetOperator() string }).GetOperator() // 获取操作符 + api := v.(interface{ GetApi() string }).GetApi() // 获取接口 + options := v.(interface { + Options(request *builder.Request) map[interface{}]interface{} + }).Options(request) // 获取属性 + load := v.(interface { + Load(request *builder.Request) map[string]string + }).Load(request) // 获取接口 + + // 搜索栏表单项 + item := (&table.SearchItem{}). + Init(). + SetName(column). + SetLabel(name). + SetOperator(operator). + SetApi(api) + + switch component { + case "input": + item = item.Input(options) + case "select": + + if load != nil { + item.SetLoad(load["field"], load["api"]) + } + + item = item.Select(options) + case "multipleSelect": + item = item.MultipleSelect(options) + case "datetime": + item = item.Datetime(options) + case "date": + item = item.Date(options) + case "cascader": + item = item.Cascader(options) + } + + search = search.SetItems(item) + } + + return search +} diff --git a/pkg/builder/template/adminresource/resource.go b/pkg/builder/template/adminresource/resource.go new file mode 100644 index 0000000..d64c27e --- /dev/null +++ b/pkg/builder/template/adminresource/resource.go @@ -0,0 +1,189 @@ +package adminresource + +import ( + "github.com/quarkcms/quark-go/pkg/builder" + "github.com/quarkcms/quark-go/pkg/builder/template" + "github.com/quarkcms/quark-go/pkg/dal/db" +) + +// 后台增删改查模板 +type Template struct { + template.AdminTemplate + Title string // 标题 + SubTitle string // 子标题 + PerPage interface{} + IndexPolling int + IndexOrder string + Model interface{} + Field map[string]interface{} + WithExport bool +} + +const ( + IndexRoute = "/api/admin/:resource/index" // 后台增删改查,列表路由 + EditableRoute = "/api/admin/:resource/editable" // 后台增删改查,表格行内编辑路由 + ActionRoute = "/api/admin/:resource/action/:uriKey" // 后台增删改查,执行行为路由 + CreateRoute = "/api/admin/:resource/create" // 后台增删改查,创建页面路由 + StoreRoute = "/api/admin/:resource/store" // 后台增删改查,创建方法路由 + EditRoute = "/api/admin/:resource/edit" // 后台增删改查,编辑页面路由 + EditValuesRoute = "/api/admin/:resource/edit/values" // 后台增删改查,获取编辑表单值路由 + SaveRoute = "/api/admin/:resource/save" // 后台增删改查,保存编辑值路由 + ImportRoute = "/api/admin/:resource/import" // 后台增删改查,详情页面路由 + ExportRoute = "/api/admin/:resource/export" // 后台增删改查,导出数据路由 + DetailRoute = "/api/admin/:resource/detail" // 后台增删改查,导入数据路由 + ImportTemplateRoute = "/api/admin/:resource/import/template" // 后台增删改查,导入模板路由 + FormRoute = "/api/admin/:resource/:uriKey/form" // 后台增删改查,通用表单资源 +) + +// 初始化 +func (p *Template) Init() interface{} { + p.TemplateInit() + + return p +} + +// 初始化模板 +func (p *Template) TemplateInit() interface{} { + + // 初始化数据对象 + p.DB = db.Client + + // 清空路由 + p.Routes = nil + + // 注册路由 + p.AddRoute(IndexRoute, "Render") // 后台增删改查,列表路由 + p.AddRoute(EditableRoute, "Render") // 后台增删改查,表格行内编辑路由 + p.AddRoute(ActionRoute, "Render") // 后台增删改查,执行行为路由 + p.AddRoute(CreateRoute, "Render") // 后台增删改查,创建页面路由 + p.AddRoute(StoreRoute, "Render") // 后台增删改查,创建方法路由 + p.AddRoute(EditRoute, "Render") // 后台增删改查,编辑页面路由 + p.AddRoute(EditValuesRoute, "Render") // 后台增删改查,获取编辑表单值路由 + p.AddRoute(SaveRoute, "Render") // 后台增删改查,保存编辑值路由 + p.AddRoute(DetailRoute, "Render") // 后台增删改查,详情页面路由 + p.AddRoute(ExportRoute, "Render") // 后台增删改查,导出数据路由 + p.AddRoute(ImportRoute, "Render") // 后台增删改查,导入数据路由 + p.AddRoute(ImportTemplateRoute, "Render") // 后台增删改查,导入模板路由 + p.AddRoute(FormRoute, "Render") // 后台增删改查,通用表单资源 + + return p +} + +// 设置单列字段 +func (p *Template) SetField(fieldData map[string]interface{}) interface{} { + p.Field = fieldData + + return p +} + +// 数据导出前回调 +func (p *Template) BeforeExporting(request *builder.Request, list []map[string]interface{}) []interface{} { + result := []interface{}{} + for _, v := range list { + result = append(result, v) + } + + return result +} + +// 数据导入前回调 +func (p *Template) BeforeImporting(request *builder.Request, list [][]interface{}) [][]interface{} { + return list +} + +// 组件渲染 +func (p *Template) Render(request *builder.Request, resource *builder.Resource, templateInstance interface{}) interface{} { + var result interface{} + switch request.FullPath() { + case IndexRoute: // 列表 + data := (&IndexRequest{}).QueryData(request, templateInstance) + body := p.IndexComponentRender(request, templateInstance, data) + + result = templateInstance.(interface { + PageComponentRender(request *builder.Request, templateInstance interface{}, body interface{}) interface{} + }).PageComponentRender(request, templateInstance, body) + case EditableRoute: // 表格行内编辑 + result = (&EditableRequest{}).Handle(request, templateInstance) + case ActionRoute: // 执行行为路由 + result = (&ActionRequest{}).Handle(request, templateInstance) + case CreateRoute: // 创建页面路由 + + // 断言BeforeCreating方法,获取初始数据 + data := templateInstance.(interface { + BeforeCreating(request *builder.Request) map[string]interface{} + }).BeforeCreating(request) + + // 断言CreationComponentRender方法 + body := templateInstance.(interface { + CreationComponentRender(*builder.Request, interface{}, map[string]interface{}) interface{} + }).CreationComponentRender(request, templateInstance, data) + + result = templateInstance.(interface { + PageComponentRender(request *builder.Request, templateInstance interface{}, body interface{}) interface{} + }).PageComponentRender(request, templateInstance, body) + case StoreRoute: // 创建方法路由 + result = (&StoreRequest{}).Handle(request, templateInstance) + case EditRoute: // 编辑页面路由 + + // 获取数据 + data := (&EditRequest{}).FillData(request, templateInstance) + + // 断言BeforeEditing方法,获取初始数据 + data = templateInstance.(interface { + BeforeEditing(*builder.Request, map[string]interface{}) map[string]interface{} + }).BeforeEditing(request, data) + + // 断言UpdateComponentRender方法 + body := templateInstance.(interface { + UpdateComponentRender(*builder.Request, interface{}, map[string]interface{}) interface{} + }).UpdateComponentRender(request, templateInstance, data) + + result = templateInstance.(interface { + PageComponentRender(request *builder.Request, templateInstance interface{}, body interface{}) interface{} + }).PageComponentRender(request, templateInstance, body) + case EditValuesRoute: // 获取编辑表单值 + + result = (&EditRequest{}).Values(request, templateInstance) + case SaveRoute: // 保存编辑值 + + result = (&UpdateRequest{}).Handle(request, templateInstance) + case DetailRoute: // 详情页面 + data := (&DetailRequest{}).FillData(request, templateInstance) + + // 断言方法,获取初始数据 + data = templateInstance.(interface { + BeforeDetailShowing(*builder.Request, map[string]interface{}) map[string]interface{} + }).BeforeDetailShowing(request, data) + + // 断言方法 + body := templateInstance.(interface { + DetailComponentRender(*builder.Request, interface{}, map[string]interface{}) interface{} + }).DetailComponentRender(request, templateInstance, data) + + result = templateInstance.(interface { + PageComponentRender(request *builder.Request, templateInstance interface{}, body interface{}) interface{} + }).PageComponentRender(request, templateInstance, body) + case ExportRoute: // 导出数据 + result = (&ExportRequest{}).Handle(request, templateInstance) + case ImportRoute: // 导入数据 + result = (&ImportRequest{}).Handle(request, templateInstance) + case ImportTemplateRoute: // 导入模板 + result = (&ImportTemplateRequest{}).Handle(request, templateInstance) + case FormRoute: // 通用表单资源 + // 断言BeforeCreating方法,获取初始数据 + data := templateInstance.(interface { + BeforeCreating(request *builder.Request) map[string]interface{} + }).BeforeCreating(request) + + // 断言CreationComponentRender方法 + body := templateInstance.(interface { + CreationComponentRender(*builder.Request, interface{}, map[string]interface{}) interface{} + }).CreationComponentRender(request, templateInstance, data) + + result = templateInstance.(interface { + PageComponentRender(request *builder.Request, templateInstance interface{}, body interface{}) interface{} + }).PageComponentRender(request, templateInstance, body) + } + + return result +} diff --git a/pkg/builder/template/adminresource/resource_create.go b/pkg/builder/template/adminresource/resource_create.go new file mode 100644 index 0000000..3c435d7 --- /dev/null +++ b/pkg/builder/template/adminresource/resource_create.go @@ -0,0 +1,50 @@ +package adminresource + +import ( + "strings" + + "github.com/gobeam/stringy" + "github.com/quarkcms/quark-go/pkg/builder" +) + +// 创建表单的接口 +func (p *Template) CreationApi(request *builder.Request, templateInstance interface{}) string { + formApi := templateInstance.(interface { + FormApi(request *builder.Request) string + }).FormApi(request) + if formApi != "" { + return formApi + } + + uri := strings.Split(request.Path(), "/") + if uri[len(uri)-1] == "index" { + return stringy.New(request.Path()).ReplaceLast("/index", "/store") + } + + return stringy.New(request.Path()).ReplaceLast("/create", "/store") +} + +// 渲染创建页组件 +func (p *Template) CreationComponentRender(request *builder.Request, templateInstance interface{}, data map[string]interface{}) interface{} { + title := p.FormTitle(request, templateInstance) + formExtraActions := p.FormExtraActions(request, templateInstance) + api := p.CreationApi(request, templateInstance) + fields := p.CreationFieldsWithinComponents(request, templateInstance) + formActions := p.FormActions(request, templateInstance) + + return p.FormComponentRender( + request, + templateInstance, + title, + formExtraActions, + api, + fields, + formActions, + data, + ) +} + +// 创建页面显示前回调 +func (p *Template) BeforeCreating(request *builder.Request) map[string]interface{} { + return map[string]interface{}{} +} diff --git a/pkg/builder/template/adminresource/resource_detail.go b/pkg/builder/template/adminresource/resource_detail.go new file mode 100644 index 0000000..3054a81 --- /dev/null +++ b/pkg/builder/template/adminresource/resource_detail.go @@ -0,0 +1,71 @@ +package adminresource + +import ( + "reflect" + + "github.com/quarkcms/quark-go/pkg/builder" + "github.com/quarkcms/quark-go/pkg/component/admin/card" + "github.com/quarkcms/quark-go/pkg/component/admin/tabs" +) + +// 详情页标题 +func (p *Template) DetailTitle(request *builder.Request, templateInstance interface{}) string { + value := reflect.ValueOf(templateInstance).Elem() + title := value.FieldByName("Title").String() + + return title + "详情" +} + +// 渲染详情页组件 +func (p *Template) DetailComponentRender(request *builder.Request, templateInstance interface{}, data map[string]interface{}) interface{} { + title := p.DetailTitle(request, templateInstance) + formExtraActions := p.DetailExtraActions(request, templateInstance) + fields := p.DetailFieldsWithinComponents(request, templateInstance, data) + formActions := p.DetailActions(request, templateInstance) + + return p.DetailWithinCard( + request, + templateInstance, + title, + formExtraActions, + fields, + formActions, + data, + ) +} + +// 在卡片内的详情页组件 +func (p *Template) DetailWithinCard( + request *builder.Request, + templateInstance interface{}, + title string, + extra interface{}, + fields interface{}, + actions []interface{}, + data map[string]interface{}) interface{} { + + return (&card.Component{}). + Init(). + SetTitle(title). + SetHeaderBordered(true). + SetExtra(extra). + SetBody(fields) +} + +// 在标签页内的详情页组件 +func (p *Template) DetailWithinTabs( + request *builder.Request, + templateInstance interface{}, + title string, + extra interface{}, + fields interface{}, + actions []interface{}, + data map[string]interface{}) interface{} { + + return (&tabs.Component{}).Init().SetTabPanes(fields).SetTabBarExtraContent(extra) +} + +// 详情页页面显示前回调 +func (p *Template) BeforeDetailShowing(request *builder.Request, data map[string]interface{}) map[string]interface{} { + return data +} diff --git a/pkg/builder/template/adminresource/resource_edit.go b/pkg/builder/template/adminresource/resource_edit.go new file mode 100644 index 0000000..dad87b2 --- /dev/null +++ b/pkg/builder/template/adminresource/resource_edit.go @@ -0,0 +1,58 @@ +package adminresource + +import ( + "strings" + + "github.com/gobeam/stringy" + "github.com/quarkcms/quark-go/pkg/builder" +) + +//更新表单的接口 +func (p *Template) UpdateApi(request *builder.Request, templateInstance interface{}) string { + formApi := templateInstance.(interface{ FormApi(*builder.Request) string }).FormApi(request) + if formApi != "" { + return formApi + } + + uri := strings.Split(request.Path(), "/") + if uri[len(uri)-1] == "index" { + return stringy.New(request.Path()).ReplaceLast("/index", "/save") + } + + return stringy.New(request.Path()).ReplaceLast("/edit", "/save") +} + +// 编辑页面获取表单数据接口 +func (p *Template) EditValueApi(request *builder.Request) string { + uri := strings.Split(request.Path(), "/") + if uri[len(uri)-1] == "index" { + return stringy.New(request.Path()).ReplaceLast("/index", "/edit/values?id=${id}") + } + + return stringy.New(request.Path()).ReplaceLast("/edit", "/edit/values?id=${id}") +} + +// 渲染编辑页组件 +func (p *Template) UpdateComponentRender(request *builder.Request, templateInstance interface{}, data map[string]interface{}) interface{} { + title := p.FormTitle(request, templateInstance) + formExtraActions := p.FormExtraActions(request, templateInstance) + api := p.UpdateApi(request, templateInstance) + fields := p.UpdateFieldsWithinComponents(request, templateInstance) + formActions := p.FormActions(request, templateInstance) + + return p.FormComponentRender( + request, + templateInstance, + title, + formExtraActions, + api, + fields, + formActions, + data, + ) +} + +// 编辑页面显示前回调 +func (p *Template) BeforeEditing(request *builder.Request, data map[string]interface{}) map[string]interface{} { + return data +} diff --git a/pkg/builder/template/adminresource/resource_form.go b/pkg/builder/template/adminresource/resource_form.go new file mode 100644 index 0000000..de12244 --- /dev/null +++ b/pkg/builder/template/adminresource/resource_form.go @@ -0,0 +1,130 @@ +package adminresource + +import ( + "reflect" + "strings" + + "github.com/quarkcms/quark-go/pkg/builder" + "github.com/quarkcms/quark-go/pkg/component/admin/card" + "github.com/quarkcms/quark-go/pkg/component/admin/form" + "github.com/quarkcms/quark-go/pkg/component/admin/tabs" + "github.com/quarkcms/quark-go/pkg/msg" + "gorm.io/gorm" +) + +// 表单接口 +func (p *Template) FormApi(request *builder.Request) string { + return "" +} + +// 表单标题 +func (p *Template) FormTitle(request *builder.Request, templateInstance interface{}) string { + value := reflect.ValueOf(templateInstance).Elem() + title := value.FieldByName("Title").String() + if request.IsCreating() { + return "创建" + title + } else { + if request.IsEditing() { + return "编辑" + title + } + } + + return title +} + +// 渲染表单组件 +func (p *Template) FormComponentRender( + request *builder.Request, + templateInstance interface{}, + title string, + extra interface{}, + api string, + fields interface{}, + actions []interface{}, + data map[string]interface{}) interface{} { + + getFields, ok := fields.([]interface{}) + + if ok { + component := reflect. + ValueOf(fields.([]interface{})[0]). + Elem(). + FieldByName("Component").String() + + if component == "tabPane" { + return p.FormWithinTabs(request, templateInstance, title, extra, api, getFields, actions, data) + } else { + return p.FormWithinCard(request, templateInstance, title, extra, api, fields, actions, data) + } + } else { + return p.FormWithinCard(request, templateInstance, title, extra, api, fields, actions, data) + } +} + +// 在卡片内的From组件 +func (p *Template) FormWithinCard( + request *builder.Request, + templateInstance interface{}, + title string, + extra interface{}, + api string, + fields interface{}, + actions []interface{}, + data map[string]interface{}) interface{} { + + formComponent := (&form.Component{}). + Init(). + SetStyle(map[string]interface{}{ + "padding": "24px", + }). + SetApi(api). + SetActions(actions). + SetBody(fields). + SetInitialValues(data) + + return (&card.Component{}). + Init(). + SetTitle(title). + SetHeaderBordered(true). + SetExtra(extra). + SetBody(formComponent) +} + +// 在标签页内的From组件 +func (p *Template) FormWithinTabs( + request *builder.Request, + templateInstance interface{}, + title string, + extra interface{}, + api string, + fields interface{}, + actions []interface{}, + data map[string]interface{}) interface{} { + + tabsComponent := (&tabs.Component{}).Init().SetTabPanes(fields).SetTabBarExtraContent(extra) + + return (&form.Component{}). + Init(). + SetStyle(map[string]interface{}{ + "backgroundColor": "#fff", + "paddingBottom": "20px", + }). + SetApi(api). + SetActions(actions). + SetBody(tabsComponent). + SetInitialValues(data) +} + +// 保存数据前回调 +func (p *Template) BeforeSaving(request *builder.Request, submitData map[string]interface{}) (map[string]interface{}, error) { + return submitData, nil +} + +// 保存数据后回调 +func (p *Template) AfterSaved(request *builder.Request, model *gorm.DB) interface{} { + if model.Error != nil { + return msg.Error(model.Error.Error(), "") + } + + return msg.Success("操作成功!", strings.Replace("/index?api="+IndexRoute, ":resource", request.Param("resource"), -1), "") +} diff --git a/pkg/builder/template/adminresource/resource_index.go b/pkg/builder/template/adminresource/resource_index.go new file mode 100644 index 0000000..071b80b --- /dev/null +++ b/pkg/builder/template/adminresource/resource_index.go @@ -0,0 +1,94 @@ +package adminresource + +import ( + "reflect" + + "github.com/quarkcms/quark-go/pkg/builder" + "github.com/quarkcms/quark-go/pkg/component/admin/table" +) + +// 列表页表格主体 +func (p *Template) IndexExtraRender(request *builder.Request, templateInstance interface{}) interface{} { + return nil +} + +// 列表页工具栏 +func (p *Template) IndexToolBar(request *builder.Request, templateInstance interface{}) interface{} { + return (&table.ToolBar{}).Init().SetTitle(p.IndexTitle(request, templateInstance)).SetActions(p.IndexActions(request, templateInstance)) +} + +// 列表标题 +func (p *Template) IndexTitle(request *builder.Request, templateInstance interface{}) string { + return reflect. + ValueOf(templateInstance). + Elem(). + FieldByName("Title"). + String() + "列表" +} + +// 列表页组件渲染 +func (p *Template) IndexComponentRender(request *builder.Request, templateInstance interface{}, data interface{}) interface{} { + var component interface{} + + // 列表标题 + title := p.IndexTitle(request, templateInstance) + + // 反射获取参数 + value := reflect.ValueOf(templateInstance).Elem() + indexPolling := value.FieldByName("IndexPolling").Int() + + // 列表页表格主体 + indexExtraRender := p.IndexExtraRender(request, templateInstance) + + // 列表页工具栏 + indexToolBar := p.IndexToolBar(request, templateInstance) + + // 列表页表格列 + indexColumns := p.IndexColumns(request, templateInstance) + + // 列表页批量操作 + indexTableAlertActions := p.IndexTableAlertActions(request, templateInstance) + + // 列表页搜索栏 + indexSearches := p.IndexSearches(request, templateInstance) + + table := (&table.Component{}). + Init(). + SetPolling(int(indexPolling)). + SetTitle(title). + SetTableExtraRender(indexExtraRender). + SetToolBar(indexToolBar). + SetColumns(indexColumns). + SetBatchActions(indexTableAlertActions). + SetSearches(indexSearches) + + // 获取分页 + perPage := reflect. + ValueOf(templateInstance). + Elem(). + FieldByName("PerPage").Interface() + + // 不分页,直接返回数据 + if reflect.TypeOf(perPage).String() != "int" { + component = table.SetDatasource(data) + } else { + current := data.(map[string]interface{})["currentPage"] + perPage := data.(map[string]interface{})["perPage"] + total := data.(map[string]interface{})["total"] + items := data.(map[string]interface{})["items"] + + component = table.SetPagination(current.(int), perPage.(int), int(total.(int64)), 1).SetDatasource(items) + } + + return component +} + +// 列表页面显示前回调 +func (p *Template) BeforeIndexShowing(request *builder.Request, list []map[string]interface{}) []interface{} { + result := []interface{}{} + for _, v := range list { + result = append(result, v) + } + + return result +} diff --git a/pkg/builder/template/template.go b/pkg/builder/template/template.go new file mode 100644 index 0000000..a6a6707 --- /dev/null +++ b/pkg/builder/template/template.go @@ -0,0 +1,125 @@ +package template + +import ( + "reflect" + + "github.com/quarkcms/quark-go/pkg/app/model" + "github.com/quarkcms/quark-go/pkg/builder" + "github.com/quarkcms/quark-go/pkg/component/admin/footer" + "github.com/quarkcms/quark-go/pkg/component/admin/layout" + "github.com/quarkcms/quark-go/pkg/component/admin/page" + "github.com/quarkcms/quark-go/pkg/component/admin/pagecontainer" + "github.com/quarkcms/quark-go/pkg/msg" + "gorm.io/gorm" +) + +// 模板 +type AdminTemplate struct { + DB *gorm.DB // DB对象 + Model interface{} // DB模型结构体 + Routes []*builder.Route +} + +// 获取路由 +func (p *AdminTemplate) GetRoutes() []*builder.Route { + return p.Routes +} + +// 注册路由 +func (p *AdminTemplate) AddRoute(path string, handlerName string) *AdminTemplate { + getRoute := &builder.Route{ + Path: path, + HandlerName: handlerName, + } + p.Routes = append(p.Routes, getRoute) + + return p +} + +// 页面组件渲染 +func (p *AdminTemplate) PageComponentRender(request *builder.Request, templateInstance interface{}, body interface{}) interface{} { + + // Layout组件 + layoutComponent := templateInstance.(interface { + LayoutComponentRender(request *builder.Request, templateInstance interface{}, body interface{}) interface{} + }).LayoutComponentRender(request, templateInstance, body) + + return (&page.Component{}). + Init(). + SetStyle(map[string]interface{}{ + "height": "100vh", + }). + SetBody(layoutComponent). + JsonSerialize() +} + +// 页面布局组件渲染 +func (p *AdminTemplate) LayoutComponentRender(request *builder.Request, templateInstance interface{}, body interface{}) interface{} { + admin := &model.Admin{} + + // 获取登录管理员信息 + adminInfo, err := admin.GetAuthUser(request.Token()) + if err != nil { + return msg.Error(err.Error(), "") + } + + // 获取管理员菜单 + getMenus, err := admin.GetMenuListById(adminInfo.Id) + if err != nil { + return msg.Error(err.Error(), "") + } + + adminLayout := builder.GetAdminLayoutConfig() + + // 页脚 + footer := (&footer.Component{}). + Init(). + SetCopyright(adminLayout.Copyright). + SetLinks(adminLayout.Links) + + // 页面容器组件渲染 + pageContainerComponent := templateInstance.(interface { + PageContainerComponentRender(request *builder.Request, templateInstance interface{}, body interface{}) interface{} + }).PageContainerComponentRender(request, templateInstance, body) + + return (&layout.Component{}). + Init(). + SetTitle(adminLayout.Title). + SetLogo(adminLayout.Logo). + SetHeaderActions(adminLayout.HeaderActions). + SetLayout(adminLayout.Layout). + SetSplitMenus(adminLayout.SplitMenus). + SetHeaderTheme(adminLayout.HeaderTheme). + SetContentWidth(adminLayout.ContentWidth). + SetNavTheme(adminLayout.NavTheme). + SetPrimaryColor(adminLayout.PrimaryColor). + SetFixSiderbar(adminLayout.FixSiderbar). + SetFixedHeader(adminLayout.FixedHeader). + SetIconfontUrl(adminLayout.IconfontUrl). + SetLocale(adminLayout.Locale). + SetSiderWidth(adminLayout.SiderWidth). + SetMenu(getMenus). + SetBody(pageContainerComponent). + SetFooter(footer) +} + +// 页面容器组件渲染 +func (p *AdminTemplate) PageContainerComponentRender(request *builder.Request, templateInstance interface{}, body interface{}) interface{} { + value := reflect.ValueOf(templateInstance).Elem() + title := value.FieldByName("Title").String() + subTitle := value.FieldByName("SubTitle").String() + + // 设置头部 + header := (&pagecontainer.PageHeader{}). + Init(). + SetTitle(title). + SetSubTitle(subTitle) + + return (&pagecontainer.Component{}).Init().SetHeader(header).SetBody(body) +} + +// 默认组件渲染 +func (p *AdminTemplate) Render(request *builder.Request, resource *builder.Resource, templateInstance interface{}) interface{} { + + return msg.Error("请实现组件渲染方法", "") +} diff --git a/pkg/component/admin/action/action.go b/pkg/component/admin/action/action.go new file mode 100644 index 0000000..96040c1 --- /dev/null +++ b/pkg/component/admin/action/action.go @@ -0,0 +1,205 @@ +package action + +import "github.com/quarkcms/quark-go/pkg/component/admin/component" + +type Component struct { + component.Element + Label string `json:"label"` + Block bool `json:"block"` + Danger bool `json:"danger"` + Disabled bool `json:"disabled"` + Ghost bool `json:"ghost"` + Icon string `json:"icon"` + Shape string `json:"shape"` + Size string `json:"size"` + Type string `json:"type"` + ActionType string `json:"actionType"` + SubmitForm any `json:"submitForm"` + Href string `json:"href"` + Target string `json:"target"` + Modal interface{} `json:"modal"` + Drawer interface{} `json:"drawer"` + ConfirmTitle string `json:"confirmTitle"` + ConfirmText string `json:"confirmText"` + ConfirmType string `json:"confirmType"` + Api string `json:"api"` + Reload string `json:"reload"` + WithLoading bool `json:"withLoading"` +} + +// 初始化 +func (p *Component) Init() *Component { + p.Component = "action" + p.Size = "default" + p.Type = "default" + + p.SetKey("action", component.DEFAULT_CRYPT) + + return p +} + +// Set style. +func (p *Component) SetStyle(style map[string]interface{}) *Component { + p.Style = style + + return p +} + +// 设置按钮文字 +func (p *Component) SetLabel(label string) *Component { + p.Label = label + + return p +} + +// 将按钮宽度调整为其父宽度的选项 +func (p *Component) SetBlock(block bool) *Component { + p.Block = block + + return p +} + +// 设置危险按钮 +func (p *Component) SetDanger(danger bool) *Component { + p.Danger = danger + + return p +} + +// 按钮失效状态 +func (p *Component) SetDisabled(disabled bool) *Component { + p.Disabled = disabled + + return p +} + +// 幽灵属性,使按钮背景透明 +func (p *Component) SetGhost(ghost bool) *Component { + p.Ghost = ghost + + return p +} + +// 设置按钮图标 +func (p *Component) SetIcon(icon string) *Component { + p.Icon = "icon-" + icon + + return p +} + +// 设置按钮形状,可选值为 circle、 round 或者不设 +func (p *Component) SetShape(shape string) *Component { + p.Shape = shape + + return p +} + +// 设置按钮类型,primary | ghost | dashed | link | text | default +func (p *Component) SetType(buttonType string, danger bool) *Component { + p.Type = buttonType + p.Danger = danger + + return p +} + +// 设置按钮大小,large | middle | small | default +func (p *Component) SetSize(size string) *Component { + p.Size = size + + return p +} + +//【必填】这是 action 最核心的配置,来指定该 action 的作用类型,支持:ajax、link、url、drawer、dialog、confirm、cancel、prev、next、copy、close。 +func (p *Component) SetActionType(actionType string) *Component { + p.ActionType = actionType + + return p +} + +// 当action 的作用类型为submit的时候,可以指定提交哪个表格,submitForm为提交表单的key值,为空时提交当前表单 +func (p *Component) SetSubmitForm(formKey string) *Component { + p.SubmitForm = formKey + + return p +} + +// 点击跳转的地址,指定此属性 button 的行为和 a 链接一致 +func (p *Component) SetHref(href string) *Component { + p.Href = href + + return p +} + +// 相当于 a 链接的 target 属性,href 存在时生效 +func (p *Component) SetTarget(target string) *Component { + p.Target = target + + return p +} + +// 设置跳转链接 +func (p *Component) SetLink(href string, target string) *Component { + p.SetHref(href) + p.SetTarget(target) + p.ActionType = "link" + + return p +} + +// 弹窗 +func (p *Component) SetModal(callback interface{}) *Component { + modal := (&Modal{}).Init() + getCallback := callback.(func(modal *Modal) interface{}) + + p.Modal = getCallback(modal) + + return p +} + +// 抽屉 +func (p *Component) SetDrawer(callback interface{}) *Component { + drawer := (&Drawer{}).Init() + getCallback := callback.(func(drawer *Drawer) interface{}) + + p.Drawer = getCallback(drawer) + + return p +} + +// 设置行为前的确认操作 +func (p *Component) SetWithConfirm(title string, text string, confirmType string) *Component { + p.ConfirmTitle = title + p.ConfirmText = text + p.ConfirmType = confirmType + + return p +} + +// 执行行为的接口链接 +func (p *Component) SetApi(api string) *Component { + p.Api = api + p.ActionType = "ajax" + + return p +} + +// 执行成功后刷新的组件 +func (p *Component) SetReload(reload string) *Component { + p.Reload = reload + + return p +} + +// 是否具有loading +func (p *Component) SetWithLoading(loading bool) *Component { + p.WithLoading = loading + + return p +} + +// 组件json序列化 +func (p *Component) JsonSerialize() *Component { + p.Component = "action" + + return p +} diff --git a/pkg/component/admin/action/drawer.go b/pkg/component/admin/action/drawer.go new file mode 100644 index 0000000..83a9f5f --- /dev/null +++ b/pkg/component/admin/action/drawer.go @@ -0,0 +1,177 @@ +package action + +import "github.com/quarkcms/quark-go/pkg/component/admin/component" + +type Drawer struct { + component.Element + Title string `json:"title"` + BodyStyle interface{} `json:"bodyStyle"` + Closable bool `json:"closable"` + ContentWrapperStyle interface{} `json:"contentWrapperStyle"` + DestroyOnClose bool `json:"destroyOnClose"` + DrawerStyle interface{} `json:"drawerStyle"` + FooterStyle interface{} `json:"footerStyle"` + Height int `json:"height"` + Keyboard bool `json:"keyboard"` + Mask bool `json:"mask"` + MaskClosable bool `json:"maskClosable"` + MaskStyle interface{} `json:"maskStyle"` + Visible bool `json:"visible"` + Width int `json:"width"` + ZIndex int `json:"zIndex"` + Actions []interface{} `json:"actions"` + Placement string `json:"placement"` + Body interface{} `json:"body"` +} + +// 初始化 +func (p *Drawer) Init() *Drawer { + p.Component = "drawer" + p.SetKey("drawer", component.DEFAULT_CRYPT) + p.Closable = true + p.FooterStyle = map[string]interface{}{ + "textAlign": "right", + } + p.Height = 256 + p.Keyboard = true + p.Mask = true + p.MaskClosable = true + p.Placement = "right" + p.Width = 256 + p.ZIndex = 1000 + + return p +} + +// Set style. +func (p *Drawer) SetStyle(style map[string]interface{}) *Drawer { + p.Style = style + + return p +} + +// 标题 +func (p *Drawer) SetTitle(title string) *Drawer { + p.Title = title + + return p +} + +// Modal body 样式 +func (p *Drawer) SetBodyStyle(style interface{}) *Drawer { + p.BodyStyle = style + + return p +} + +// 容器控件里面的内容 +func (p *Drawer) SetBody(body interface{}) *Drawer { + p.Body = body + + return p +} + +// 是否显示右上角的关闭按钮 +func (p *Drawer) SetClosable(closable bool) *Drawer { + p.Closable = closable + + return p +} + +// 可用于设置 Drawer 包裹内容部分的样式 +func (p *Drawer) SetContentWrapperStyle(style interface{}) *Drawer { + p.ContentWrapperStyle = style + + return p +} + +// 关闭时销毁 Modal 里的子元素 +func (p *Drawer) SetDestroyOnClose(destroyOnClose bool) *Drawer { + p.DestroyOnClose = destroyOnClose + + return p +} + +// 用于设置 Drawer 弹出层的样式 +func (p *Drawer) SetDrawerStyle(style interface{}) *Drawer { + p.DrawerStyle = style + + return p +} + +// 抽屉页脚部件的样式 +func (p *Drawer) SetFooterStyle(style interface{}) *Drawer { + p.FooterStyle = style + + return p +} + +// 高度, 在 placement 为 top 或 bottom 时使用 +func (p *Drawer) SetHeight(height int) *Drawer { + p.Height = height + + return p +} + +// 是否支持键盘 esc 关闭 +func (p *Drawer) SetKeyboard(keyboard bool) *Drawer { + p.Keyboard = keyboard + + return p +} + +// 是否展示遮罩 +func (p *Drawer) SetMask(mask bool) *Drawer { + p.Mask = mask + + return p +} + +// 点击蒙层是否允许关闭 +func (p *Drawer) SetMaskClosable(maskClosable bool) *Drawer { + p.MaskClosable = maskClosable + + return p +} + +// 遮罩样式 +func (p *Drawer) SetMaskStyle(style interface{}) *Drawer { + p.MaskStyle = style + + return p +} + +// 抽屉的方向,top | right | bottom | left +func (p *Drawer) SetPlacement(placement string) *Drawer { + p.Placement = placement + + return p +} + +// 对话框是否可见 +func (p *Drawer) SetVisible(visible bool) *Drawer { + p.Visible = visible + + return p +} + +// 宽度 +func (p *Drawer) SetWidth(width int) *Drawer { + p.Width = width + + return p +} + +// 设置 Modal 的 z-index +func (p *Drawer) SetZIndex(zIndex int) *Drawer { + p.ZIndex = zIndex + + return p +} + +// 弹窗行为 +func (p *Drawer) SetActions(actions []interface{}) *Drawer { + p.Actions = actions + + return p +} diff --git a/pkg/component/admin/action/modal.go b/pkg/component/admin/action/modal.go new file mode 100644 index 0000000..9678e42 --- /dev/null +++ b/pkg/component/admin/action/modal.go @@ -0,0 +1,148 @@ +package action + +import "github.com/quarkcms/quark-go/pkg/component/admin/component" + +type Modal struct { + component.Element + Title string `json:"title"` + BodyStyle interface{} `json:"bodyStyle"` + Centered bool `json:"centered"` + Closable bool `json:"closable"` + DestroyOnClose bool `json:"destroyOnClose"` + FocusTriggerAfterClose bool `json:"focusTriggerAfterClose"` + Keyboard bool `json:"keyboard"` + Mask bool `json:"mask"` + MaskClosable bool `json:"maskClosable"` + MaskStyle interface{} `json:"maskStyle"` + Visible bool `json:"visible"` + Width int `json:"width"` + ZIndex int `json:"zIndex"` + Actions []interface{} `json:"actions"` + Body interface{} `json:"body"` +} + +// 初始化 +func (p *Modal) Init() *Modal { + p.Component = "modal" + p.SetKey("modal", component.DEFAULT_CRYPT) + p.Closable = true + p.Keyboard = true + p.Mask = true + p.MaskClosable = true + p.Width = 520 + p.ZIndex = 1000 + + return p +} + +// Set style. +func (p *Modal) SetStyle(style map[string]interface{}) *Modal { + p.Style = style + + return p +} + +// 标题 +func (p *Modal) SetTitle(title string) *Modal { + p.Title = title + + return p +} + +// Modal body 样式 +func (p *Modal) SetBodyStyle(style interface{}) *Modal { + p.BodyStyle = style + + return p +} + +// 容器控件里面的内容 +func (p *Modal) SetBody(body interface{}) *Modal { + p.Body = body + + return p +} + +// 垂直居中展示 Modal +func (p *Modal) SetCentered(centered bool) *Modal { + p.Centered = centered + + return p +} + +// 是否显示右上角的关闭按钮 +func (p *Modal) SetClosable(closable bool) *Modal { + p.Closable = closable + + return p +} + +// 关闭时销毁 Modal 里的子元素 +func (p *Modal) SetDestroyOnClose(destroyOnClose bool) *Modal { + p.DestroyOnClose = destroyOnClose + + return p +} + +// 设置按钮形状,可选值为 circle、 round 或者不设 +func (p *Modal) SetFocusTriggerAfterClose(focusTriggerAfterClose bool) *Modal { + p.FocusTriggerAfterClose = focusTriggerAfterClose + + return p +} + +// 是否支持键盘 esc 关闭 +func (p *Modal) SetKeyboard(keyboard bool) *Modal { + p.Keyboard = keyboard + + return p +} + +// 是否展示遮罩 +func (p *Modal) SetMask(mask bool) *Modal { + p.Mask = mask + + return p +} + +// 点击蒙层是否允许关闭 +func (p *Modal) SetMaskClosable(maskClosable bool) *Modal { + p.MaskClosable = maskClosable + + return p +} + +// 遮罩样式 +func (p *Modal) SetMaskStyle(style map[string]interface{}) *Modal { + p.MaskStyle = style + + return p +} + +// 对话框是否可见 +func (p *Modal) SetVisible(visible bool) *Modal { + p.Visible = visible + + return p +} + +// 宽度 +func (p *Modal) SetWidth(width int) *Modal { + p.Width = width + + return p +} + +// 设置 Modal 的 z-index +func (p *Modal) SetZIndex(zIndex int) *Modal { + p.ZIndex = zIndex + + return p +} + +// 弹窗行为 +func (p *Modal) SetActions(actions []interface{}) *Modal { + p.Actions = actions + + return p +} diff --git a/pkg/component/admin/card/card.go b/pkg/component/admin/card/card.go new file mode 100644 index 0000000..fa81973 --- /dev/null +++ b/pkg/component/admin/card/card.go @@ -0,0 +1,153 @@ +package card + +import "github.com/quarkcms/quark-go/pkg/component/admin/component" + +type Component struct { + component.Element + Title string `json:"title"` + SubTitle string `json:"subTitle"` + Tip string `json:"tip"` + Extra interface{} `json:"extra"` + Layout string `json:"layout"` + Loading bool `json:"loading"` + ColSpan interface{} `json:"colSpan"` + Gutter interface{} `json:"gutter"` + Split string `json:"split"` + Bordered bool `json:"bordered"` + Ghost bool `json:"ghost"` + HeaderBordered bool `json:"headerBordered"` + Collapsible bool `json:"collapsible"` + DefaultCollapsed bool `json:"defaultCollapsed"` + Body interface{} `json:"body"` +} + +// 初始化 +func (p *Component) Init() *Component { + p.Component = "card" + p.Layout = "default" + p.ColSpan = 24 + p.Gutter = 0 + + p.SetKey(component.DEFAULT_KEY, component.DEFAULT_CRYPT) + + return p +} + +// Set style. +func (p *Component) SetStyle(style map[string]interface{}) *Component { + p.Style = style + + return p +} + +// 设置标题文字 +func (p *Component) SetTitle(title string) *Component { + p.Title = title + + return p +} + +// 设置二级标题文字 +func (p *Component) SetSubTitle(subTitle string) *Component { + p.SubTitle = subTitle + + return p +} + +// 标题右侧图标 hover 提示信息 +func (p *Component) SetTip(tip string) *Component { + p.Tip = tip + + return p +} + +// 右上角自定义区域 +func (p *Component) SetExtra(extra interface{}) *Component { + p.Extra = extra + + return p +} + +// 内容布局,支持垂直居中 default | center +func (p *Component) SetLayout(layout string) *Component { + p.Layout = layout + + return p +} + +// 加载中,支持自定义 loading 样式 +func (p *Component) SetLoading(loading bool) *Component { + p.Loading = loading + + return p +} + +// 栅格布局宽度,24 栅格,支持指定宽度 px 或百分比, 支持响应式的对象写法 { xs: 8, sm: 16, md: 24} +func (p *Component) SetColSpan(colSpan interface{}) *Component { + p.ColSpan = colSpan + + return p +} + +// 栅格布局宽度,24 栅格,支持指定宽度 px 或百分比, 支持响应式的对象写法 { xs: 8, sm: 16, md: 24} +func (p *Component) SetGutter(gutter interface{}) *Component { + p.Gutter = gutter + + return p +} + +// 拆分卡片的方向,vertical | horizontal +func (p *Component) SetSplit(split string) *Component { + p.Split = split + + return p +} + +// 是否有边框 +func (p *Component) SetBordered(bordered bool) *Component { + p.Bordered = bordered + + return p +} + +// 幽灵模式,即是否取消卡片内容区域的 padding 和 卡片的背景颜色。 +func (p *Component) SetGhost(ghost bool) *Component { + p.Ghost = ghost + + return p +} + +// 页头是否有分割线 +func (p *Component) SetHeaderBordered(headerBordered bool) *Component { + p.HeaderBordered = headerBordered + + return p +} + +// 页头是否有分割线 +func (p *Component) SetCollapsible(collapsible bool) *Component { + p.Collapsible = collapsible + + return p +} + +// 默认折叠, 受控时无效 +func (p *Component) SetDefaultCollapsed(defaultCollapsed bool) *Component { + p.DefaultCollapsed = defaultCollapsed + + return p +} + +// 卡牌内容 +func (p *Component) SetBody(body interface{}) *Component { + p.Body = body + + return p +} + +// 组件json序列化 +func (p *Component) JsonSerialize() *Component { + p.Component = "card" + + return p +} diff --git a/pkg/component/admin/chart/chart.go b/pkg/component/admin/chart/chart.go new file mode 100644 index 0000000..36fe285 --- /dev/null +++ b/pkg/component/admin/chart/chart.go @@ -0,0 +1,21 @@ +package chart + +import "github.com/quarkcms/quark-go/pkg/component/admin/component" + +type Component struct { + component.Element +} + +// 初始化 +func (p *Component) Init() *Component { + p.Component = "chart" + p.SetKey(component.DEFAULT_KEY, component.DEFAULT_CRYPT) + + return p +} + +// 折线图表 +func (p *Component) Line(data interface{}) *Line { + + return (&Line{}).Init().SetData(data) +} diff --git a/pkg/component/admin/chart/line.go b/pkg/component/admin/chart/line.go new file mode 100644 index 0000000..6d0dfb5 --- /dev/null +++ b/pkg/component/admin/chart/line.go @@ -0,0 +1,114 @@ +package chart + +import "github.com/quarkcms/quark-go/pkg/component/admin/component" + +type Line struct { + component.Element + Api string `json:"api"` + Width int `json:"width"` + Height int `json:"height"` + AutoFit bool `json:"autoFit"` + Padding interface{} `json:"padding"` + AppendPadding interface{} `json:"appendPadding"` + Renderer string `json:"renderer"` + LimitInPlot bool `json:"limitInPlot"` + Locale string `json:"locale"` + Data interface{} `json:"data"` + XField string `json:"xField"` + YField string `json:"yField"` + Meta interface{} `json:"meta"` + Smooth bool `json:"smooth"` +} + +// 初始化 +func (p *Line) Init() *Line { + p.Component = "line" + p.SetKey(component.DEFAULT_KEY, component.DEFAULT_CRYPT) + + return p +} + +// 数据接口 +func (p *Line) SetApi(api string) *Line { + p.Api = api + return p +} + +// 设置图表宽度 +func (p *Line) SetWidth(width int) *Line { + p.Width = width + return p +} + +// 设置图表高度 +func (p *Line) SetHeight(height int) *Line { + p.Height = height + return p +} + +// 图表是否自适应容器宽高。当 autoFit 设置为 true 时,width 和 height 的设置将失效。 +func (p *Line) SetAutoFit(autoFit bool) *Line { + p.AutoFit = autoFit + return p +} + +// 画布的 padding 值,代表图表在上右下左的间距,可以为单个数字 16,或者数组 [16, 8, 16, 8] 代表四个方向,或者开启 auto,由底层自动计算间距。 +func (p *Line) SetPadding(padding interface{}) *Line { + p.Padding = padding + return p +} + +// 额外增加的 appendPadding 值,在 padding 的基础上,设置额外的 padding 数值,可以是单个数字 16,或者数组 [16, 8, 16, 8] 代表四个方向。 +func (p *Line) SetAppendPadding(appendPadding interface{}) *Line { + p.AppendPadding = appendPadding + return p +} + +// 设置图表渲染方式为 canvas 或 svg。 +func (p *Line) SetRenderer(renderer string) *Line { + p.Renderer = renderer + return p +} + +// 是否对超出坐标系范围的 Geometry 进行剪切。 +func (p *Line) SetLimitInPlot(limitInPlot bool) *Line { + p.LimitInPlot = limitInPlot + return p +} + +// 指定具体语言,目前内置 'zh-CN' and 'en-US' 两个语言,你也可以使用 G2Plot.registerLocale 方法注册新的语言。语言包格式参考:src/locales/en_US.ts +func (p *Line) SetLocale(locale string) *Line { + p.Locale = locale + return p +} + +// 数据 +func (p *Line) SetData(data interface{}) *Line { + p.Data = data + return p +} + +// X轴字段 +func (p *Line) SetXField(xField string) *Line { + p.XField = xField + return p +} + +// y轴字段 +func (p *Line) SetYField(yField string) *Line { + p.YField = yField + return p +} + +// 通过 meta 可以全局化配置图表数据元信息,以字段为单位进行配置。在 meta 上的配置将同时影响所有组件的文本信息。传入以字段名为 key,MetaOption 为 value 的配置,同时设置多个字段的元信息。 +func (p *Line) SetMeta(meta interface{}) *Line { + p.Meta = meta + + return p +} + +// 是否平滑 +func (p *Line) SetSmooth(smooth bool) *Line { + p.Smooth = smooth + return p +} diff --git a/pkg/component/admin/component/element.go b/pkg/component/admin/component/element.go new file mode 100644 index 0000000..90f8904 --- /dev/null +++ b/pkg/component/admin/component/element.go @@ -0,0 +1,37 @@ +package component + +import ( + "crypto/md5" + "encoding/hex" + + "github.com/go-basic/uuid" +) + +type Element struct { + Key string `json:"key"` + ComponentKey string `json:"componentKey"` + Component string `json:"component"` + Style map[string]interface{} `json:"style"` +} + +const DEFAULT_KEY = "" +const DEFAULT_CRYPT = true + +// 设置Key +func (p *Element) SetKey(key string, crypt bool) *Element { + + if key == "" { + key = uuid.New() + } + + if crypt { + h := md5.New() + h.Write([]byte(key)) + key = hex.EncodeToString(h.Sum(nil)) + } + + p.Key = key + p.ComponentKey = key + + return p +} diff --git a/pkg/component/admin/descriptions/descriptions.go b/pkg/component/admin/descriptions/descriptions.go new file mode 100644 index 0000000..523ff51 --- /dev/null +++ b/pkg/component/admin/descriptions/descriptions.go @@ -0,0 +1,118 @@ +package descriptions + +import "github.com/quarkcms/quark-go/pkg/component/admin/component" + +type Component struct { + component.Element + Title string `json:"title"` + Tooltip string `json:"tooltip"` + Bordered bool `json:"bordered"` + Layout string `json:"layout"` + Column interface{} `json:"column"` + Columns interface{} `json:"columns"` + DataSource interface{} `json:"dataSource"` + Size string `json:"size"` + Colon bool `json:"colon"` + Data interface{} `json:"data"` + Items interface{} `json:"items"` + Actions interface{} `json:"actions"` +} + +// 初始化 +func (p *Component) Init() *Component { + p.Component = "descriptions" + p.Column = 1 + p.Layout = "horizontal" + p.Colon = true + p.Size = "default" + + p.SetKey(component.DEFAULT_KEY, component.DEFAULT_CRYPT) + + return p +} + +// Set style. +func (p *Component) SetStyle(style map[string]interface{}) *Component { + p.Style = style + + return p +} + +// 标题 +func (p *Component) SetTitle(title string) *Component { + p.Title = title + return p +} + +// 内容的补充描述,hover 后显示 +func (p *Component) SetTooltip(tooltip string) *Component { + p.Tooltip = tooltip + return p +} + +// 是否展示边框 +func (p *Component) SetBordered(bordered bool) *Component { + p.Bordered = bordered + return p +} + +// 布局,horizontal|vertical +func (p *Component) SetLayout(layout string) *Component { + p.Layout = layout + return p +} + +// 一行的 ProDescriptionsItems 数量,可以写成像素值或支持响应式的对象写法 { xs: 8, sm: 16, md: 24} +func (p *Component) SetColumn(column interface{}) *Component { + p.Column = column + return p +} + +// 列 +func (p *Component) SetColumns(columns interface{}) *Component { + p.Columns = columns + return p +} + +// 数据 +func (p *Component) SetDataSource(dataSource interface{}) *Component { + p.DataSource = dataSource + return p +} + +// 设置尺寸 +func (p *Component) SetSize(size string) *Component { + p.Size = size + return p +} + +// 配置 ProDescriptions.Item 的 colon 的默认值 +func (p *Component) SetColon(colon bool) *Component { + p.Colon = colon + return p +} + +// 数据 +func (p *Component) SetData(data interface{}) *Component { + p.Data = data + return p +} + +// 数据项 +func (p *Component) SetItems(items interface{}) *Component { + p.Items = items + return p +} + +// 行为 +func (p *Component) SetActions(actions interface{}) *Component { + p.Actions = actions + return p +} + +// 组件json序列化 +func (p *Component) JsonSerialize() *Component { + p.Component = "descriptions" + + return p +} diff --git a/pkg/component/admin/descriptions/field.go b/pkg/component/admin/descriptions/field.go new file mode 100644 index 0000000..f011bc4 --- /dev/null +++ b/pkg/component/admin/descriptions/field.go @@ -0,0 +1,33 @@ +package descriptions + +import ( + "github.com/quarkcms/quark-go/pkg/component/admin/component" + "github.com/quarkcms/quark-go/pkg/component/admin/descriptions/fields" +) + +type Field struct { + component.Element +} + +// 初始化 +func (p *Field) Init() *Field { + p.Component = "descriptionField" + + p.SetKey(component.DEFAULT_KEY, component.DEFAULT_CRYPT) + + return p +} + +// text组件 +func (p *Field) Text(params ...string) *fields.Text { + + fields := &fields.Text{} + + if len(params) == 1 { + fields = fields.Init().SetDataIndex(params[0]).SetLabel(params[0]) + } else { + fields = fields.Init().SetDataIndex(params[0]).SetLabel(params[1]) + } + + return fields +} diff --git a/pkg/component/admin/descriptions/fields/text.go b/pkg/component/admin/descriptions/fields/text.go new file mode 100644 index 0000000..4e2b795 --- /dev/null +++ b/pkg/component/admin/descriptions/fields/text.go @@ -0,0 +1,80 @@ +package fields + +import "github.com/quarkcms/quark-go/pkg/component/admin/component" + +type Text struct { + component.Element + Label string `json:"label"` + Tooltip string `json:"tooltip"` + Span string `json:"span"` + ValueType string `json:"valueType"` + ValueEnum string `json:"valueEnum"` + DataIndex string `json:"dataIndex"` + Value interface{} `json:"value"` +} + +// 初始化 +func (p *Text) Init() *Text { + p.Component = "text" + p.ValueType = "text" + + p.SetKey(component.DEFAULT_KEY, component.DEFAULT_CRYPT) + + return p +} + +// Set style. +func (p *Text) SetStyle(style map[string]interface{}) *Text { + p.Style = style + + return p +} + +// 内容的描述 +func (p *Text) SetLabel(label string) *Text { + p.Label = label + + return p +} + +// 内容的补充描述,hover 后显示 +func (p *Text) SetTooltip(tooltip string) *Text { + p.Tooltip = tooltip + + return p +} + +// 列数 +func (p *Text) SetSpan(span string) *Text { + p.Span = span + + return p +} + +// 值类型 +func (p *Text) SetValueType(valueType string) *Text { + p.ValueType = valueType + + return p +} + +// 值枚举 +func (p *Text) SetValueEnum(valueEnum string) *Text { + p.ValueEnum = valueEnum + + return p +} + +// 索引 +func (p *Text) SetDataIndex(dataIndex string) *Text { + p.DataIndex = dataIndex + + return p +} + +// 设置保存值。 +func (p *Text) SetValue(value interface{}) *Text { + p.Value = value + + return p +} diff --git a/pkg/component/admin/divider/divider.go b/pkg/component/admin/divider/divider.go new file mode 100644 index 0000000..0ffe655 --- /dev/null +++ b/pkg/component/admin/divider/divider.go @@ -0,0 +1,89 @@ +package divider + +import "github.com/quarkcms/quark-go/pkg/component/admin/component" + +type Component struct { + component.Element + Dashed bool `json:"dashed"` + Orientation string `json:"orientation"` + Plain bool `json:"plain"` + Type string `json:"type"` + Body interface{} `json:"body"` +} + +// 初始化 +func (p *Component) Init() *Component { + p.Component = "divider" + p.SetKey(component.DEFAULT_KEY, component.DEFAULT_CRYPT) + p.Type = "horizontal" + p.Orientation = "center" + + return p +} + +// 是否虚线 +func (p *Component) SetDashed(dashed bool) *Component { + p.Dashed = dashed + + return p +} + +// 间距方向,'left', 'right', 'center' +func (p *Component) SetOrientation(orientation string) *Component { + + limits := []string{ + "left", "right", "center", + } + + inSlice := false + for _, limit := range limits { + if limit == orientation { + inSlice = true + } + } + + if inSlice == false { + panic("Argument must be in 'left', 'right', 'center'!") + } + + p.Orientation = orientation + + return p +} + +// 文字是否显示为普通正文样式 +func (p *Component) SetPlain(plain bool) *Component { + p.Plain = plain + + return p +} + +// 水平还是垂直类型,horizontal | vertical +func (p *Component) SetType(dividerType string) *Component { + + limits := []string{ + "vertical", "horizontal", + } + + inSlice := false + for _, limit := range limits { + if limit == dividerType { + inSlice = true + } + } + + if inSlice == false { + panic("Argument must be in 'vertical', 'horizontal'!") + } + + p.Type = dividerType + + return p +} + +// 容器控件里面的内容 +func (p *Component) SetBody(body interface{}) *Component { + p.Body = body + + return p +} diff --git a/pkg/component/admin/dropdown/dropdown.go b/pkg/component/admin/dropdown/dropdown.go new file mode 100644 index 0000000..a6f4828 --- /dev/null +++ b/pkg/component/admin/dropdown/dropdown.go @@ -0,0 +1,160 @@ +package dropdown + +import "github.com/quarkcms/quark-go/pkg/component/admin/component" + +type Component struct { + component.Element + Label string `json:"label"` + Block bool `json:"block"` + Danger bool `json:"danger"` + Disabled bool `json:"disabled"` + Ghost bool `json:"ghost"` + Icon string `json:"icon"` + Shape string `json:"shape"` + Size string `json:"size"` + Type string `json:"type"` + Arrow bool `json:"arrow"` + DestroyPopupOnHide bool `json:"destroyPopupOnHide"` + Overlay interface{} `json:"overlay"` + OverlayClassName string `json:"overlayClassName"` + OverlayStyle map[string]interface{} `json:"overlayStyle"` + Placement string `json:"placement"` + Trigger []string `json:"trigger"` + Visible bool `json:"-"` +} + +// 初始化 +func (p *Component) Init() *Component { + p.Component = "dropdown" + p.SetKey(component.DEFAULT_KEY, component.DEFAULT_CRYPT) + p.Visible = true + + return p +} + +// Set style. +func (p *Component) SetStyle(style map[string]interface{}) *Component { + p.Style = style + + return p +} + +// 设置按钮文字 +func (p *Component) SetLabel(label string) *Component { + p.Label = label + + return p +} + +// 将按钮宽度调整为其父宽度的选项 +func (p *Component) SetBlock(block bool) *Component { + p.Block = block + + return p +} + +// 设置危险按钮 +func (p *Component) SetDanger(danger bool) *Component { + p.Danger = danger + + return p +} + +// 按钮失效状态 +func (p *Component) SetDisabled(disabled bool) *Component { + p.Disabled = disabled + + return p +} + +// 幽灵属性,使按钮背景透明 +func (p *Component) SetGhost(ghost bool) *Component { + p.Ghost = ghost + + return p +} + +// 设置按钮图标 +func (p *Component) SetIcon(icon string) *Component { + p.Icon = "icon-" + icon + + return p +} + +// 设置按钮形状,可选值为 circle、 round 或者不设 +func (p *Component) SetShape(shape string) *Component { + p.Shape = shape + + return p +} + +// 设置按钮类型,primary | ghost | dashed | link | text | default +func (p *Component) SetType(buttonType string, danger bool) *Component { + p.Type = buttonType + p.Danger = danger + + return p +} + +// 设置按钮大小,large | middle | small | default +func (p *Component) SetSize(size string) *Component { + p.Size = size + + return p +} + +// 下拉框箭头是否显示 +func (p *Component) SetArrow(arrow bool) *Component { + p.Arrow = arrow + + return p +} + +// 关闭后是否销毁 Dropdown +func (p *Component) SetDestroyPopupOnHide(destroyPopupOnHide bool) *Component { + p.DestroyPopupOnHide = destroyPopupOnHide + + return p +} + +// 菜单 +func (p *Component) SetOverlay(overlay interface{}) *Component { + p.Overlay = overlay + + return p +} + +// 下拉根元素的类名称 +func (p *Component) SetOverlayClassName(overlayClassName string) *Component { + p.OverlayClassName = overlayClassName + + return p +} + +// 下拉根元素的样式 +func (p *Component) SetOverlayStyle(overlayStyle map[string]interface{}) *Component { + p.OverlayStyle = overlayStyle + + return p +} + +// 菜单弹出位置:bottomLeft bottomCenter bottomRight topLeft topCenter topRight +func (p *Component) SetPlacement(placement string) *Component { + p.Placement = placement + + return p +} + +// 触发下拉的行为, 移动端不支持 hover,Array +func (p *Component) SetTrigger(trigger []string) *Component { + p.Trigger = trigger + + return p +} + +// 菜单是否显示 +func (p *Component) SetVisible(visible bool) *Component { + p.Visible = visible + + return p +} diff --git a/pkg/component/admin/dropdown/item.go b/pkg/component/admin/dropdown/item.go new file mode 100644 index 0000000..2911783 --- /dev/null +++ b/pkg/component/admin/dropdown/item.go @@ -0,0 +1,198 @@ +package dropdown + +import ( + "github.com/quarkcms/quark-go/pkg/component/admin/action" + "github.com/quarkcms/quark-go/pkg/component/admin/component" +) + +type Item struct { + component.Element + Label string `json:"label"` + Block bool `json:"block"` + Danger bool `json:"danger"` + Disabled bool `json:"disabled"` + Ghost bool `json:"ghost"` + Icon string `json:"icon"` + Shape string `json:"shape"` + Size string `json:"size"` + Type string `json:"type"` + ActionType string `json:"actionType"` + SubmitForm any `json:"submitForm"` + Href string `json:"href"` + Target string `json:"target"` + Modal interface{} `json:"modal"` + Drawer interface{} `json:"drawer"` + ConfirmTitle string `json:"confirmTitle"` + ConfirmText string `json:"confirmText"` + ConfirmType string `json:"confirmType"` + Api string `json:"api"` + Reload string `json:"reload"` + WithLoading bool `json:"withLoading"` +} + +// 初始化 +func (p *Item) Init() *Item { + p.Component = "itemStyle" + p.SetKey(component.DEFAULT_KEY, component.DEFAULT_CRYPT) + + return p +} + +// Set style. +func (p *Item) SetStyle(style map[string]interface{}) *Item { + p.Style = style + + return p +} + +// 设置按钮文字 +func (p *Item) SetLabel(label string) *Item { + p.Label = label + + return p +} + +// 将按钮宽度调整为其父宽度的选项 +func (p *Item) SetBlock(block bool) *Item { + p.Block = block + + return p +} + +// 设置危险按钮 +func (p *Item) SetDanger(danger bool) *Item { + p.Danger = danger + + return p +} + +// 按钮失效状态 +func (p *Item) SetDisabled(disabled bool) *Item { + p.Disabled = disabled + + return p +} + +// 幽灵属性,使按钮背景透明 +func (p *Item) SetGhost(ghost bool) *Item { + p.Ghost = ghost + + return p +} + +// 设置按钮图标 +func (p *Item) SetIcon(icon string) *Item { + p.Icon = "icon-" + icon + + return p +} + +// 设置按钮形状,可选值为 circle、 round 或者不设 +func (p *Item) SetShape(shape string) *Item { + p.Shape = shape + + return p +} + +// 设置按钮类型,primary | ghost | dashed | link | text | default +func (p *Item) SetType(buttonType string, danger bool) *Item { + p.Type = buttonType + p.Danger = danger + + return p +} + +// 设置按钮大小,large | middle | small | default +func (p *Item) SetSize(size string) *Item { + p.Size = size + + return p +} + +// 【必填】这是 action 最核心的配置,来指定该 action 的作用类型,支持:ajax、link、url、drawer、dialog、confirm、cancel、prev、next、copy、close。 +func (p *Item) SetActionType(actionType string) *Item { + p.ActionType = actionType + + return p +} + +// 当action 的作用类型为submit的时候,可以指定提交哪个表格,submitForm为提交表单的key值,为空时提交当前表单 +func (p *Item) SetSubmitForm(formKey string) *Item { + p.SubmitForm = formKey + + return p +} + +// 点击跳转的地址,指定此属性 button 的行为和 a 链接一致 +func (p *Item) SetHref(href string) *Item { + p.Href = href + + return p +} + +// 相当于 a 链接的 target 属性,href 存在时生效 +func (p *Item) SetTarget(target string) *Item { + p.Target = target + + return p +} + +// 设置跳转链接 +func (p *Item) SetLink(href string, target string) *Item { + p.SetHref(href) + p.SetTarget(target) + p.ActionType = "link" + + return p +} + +// 弹窗 +func (p *Item) SetModal(callback interface{}) *Item { + modal := (&action.Modal{}).Init() + getCallback := callback.(func(modal *action.Modal) interface{}) + + p.Modal = getCallback(modal) + + return p +} + +// 抽屉 +func (p *Item) SetDrawer(callback interface{}) *Item { + drawer := (&action.Drawer{}).Init() + getCallback := callback.(func(drawer *action.Drawer) interface{}) + + p.Drawer = getCallback(drawer) + + return p +} + +// 设置行为前的确认操作 +func (p *Item) SetWithConfirm(title string, text string, confirmType string) *Item { + p.ConfirmTitle = title + p.ConfirmText = text + p.ConfirmType = confirmType + + return p +} + +// 执行行为的接口链接 +func (p *Item) SetApi(api string) *Item { + p.Api = api + p.ActionType = "ajax" + + return p +} + +// 执行成功后刷新的组件 +func (p *Item) SetReload(reload string) *Item { + p.Reload = reload + + return p +} + +// 是否具有loading +func (p *Item) SetWithLoading(loading bool) *Item { + p.WithLoading = loading + + return p +} diff --git a/pkg/component/admin/footer/footer.go b/pkg/component/admin/footer/footer.go new file mode 100644 index 0000000..f2d58db --- /dev/null +++ b/pkg/component/admin/footer/footer.go @@ -0,0 +1,44 @@ +package footer + +import "github.com/quarkcms/quark-go/pkg/component/admin/component" + +type Component struct { + component.Element + Copyright string `json:"copyright"` + Links []map[string]interface{} `json:"links"` +} + +// 初始化 +func (p *Component) Init() *Component { + p.Component = "footer" + + p.SetKey(component.DEFAULT_KEY, component.DEFAULT_CRYPT) + + return p +} + +// Set style. +func (p *Component) SetStyle(style map[string]interface{}) *Component { + p.Style = style + + return p +} + +// 版权信息 +func (p *Component) SetCopyright(copyright string) *Component { + p.Copyright = copyright + return p +} + +// 版权信息 +func (p *Component) SetLinks(links []map[string]interface{}) *Component { + p.Links = links + return p +} + +// 组件json序列化 +func (p *Component) JsonSerialize() *Component { + p.Component = "footer" + + return p +} diff --git a/pkg/component/admin/form/fields/cascader.go b/pkg/component/admin/form/fields/cascader.go new file mode 100644 index 0000000..01c4904 --- /dev/null +++ b/pkg/component/admin/form/fields/cascader.go @@ -0,0 +1,43 @@ +package fields + +import "github.com/quarkcms/quark-go/pkg/component/admin/component" + +type Cascader struct { + Item +} + +// 初始化 +func (p *Cascader) Init() *Cascader { + p.Component = "cascaderField" + p.InitItem().SetKey(component.DEFAULT_KEY, component.DEFAULT_CRYPT) + p.Placeholder = "请选择" + + return p +} + +// 设置属性 +func (p *Cascader) SetOptions(options interface{}) *Cascader { + p.Options = options + + return p +} + +// 控件大小。注:标准表单内的输入框大小限制为 large。可选 large default small +func (p *Cascader) SetSize(size string) *Cascader { + p.Size = size + + return p +} + +// 可以点击清除图标删除内容 +func (p *Cascader) SetAllowClear(allowClear bool) *Cascader { + p.AllowClear = allowClear + + return p +} + +// 获取数据接口 +func (p *Cascader) SetApi(api string) *Cascader { + p.Api = api + return p +} diff --git a/pkg/component/admin/form/fields/checkbox.go b/pkg/component/admin/form/fields/checkbox.go new file mode 100644 index 0000000..590463d --- /dev/null +++ b/pkg/component/admin/form/fields/checkbox.go @@ -0,0 +1,53 @@ +package fields + +import "github.com/quarkcms/quark-go/pkg/component/admin/component" + +type Checkbox struct { + Item + Layout string +} + +// 初始化 +func (p *Checkbox) Init() *Checkbox { + p.Component = "checkboxField" + p.InitItem().SetKey(component.DEFAULT_KEY, component.DEFAULT_CRYPT) + + return p +} + +// 设置单选属性,[]map[string]interface{}{{"label": "Title1","value": "value1"},{"label": "Title2","value": "value2"}} +// 或者 map[interface{}]interface{}{"value1":"Title1","value2":"Title2"} +func (p *Checkbox) SetOptions(options interface{}) *Checkbox { + var data []map[string]interface{} + + if mapOptions, ok := options.(map[interface{}]interface{}); ok { + for k, v := range mapOptions { + option := map[string]interface{}{ + "label": v, + "value": k, + } + + data = append(data, option) + } + } else if sliceOptions, ok := options.([]map[string]interface{}); ok { + data = sliceOptions + } + + p.Options = data + + return p +} + +// 配置 checkbox 的样子,支持垂直vertical 和 horizontal +func (p *Checkbox) SetLayout(layout string) *Checkbox { + p.Layout = layout + + return p +} + +// 组件json序列化 +func (p *Checkbox) JsonSerialize() *Checkbox { + p.Component = "checkboxField" + + return p +} diff --git a/pkg/component/admin/form/fields/date.go b/pkg/component/admin/form/fields/date.go new file mode 100644 index 0000000..d12b988 --- /dev/null +++ b/pkg/component/admin/form/fields/date.go @@ -0,0 +1,62 @@ +package fields + +import "github.com/quarkcms/quark-go/pkg/component/admin/component" + +type Date struct { + Item + Picker string `json:"picker"` + Format string `json:"format"` +} + +// 初始化 +func (p *Date) Init() *Date { + p.Component = "dateField" + p.InitItem().SetKey(component.DEFAULT_KEY, component.DEFAULT_CRYPT) + p.Picker = "date" + p.Format = "YYYY-MM-DD" + + return p +} + +// 设置选择器类型,date | week | month | quarter | year +func (p *Date) SetPicker(picker string) *Date { + + limits := []string{ + "date", "week", "month", "quarter", "year", + } + + inSlice := false + for _, limit := range limits { + if limit == picker { + inSlice = true + } + } + + if inSlice == false { + panic("argument must be in 'date', 'week', 'month', 'quarter', 'year'!") + } + + switch picker { + case "date": + p.SetFormat("YYYY-MM-DD") + case "week": + p.SetFormat("MM-DD") + case "month": + p.SetFormat("YYYY-MM") + case "quarter": + p.SetFormat("YYYY-MM") + case "year": + p.SetFormat("YYYY") + } + + p.Picker = picker + + return p +} + +// 使用 format 属性,可以自定义日期显示格式 +func (p *Date) SetFormat(format string) *Date { + p.Format = format + + return p +} diff --git a/pkg/component/admin/form/fields/date_range.go b/pkg/component/admin/form/fields/date_range.go new file mode 100644 index 0000000..168974f --- /dev/null +++ b/pkg/component/admin/form/fields/date_range.go @@ -0,0 +1,63 @@ +package fields + +import "github.com/quarkcms/quark-go/pkg/component/admin/component" + +type DateRange struct { + Item + Picker string `json:"picker"` + Format string `json:"format"` +} + +// 初始化 +func (p *DateRange) Init() *DateRange { + p.Component = "dateRangeField" + p.InitItem().SetKey(component.DEFAULT_KEY, component.DEFAULT_CRYPT) + p.Picker = "date" + p.Format = "YYYY-MM-DD" + p.DefaultValue = []interface{}{nil, nil} + + return p +} + +// 设置选择器类型,date | week | month | quarter | year +func (p *DateRange) SetPicker(picker string) *DateRange { + + limits := []string{ + "date", "week", "month", "quarter", "year", + } + + inSlice := false + for _, limit := range limits { + if limit == picker { + inSlice = true + } + } + + if inSlice == false { + panic("argument must be in 'date', 'week', 'month', 'quarter', 'year'!") + } + + switch picker { + case "date": + p.SetFormat("YYYY-MM-DD") + case "week": + p.SetFormat("MM-DD") + case "month": + p.SetFormat("YYYY-MM") + case "quarter": + p.SetFormat("YYYY-MM") + case "year": + p.SetFormat("YYYY") + } + + p.Picker = picker + + return p +} + +// 使用 format 属性,可以自定义日期显示格式 +func (p *DateRange) SetFormat(format string) *DateRange { + p.Format = format + + return p +} diff --git a/pkg/component/admin/form/fields/datetime.go b/pkg/component/admin/form/fields/datetime.go new file mode 100644 index 0000000..709a716 --- /dev/null +++ b/pkg/component/admin/form/fields/datetime.go @@ -0,0 +1,15 @@ +package fields + +import "github.com/quarkcms/quark-go/pkg/component/admin/component" + +type Datetime struct { + Item +} + +// 初始化 +func (p *Datetime) Init() *Datetime { + p.Component = "datetimeField" + p.InitItem().SetKey(component.DEFAULT_KEY, component.DEFAULT_CRYPT) + + return p +} diff --git a/pkg/component/admin/form/fields/datetime_range.go b/pkg/component/admin/form/fields/datetime_range.go new file mode 100644 index 0000000..bfa19db --- /dev/null +++ b/pkg/component/admin/form/fields/datetime_range.go @@ -0,0 +1,16 @@ +package fields + +import "github.com/quarkcms/quark-go/pkg/component/admin/component" + +type DatetimeRange struct { + Item +} + +// 初始化 +func (p *DatetimeRange) Init() *DatetimeRange { + p.Component = "datetimeRangeField" + p.InitItem().SetKey(component.DEFAULT_KEY, component.DEFAULT_CRYPT) + p.DefaultValue = []interface{}{nil, nil} + + return p +} diff --git a/pkg/component/admin/form/fields/display.go b/pkg/component/admin/form/fields/display.go new file mode 100644 index 0000000..591ba7c --- /dev/null +++ b/pkg/component/admin/form/fields/display.go @@ -0,0 +1,15 @@ +package fields + +import "github.com/quarkcms/quark-go/pkg/component/admin/component" + +type Display struct { + Item +} + +// 初始化 +func (p *Display) Init() *Display { + p.Component = "displayField" + p.InitItem().SetKey(component.DEFAULT_KEY, component.DEFAULT_CRYPT) + + return p +} diff --git a/pkg/component/admin/form/fields/editor.go b/pkg/component/admin/form/fields/editor.go new file mode 100644 index 0000000..9be0acd --- /dev/null +++ b/pkg/component/admin/form/fields/editor.go @@ -0,0 +1,33 @@ +package fields + +import "github.com/quarkcms/quark-go/pkg/component/admin/component" + +type Editor struct { + Item +} + +// 初始化 +func (p *Editor) Init() *Editor { + p.Component = "editorField" + p.InitItem().SetKey(component.DEFAULT_KEY, component.DEFAULT_CRYPT) + p.Style = map[string]interface{}{ + "height": 500, + "width": "100%", + } + + return p +} + +// 高度 +func (p *Editor) SetHeight(height interface{}) *Editor { + style := make(map[string]interface{}) + + for k, v := range p.Style { + style[k] = v + } + + style["height"] = height + p.Style = style + + return p +} diff --git a/pkg/component/admin/form/fields/file.go b/pkg/component/admin/form/fields/file.go new file mode 100644 index 0000000..79d85f0 --- /dev/null +++ b/pkg/component/admin/form/fields/file.go @@ -0,0 +1,55 @@ +package fields + +import "github.com/quarkcms/quark-go/pkg/component/admin/component" + +type File struct { + Item +} + +// 初始化 +func (p *File) Init() *File { + p.Component = "fileField" + p.InitItem().SetKey(component.DEFAULT_KEY, component.DEFAULT_CRYPT) + p.Button = "上传文件" + p.LimitSize = 2 + p.LimitNum = 3 + p.LimitType = []string{ + "jpeg", + "png", + "doc", + "docx", + } + p.Api = "/api/admin/file/upload" + + return p +} + +// 上传文件大小限制 +func (p *File) SetLimitSize(limitSize int) *File { + p.LimitSize = limitSize + return p +} + +// 上传文件类型限制 +func (p *File) SetLimitType(limitType []string) *File { + p.LimitType = limitType + return p +} + +// 上传文件数量限制 +func (p *File) SetLimitNum(limitNum int) *File { + p.LimitNum = limitNum + return p +} + +// 上传的api接口 +func (p *File) SetApi(api string) *File { + p.Api = api + return p +} + +// 上传按钮的标题 +func (p *File) SetButton(text string) *File { + p.Button = text + return p +} diff --git a/pkg/component/admin/form/fields/geofence.go b/pkg/component/admin/form/fields/geofence.go new file mode 100644 index 0000000..02ec196 --- /dev/null +++ b/pkg/component/admin/form/fields/geofence.go @@ -0,0 +1,90 @@ +package fields + +import "github.com/quarkcms/quark-go/pkg/component/admin/component" + +type Geofence struct { + Item + Zoom int `json:"zoom"` + MapKey string `json:"mapKey"` + ButtonPosition string `json:"buttonPosition"` + AlwaysShowItemLabel bool `json:"alwaysShowItemLabel"` +} + +// 初始化 +func (p *Geofence) Init() *Geofence { + p.Component = "geofenceField" + p.InitItem().SetKey(component.DEFAULT_KEY, component.DEFAULT_CRYPT) + p.Value = map[string]interface{}{ + "center": map[string]interface{}{ + "longitude": "116.397724", + "latitude": "39.903755", + }, + "points": []interface{}{}, + } + p.Zoom = 14 + p.MapKey = "788e08def03f95c670944fe2c78fa76f" + p.Style = map[string]interface{}{ + "height": 500, + "width": "100%", + "marginTop": "10px", + } + + return p +} + +// zoom +func (p *Geofence) SetZoom(zoom int) *Geofence { + p.Zoom = zoom + return p +} + +// 高德地图key +func (p *Geofence) SetMapKey(key string) *Geofence { + p.MapKey = key + return p +} + +// 地图宽度 +func (p *Geofence) SetWidth(width interface{}) *Geofence { + style := make(map[string]interface{}) + + for k, v := range p.Style { + style[k] = v + } + + style["width"] = width + p.Style = style + + return p +} + +// 地图高度 +func (p *Geofence) SetHeight(height interface{}) *Geofence { + style := make(map[string]interface{}) + + for k, v := range p.Style { + style[k] = v + } + + style["height"] = height + p.Style = style + + return p +} + +// 中心点 +func (p *Geofence) SetCenter(longitude string, latitude string) *Geofence { + p.Value.(map[string]interface{})["center"] = map[string]interface{}{ + "longitude": longitude, + "latitude": latitude, + } + + return p +} + +// 多边形围栏坐标点 +func (p *Geofence) SetPoints(points []interface{}) *Geofence { + p.Value.(map[string]interface{})["points"] = points + + return p +} diff --git a/pkg/component/admin/form/fields/group.go b/pkg/component/admin/form/fields/group.go new file mode 100644 index 0000000..8401af2 --- /dev/null +++ b/pkg/component/admin/form/fields/group.go @@ -0,0 +1,33 @@ +package fields + +import "github.com/quarkcms/quark-go/pkg/component/admin/component" + +type Group struct { + Item + Body interface{} `json:"body"` + Size int `json:"size"` +} + +// 初始化 +func (p *Group) Init() *Group { + p.Component = "groupField" + p.InitItem().SetKey(component.DEFAULT_KEY, component.DEFAULT_CRYPT) + p.Size = 32 + p.OnlyOnForms() + + return p +} + +// 组件内容 +func (p *Group) SetBody(body interface{}) *Group { + p.Body = body + + return p +} + +// 子元素个数 +func (p *Group) SetSize(size int) *Group { + p.Size = size + + return p +} diff --git a/pkg/component/admin/form/fields/hidden.go b/pkg/component/admin/form/fields/hidden.go new file mode 100644 index 0000000..bf57a67 --- /dev/null +++ b/pkg/component/admin/form/fields/hidden.go @@ -0,0 +1,15 @@ +package fields + +import "github.com/quarkcms/quark-go/pkg/component/admin/component" + +type Hidden struct { + Item +} + +// 初始化 +func (p *Hidden) Init() *Hidden { + p.Component = "hiddenField" + p.InitItem().SetKey(component.DEFAULT_KEY, component.DEFAULT_CRYPT) + + return p +} diff --git a/pkg/component/admin/form/fields/icon.go b/pkg/component/admin/form/fields/icon.go new file mode 100644 index 0000000..38c9891 --- /dev/null +++ b/pkg/component/admin/form/fields/icon.go @@ -0,0 +1,99 @@ +package fields + +import "github.com/quarkcms/quark-go/pkg/component/admin/component" + +type Icon struct { + Item + Size string `json:"size"` + AllowClear bool `json:"allowClear"` +} + +// 初始化 +func (p *Icon) Init() *Icon { + p.Component = "iconField" + p.InitItem().SetKey(component.DEFAULT_KEY, component.DEFAULT_CRYPT) + p.Options = []string{ + "icon-database", "icon-sever", "icon-mobile", "icon-tablet", "icon-redenvelope", + "icon-book", "icon-filedone", "icon-reconciliation", "icon-file-exception", + "icon-filesync", "icon-filesearch", "icon-solution", "icon-fileprotect", + "icon-file-add", "icon-file-excel", "icon-file-exclamation", "icon-file-pdf", + "icon-file-image", "icon-file-markdown", "icon-file-unknown", "icon-file-ppt", + "icon-file-word", "icon-file", "icon-file-zip", "icon-file-text", "icon-file-copy", + "icon-snippets", "icon-audit", "icon-diff", "icon-Batchfolding", "icon-securityscan", + "icon-propertysafety", "icon-insurance", "icon-alert", "icon-delete", "icon-hourglass", + "icon-bulb", "icon-experiment", "icon-bell", "icon-trophy", "icon-rest", "icon-USB", + "icon-skin", "icon-home", "icon-bank", "icon-filter", "icon-funnelplot", "icon-like", + "icon-unlike", "icon-unlock", "icon-lock", "icon-customerservice", "icon-flag", + "icon-moneycollect", "icon-medicinebox", "icon-shop", "icon-rocket", "icon-shopping", + "icon-folder", "icon-folder-open", "icon-folder-add", "icon-deploymentunit", + "icon-accountbook", "icon-contacts", "icon-carryout", "icon-calendar-check", + "icon-calendar", "icon-scan", "icon-select", "icon-boxplot", "icon-build", "icon-sliders", + "icon-laptop", "icon-barcode", "icon-camera", "icon-cluster", "icon-gateway", "icon-car", + "icon-printer", "icon-read", "icon-cloud-server", "icon-cloud-upload", "icon-cloud", + "icon-cloud-download", "icon-cloud-sync", "icon-video", "icon-notification", "icon-sound", + "icon-radarchart", "icon-qrcode", "icon-fund", "icon-image", "icon-mail", "icon-table", + "icon-idcard", "icon-creditcard", "icon-heart", "icon-block", "icon-error", "icon-star", + "icon-gold", "icon-heatmap", "icon-wifi", "icon-attachment", "icon-edit", "icon-key", + "icon-api", "icon-disconnect", "icon-highlight", "icon-monitor", "icon-link", "icon-man", + "icon-percentage", "icon-pushpin", "icon-phone", "icon-shake", "icon-tag", "icon-wrench", + "icon-tags", "icon-scissor", "icon-mr", "icon-share", "icon-branches", "icon-fork", "icon-shrink", + "icon-arrawsalt", "icon-verticalright", "icon-verticalleft", "icon-right", "icon-left", + "icon-up", "icon-down", "icon-fullscreen", "icon-fullscreen-exit", "icon-doubleleft", + "icon-doubleright", "icon-arrowright", "icon-arrowup", "icon-arrowleft", "icon-arrowdown", + "icon-upload", "icon-colum-height", "icon-vertical-align-botto", "icon-vertical-align-middl", + "icon-totop", "icon-vertical-align-top", "icon-download", "icon-sort-descending", + "icon-sort-ascending", "icon-fall", "icon-swap", "icon-stock", "icon-rise", "icon-indent", + "icon-outdent", "icon-menu", "icon-unorderedlist", "icon-orderedlist", "icon-align-right", + "icon-align-center", "icon-align-left", "icon-pic-center", "icon-pic-right", "icon-pic-left", + "icon-bold", "icon-font-colors", "icon-exclaimination", "icon-font-size", "icon-check-circle", + "icon-infomation", "icon-CI", "icon-line-height", "icon-Dollar", "icon-strikethrough", "icon-compass", + "icon-underline", "icon-close-circle", "icon-number", "icon-frown", "icon-italic", "icon-info-circle", + "icon-code", "icon-left-circle", "icon-column-width", "icon-down-circle", "icon-check", "icon-EURO", + "icon-ellipsis", "icon-copyright", "icon-dash", "icon-minus-circle", "icon-close", "icon-meh", + "icon-enter", "icon-plus-circle", "icon-line", "icon-play-circle", "icon-minus", "icon-question-circle", + "icon-question", "icon-Pound", "icon-rollback", "icon-right-circle", "icon-small-dash", "icon-smile", + "icon-pause", "icon-trademark", "icon-bg-colors", "icon-time-circle", "icon-crown", "icon-timeout", + "icon-drag", "icon-earth", "icon-desktop", "icon-YUAN", "icon-gift", "icon-up-circle", "icon-stop", + "icon-warning-circle", "icon-fire", "icon-sync", "icon-thunderbolt", "icon-transaction", + "icon-alipay", "icon-undo", "icon-taobao", "icon-redo", "icon-wechat-fill", "icon-reload", + "icon-comment", "icon-reloadtime", "icon-login", "icon-message", "icon-clear", "icon-dashboard", + "icon-issuesclose", "icon-poweroff", "icon-logout", "icon-piechart", "icon-setting", + "icon-eye", "icon-location", "icon-edit-square", "icon-export", "icon-save", "icon-Import", + "icon-appstore", "icon-close-square", "icon-down-square", "icon-layout", "icon-left-square", + "icon-play-square", "icon-control", "icon-codelibrary", "icon-detail", "icon-minus-square", + "icon-plus-square", "icon-right-square", "icon-project", "icon-wallet", "icon-up-square", + "icon-calculator", "icon-interation", "icon-check-square", "icon-border", "icon-border-outer", + "icon-border-top", "icon-border-bottom", "icon-border-left", "icon-border-right", "icon-border-inner", + "icon-border-verticle", "icon-border-horizontal", "icon-radius-bottomleft", "icon-radius-bottomright", + "icon-radius-upleft", "icon-radius-upright", "icon-radius-setting", "icon-adduser", "icon-deleteteam", + "icon-deleteuser", "icon-addteam", "icon-user", "icon-team", "icon-areachart", "icon-linechart", + "icon-barchart", "icon-pointmap", "icon-container", "icon-atom", "icon-zanwutupian", "icon-safetycertificate", + "icon-password", "icon-article", "icon-page", "icon-plugin", "icon-admin", "icon-banner", + } + + p.SetWidth(200) + p.SetDefault("") + + return p +} + +// 设置单选属性 +func (p *Icon) SetOptions(options []string) *Icon { + p.Options = options + + return p +} + +// 控件大小。注:标准表单内的输入框大小限制为 large。可选 large default small +func (p *Icon) SetSize(size string) *Icon { + p.Size = size + + return p +} + +// 可以点击清除图标删除内容 +func (p *Icon) SetAllowClear(allowClear bool) *Icon { + p.AllowClear = allowClear + + return p +} diff --git a/pkg/component/admin/form/fields/id.go b/pkg/component/admin/form/fields/id.go new file mode 100644 index 0000000..c3aa2f2 --- /dev/null +++ b/pkg/component/admin/form/fields/id.go @@ -0,0 +1,45 @@ +package fields + +import "github.com/quarkcms/quark-go/pkg/component/admin/component" + +type ID struct { + Item + OnIndexDisplayed bool `json:"onIndexDisplayed"` + OnDetailDisplayed bool `json:"onDetailDisplayed"` + OnFormDisplayed bool `json:"onFormDisplayed"` + OnExportDisplayed bool `json:"onExportDisplayed"` +} + +// 初始化 +func (p *ID) Init() *ID { + p.Component = "idField" + p.InitItem().SetKey(component.DEFAULT_KEY, component.DEFAULT_CRYPT) + p.OnIndexDisplayed = true + p.ShowOnImport = false + + return p +} + +// 在列表页是否显示字段 +func (p *ID) SetOnIndexDisplayed(displayed bool) *ID { + p.OnIndexDisplayed = displayed + return p +} + +// 在详情页是否显示字段 +func (p *ID) SetOnDetailDisplayed(displayed bool) *ID { + p.OnDetailDisplayed = displayed + return p +} + +// 在表单页是否显示控件 +func (p *ID) SetOnFormDisplayed(displayed bool) *ID { + p.OnFormDisplayed = displayed + return p +} + +// 在导出页是否显示字段 +func (p *ID) SetOnExportDisplayed(displayed bool) *ID { + p.OnExportDisplayed = displayed + return p +} diff --git a/pkg/component/admin/form/fields/image.go b/pkg/component/admin/form/fields/image.go new file mode 100644 index 0000000..7d14740 --- /dev/null +++ b/pkg/component/admin/form/fields/image.go @@ -0,0 +1,97 @@ +package fields + +import "github.com/quarkcms/quark-go/pkg/component/admin/component" + +type Image struct { + Item +} + +// 初始化 +func (p *Image) Init() *Image { + p.Component = "imageField" + p.InitItem().SetKey(component.DEFAULT_KEY, component.DEFAULT_CRYPT) + p.Mode = "single" + p.Button = "上传图片" + p.LimitSize = 2 + p.LimitNum = 3 + p.LimitType = []string{ + "image/jpeg", + "image/png", + } + p.Api = "/api/admin/picture/upload" + p.LimitWH = map[string]int{ + "width": 0, + "height": 0, + } + + return p +} + +// 上传模式,单图或多图,single|multiple +func (p *Image) SetMode(mode string) *Image { + if mode == "s" { + mode = "single" + } + + if mode == "m" { + mode = "multiple" + } + + limits := []string{ + "single", "multiple", + } + + inSlice := false + for _, limit := range limits { + if limit == mode { + inSlice = true + } + } + + if inSlice == false { + panic("argument must be in 'single', 'multiple'!") + } + + p.Mode = mode + return p +} + +// 上传文件大小限制 +func (p *Image) SetLimitSize(limitSize int) *Image { + p.LimitSize = limitSize + return p +} + +// 上传文件类型限制 +func (p *Image) SetLimitType(limitType []string) *Image { + p.LimitType = limitType + return p +} + +// 上传文件数量限制 +func (p *Image) SetLimitNum(limitNum int) *Image { + p.LimitNum = limitNum + return p +} + +// 上传图片限制尺寸 +func (p *Image) SetLimitWH(width int, height int) *Image { + p.LimitWH = map[string]int{ + "width": width, + "height": height, + } + + return p +} + +// 上传的api接口 +func (p *Image) SetApi(api string) *Image { + p.Api = api + return p +} + +// 上传按钮的标题 +func (p *Image) SetButton(text string) *Image { + p.Button = text + return p +} diff --git a/pkg/component/admin/form/fields/item.go b/pkg/component/admin/form/fields/item.go new file mode 100644 index 0000000..8fc6b08 --- /dev/null +++ b/pkg/component/admin/form/fields/item.go @@ -0,0 +1,688 @@ +package fields + +import ( + "crypto/md5" + "encoding/hex" + "encoding/json" + "strconv" + "strings" + + "github.com/go-basic/uuid" + "github.com/quarkcms/quark-go/pkg/component/admin/table" +) + +type Item struct { + Key string `json:"-"` + ComponentKey string `json:"componentKey"` + Component string `json:"component"` + Style map[string]interface{} `json:"style"` + Tooltip string `json:"tooltip"` + Colon bool `json:"colon"` + Value interface{} `json:"value"` + DefaultValue interface{} `json:"defaultValue"` + Extra string `json:"extra"` + HasFeedback bool `json:"hasFeedback"` + Help string `json:"help"` + NoStyle bool `json:"noStyle"` + Label string `json:"label"` + LabelAlign string `json:"labelAlign"` + LabelCol interface{} `json:"labelCol"` + Name string `json:"name"` + Required bool `json:"required"` + Disabled bool `json:"disabled"` + Ignore bool `json:"ignore"` + Rules []string `json:"-"` + RuleMessages map[string]string `json:"-"` + CreationRules []string `json:"-"` + CreationRuleMessages map[string]string `json:"-"` + UpdateRules []string `json:"-"` + UpdateRuleMessages map[string]string `json:"-"` + FrontendRules interface{} `json:"frontendRules"` + ValuePropName string `json:"valuePropName"` + WrapperCol interface{} `json:"wrapperCol"` + When interface{} `json:"when"` + WhenItem []interface{} `json:"-"` + ShowOnIndex bool `json:"-"` + ShowOnDetail bool `json:"-"` + ShowOnCreation bool `json:"-"` + ShowOnUpdate bool `json:"-"` + ShowOnExport bool `json:"-"` + ShowOnImport bool `json:"-"` + Editable bool `json:"-"` + Options interface{} `json:"options"` + Column *table.Column `json:"-"` + Callback interface{} `json:"-"` + Placeholder string `json:"placeholder"` + TreeData interface{} `json:"treeData"` + Mode string `json:"mode"` + Size string `json:"size"` + AllowClear bool `json:"allowClear"` + Load map[string]string `json:"load"` + Button string `json:"button"` + LimitSize int `json:"limitSize"` + LimitType []string `json:"limitType"` + LimitNum int `json:"limitNum"` + LimitWH map[string]int `json:"limitWH"` + Api string `json:"api"` + AutoSize interface{} `json:"autoSize"` +} + +const DEFAULT_KEY = "" +const DEFAULT_CRYPT = true + +// 初始化 +func (p *Item) InitItem() *Item { + p.Colon = true + p.LabelAlign = "right" + p.ShowOnIndex = true + p.ShowOnDetail = true + p.ShowOnCreation = true + p.ShowOnUpdate = true + p.ShowOnExport = true + p.ShowOnImport = true + p.Column = (&table.Column{}).Init() + + return p +} + +// 设置Key +func (p *Item) SetKey(key string, crypt bool) *Item { + + if key == "" { + key = uuid.New() + } + + if crypt { + h := md5.New() + h.Write([]byte(key)) + key = hex.EncodeToString(h.Sum(nil)) + } + + p.Key = key + p.ComponentKey = key + + return p +} + +// Set style. +func (p *Item) SetStyle(style map[string]interface{}) *Item { + p.Style = style + + return p +} + +// 会在 label 旁增加一个 icon,悬浮后展示配置的信息 +func (p *Item) SetTooltip(tooltip string) *Item { + p.Tooltip = tooltip + + return p +} + +// Field 的长度,我们归纳了常用的 Field 长度以及适合的场景,支持了一些枚举 "xs" , "s" , "m" , "l" , "x" +func (p *Item) SetWidth(width interface{}) *Item { + style := make(map[string]interface{}) + + for k, v := range p.Style { + style[k] = v + } + + style["width"] = width + p.Style = style + + return p +} + +// 配合 label 属性使用,表示是否显示 label 后面的冒号 +func (p *Item) SetColon(colon bool) *Item { + p.Colon = colon + return p +} + +// 额外的提示信息,和 help 类似,当需要错误信息和提示文案同时出现时,可以使用这个。 +func (p *Item) SetExtra(extra string) *Item { + p.Extra = extra + return p +} + +// 配合 validateStatus 属性使用,展示校验状态图标,建议只配合 Input 组件使用 +func (p *Item) SetHasFeedback(hasFeedback bool) *Item { + p.HasFeedback = hasFeedback + return p +} + +// 配合 help 属性使用,展示校验状态图标,建议只配合 Input 组件使用 +func (p *Item) SetHelp(help string) *Item { + p.Help = help + return p +} + +// 为 true 时不带样式,作为纯字段控件使用 +func (p *Item) SetNoStyle() *Item { + p.NoStyle = true + return p +} + +// label 标签的文本 +func (p *Item) SetLabel(label string) *Item { + p.Label = label + + return p +} + +// 标签文本对齐方式 +func (p *Item) SetLabelAlign(align string) *Item { + p.LabelAlign = align + return p +} + +// label 标签布局,同 组件,设置 span offset 值,如 {span: 3, offset: 12} 或 sm: {span: 3, offset: 12}。 +// 你可以通过 Form 的 labelCol 进行统一设置。当和 Form 同时设置时,以 Item 为准 +func (p *Item) SetLabelCol(col interface{}) *Item { + p.LabelCol = col + return p +} + +// 字段名,支持数组 +func (p *Item) SetName(name string) *Item { + p.Name = name + return p +} + +// 是否必填,如不设置,则会根据校验规则自动生成 +func (p *Item) SetRequired() *Item { + p.Required = true + return p +} + +// 解析成前端验证规则 +func (p *Item) parseFrontendRules(rules []string, messages map[string]string) []map[string]interface{} { + result := []map[string]interface{}{} + values := []string{} + rule := "" + + for _, v := range rules { + if strings.Contains(v, ":") { + values = strings.Split(v, ":") + rule = values[0] + } else { + rule = v + } + + data := map[string]interface{}{} + + switch rule { + case "required": + data = map[string]interface{}{ + "required": true, + "message": messages["required"], + } + case "min": + min, _ := strconv.Atoi(values[1]) + + data = map[string]interface{}{ + "min": min, + "message": messages["min"], + } + case "max": + max, _ := strconv.Atoi(values[1]) + + data = map[string]interface{}{ + "max": max, + "message": messages["max"], + } + + case "email": + data = map[string]interface{}{ + "type": "email", + "message": messages["email"], + } + + case "numeric": + data = map[string]interface{}{ + "type": "number", + "message": messages["numeric"], + } + + case "url": + data = map[string]interface{}{ + "type": "url", + "message": messages["url"], + } + + case "integer": + data = map[string]interface{}{ + "type": "integer", + "message": messages["integer"], + } + + case "date": + data = map[string]interface{}{ + "type": "date", + "message": messages["date"], + } + case "boolean": + data = map[string]interface{}{ + "type": "boolean", + "message": messages["boolean"], + } + } + + if len(data) > 0 { + result = append(result, data) + } + } + + return result +} + +// 自动创建前端验证规则 +func (p *Item) BuildFrontendRules(path string) interface{} { + frontendRules := []map[string]interface{}{} + + var ( + rules []map[string]interface{} + creationRules []map[string]interface{} + updateRules []map[string]interface{} + ) + + uri := strings.Split(path, "/") + isCreating := (uri[len(uri)-1] == "create") || (uri[len(uri)-1] == "store") + isEditing := (uri[len(uri)-1] == "edit") || (uri[len(uri)-1] == "update") + + if len(p.Rules) > 0 { + rules = p.parseFrontendRules(p.Rules, p.RuleMessages) + } + if isCreating && len(p.CreationRules) > 0 { + creationRules = p.parseFrontendRules(p.CreationRules, p.CreationRuleMessages) + } + if isEditing && len(p.UpdateRules) > 0 { + updateRules = p.parseFrontendRules(p.UpdateRules, p.UpdateRuleMessages) + } + if len(rules) > 0 { + frontendRules = append(frontendRules, rules...) + } + if len(creationRules) > 0 { + frontendRules = append(frontendRules, creationRules...) + } + if len(updateRules) > 0 { + frontendRules = append(frontendRules, updateRules...) + } + p.FrontendRules = frontendRules + + return p +} + +// 校验规则,设置字段的校验逻辑 +func (p *Item) SetRules(rules []string, messages map[string]string) *Item { + p.Rules = rules + p.RuleMessages = messages + + return p +} + +// 校验规则,只在创建表单提交时生效 +func (p *Item) SetCreationRules(rules []string, messages map[string]string) *Item { + p.CreationRules = rules + p.CreationRuleMessages = messages + + return p +} + +// 校验规则,只在更新表单提交时生效 +func (p *Item) SetUpdateRules(rules []string, messages map[string]string) *Item { + p.UpdateRules = rules + p.UpdateRuleMessages = messages + + return p +} + +// 子节点的值的属性,如 Switch 的是 "checked" +func (p *Item) SetValuePropName(valuePropName string) *Item { + p.ValuePropName = valuePropName + return p +} + +// 需要为输入控件设置布局样式时,使用该属性,用法同 labelCol。 +// 你可以通过 Form 的 wrapperCol 进行统一设置。当和 Form 同时设置时,以 Item 为准。 +func (p *Item) SetWrapperCol(col interface{}) *Item { + p.WrapperCol = col + return p +} + +// 设置保存值。 +func (p *Item) SetValue(value interface{}) *Item { + p.Value = value + return p +} + +// 设置默认值。 +func (p *Item) SetDefault(value interface{}) *Item { + p.DefaultValue = value + return p +} + +// 是否禁用状态,默认为 false +func (p *Item) SetDisabled(disabled bool) *Item { + p.Disabled = disabled + return p +} + +// 是否忽略保存到数据库,默认为 false +func (p *Item) SetIgnore(ignore bool) *Item { + p.Ignore = ignore + return p +} + +// 表单联动 +func (p *Item) SetWhen(value ...any) *Item { + whenItem := map[string]any{} + when := map[string]any{} + var operator string + var option any + + if len(value) == 2 { + operator = "=" + option = value[0] + callback := value[1].(func() interface{}) + + whenItem["body"] = callback() + } + + if len(value) == 3 { + operator = value[0].(string) + option = value[1] + callback := value[2].(func() interface{}) + + whenItem["body"] = callback() + } + + switch operator { + case "=": + whenItem["condition"] = "<%=String(" + p.Name + ") === '" + option.(string) + "' %>" + break + case ">": + whenItem["condition"] = "<%=String(" + p.Name + ") > '" + option.(string) + "' %>" + break + case "<": + whenItem["condition"] = "<%=String(" + p.Name + ") < '" + option.(string) + "' %>" + break + case "<=": + whenItem["condition"] = "<%=String(" + p.Name + ") <= '" + option.(string) + "' %>" + break + case ">=": + whenItem["condition"] = "<%=String(" + p.Name + ") => '" + option.(string) + "' %>" + break + case "has": + whenItem["condition"] = "<%=(String(" + p.Name + ").indexOf('" + option.(string) + "') !=-1) %>" + break + case "in": + jsonStr, _ := json.Marshal(option) + whenItem["condition"] = "<%=(" + string(jsonStr) + ".indexOf(" + p.Name + ") !=-1) %>" + break + default: + whenItem["condition"] = "<%=String(" + p.Name + ") === '" + option.(string) + "' %>" + break + } + + whenItem["condition_name"] = p.Name + whenItem["condition_operator"] = operator + whenItem["condition_option"] = option + p.WhenItem = append(p.WhenItem, whenItem) + + when["component"] = "when" + when["items"] = whenItem + p.When = when + + return p +} + +// Specify that the element should be hidden from the index view. +func (p *Item) HideFromIndex(callback bool) *Item { + p.ShowOnIndex = !callback + + return p +} + +// Specify that the element should be hidden from the detail view. +func (p *Item) HideFromDetail(callback bool) *Item { + p.ShowOnDetail = !callback + + return p +} + +// Specify that the element should be hidden from the creation view. +func (p *Item) HideWhenCreating(callback bool) *Item { + p.ShowOnCreation = !callback + + return p +} + +// Specify that the element should be hidden from the update view. +func (p *Item) HideWhenUpdating(callback bool) *Item { + p.ShowOnUpdate = !callback + + return p +} + +// Specify that the element should be hidden from the export file. +func (p *Item) HideWhenExporting(callback bool) *Item { + p.ShowOnExport = !callback + + return p +} + +// Specify that the element should be hidden from the import file. +func (p *Item) HideWhenImporting(callback bool) *Item { + p.ShowOnImport = !callback + + return p +} + +// Specify that the element should be hidden from the index view. +func (p *Item) OnIndexShowing(callback bool) *Item { + p.ShowOnIndex = callback + + return p +} + +// Specify that the element should be hidden from the detail view. +func (p *Item) OnDetailShowing(callback bool) *Item { + p.ShowOnDetail = callback + + return p +} + +// Specify that the element should be hidden from the creation view. +func (p *Item) ShowOnCreating(callback bool) *Item { + p.ShowOnCreation = callback + + return p +} + +// Specify that the element should be hidden from the update view. +func (p *Item) ShowOnUpdating(callback bool) *Item { + p.ShowOnUpdate = callback + + return p +} + +// Specify that the element should be hidden from the export file. +func (p *Item) ShowOnExporting(callback bool) *Item { + p.ShowOnExport = callback + + return p +} + +// Specify that the element should be hidden from the import file. +func (p *Item) ShowOnImporting(callback bool) *Item { + p.ShowOnImport = callback + + return p +} + +// Specify that the element should only be shown on the index view. +func (p *Item) OnlyOnIndex() *Item { + p.ShowOnIndex = true + p.ShowOnDetail = false + p.ShowOnCreation = false + p.ShowOnUpdate = false + p.ShowOnExport = false + p.ShowOnImport = false + + return p +} + +// Specify that the element should only be shown on the detail view. +func (p *Item) OnlyOnDetail() *Item { + p.ShowOnIndex = false + p.ShowOnDetail = true + p.ShowOnCreation = false + p.ShowOnUpdate = false + p.ShowOnExport = false + p.ShowOnImport = false + + return p +} + +// Specify that the element should only be shown on forms. +func (p *Item) OnlyOnForms() *Item { + p.ShowOnIndex = false + p.ShowOnDetail = false + p.ShowOnCreation = true + p.ShowOnUpdate = true + p.ShowOnExport = false + p.ShowOnImport = false + + return p +} + +// Specify that the element should only be shown on export file. +func (p *Item) OnlyOnExport() *Item { + p.ShowOnIndex = false + p.ShowOnDetail = false + p.ShowOnCreation = false + p.ShowOnUpdate = false + p.ShowOnExport = true + p.ShowOnImport = false + + return p +} + +// Specify that the element should only be shown on import file. +func (p *Item) OnlyOnImport() *Item { + p.ShowOnIndex = false + p.ShowOnDetail = false + p.ShowOnCreation = false + p.ShowOnUpdate = false + p.ShowOnExport = false + p.ShowOnImport = true + + return p +} + +// Specify that the element should be hidden from forms. +func (p *Item) ExceptOnForms() *Item { + p.ShowOnIndex = true + p.ShowOnDetail = true + p.ShowOnCreation = false + p.ShowOnUpdate = false + p.ShowOnExport = true + p.ShowOnImport = true + + return p +} + +// Check for showing when updating. +func (p *Item) IsShownOnUpdate() bool { + return p.ShowOnUpdate +} + +// Check showing on index. +func (p *Item) IsShownOnIndex() bool { + return p.ShowOnIndex +} + +// Check showing on detail. +func (p *Item) IsShownOnDetail() bool { + return p.ShowOnDetail +} + +// Check for showing when creating. +func (p *Item) IsShownOnCreation() bool { + return p.ShowOnCreation +} + +// Check for showing when exporting. +func (p *Item) IsShownOnExport() bool { + return p.ShowOnExport +} + +// Check for showing when importing. +func (p *Item) IsShownOnImport() bool { + return p.ShowOnImport +} + +// 设置为可编辑列 +func (p *Item) SetEditable(editable bool) *Item { + p.Editable = editable + + return p +} + +// 闭包,透传表格列的属性 +func (p *Item) SetColumn(f func(column *table.Column) *table.Column) *Item { + p.Column = f(p.Column) + + return p +} + +// 当前列值的枚举 valueEnum +func (p *Item) GetValueEnum() map[interface{}]interface{} { + data := map[interface{}]interface{}{} + + if options, ok := p.Options.([]map[string]interface{}); ok { + for _, v := range options { + + data[v["value"]] = v["label"] + } + } + + return data +} + +// Switch组件值的枚举 valueEnum +func (p *Item) GetSwitchValueEnum() map[interface{}]interface{} { + data := map[interface{}]interface{}{} + for k, v := range p.Options.(map[string]interface{}) { + var key int + if k == "on" { + key = 1 + } else { + key = 0 + } + data[key] = v + } + + return data +} + +// 设置回调函数 +func (p *Item) SetCallback(closure func() interface{}) *Item { + if closure != nil { + p.Callback = closure + } + + return p +} + +// 获取回调函数 +func (p *Item) GetCallback() interface{} { + return p.Callback +} + +// 控件占位符 +func (p *Item) SetPlaceholder(placeholder string) *Item { + p.Placeholder = placeholder + + return p +} diff --git a/pkg/component/admin/form/fields/list.go b/pkg/component/admin/form/fields/list.go new file mode 100644 index 0000000..68abcdf --- /dev/null +++ b/pkg/component/admin/form/fields/list.go @@ -0,0 +1,46 @@ +package fields + +import "github.com/quarkcms/quark-go/pkg/component/admin/component" + +type List struct { + Item + Items interface{} `json:"items"` + ButtonText string `json:"buttonText"` + ButtonPosition string `json:"buttonPosition"` + AlwaysShowItemLabel bool `json:"alwaysShowItemLabel"` +} + +// 初始化 +func (p *List) Init() *List { + p.Component = "listField" + p.InitItem().SetKey(component.DEFAULT_KEY, component.DEFAULT_CRYPT) + p.ButtonText = "添加一行数据" + p.ButtonPosition = "top" + p.AlwaysShowItemLabel = true + + return p +} + +// 按钮名称 +func (p *List) SetButton(text string, position string) *List { + p.ButtonText = text + p.ButtonPosition = position + + return p +} + +// 表单项 +func (p *List) SetItem(callback interface{}) *List { + getCallback := callback.(func() interface{}) + + p.Items = getCallback() + + return p +} + +// Item 中总是展示 label +func (p *List) SetAlwaysShowItemLabel(alwaysShowItemLabel bool) *List { + p.AlwaysShowItemLabel = alwaysShowItemLabel + + return p +} diff --git a/pkg/component/admin/form/fields/map.go b/pkg/component/admin/form/fields/map.go new file mode 100644 index 0000000..9943103 --- /dev/null +++ b/pkg/component/admin/form/fields/map.go @@ -0,0 +1,79 @@ +package fields + +import "github.com/quarkcms/quark-go/pkg/component/admin/component" + +type Map struct { + Item + Zoom int `json:"zoom"` + MapKey string `json:"mapKey"` + ButtonPosition string `json:"buttonPosition"` + AlwaysShowItemLabel bool `json:"alwaysShowItemLabel"` +} + +// 初始化 +func (p *Map) Init() *Map { + p.Component = "mapField" + p.InitItem().SetKey(component.DEFAULT_KEY, component.DEFAULT_CRYPT) + p.Value = map[string]string{ + "longitude": "116.397724", + "latitude": "39.903755", + } + p.Zoom = 14 + p.MapKey = "788e08def03f95c670944fe2c78fa76f" + p.Style = map[string]interface{}{ + "height": 500, + "width": "100%", + "marginTop": "10px", + } + + return p +} + +// zoom +func (p *Map) SetZoom(zoom int) *Map { + p.Zoom = zoom + return p +} + +// 高德地图key +func (p *Map) SetMapKey(key string) *Map { + p.MapKey = key + return p +} + +// 地图宽度 +func (p *Map) SetWidth(width interface{}) *Map { + style := make(map[string]interface{}) + + for k, v := range p.Style { + style[k] = v + } + + style["width"] = width + p.Style = style + + return p +} + +// 地图高度 +func (p *Map) SetHeight(height interface{}) *Map { + style := make(map[string]interface{}) + + for k, v := range p.Style { + style[k] = v + } + + style["height"] = height + p.Style = style + + return p +} + +// 坐标位置 +func (p *Map) SetPosition(longitude string, latitude string) *Map { + p.Value = map[string]string{ + "longitude": longitude, + "latitude": latitude, + } + return p +} diff --git a/pkg/component/admin/form/fields/month.go b/pkg/component/admin/form/fields/month.go new file mode 100644 index 0000000..4d89153 --- /dev/null +++ b/pkg/component/admin/form/fields/month.go @@ -0,0 +1,15 @@ +package fields + +import "github.com/quarkcms/quark-go/pkg/component/admin/component" + +type Month struct { + Item +} + +// 初始化 +func (p *Month) Init() *Month { + p.Component = "monthField" + p.InitItem().SetKey(component.DEFAULT_KEY, component.DEFAULT_CRYPT) + + return p +} diff --git a/pkg/component/admin/form/fields/number.go b/pkg/component/admin/form/fields/number.go new file mode 100644 index 0000000..7da069d --- /dev/null +++ b/pkg/component/admin/form/fields/number.go @@ -0,0 +1,52 @@ +package fields + +import "github.com/quarkcms/quark-go/pkg/component/admin/component" + +type Number struct { + Item + Min int `json:"min"` + Max int `json:"max"` + Step int `json:"step"` + Precision int `json:"precision"` +} + +// 初始化 +func (p *Number) Init() *Number { + p.Component = "inputNumberField" + p.InitItem().SetKey(component.DEFAULT_KEY, component.DEFAULT_CRYPT) + p.Min = -10000 + p.Max = 10000 + p.Step = 1 + p.Precision = 0 + p.SetWidth(200) + + return p +} + +// 最小值 +func (p *Number) SetMin(min int) *Number { + p.Min = min + + return p +} + +// 最大值 +func (p *Number) SetMax(max int) *Number { + p.Max = max + + return p +} + +// 每次改变步数,可以为小数 +func (p *Number) SetStep(step int) *Number { + p.Step = step + + return p +} + +// 数值精度 +func (p *Number) SetPrecision(precision int) *Number { + p.Precision = precision + + return p +} diff --git a/pkg/component/admin/form/fields/password.go b/pkg/component/admin/form/fields/password.go new file mode 100644 index 0000000..17a8214 --- /dev/null +++ b/pkg/component/admin/form/fields/password.go @@ -0,0 +1,82 @@ +package fields + +import "github.com/quarkcms/quark-go/pkg/component/admin/component" + +type Password struct { + Item + AddonAfter string `json:"addonAfter"` + AddonBefore string `json:"addonBefore"` + MaxLength int `json:"maxLength"` + Prefix string `json:"prefix"` + Size string `json:"size"` + Suffix string `json:"suffix"` + AllowClear bool `json:"allowClear"` + VisibilityToggle bool `json:"visibilityToggle"` +} + +// 初始化 +func (p *Password) Init() *Password { + p.Component = "passwordField" + p.MaxLength = 200 + p.InitItem().SetKey(component.DEFAULT_KEY, component.DEFAULT_CRYPT) + p.SetWidth(200) + p.VisibilityToggle = true + + return p +} + +// 带标签的 input,设置后置标签。例如:'http://' +func (p *Password) SetAddonAfter(addonAfter string) *Password { + p.AddonAfter = addonAfter + + return p +} + +// 带标签的 input,设置前置标签。例如:'.com' +func (p *Password) SetAddonBefore(addonBefore string) *Password { + p.AddonBefore = addonBefore + + return p +} + +// 最大长度 +func (p *Password) SetMaxLength(maxLength int) *Password { + p.MaxLength = maxLength + + return p +} + +// 带有前缀图标的 input +func (p *Password) SetPrefix(prefix string) *Password { + p.Prefix = prefix + + return p +} + +// 控件大小。注:标准表单内的输入框大小限制为 large。可选 large default small +func (p *Password) SetSize(size string) *Password { + p.Size = size + + return p +} + +// 带有后缀图标的 input +func (p *Password) SetSuffix(suffix string) *Password { + p.Suffix = suffix + + return p +} + +// 可以点击清除图标删除内容 +func (p *Password) SetAllowClear(allowClear bool) *Password { + p.AllowClear = allowClear + + return p +} + +// 组件json序列化 +func (p *Password) JsonSerialize() *Password { + p.Component = "passwordField" + + return p +} diff --git a/pkg/component/admin/form/fields/quarter.go b/pkg/component/admin/form/fields/quarter.go new file mode 100644 index 0000000..d723b63 --- /dev/null +++ b/pkg/component/admin/form/fields/quarter.go @@ -0,0 +1,15 @@ +package fields + +import "github.com/quarkcms/quark-go/pkg/component/admin/component" + +type Quarter struct { + Item +} + +// 初始化 +func (p *Quarter) Init() *Quarter { + p.Component = "quarterField" + p.InitItem().SetKey(component.DEFAULT_KEY, component.DEFAULT_CRYPT) + + return p +} diff --git a/pkg/component/admin/form/fields/radio.go b/pkg/component/admin/form/fields/radio.go new file mode 100644 index 0000000..3c1873d --- /dev/null +++ b/pkg/component/admin/form/fields/radio.go @@ -0,0 +1,45 @@ +package fields + +import "github.com/quarkcms/quark-go/pkg/component/admin/component" + +type Radio struct { + Item +} + +// 初始化 +func (p *Radio) Init() *Radio { + p.Component = "radioField" + p.InitItem().SetKey(component.DEFAULT_KEY, component.DEFAULT_CRYPT) + + return p +} + +// 设置单选属性,[]map[string]interface{}{{"label": "Title1","value": "value1"},{"label": "Title2","value": "value2"}} +// 或者 map[interface{}]interface{}{"value1":"Title1","value2":"Title2"} +func (p *Radio) SetOptions(options interface{}) *Radio { + var data []map[string]interface{} + + if mapOptions, ok := options.(map[interface{}]interface{}); ok { + for k, v := range mapOptions { + option := map[string]interface{}{ + "label": v, + "value": k, + } + + data = append(data, option) + } + } else if sliceOptions, ok := options.([]map[string]interface{}); ok { + data = sliceOptions + } + + p.Options = data + + return p +} + +// 组件json序列化 +func (p *Radio) JsonSerialize() *Radio { + p.Component = "radioField" + + return p +} diff --git a/pkg/component/admin/form/fields/search.go b/pkg/component/admin/form/fields/search.go new file mode 100644 index 0000000..df276f0 --- /dev/null +++ b/pkg/component/admin/form/fields/search.go @@ -0,0 +1,69 @@ +package fields + +import "github.com/quarkcms/quark-go/pkg/component/admin/component" + +type Search struct { + Item +} + +// 初始化 +func (p *Search) Init() *Search { + p.Component = "searchField" + p.InitItem().SetKey(component.DEFAULT_KEY, component.DEFAULT_CRYPT) + p.SetWidth(200) + p.Placeholder = "请输入要搜索的内容" + p.AllowClear = true + + return p +} + +// api +func (p *Search) SetApi(api string) *Search { + p.Api = api + + return p +} + +// 设置单选属性,[]map[string]interface{}{{"label": "Title1","value": "value1"},{"label": "Title2","value": "value2"}} +// 或者 map[interface{}]interface{}{"value1":"Title1","value2":"Title2"} +func (p *Search) SetOptions(options interface{}) *Search { + var data []map[string]interface{} + + if mapOptions, ok := options.(map[interface{}]interface{}); ok { + for k, v := range mapOptions { + option := map[string]interface{}{ + "label": v, + "value": k, + } + + data = append(data, option) + } + } else if sliceOptions, ok := options.([]map[string]interface{}); ok { + data = sliceOptions + } + + p.Options = data + + return p +} + +// 设置 Search 的模式为多选或标签,multiple | tags +func (p *Search) SetMode(mode string) *Search { + p.Mode = mode + + return p +} + +// 控件大小。注:标准表单内的输入框大小限制为 large。可选 large default small +func (p *Search) SetSize(size string) *Search { + p.Size = size + + return p +} + +// 可以点击清除图标删除内容 +func (p *Search) SetAllowClear(allowClear bool) *Search { + p.AllowClear = allowClear + + return p +} diff --git a/pkg/component/admin/form/fields/select.go b/pkg/component/admin/form/fields/select.go new file mode 100644 index 0000000..0255f54 --- /dev/null +++ b/pkg/component/admin/form/fields/select.go @@ -0,0 +1,70 @@ +package fields + +import "github.com/quarkcms/quark-go/pkg/component/admin/component" + +type Select struct { + Item +} + +// 初始化 +func (p *Select) Init() *Select { + p.Component = "selectField" + p.InitItem().SetKey(component.DEFAULT_KEY, component.DEFAULT_CRYPT) + p.SetWidth(200) + + return p +} + +// 单向联动 +func (p *Select) SetLoad(field string, api string) *Select { + p.Load = map[string]string{ + "field": field, + "api": api, + } + + return p +} + +// 设置单选属性,[]map[string]interface{}{{"label": "Title1","value": "value1"},{"label": "Title2","value": "value2"}} +// 或者 map[interface{}]interface{}{"value1":"Title1","value2":"Title2"} +func (p *Select) SetOptions(options interface{}) *Select { + var data []map[string]interface{} + + if mapOptions, ok := options.(map[interface{}]interface{}); ok { + for k, v := range mapOptions { + option := map[string]interface{}{ + "label": v, + "value": k, + } + + data = append(data, option) + } + } else if sliceOptions, ok := options.([]map[string]interface{}); ok { + data = sliceOptions + } + + p.Options = data + + return p +} + +// 设置 Select 的模式为多选或标签,multiple | tags +func (p *Select) SetMode(mode string) *Select { + p.Mode = mode + + return p +} + +// 控件大小。注:标准表单内的输入框大小限制为 large。可选 large default small +func (p *Select) SetSize(size string) *Select { + p.Size = size + + return p +} + +// 可以点击清除图标删除内容 +func (p *Select) SetAllowClear(allowClear bool) *Select { + p.AllowClear = allowClear + + return p +} diff --git a/pkg/component/admin/form/fields/selects.go b/pkg/component/admin/form/fields/selects.go new file mode 100644 index 0000000..4103271 --- /dev/null +++ b/pkg/component/admin/form/fields/selects.go @@ -0,0 +1,23 @@ +package fields + +import "github.com/quarkcms/quark-go/pkg/component/admin/component" + +type Selects struct { + Item + Body interface{} `json:"body"` +} + +// 初始化 +func (p *Selects) Init() *Selects { + p.Component = "selects" + p.InitItem().SetKey(component.DEFAULT_KEY, component.DEFAULT_CRYPT) + + return p +} + +// 组件内容 +func (p *Selects) SetBody(body interface{}) *Selects { + p.Body = body + + return p +} diff --git a/pkg/component/admin/form/fields/switch.go b/pkg/component/admin/form/fields/switch.go new file mode 100644 index 0000000..8068de5 --- /dev/null +++ b/pkg/component/admin/form/fields/switch.go @@ -0,0 +1,61 @@ +package fields + +import ( + "github.com/quarkcms/quark-go/pkg/component/admin/component" +) + +type Switch struct { + Item +} + +// 初始化 +func (p *Switch) Init() *Switch { + p.Component = "switchField" + p.InitItem().SetKey(component.DEFAULT_KEY, component.DEFAULT_CRYPT) + + return p +} + +/** + * 设置开状态文字 + * + * @param string $value + * @return $this + */ +func (p *Switch) SetTrueValue(value string) *Switch { + var off interface{} + options, ok := p.Options.(map[string]interface{}) + + if ok { + off = options["off"] + } + + p.Options = map[string]interface{}{ + "on": value, + "off": off, + } + + return p +} + +/** + * 设置关状态文字 + * + * @param string $value + * @return $this + */ +func (p *Switch) SetFalseValue(value string) *Switch { + var on interface{} + options, ok := p.Options.(map[string]interface{}) + + if ok { + on = options["on"] + } + + p.Options = map[string]interface{}{ + "on": on, + "off": value, + } + + return p +} diff --git a/pkg/component/admin/form/fields/text.go b/pkg/component/admin/form/fields/text.go new file mode 100644 index 0000000..596a1c6 --- /dev/null +++ b/pkg/component/admin/form/fields/text.go @@ -0,0 +1,80 @@ +package fields + +import "github.com/quarkcms/quark-go/pkg/component/admin/component" + +type Text struct { + Item + AddonAfter string `json:"addonAfter"` + AddonBefore string `json:"addonBefore"` + MaxLength int `json:"maxLength"` + Prefix string `json:"prefix"` + Size string `json:"size"` + Suffix string `json:"suffix"` + AllowClear bool `json:"allowClear"` +} + +// 初始化 +func (p *Text) Init() *Text { + p.Component = "textField" + p.MaxLength = 200 + p.InitItem().SetKey(component.DEFAULT_KEY, component.DEFAULT_CRYPT) + p.SetWidth(200) + + return p +} + +// 带标签的 input,设置后置标签。例如:'http://' +func (p *Text) SetAddonAfter(addonAfter string) *Text { + p.AddonAfter = addonAfter + + return p +} + +// 带标签的 input,设置前置标签。例如:'.com' +func (p *Text) SetAddonBefore(addonBefore string) *Text { + p.AddonBefore = addonBefore + + return p +} + +// 最大长度 +func (p *Text) SetMaxLength(maxLength int) *Text { + p.MaxLength = maxLength + + return p +} + +// 带有前缀图标的 input +func (p *Text) SetPrefix(prefix string) *Text { + p.Prefix = prefix + + return p +} + +// 控件大小。注:标准表单内的输入框大小限制为 large。可选 large default small +func (p *Text) SetSize(size string) *Text { + p.Size = size + + return p +} + +// 带有后缀图标的 input +func (p *Text) SetSuffix(suffix string) *Text { + p.Suffix = suffix + + return p +} + +// 可以点击清除图标删除内容 +func (p *Text) SetAllowClear(allowClear bool) *Text { + p.AllowClear = allowClear + + return p +} + +// 组件json序列化 +func (p *Text) JsonSerialize() *Text { + p.Component = "textField" + + return p +} diff --git a/pkg/component/admin/form/fields/textarea.go b/pkg/component/admin/form/fields/textarea.go new file mode 100644 index 0000000..beb9690 --- /dev/null +++ b/pkg/component/admin/form/fields/textarea.go @@ -0,0 +1,52 @@ +package fields + +import "github.com/quarkcms/quark-go/pkg/component/admin/component" + +type TextArea struct { + Item + MinRows int `json:"-"` + MaxRows int `json:"-"` +} + +// 初始化 +func (p *TextArea) Init() *TextArea { + p.Component = "textAreaField" + p.InitItem().SetKey(component.DEFAULT_KEY, component.DEFAULT_CRYPT) + p.SetWidth(400) + p.AutoSize = map[string]int{ + "minRows": 2, + "maxRows": 5, + } + + return p +} + +// autoSize 属性适用于 textarea 节点,并且只有高度会自动变化。另外 autoSize 可以设定为一个对象,指定最小行数和最大行数。 +func (p *TextArea) SetAutoSize(autoSize interface{}) *TextArea { + p.AutoSize = autoSize + return p +} + +// 指定最小行数。 +func (p *TextArea) SetMinRows(rows int) *TextArea { + p.MinRows = rows + autoSize := map[string]int{ + "minRows": rows, + "maxRows": p.MaxRows, + } + p.AutoSize = autoSize + + return p +} + +// 指定最大行数。 +func (p *TextArea) SetMaxRows(rows int) *TextArea { + p.MaxRows = rows + autoSize := map[string]int{ + "minRows": p.MinRows, + "maxRows": rows, + } + p.AutoSize = autoSize + + return p +} diff --git a/pkg/component/admin/form/fields/time.go b/pkg/component/admin/form/fields/time.go new file mode 100644 index 0000000..aa5e397 --- /dev/null +++ b/pkg/component/admin/form/fields/time.go @@ -0,0 +1,24 @@ +package fields + +import "github.com/quarkcms/quark-go/pkg/component/admin/component" + +type Time struct { + Item + Format string `json:"format"` +} + +// 初始化 +func (p *Time) Init() *Time { + p.Component = "timeField" + p.InitItem().SetKey(component.DEFAULT_KEY, component.DEFAULT_CRYPT) + p.Format = "HH:mm" + + return p +} + +// 使用 format 属性,可以自定义日期显示格式 +func (p *Time) SetFormat(format string) *Time { + p.Format = format + + return p +} diff --git a/pkg/component/admin/form/fields/time_range.go b/pkg/component/admin/form/fields/time_range.go new file mode 100644 index 0000000..3578ce3 --- /dev/null +++ b/pkg/component/admin/form/fields/time_range.go @@ -0,0 +1,25 @@ +package fields + +import "github.com/quarkcms/quark-go/pkg/component/admin/component" + +type TimeRange struct { + Item + Format string `json:"format"` +} + +// 初始化 +func (p *TimeRange) Init() *TimeRange { + p.Component = "timeRangeField" + p.InitItem().SetKey(component.DEFAULT_KEY, component.DEFAULT_CRYPT) + p.Format = "HH:mm" + p.DefaultValue = []interface{}{nil, nil} + + return p +} + +// 使用 format 属性,可以自定义日期显示格式 +func (p *TimeRange) SetFormat(format string) *TimeRange { + p.Format = format + + return p +} diff --git a/pkg/component/admin/form/fields/tree.go b/pkg/component/admin/form/fields/tree.go new file mode 100644 index 0000000..cc80bf4 --- /dev/null +++ b/pkg/component/admin/form/fields/tree.go @@ -0,0 +1,22 @@ +package fields + +import "github.com/quarkcms/quark-go/pkg/component/admin/component" + +type Tree struct { + Item +} + +// 初始化 +func (p *Tree) Init() *Tree { + p.Component = "treeField" + p.InitItem().SetKey(component.DEFAULT_KEY, component.DEFAULT_CRYPT) + + return p +} + +// 设置树形组件数据 +func (p *Tree) SetData(data interface{}) *Tree { + p.TreeData = data + + return p +} diff --git a/pkg/component/admin/form/fields/week.go b/pkg/component/admin/form/fields/week.go new file mode 100644 index 0000000..4376b61 --- /dev/null +++ b/pkg/component/admin/form/fields/week.go @@ -0,0 +1,15 @@ +package fields + +import "github.com/quarkcms/quark-go/pkg/component/admin/component" + +type Week struct { + Item +} + +// 初始化 +func (p *Week) Init() *Week { + p.Component = "weekField" + p.InitItem().SetKey(component.DEFAULT_KEY, component.DEFAULT_CRYPT) + + return p +} diff --git a/pkg/component/admin/form/fields/year.go b/pkg/component/admin/form/fields/year.go new file mode 100644 index 0000000..2a55c6e --- /dev/null +++ b/pkg/component/admin/form/fields/year.go @@ -0,0 +1,15 @@ +package fields + +import "github.com/quarkcms/quark-go/pkg/component/admin/component" + +type Year struct { + Item +} + +// 初始化 +func (p *Year) Init() *Year { + p.Component = "yearField" + p.InitItem().SetKey(component.DEFAULT_KEY, component.DEFAULT_CRYPT) + + return p +} diff --git a/pkg/component/admin/form/form.go b/pkg/component/admin/form/form.go new file mode 100644 index 0000000..b5152a9 --- /dev/null +++ b/pkg/component/admin/form/form.go @@ -0,0 +1,370 @@ +package form + +import ( + "crypto/md5" + "encoding/hex" + "encoding/json" + "fmt" + "reflect" + "strings" + + "github.com/go-basic/uuid" + "github.com/quarkcms/quark-go/pkg/component/admin/component" +) + +type Component struct { + component.Element + Title string `json:"title"` + Width string `json:"width"` + Colon bool `json:"colon"` + Values map[string]interface{} `json:"values"` + InitialValues map[string]interface{} `json:"initialValues"` + LabelAlign string `json:"labelAlign"` + Name string `json:"name"` + Preserve bool `json:"preserve"` + RequiredMark bool `json:"requiredMark"` + ScrollToFirstError bool `json:"scrollToFirstError"` + Size string `json:"size"` + DateFormatter string `json:"dateFormatter"` + Layout string `json:"layout"` + LabelCol map[string]interface{} `json:"labelCol"` + WrapperCol map[string]interface{} `json:"wrapperCol"` + ButtonWrapperCol map[string]interface{} `json:"buttonWrapperCol"` + Api string `json:"api"` + ApiType string `json:"apiType"` + TargetBlank bool `json:"targetBlank"` + InitApi string `json:"initApi"` + Body interface{} `json:"body"` + Actions []interface{} `json:"actions"` +} + +// 设置Key +func (p *Component) SetKey(key string, crypt bool) *Component { + + if key == "" { + key = uuid.New() + } + + if crypt { + h := md5.New() + h.Write([]byte(key)) + key = hex.EncodeToString(h.Sum(nil)) + } + + p.Key = key + p.ComponentKey = key + + return p +} + +// 初始化 +func (p *Component) Init() *Component { + p.Component = "form" + p.Colon = true + p.LabelAlign = "right" + p.Preserve = true + p.RequiredMark = true + p.Size = "default" + p.DateFormatter = "string" + p.Layout = "horizontal" + p.LabelCol = map[string]interface{}{ + "span": 4, + } + p.WrapperCol = map[string]interface{}{ + "span": 20, + } + p.ButtonWrapperCol = map[string]interface{}{ + "offset": 4, + "span": 20, + } + p.ApiType = "POST" + p.SetKey(component.DEFAULT_KEY, component.DEFAULT_CRYPT) + + return p +} + +// Set style. +func (p *Component) SetStyle(style map[string]interface{}) *Component { + p.Style = style + + return p +} + +// 配置表单标题 +func (p *Component) SetTitle(title string) *Component { + p.Title = title + return p +} + +// 配置表单宽度 +func (p *Component) SetWidth(width string) *Component { + p.Width = width + + return p +} + +// 配置 Form.Item 的 colon 的默认值。表示是否显示 label 后面的冒号 (只有在属性 layout 为 horizontal 时有效) +func (p *Component) SetColon(colon bool) *Component { + p.Colon = colon + + return p +} + +// 解析initialValue +func (p *Component) parseInitialValue(item interface{}, initialValues map[string]interface{}) interface{} { + reflectElem := reflect. + ValueOf(item). + Elem() + + name := reflectElem. + FieldByName("Name"). + String() + + if name == "" { + return nil + } + + var value any + + issetDefaultValue := reflectElem. + FieldByName("DefaultValue").IsValid() + + if issetDefaultValue { + defaultValue := reflectElem. + FieldByName("DefaultValue"). + Interface() + + if defaultValue != nil { + value = defaultValue + } + } + + if initialValues[name] != nil { + value = initialValues[name] + } + + issetValue := reflectElem. + FieldByName("Value").IsValid() + + if issetValue { + getValue := reflectElem. + FieldByName("Value"). + Interface() + + if getValue != nil { + value = getValue + } + } + + return value +} + +// 表单默认值,只有初始化以及重置时生效 +func (p *Component) SetInitialValues(initialValues map[string]interface{}) *Component { + data := initialValues + + if body, ok := p.Body.([]any); ok { + for _, v := range body { + value := p.parseInitialValue(v, initialValues) + if value != nil { + name := reflect. + ValueOf(v). + Elem(). + FieldByName("Name").String() + + data[name] = value + } + } + } + + for k, v := range data { + getV, ok := v.(string) + if ok { + if strings.Contains(getV, "[") || strings.Contains(getV, "{") { + m := make(map[string]string) + err := json.Unmarshal([]byte(getV), &m) + if err != nil { + fmt.Printf("Unmarshal with error: %+v\n", err) + } + v = m + } + } + + data[k] = v + } + + p.InitialValues = data + + return p +} + +// label 标签的文本对齐方式,left | right +func (p *Component) SetLabelAlign(labelAlign string) *Component { + p.LabelAlign = labelAlign + + return p +} + +// 表单名称,会作为表单字段 id 前缀使用 +func (p *Component) SetName(name string) *Component { + p.Name = name + + return p +} + +// 当字段被删除时保留字段值 +func (p *Component) SetPreserve(preserve bool) *Component { + p.Preserve = preserve + + return p +} + +// 必选样式,可以切换为必选或者可选展示样式。此为 Form 配置,Form.Item 无法单独配置 +func (p *Component) SetRequiredMark(requiredMark bool) *Component { + p.RequiredMark = requiredMark + + return p +} + +// 提交失败自动滚动到第一个错误字段 +func (p *Component) SetScrollToFirstError(scrollToFirstError bool) *Component { + p.ScrollToFirstError = scrollToFirstError + + return p +} + +// 设置字段组件的尺寸(仅限 antd 组件),small | middle | large +func (p *Component) SetSize(size string) *Component { + p.Size = size + + return p +} + +// 自动格式数据,例如 moment 的表单,支持 string 和 number 两种模式 +func (p *Component) SetDateFormatter(dateFormatter string) *Component { + p.DateFormatter = dateFormatter + + return p +} + +// 表单布局,horizontal|vertical +func (p *Component) SetLayout(layout string) *Component { + + if layout == "vertical" { + p.LabelCol = nil + p.WrapperCol = nil + p.ButtonWrapperCol = nil + } + + p.Layout = layout + + return p +} + +// label 标签布局,同 组件,设置 span offset 值,如 {span: 3, offset: 12} 或 sm: {span: 3, offset: 12} +func (p *Component) SetLabelCol(labelCol map[string]interface{}) *Component { + p.LabelCol = labelCol + + return p +} + +// 需要为输入控件设置布局样式时,使用该属性,用法同 labelCol +func (p *Component) SetWrapperCol(wrapperCol map[string]interface{}) *Component { + if p.Layout == "vertical" { + panic("If layout set vertical mode,can't set wrapperCol!") + } + + p.WrapperCol = wrapperCol + + return p +} + +// 表单按钮布局样式,默认:['offset' => 2, 'span' => 22 ] +func (p *Component) SetButtonWrapperCol(buttonWrapperCol map[string]interface{}) *Component { + if p.Layout == "vertical" { + panic("If layout set vertical mode,can't set buttonWrapperCol!") + } + + p.ButtonWrapperCol = buttonWrapperCol + + return p +} + +// 表单提交的接口链接 +func (p *Component) SetApi(api string) *Component { + p.Api = api + + return p +} + +// 表单提交接口的类型 +func (p *Component) SetApiType(apiType string) *Component { + p.ApiType = apiType + + return p +} + +// 提交表单的数据是否打开新页面,只有在GET类型的时候有效 +func (p *Component) SetTargetBlank(targetBlank bool) *Component { + p.TargetBlank = targetBlank + + return p +} + +// 获取表单数据 +func (p *Component) SetInitApi(initApi string) *Component { + p.InitApi = initApi + + return p +} + +// 表单项 +func (p *Component) SetBody(items interface{}) *Component { + p.Body = items + + return p +} + +// 解析保存提交数据库前的值 +func (p *Component) parseSubmitData(data map[string]interface{}) interface{} { + items := p.Body + + for _, v := range items.([]any) { + ignore := reflect. + ValueOf(v). + Elem(). + FieldByName("Ignore").Bool() + + // 删除忽略的值 + if ignore { + + name := reflect. + ValueOf(v). + Elem(). + FieldByName("Name").String() + + if name != "" { + if data[name] != nil { + delete(data, name) + } + } + } + } + + for k, v := range data { + getValue, ok := v.(map[string]interface{}) + if ok { + jsonString, _ := json.Marshal(getValue) + data[k] = jsonString + } + } + + return data +} + +// 设置表单行为 +func (p *Component) SetActions(actions []interface{}) *Component { + p.Actions = actions + + return p +} diff --git a/pkg/component/admin/grid/col.go b/pkg/component/admin/grid/col.go new file mode 100644 index 0000000..f988ab9 --- /dev/null +++ b/pkg/component/admin/grid/col.go @@ -0,0 +1,138 @@ +package grid + +import "github.com/quarkcms/quark-go/pkg/component/admin/component" + +type Col struct { + component.Element + Flex string `json:"flex"` + Offset int `json:"offset"` + Order int `json:"order"` + Pull int `json:"pull"` + Push int `json:"push"` + Span int `json:"span"` + Xs interface{} `json:"xs"` + Sm interface{} `json:"sm"` + Md interface{} `json:"md"` + Lg interface{} `json:"lg"` + Xl interface{} `json:"xl"` + Xxl interface{} `json:"xxl"` + Body interface{} `json:"body"` +} + +// 初始化 +func (p *Col) Init() *Col { + p.Component = "col" + p.Offset = 0 + p.Order = 0 + p.Pull = 0 + p.Push = 0 + + p.SetKey(component.DEFAULT_KEY, component.DEFAULT_CRYPT) + + return p +} + +// Set style. +func (p *Col) SetStyle(style map[string]interface{}) *Col { + p.Style = style + + return p +} + +// 布局属性 +func (p *Col) SetFlex(flex string) *Col { + p.Flex = flex + + return p +} + +// 栅格左侧的间隔格数,间隔内不可以有栅格 +func (p *Col) SetOffset(offset int) *Col { + p.Offset = offset + + return p +} + +// 栅格顺序 +func (p *Col) SetOrder(order int) *Col { + p.Order = order + + return p +} + +// 栅格向左移动格数 +func (p *Col) SetPull(pull int) *Col { + p.Pull = pull + + return p +} + +// 栅格向右移动格数 +func (p *Col) SetPush(push int) *Col { + p.Push = push + + return p +} + +// 栅格占位格数,为 0 时相当于 display: none +func (p *Col) SetSpan(span int) *Col { + p.Span = span + + return p +} + +// 屏幕 < 576px 响应式栅格,可为栅格数或一个包含其他属性的对象 +func (p *Col) SetXs(xs interface{}) *Col { + p.Xs = xs + + return p +} + +// 屏幕 ≥ 576px 响应式栅格,可为栅格数或一个包含其他属性的对象 +func (p *Col) SetSm(sm interface{}) *Col { + p.Sm = sm + + return p +} + +// 屏幕 ≥ 768px 响应式栅格,可为栅格数或一个包含其他属性的对象 +func (p *Col) SetMd(md interface{}) *Col { + p.Md = md + + return p +} + +// 屏幕 ≥ 992px 响应式栅格,可为栅格数或一个包含其他属性的对象 +func (p *Col) SetLg(lg interface{}) *Col { + p.Lg = lg + + return p +} + +// 屏幕 ≥ 1200px 响应式栅格,可为栅格数或一个包含其他属性的对象 +func (p *Col) SetXl(xl interface{}) *Col { + p.Xl = xl + + return p +} + +// 屏幕 ≥ 1600px 响应式栅格,可为栅格数或一个包含其他属性的对象 +func (p *Col) SetXxl(xxl interface{}) *Col { + p.Xxl = xxl + + return p +} + +// 卡牌内容 +func (p *Col) SetBody(body interface{}) *Col { + p.Body = body + + return p +} + +// 组件json序列化 +func (p *Col) JsonSerialize() *Col { + p.Component = "col" + + return p +} diff --git a/pkg/component/admin/grid/row.go b/pkg/component/admin/grid/row.go new file mode 100644 index 0000000..520c0d5 --- /dev/null +++ b/pkg/component/admin/grid/row.go @@ -0,0 +1,79 @@ +package grid + +import "github.com/quarkcms/quark-go/pkg/component/admin/component" + +type Row struct { + component.Element + Align string `json:"align"` + Gutter interface{} `json:"gutter"` + Justify string `json:"justify"` + Wrap bool `json:"wrap"` + Col *Col `json:"col"` + Body interface{} `json:"body"` +} + +// 初始化 +func (p *Row) Init() *Row { + p.Component = "row" + + p.SetKey(component.DEFAULT_KEY, component.DEFAULT_CRYPT) + + return p +} + +// Set style. +func (p *Row) SetStyle(style map[string]interface{}) *Row { + p.Style = style + + return p +} + +// 垂直对齐方式 +func (p *Row) SetAlign(align string) *Row { + p.Align = align + + return p +} + +// 栅格间隔,可以写成像素值或支持响应式的对象写法来设置水平间隔 { xs: 8, sm: 16, md: 24}。 +// 或者使用数组形式同时设置 [水平间距, 垂直间距] +func (p *Row) SetGutter(gutter interface{}) *Row { + p.Gutter = gutter + + return p +} + +// 水平排列方式,start | end | center | space-around | space-between +func (p *Row) SetJustify(justify string) *Row { + p.Justify = justify + + return p +} + +// 是否自动换行 +func (p *Row) SetWrap(wrap bool) *Row { + p.Wrap = wrap + + return p +} + +// 设置列 +func (p *Row) SetCol(col *Col) *Row { + p.Col = col + + return p +} + +// 内容 +func (p *Row) SetBody(body interface{}) *Row { + p.Body = body + + return p +} + +// 组件json序列化 +func (p *Row) JsonSerialize() *Row { + p.Component = "row" + + return p +} diff --git a/pkg/component/admin/layout/layout.go b/pkg/component/admin/layout/layout.go new file mode 100644 index 0000000..eb781a5 --- /dev/null +++ b/pkg/component/admin/layout/layout.go @@ -0,0 +1,173 @@ +package layout + +import "github.com/quarkcms/quark-go/pkg/component/admin/component" + +type Component struct { + component.Element + ComponentKey string `json:"componentKey"` + Cache bool `json:"cache"` + Title string `json:"title"` + Logo interface{} `json:"logo"` + Loading bool `json:"loading"` + ContentStyle map[string]string `json:"contentStyle"` + HeaderActions []map[string]interface{} `json:"headerActions"` + Layout string `json:"layout"` + HeaderTheme string `json:"headerTheme"` + SplitMenus bool `json:"splitMenus"` + ContentWidth string `json:"contentWidth"` + NavTheme string `json:"navTheme"` + PrimaryColor string `json:"primaryColor"` + FixedHeader bool `json:"fixedHeader"` + FixSiderbar bool `json:"fixSiderbar"` + IconfontUrl string `json:"iconfontUrl"` + Locale string `json:"locale"` + SiderWidth int `json:"siderWidth"` + Menu interface{} `json:"menu"` + Footer interface{} `json:"footer"` + Body interface{} `json:"body"` +} + +// 初始化 +func (p *Component) Init() *Component { + p.Component = "layout" + p.Cache = true + + p.SetKey("layout", component.DEFAULT_CRYPT) + p.ComponentKey = p.Key + + return p +} + +// Set style. +func (p *Component) SetStyle(style map[string]interface{}) *Component { + p.Style = style + + return p +} + +// 是否缓存layout +func (p *Component) SetCache(cache bool) *Component { + p.Cache = cache + return p +} + +// layout 的左上角 的 title +func (p *Component) SetTitle(title string) *Component { + p.Title = title + return p +} + +// layout 的左上角的 logo +func (p *Component) SetLogo(logo interface{}) *Component { + p.Logo = logo + return p +} + +// layout 的加载态 +func (p *Component) SetLoading(loading bool) *Component { + p.Loading = loading + return p +} + +// layout 的内容区 style +func (p *Component) SetContentStyle(contentStyle map[string]string) *Component { + p.ContentStyle = contentStyle + return p +} + +// layout 的头部行为 +func (p *Component) SetHeaderActions(headerActions []map[string]interface{}) *Component { + p.HeaderActions = headerActions + return p +} + +// layout 的布局模式,side:右侧导航,top:顶部导航,mix:混合模式 +func (p *Component) SetLayout(layout string) *Component { + p.Layout = layout + return p +} + +// layout为mix时,顶部主题 dark | light +func (p *Component) SetHeaderTheme(headerTheme string) *Component { + p.HeaderTheme = headerTheme + return p +} + +// layout 的内容模式,Fluid:定宽 1200px,Fixed:自适应 +func (p *Component) SetContentWidth(contentWidth string) *Component { + p.ContentWidth = contentWidth + return p +} + +// 导航的主题,'light' | 'dark' +func (p *Component) SetNavTheme(navTheme string) *Component { + p.NavTheme = navTheme + return p +} + +// 容器控件里面的内容 +func (p *Component) SetPrimaryColor(primaryColor string) *Component { + p.PrimaryColor = primaryColor + return p +} + +// 是否固定 header 到顶部 +func (p *Component) SetFixedHeader(fixedHeader bool) *Component { + p.FixedHeader = fixedHeader + return p +} + +// 是否固定导航 +func (p *Component) SetFixSiderbar(fixSiderbar bool) *Component { + p.FixSiderbar = fixSiderbar + return p +} + +// 使用 IconFont 的图标配置 +func (p *Component) SetIconfontUrl(iconfontUrl string) *Component { + p.IconfontUrl = iconfontUrl + return p +} + +// 当前 layout 的语言设置,'zh-CN' | 'zh-TW' | 'en-US' +func (p *Component) SetLocale(locale string) *Component { + p.Locale = locale + return p +} + +// 侧边菜单宽度 +func (p *Component) SetSiderWidth(siderWidth int) *Component { + p.SiderWidth = siderWidth + return p +} + +// 自动分割菜单 +func (p *Component) SetSplitMenus(splitMenus bool) *Component { + p.SplitMenus = splitMenus + return p +} + +// 菜单 +func (p *Component) SetMenu(menu interface{}) *Component { + p.Menu = menu + return p +} + +// 页脚 +func (p *Component) SetFooter(footer interface{}) *Component { + p.Footer = footer + return p +} + +// 内容 +func (p *Component) SetBody(body interface{}) *Component { + p.Body = body + return p +} + +// 组件json序列化 +func (p *Component) JsonSerialize() *Component { + p.Component = "layout" + + return p +} diff --git a/pkg/component/admin/lists/lists.go b/pkg/component/admin/lists/lists.go new file mode 100644 index 0000000..aa1acf2 --- /dev/null +++ b/pkg/component/admin/lists/lists.go @@ -0,0 +1,191 @@ +package lists + +import "github.com/quarkcms/quark-go/pkg/component/admin/component" + +type Component struct { + component.Element + RowKey string `json:"rowKey"` + Api string `json:"api"` + ApiType string `json:"apiType"` + HeaderTitle string `json:"headerTitle"` + Metas interface{} `json:"metas"` + RowSelection interface{} `json:"rowSelection"` + Striped bool `json:"striped"` + Datasource interface{} `json:"datasource"` + Pagination interface{} `json:"pagination"` + ToolBar interface{} `json:"toolBar"` +} + +// 初始化 +func (p *Component) Init() *Component { + p.Component = "list" + p.SetKey(component.DEFAULT_KEY, component.DEFAULT_CRYPT) + + return p +} + +// Set style. +func (p *Component) SetStyle(style map[string]interface{}) *Component { + p.Style = style + + return p +} + +// layout 的左上角 的 title +func (p *Component) SetRowKey(rowKey string) *Component { + p.RowKey = rowKey + return p +} + +/** + * 获取表格数据接口 + * + * @param string api + * @return p + */ +func (p *Component) SetApi(api string) *Component { + p.Api = api + + return p +} + +/** + * 获取表格数据接口类型 + * + * @param string apiType + * @return p + */ +func (p *Component) SetApiType(apiType string) *Component { + p.ApiType = apiType + + return p +} + +/** + * 表头标题 + * + * @param string title + * @return p + */ +func (p *Component) SetTitle(title string) *Component { + p.HeaderTitle = title + + return p +} + +/** + * 表头标题 + * + * @param string headerTitle + * @return p + */ +func (p *Component) SetHeaderTitle(headerTitle string) *Component { + p.HeaderTitle = headerTitle + + return p +} + +/** + * 批量设置表格列 + * + * @param array metas + * @return p + */ +func (p *Component) SetMetas(metas interface{}) *Component { + + limits := []string{ + "type", + "title", + "subTitle", + "description", + "avatar", + "actions", + "content", + "extra", + } + + for k, _ := range metas.(map[string]interface{}) { + inSlice := false + for _, limit := range limits { + if limit == k { + inSlice = true + } + } + + if inSlice == false { + panic("meta index key must be in 'type','title','subTitle','description','avatar','actions','content','extra'!") + } + } + + p.Metas = metas + + return p +} + +/** + * 批量操作选择项 + * + * @param array rowSelection + * @return p + */ +func (p *Component) SetRowSelection(rowSelection []interface{}) *Component { + p.RowSelection = rowSelection + + return p +} + +/** + * 透传 ProUtils 中的 ListToolBar 配置项 + * + * @param void + * @return p + */ +func (p *Component) SetToolBar(toolBar interface{}) *Component { + p.ToolBar = toolBar + + return p +} + +/** + * 设置表格滚动 + * + * @param bool striped + * @return p + */ +func (p *Component) striped(striped bool) *Component { + p.Striped = striped + + return p +} + +/** + * 表格数据 + * + * @param array|string datasource + * @return p + */ +func (p *Component) SetDatasource(datasource interface{}) *Component { + p.Datasource = datasource + + return p +} + +/** + * 表格分页 + * + * @param number current + * @param number pageSize + * @param number total + * @param number defaultCurrent + * @return p + */ +func (p *Component) SetPagination(current int, pageSize int, total int, defaultCurrent int) *Component { + p.Pagination = map[string]int{ + "current": current, + "pageSize": pageSize, + "total": total, + "defaultCurrent": defaultCurrent, + } + + return p +} diff --git a/pkg/component/admin/lists/meta.go b/pkg/component/admin/lists/meta.go new file mode 100644 index 0000000..59e5324 --- /dev/null +++ b/pkg/component/admin/lists/meta.go @@ -0,0 +1,126 @@ +package lists + +import "github.com/quarkcms/quark-go/pkg/component/admin/component" + +type Meta struct { + component.Element + Title string `json:"title"` + Attribute string `json:"attribute"` + DataIndex string `json:"dataIndex"` + Ellipsis bool `json:"ellipsis"` + Copyable bool `json:"copyable"` + ValueEnum interface{} `json:"valueEnum"` + ValueType string `json:"valueType"` + Search bool `json:"search"` + Actions bool `json:"actions"` +} + +// 初始化 +func (p *Meta) Init() *Meta { + p.Component = "meta" + p.SetKey(component.DEFAULT_KEY, component.DEFAULT_CRYPT) + + return p +} + +// Set style. +func (p *Meta) SetStyle(style map[string]interface{}) *Meta { + p.Style = style + + return p +} + +/** + * 列头显示文字,既字段的列名 + * + * @param string title + * @return p + */ +func (p *Meta) SetTitle(title string) *Meta { + p.Title = title + return p +} + +/** + * 字段名称|字段的列名 + * + * @param string attribute + * @return p + */ +func (p *Meta) SetAttribute(attribute string) *Meta { + p.SetKey(attribute, false) + p.ComponentKey = attribute + p.DataIndex = attribute + p.Attribute = attribute + + return p +} + +/** + * 是否自动缩略 + * + * @param bool ellipsis + * @return p + */ +func (p *Meta) SetEllipsis(ellipsis bool) *Meta { + p.Ellipsis = ellipsis + return p +} + +/** + * 是否支持复制 + * + * @param bool copyable + * @return p + */ +func (p *Meta) SetCopyable(copyable bool) *Meta { + p.Copyable = copyable + return p +} + +/** + * 值的枚举,会自动转化把值当成 key 来取出要显示的内容 + * + * @param array valueEnum + * @return p + */ +func (p *Meta) SetValueEnum(valueEnum interface{}) *Meta { + valueEnumStr := map[string]interface{}{} + valueEnumInt := map[int]interface{}{} + + for k, v := range valueEnum.(map[interface{}]interface{}) { + if value, ok := k.(string); ok == true { + valueEnumStr[value] = v + } else if value, ok := k.(int); ok == true { + valueEnumInt[value] = v + } + } + + if len(valueEnumStr) > 0 { + p.ValueEnum = valueEnumStr + } + + if len(valueEnumInt) > 0 { + p.ValueEnum = valueEnumInt + } + + return p +} + +/** + * 值的类型,"money" | "option" | "date" | "dateTime" | "time" | "text"| "index" | "indexBorder" + * + * @param string valueType + * @return p + */ +func (p *Meta) SetValueType(valueType string) *Meta { + p.ValueType = valueType + return p +} + +// 在查询表单中不展示此项 +func (p *Meta) SetSearch(search bool) *Meta { + p.Search = search + + return p +} diff --git a/pkg/component/admin/login/login.go b/pkg/component/admin/login/login.go new file mode 100644 index 0000000..1fa0549 --- /dev/null +++ b/pkg/component/admin/login/login.go @@ -0,0 +1,94 @@ +package login + +import "github.com/quarkcms/quark-go/pkg/component/admin/component" + +type Component struct { + component.Element + Component string `json:"component"` + Api string `json:"api"` + Redirect string `json:"redirect"` + Logo interface{} `json:"logo"` + Title string `json:"title"` + Description string `json:"description"` + CaptchaIdUrl string `json:"captchaIdUrl"` + CaptchaUrl string `json:"captchaUrl"` + Copyright string `json:"copyright"` + Links []map[string]interface{} `json:"links"` +} + +// 初始化 +func (p *Component) Init() *Component { + p.Component = "login" + + p.SetKey(component.DEFAULT_KEY, component.DEFAULT_CRYPT) + + return p +} + +// Set style. +func (p *Component) SetStyle(style map[string]interface{}) *Component { + p.Style = style + + return p +} + +// 登录接口 +func (p *Component) SetApi(api string) *Component { + p.Api = api + return p +} + +// 登录后跳转地址 +func (p *Component) SetRedirect(redirect string) *Component { + p.Redirect = redirect + return p +} + +// Logo +func (p *Component) SetLogo(logo interface{}) *Component { + p.Logo = logo + return p +} + +// 标题 +func (p *Component) SetTitle(title string) *Component { + p.Title = title + return p +} + +// 描述 +func (p *Component) SetDescription(description string) *Component { + p.Description = description + return p +} + +// 获取验证码ID链接 +func (p *Component) SetCaptchaIdUrl(captchaIdUrl string) *Component { + p.CaptchaIdUrl = captchaIdUrl + return p +} + +// 验证码链接 +func (p *Component) SetCaptchaUrl(captchaUrl string) *Component { + p.CaptchaUrl = captchaUrl + return p +} + +// 页脚版权信息 +func (p *Component) SetCopyright(copyright string) *Component { + p.Copyright = copyright + return p +} + +// 页脚友情链接 +func (p *Component) SetLinks(links []map[string]interface{}) *Component { + p.Links = links + return p +} + +// 组件json序列化 +func (p *Component) JsonSerialize() *Component { + p.Component = "login" + + return p +} diff --git a/pkg/component/admin/menu/divider.go b/pkg/component/admin/menu/divider.go new file mode 100644 index 0000000..1f1c085 --- /dev/null +++ b/pkg/component/admin/menu/divider.go @@ -0,0 +1,23 @@ +package menu + +import "github.com/quarkcms/quark-go/pkg/component/admin/component" + +type Divider struct { + component.Element + Dashed bool `json:"dashed"` +} + +// 初始化 +func (p *Divider) Init() *Divider { + p.Component = "menuDivider" + p.SetKey(component.DEFAULT_KEY, component.DEFAULT_CRYPT) + + return p +} + +// 子菜单项值 +func (p *Divider) SetDashed(dashed bool) *Divider { + p.Dashed = dashed + + return p +} diff --git a/pkg/component/admin/menu/item.go b/pkg/component/admin/menu/item.go new file mode 100644 index 0000000..1246a00 --- /dev/null +++ b/pkg/component/admin/menu/item.go @@ -0,0 +1,216 @@ +package menu + +import ( + "github.com/quarkcms/quark-go/pkg/component/admin/action" + "github.com/quarkcms/quark-go/pkg/component/admin/component" +) + +type Item struct { + component.Element + Title string `json:"title"` + Label string `json:"label"` + Block bool `json:"block"` + Danger bool `json:"danger"` + Disabled bool `json:"disabled"` + Ghost bool `json:"ghost"` + Icon string `json:"icon"` + Shape string `json:"shape"` + Size string `json:"size"` + Type string `json:"type"` + ActionType string `json:"actionType"` + SubmitForm any `json:"submitForm"` + Href string `json:"href"` + Target string `json:"target"` + Modal interface{} `json:"modal"` + Drawer interface{} `json:"drawer"` + ConfirmTitle string `json:"confirmTitle"` + ConfirmText string `json:"confirmText"` + ConfirmType string `json:"confirmType"` + Api string `json:"api"` + Reload string `json:"reload"` + WithLoading bool `json:"withLoading"` +} + +// 初始化 +func (p *Item) Init() *Item { + p.Component = "menuItem" + p.Size = "default" + p.Type = "default" + + p.SetKey(component.DEFAULT_KEY, component.DEFAULT_CRYPT) + + return p +} + +// Set style. +func (p *Item) SetStyle(style map[string]interface{}) *Item { + p.Style = style + + return p +} + +// 设置收缩时展示的悬浮标题 +func (p *Item) SetTitle(title string) *Item { + p.Title = title + + return p +} + +// 设置按钮文字 +func (p *Item) SetLabel(label string) *Item { + p.Label = label + + return p +} + +// 将按钮宽度调整为其父宽度的选项 +func (p *Item) SetBlock(block bool) *Item { + p.Block = block + + return p +} + +// 设置危险按钮 +func (p *Item) SetDanger(danger bool) *Item { + p.Danger = danger + + return p +} + +// 按钮失效状态 +func (p *Item) SetDisabled(disabled bool) *Item { + p.Disabled = disabled + + return p +} + +// 幽灵属性,使按钮背景透明 +func (p *Item) SetGhost(ghost bool) *Item { + p.Ghost = ghost + + return p +} + +// 设置按钮图标 +func (p *Item) SetIcon(icon string) *Item { + p.Icon = "icon-" + icon + + return p +} + +// 设置按钮形状,可选值为 circle、 round 或者不设 +func (p *Item) SetShape(shape string) *Item { + p.Shape = shape + + return p +} + +// 设置按钮类型,primary | ghost | dashed | link | text | default +func (p *Item) SetType(buttonType string, danger bool) *Item { + p.Type = buttonType + p.Danger = danger + + return p +} + +// 设置按钮大小,large | middle | small | default +func (p *Item) SetSize(size string) *Item { + p.Size = size + + return p +} + +// 【必填】这是 action 最核心的配置,来指定该 action 的作用类型,支持:ajax、link、url、drawer、dialog、confirm、cancel、prev、next、copy、close。 +func (p *Item) SetActionType(actionType string) *Item { + p.ActionType = actionType + + return p +} + +// 当action 的作用类型为submit的时候,可以指定提交哪个表格,submitForm为提交表单的key值,为空时提交当前表单 +func (p *Item) SetSubmitForm(formKey string) *Item { + p.SubmitForm = formKey + + return p +} + +// 点击跳转的地址,指定此属性 button 的行为和 a 链接一致 +func (p *Item) SetHref(href string) *Item { + p.Href = href + + return p +} + +// 相当于 a 链接的 target 属性,href 存在时生效 +func (p *Item) SetTarget(target string) *Item { + p.Target = target + + return p +} + +// 设置跳转链接 +func (p *Item) SetLink(href string, target string) *Item { + p.SetHref(href) + p.SetTarget(target) + p.ActionType = "link" + + return p +} + +// 弹窗 +func (p *Item) SetModal(callback interface{}) *Item { + modal := (&action.Modal{}).Init() + getCallback := callback.(func(modal *action.Modal) interface{}) + + p.Modal = getCallback(modal) + + return p +} + +// 抽屉 +func (p *Item) SetDrawer(callback interface{}) *Item { + drawer := (&action.Drawer{}).Init() + getCallback := callback.(func(drawer *action.Drawer) interface{}) + + p.Drawer = getCallback(drawer) + + return p +} + +// 设置行为前的确认操作 +func (p *Item) SetWithConfirm(title string, text string, confirmType string) *Item { + p.ConfirmTitle = title + p.ConfirmText = text + p.ConfirmType = confirmType + + return p +} + +// 执行行为的接口链接 +func (p *Item) SetApi(api string) *Item { + p.Api = api + p.ActionType = "ajax" + + return p +} + +// 执行成功后刷新的组件 +func (p *Item) SetReload(reload string) *Item { + p.Reload = reload + + return p +} + +// 是否具有loading +func (p *Item) SetWithLoading(loading bool) *Item { + p.WithLoading = loading + + return p +} + +// 组件json序列化 +func (p *Item) JsonSerialize() *Item { + p.Component = "menuItem" + + return p +} diff --git a/pkg/component/admin/menu/item_group.go b/pkg/component/admin/menu/item_group.go new file mode 100644 index 0000000..a1f6e37 --- /dev/null +++ b/pkg/component/admin/menu/item_group.go @@ -0,0 +1,33 @@ +package menu + +import ( + "github.com/quarkcms/quark-go/pkg/component/admin/component" +) + +type ItemGroup struct { + component.Element + Title string `json:"title"` + Items interface{} `json:"items"` +} + +// 初始化 +func (p *ItemGroup) Init() *ItemGroup { + p.Component = "menuItemGroup" + p.SetKey(component.DEFAULT_KEY, component.DEFAULT_CRYPT) + + return p +} + +// 设置收缩时展示的悬浮标题 +func (p *ItemGroup) SetTitle(title string) *ItemGroup { + p.Title = title + + return p +} + +// 设置按钮文字 +func (p *ItemGroup) SetItems(items interface{}) *ItemGroup { + p.Items = items + + return p +} diff --git a/pkg/component/admin/menu/menu.go b/pkg/component/admin/menu/menu.go new file mode 100644 index 0000000..74a45df --- /dev/null +++ b/pkg/component/admin/menu/menu.go @@ -0,0 +1,131 @@ +package menu + +import "github.com/quarkcms/quark-go/pkg/component/admin/component" + +type Component struct { + component.Element + DefaultOpenKeys interface{} `json:"defaultOpenKeys"` + DefaultSelectedKeys interface{} `json:"defaultSelectedKeys"` + InlineCollapsed bool `json:"inlineCollapsed"` + InlineIndent int `json:"inlineIndent"` + Mode string `json:"mode"` + Multiple bool `json:"multiple"` + Selectable bool `json:"selectable"` + SubMenuCloseDelay float64 `json:"subMenuCloseDelay"` + SubMenuOpenDelay float64 `json:"subMenuOpenDelay"` + Theme string `json:"theme"` + TriggerSubMenuAction string `json:"triggerSubMenuAction"` + Items interface{} `json:"items"` +} + +// 初始化 +func (p *Component) Init() *Component { + p.Component = "menu" + p.SetKey(component.DEFAULT_KEY, component.DEFAULT_CRYPT) + p.InlineIndent = 24 + p.Mode = "vertical" + p.Selectable = true + p.SubMenuCloseDelay = 0.1 + p.SubMenuOpenDelay = 0 + p.Theme = "light" + p.TriggerSubMenuAction = "hover" + + return p +} + +// 初始展开的 SubMenu 菜单项 key 数组 +func (p *Component) SetDefaultOpenKeys(defaultOpenKeys interface{}) *Component { + p.DefaultOpenKeys = defaultOpenKeys + + return p +} + +// 初始选中的菜单项 key 数组 +func (p *Component) SetDefaultSelectedKeys(defaultSelectedKeys interface{}) *Component { + p.DefaultSelectedKeys = defaultSelectedKeys + + return p +} + +// inline 时菜单是否收起状态 +func (p *Component) SetInlineCollapsed(inlineCollapsed bool) *Component { + p.InlineCollapsed = inlineCollapsed + + return p +} + +// inline 模式的菜单缩进宽度 +func (p *Component) SetInlineIndent(inlineIndent int) *Component { + p.InlineIndent = inlineIndent + + return p +} + +// 菜单类型,现在支持垂直、水平、和内嵌模式三种,vertical | horizontal | inline +func (p *Component) SetMode(mode string) *Component { + p.Mode = mode + + return p +} + +// 是否允许多选 +func (p *Component) SetMultiple(multiple bool) *Component { + p.Multiple = multiple + + return p +} + +// 是否允许选中 +func (p *Component) SetSelectable(selectable bool) *Component { + p.Selectable = selectable + + return p +} + +// 用户鼠标离开子菜单后关闭延时,单位:秒 +func (p *Component) SetSubMenuCloseDelay(subMenuCloseDelay float64) *Component { + p.SubMenuCloseDelay = subMenuCloseDelay + + return p +} + +// 主题颜色,light | dark +func (p *Component) SetTheme(theme string) *Component { + p.Theme = theme + + return p +} + +// SubMenu 展开/关闭的触发行为,hover | click +func (p *Component) SetTriggerSubMenuAction(triggerSubMenuAction string) *Component { + p.TriggerSubMenuAction = triggerSubMenuAction + + return p +} + +// 设置菜单项 +func (p *Component) SetItems(items interface{}) *Component { + p.Items = items + + return p +} + +// 菜单分隔符 +func (p *Component) Divider() *Divider { + return (&Divider{}).Init() +} + +// 菜单分组 +func (p *Component) ItemGroup(title string, items interface{}) *ItemGroup { + return (&ItemGroup{}).Init().SetTitle(title).SetItems(items) +} + +// 菜单项 +func (p *Component) Item(label string, title string) *Item { + return (&Item{}).Init().SetLabel(label).SetTitle(title) +} + +// 子菜单 +func (p *Component) SubMenu(title string, items interface{}) *SubMenu { + return (&SubMenu{}).Init().SetTitle(title).SetItems(items) +} diff --git a/pkg/component/admin/menu/sub_menu.go b/pkg/component/admin/menu/sub_menu.go new file mode 100644 index 0000000..1db83d5 --- /dev/null +++ b/pkg/component/admin/menu/sub_menu.go @@ -0,0 +1,65 @@ +package menu + +import ( + "github.com/quarkcms/quark-go/pkg/component/admin/component" +) + +type SubMenu struct { + component.Element + Disabled bool `json:"disabled"` + Icon string `json:"icon"` + PopupClassName string `json:"popupClassName"` + PopupOffset interface{} `json:"popupOffset"` + Title string `json:"title"` + Items interface{} `json:"items"` +} + +// 初始化 +func (p *SubMenu) Init() *SubMenu { + p.Component = "menuSubMenu" + p.SetKey(component.DEFAULT_KEY, component.DEFAULT_CRYPT) + + return p +} + +// 是否禁用 +func (p *SubMenu) SetDisabled(disabled bool) *SubMenu { + p.Disabled = disabled + + return p +} + +// 菜单图标 +func (p *SubMenu) SetIcon(icon string) *SubMenu { + p.Icon = icon + + return p +} + +// 子菜单样式,mode="inline" 时无效 +func (p *SubMenu) SetPopupClassName(popupClassName string) *SubMenu { + p.PopupClassName = popupClassName + + return p +} + +// 子菜单偏移量,mode="inline" 时无效 +func (p *SubMenu) SetPopupOffset(popupOffset interface{}) *SubMenu { + p.PopupOffset = popupOffset + + return p +} + +// 子菜单项值 +func (p *SubMenu) SetTitle(title string) *SubMenu { + p.Title = title + + return p +} + +// 菜单项 +func (p *SubMenu) SetItems(items interface{}) *SubMenu { + p.Items = items + + return p +} diff --git a/pkg/component/admin/page/page.go b/pkg/component/admin/page/page.go new file mode 100644 index 0000000..3731fc0 --- /dev/null +++ b/pkg/component/admin/page/page.go @@ -0,0 +1,44 @@ +package page + +import "github.com/quarkcms/quark-go/pkg/component/admin/component" + +type Component struct { + component.Element + Title string `json:"title"` + Body interface{} `json:"body"` +} + +// 初始化 +func (p *Component) Init() *Component { + p.Component = "page" + + p.SetKey("page", component.DEFAULT_CRYPT) + + return p +} + +// Set style. +func (p *Component) SetStyle(style map[string]interface{}) *Component { + p.Style = style + + return p +} + +// 标题 +func (p *Component) SetTitle(title string) *Component { + p.Title = title + return p +} + +// 内容 +func (p *Component) SetBody(body interface{}) *Component { + p.Body = body + return p +} + +// 组件json序列化 +func (p *Component) JsonSerialize() *Component { + p.Component = "page" + + return p +} diff --git a/pkg/component/admin/pagecontainer/pagecontainer.go b/pkg/component/admin/pagecontainer/pagecontainer.go new file mode 100644 index 0000000..eebd587 --- /dev/null +++ b/pkg/component/admin/pagecontainer/pagecontainer.go @@ -0,0 +1,121 @@ +package pagecontainer + +import "github.com/quarkcms/quark-go/pkg/component/admin/component" + +type Component struct { + component.Element + Content interface{} `json:"content"` + ExtraContent interface{} `json:"extraContent"` + TabList []map[string]string `json:"tabList"` + TabActiveKey string `json:"tabActiveKey"` + TabBarExtraContent interface{} `json:"tabBarExtraContent"` + Header interface{} `json:"header"` + Ghost bool `json:"ghost"` + FixedHeader bool `json:"fixedHeader"` + AffixProps interface{} `json:"affixProps"` + Footer interface{} `json:"footer"` + Body interface{} `json:"body"` + WaterMarkProps interface{} `json:"waterMarkProps"` + TabProps interface{} `json:"tabProps"` +} + +// 初始化 +func (p *Component) Init() *Component { + p.Component = "pageContainer" + + p.SetKey("pageContainer", component.DEFAULT_CRYPT) + + return p +} + +// Set style. +func (p *Component) SetStyle(style map[string]interface{}) *Component { + p.Style = style + + return p +} + +// 内容区 +func (p *Component) SetContent(content interface{}) *Component { + p.Content = content + return p +} + +// 额外内容区,位于 content 的右侧 +func (p *Component) SetExtraContent(extraContent interface{}) *Component { + p.ExtraContent = extraContent + return p +} + +// tab 标题列表 +func (p *Component) SetTabList(tabList []map[string]string) *Component { + p.TabList = tabList + return p +} + +// 当前高亮的 tab 项 +func (p *Component) SetTabActiveKey(tabActiveKey string) *Component { + p.TabActiveKey = tabActiveKey + return p +} + +// tab bar 上额外的元素 +func (p *Component) SetTabBarExtraContent(tabBarExtraContent interface{}) *Component { + p.TabBarExtraContent = tabBarExtraContent + return p +} + +// PageHeader 的所有属性 +func (p *Component) SetHeader(header interface{}) *Component { + p.Header = header + return p +} + +// 配置头部区域的背景颜色为透明 +func (p *Component) SetGhost(ghost bool) *Component { + p.Ghost = ghost + return p +} + +// 固定 pageHeader 的内容到顶部,如果页面内容较少,最好不要使用,会有严重的遮挡问题 +func (p *Component) SetFixedHeader(fixedHeader bool) *Component { + p.FixedHeader = fixedHeader + return p +} + +// 固钉的配置,与 antd 完全相同 +func (p *Component) SetAffixProps(affixProps interface{}) *Component { + p.AffixProps = affixProps + return p +} + +// 悬浮在底部的操作栏,传入一个数组,会自动加空格 +func (p *Component) SetFooter(footer interface{}) *Component { + p.Footer = footer + return p +} + +// 容器控件里面的内容 +func (p *Component) SetBody(body interface{}) *Component { + p.Body = body + return p +} + +// 配置水印,Layout 会透传给 PageContainer,但是以 PageContainer 的配置优先 +func (p *Component) SetWaterMarkProps(waterMarkProps interface{}) *Component { + p.WaterMarkProps = waterMarkProps + return p +} + +// 配置水印,Layout 会透传给 PageContainer,但是以 PageContainer 的配置优先 +func (p *Component) SetTabProps(tabProps interface{}) *Component { + p.TabProps = tabProps + return p +} + +// 组件json序列化 +func (p *Component) JsonSerialize() *Component { + p.Component = "pageContainer" + + return p +} diff --git a/pkg/component/admin/pagecontainer/pageheader.go b/pkg/component/admin/pagecontainer/pageheader.go new file mode 100644 index 0000000..461292e --- /dev/null +++ b/pkg/component/admin/pagecontainer/pageheader.go @@ -0,0 +1,100 @@ +package pagecontainer + +import "github.com/quarkcms/quark-go/pkg/component/admin/component" + +type PageHeader struct { + component.Element + Avatar interface{} `json:"avatar"` + BackIcon interface{} `json:"backIcon"` + Breadcrumb interface{} `json:"breadcrumb"` + BreadcrumbRender interface{} `json:"breadcrumbRender"` + Extra interface{} `json:"extra"` + Footer interface{} `json:"footer"` + Ghost bool `json:"ghost"` + SubTitle string `json:"subTitle"` + Tags interface{} `json:"tags"` + Title string `json:"title"` +} + +// 初始化 +func (p *PageHeader) Init() *PageHeader { + p.Component = "pageHeader" + + p.SetKey(component.DEFAULT_KEY, component.DEFAULT_CRYPT) + + return p +} + +// Set style. +func (p *PageHeader) SetStyle(style map[string]interface{}) *PageHeader { + p.Style = style + + return p +} + +// 标题栏旁的头像 +func (p *PageHeader) SetAvatar(avatar interface{}) *PageHeader { + p.Avatar = avatar + return p +} + +// 自定义 back icon ,如果为 false 不渲染 back icon +func (p *PageHeader) SetBackIcon(backIcon interface{}) *PageHeader { + p.BackIcon = backIcon + return p +} + +// 面包屑的配置 +func (p *PageHeader) SetBreadcrumb(breadcrumb interface{}) *PageHeader { + p.Breadcrumb = breadcrumb + return p +} + +// 自定义面包屑区域的内容 +func (p *PageHeader) SetBreadcrumbRender(breadcrumbRender interface{}) *PageHeader { + p.BreadcrumbRender = breadcrumbRender + return p +} + +// 操作区,位于 title 行的行尾 +func (p *PageHeader) SetExtra(extra interface{}) *PageHeader { + p.Extra = extra + return p +} + +// PageHeader 的页脚,一般用于渲染 TabBar +func (p *PageHeader) SetFooter(footer interface{}) *PageHeader { + p.Footer = footer + return p +} + +// pageHeader 的类型,将会改变背景颜色 +func (p *PageHeader) SetGhost(ghost bool) *PageHeader { + p.Ghost = ghost + return p +} + +// 自定义的二级标题文字 +func (p *PageHeader) SetSubTitle(subTitle string) *PageHeader { + p.SubTitle = subTitle + return p +} + +// title 旁的 tag 列表 +func (p *PageHeader) SetTags(tags interface{}) *PageHeader { + p.Tags = tags + return p +} + +// 自定义标题文字 +func (p *PageHeader) SetTitle(title string) *PageHeader { + p.Title = title + return p +} + +// 组件json序列化 +func (p *PageHeader) JsonSerialize() *PageHeader { + p.Component = "pageHeader" + + return p +} diff --git a/pkg/component/admin/space/space.go b/pkg/component/admin/space/space.go new file mode 100644 index 0000000..537ff52 --- /dev/null +++ b/pkg/component/admin/space/space.go @@ -0,0 +1,103 @@ +package space + +import "github.com/quarkcms/quark-go/pkg/component/admin/component" + +type Component struct { + component.Element + Align string `json:"align"` + Direction string `json:"direction"` + Size string `json:"size"` + Split string `json:"split"` + Wrap bool `json:"wrap"` + Body interface{} `json:"body"` +} + +// 初始化 +func (p *Component) Init() *Component { + p.Component = "space" + p.Size = "small" + + p.SetKey("space", component.DEFAULT_CRYPT) + + return p +} + +// Set style. +func (p *Component) SetStyle(style map[string]interface{}) *Component { + p.Style = style + + return p +} + +/** + * 对齐方式 + * + * @param string align + * @return p + */ +func (p *Component) SetAlign(align string) *Component { + p.Align = align + + return p +} + +/** + * 间距方向 + * + * @param string direction + * @return p + */ +func (p *Component) SetDirection(direction string) *Component { + p.Direction = direction + + return p +} + +/** + * 间距大小 + * + * @param string size + * @return p + */ +func (p *Component) SetSize(size string) *Component { + p.Size = size + + return p +} + +/** + * 拆分卡片的方向,vertical | horizontal + * + * @param string split + * @return p + */ +func (p *Component) SetSplit(split string) *Component { + + p.Split = split + + return p +} + +/** + * 是否自动换行,仅在 horizontal 时有效 + * + * @param bool wrap + * @return p + */ +func (p *Component) SetWrap(wrap bool) *Component { + p.Wrap = wrap + + return p +} + +/** + * 容器控件里面的内容 + * + * @param string|array body + * @return p + */ +func (p *Component) SetBody(body interface{}) *Component { + p.Body = body + + return p +} diff --git a/pkg/component/admin/statistic/statistic.go b/pkg/component/admin/statistic/statistic.go new file mode 100644 index 0000000..4980011 --- /dev/null +++ b/pkg/component/admin/statistic/statistic.go @@ -0,0 +1,90 @@ +package statistic + +import "github.com/quarkcms/quark-go/pkg/component/admin/component" + +type Component struct { + component.Element + DecimalSeparator string `json:"decimalSeparator"` + GroupSeparator string `json:"groupSeparator"` + Precision int `json:"precision"` + Prefix string `json:"prefix"` + Suffix string `json:"suffix"` + Title string `json:"title"` + Value int64 `json:"value"` + ValueStyle map[string]string `json:"valueStyle"` +} + +// 初始化 +func (p *Component) Init() *Component { + p.Component = "statistic" + p.DecimalSeparator = "." + p.GroupSeparator = "," + + p.SetKey(component.DEFAULT_KEY, component.DEFAULT_CRYPT) + + return p +} + +// Set style. +func (p *Component) SetStyle(style map[string]interface{}) *Component { + p.Style = style + + return p +} + +// 设置小数点 +func (p *Component) SetDecimalSeparator(decimalSeparator string) *Component { + p.DecimalSeparator = decimalSeparator + return p +} + +// 设置千分位标识符 +func (p *Component) SetGroupSeparator(groupSeparator string) *Component { + p.GroupSeparator = groupSeparator + return p +} + +// 数值精度 +func (p *Component) SetPrecision(precision int) *Component { + p.Precision = precision + return p +} + +// 设置数值的前缀 +func (p *Component) SetPrefix(prefix string) *Component { + p.Prefix = prefix + return p +} + +// 设置数值的后缀 +func (p *Component) SetSuffix(suffix string) *Component { + p.Suffix = suffix + return p +} + +// 设置标题 +func (p *Component) SetTitle(title string) *Component { + p.Title = title + return p +} + +// 数值内容 +func (p *Component) SetValue(value int64) *Component { + p.Value = value + return p +} + +// 设置数值的样式 +func (p *Component) SetValueStyle(valueStyle map[string]string) *Component { + p.ValueStyle = valueStyle + return p +} + +// 组件json序列化 +func (p *Component) JsonSerialize() *Component { + p.Component = "statistic" + p.DecimalSeparator = "." + p.GroupSeparator = "," + + return p +} diff --git a/pkg/component/admin/table/column.go b/pkg/component/admin/table/column.go new file mode 100644 index 0000000..e9a1581 --- /dev/null +++ b/pkg/component/admin/table/column.go @@ -0,0 +1,313 @@ +package table + +import ( + "github.com/quarkcms/quark-go/pkg/component/admin/component" +) + +type Column struct { + component.Element + ComponentKey string `json:"componentKey"` + Title string `json:"title"` + Attribute string `json:"attribute"` + Align string `json:"align"` + DataIndex string `json:"dataIndex"` + Fixed interface{} `json:"fixed"` + Tooltip string `json:"tooltip"` + Ellipsis bool `json:"ellipsis"` + Copyable bool `json:"copyable"` + ValueEnum interface{} `json:"valueEnum"` + ValueType string `json:"valueType"` + HideInSearch bool `json:"hideInSearch"` + HideInTable bool `json:"hideInTable"` + HideInForm bool `json:"hideInForm"` + Filters interface{} `json:"filters"` + Order int `json:"order"` + Sorter interface{} `json:"sorter"` + Width int `json:"width"` + Editable interface{} `json:"editable"` + Actions interface{} `json:"actions"` + FormItemProps interface{} `json:"formItemProps"` +} + +// 初始化 +func (p *Column) Init() *Column { + p.Component = "column" + p.Align = "left" + p.Editable = false + p.Actions = false + p.Filters = false + + p.SetKey(component.DEFAULT_KEY, component.DEFAULT_CRYPT) + + return p +} + +// Set style. +func (p *Column) SetStyle(style map[string]interface{}) *Column { + p.Style = style + + return p +} + +/** + * 列头显示文字,既字段的列名 + * + * @param string title + * @return p + */ +func (p *Column) SetTitle(title string) *Column { + p.Title = title + return p +} + +/** + * 字段名称|字段的列名 + * + * @param string attribute + * @return p + */ +func (p *Column) SetAttribute(attribute string) *Column { + p.SetKey(attribute, false) + p.ComponentKey = attribute + p.DataIndex = attribute + p.Attribute = attribute + + return p +} + +/** + * 设置列的对齐方式,left | right | center + * + * @param string align + * @return p + */ +func (p *Column) SetAlign(align string) *Column { + p.Align = align + return p +} + +/** + * (IE 下无效)列是否固定,可选 true (等效于 left) left right + * + * @param bool|string fixed + * @return p + */ +func (p *Column) SetFixed(fixed interface{}) *Column { + p.Fixed = fixed + return p +} + +/** + * 会在 title 之后展示一个 icon,hover 之后提示一些信息 + * + * @param bool|string tooltip + * @return p + */ +func (p *Column) SetTooltip(tooltip string) *Column { + p.Tooltip = tooltip + return p +} + +/** + * 是否自动缩略 + * + * @param bool ellipsis + * @return p + */ +func (p *Column) SetEllipsis(ellipsis bool) *Column { + p.Ellipsis = ellipsis + return p +} + +/** + * 是否支持复制 + * + * @param bool copyable + * @return p + */ +func (p *Column) SetCopyable(copyable bool) *Column { + p.Copyable = copyable + return p +} + +/** + * 值的枚举,会自动转化把值当成 key 来取出要显示的内容 + * + * @param array valueEnum + * @return p + */ +func (p *Column) SetValueEnum(valueEnum interface{}) *Column { + valueEnumStr := map[string]interface{}{} + valueEnumInt := map[int]interface{}{} + + for k, v := range valueEnum.(map[interface{}]interface{}) { + if value, ok := k.(string); ok == true { + valueEnumStr[value] = v + } else if value, ok := k.(int); ok == true { + valueEnumInt[value] = v + } + } + + if len(valueEnumStr) > 0 { + p.ValueEnum = valueEnumStr + } + + if len(valueEnumInt) > 0 { + p.ValueEnum = valueEnumInt + } + + return p +} + +/** + * 值的类型,"money" | "option" | "date" | "dateTime" | "time" | "text"| "index" | "indexBorder" + * + * @param string valueType + * @return p + */ +func (p *Column) SetValueType(valueType string) *Column { + p.ValueType = valueType + return p +} + +/** + * 在查询表单中不展示此项 + * + * @param bool hideInSearch + * @return p + */ +func (p *Column) SetHideInSearch(hideInSearch bool) *Column { + p.HideInSearch = hideInSearch + return p +} + +/** + * 在 Table 中不展示此列 + * + * @param bool hideInTable + * @return p + */ +func (p *Column) SetHideInTable(hideInTable bool) *Column { + p.HideInTable = hideInTable + return p +} + +/** + * 表头的筛选菜单项,当值为 true 时,自动使用 valueEnum 生成 + * + * @param array|bool filters + * @return p + */ +func (p *Column) SetFilters(filters interface{}) *Column { + getFilters, ok := filters.(map[string]string) + + if ok { + tmpFilters := []map[string]string{} + for k, v := range getFilters { + tmpFilters = append(tmpFilters, map[string]string{ + "text": v, + "value": k, + }) + } + p.Filters = tmpFilters + } else { + p.Filters = filters + } + + return p +} + +/** + * 查询表单中的权重,权重大排序靠前 + * + * @param number order + * @return p + */ +func (p *Column) SetOrder(order int) *Column { + p.Order = order + return p +} + +/** + * 可排序列 + * + * @param bool sorter + * @return p + */ +func (p *Column) SetSorter(sorter bool) *Column { + p.Sorter = sorter + return p +} + +/** + * 设置列宽 + * + * @param string|number width + * @return p + */ +func (p *Column) SetWidth(width int) *Column { + p.Width = width + return p +} + +/** + * 设置为可编辑列 + * + * @param string name + * @param array|bool options + * @param string action + * @return p + */ +func (p *Column) SetEditable(name string, options interface{}, action string) *Column { + var getOptions interface{} + + if name == "select" { + for k, v := range options.([]interface{}) { + item := map[string]interface{}{ + "label": v, + "value": k, + } + getOptions = append(getOptions.([]map[string]interface{}), item) + } + } else { + getOptions = options + } + + p.Editable = map[string]interface{}{ + "name": name, + "options": getOptions, + "action": action, + } + + return p +} + +/** + * 设置为数据操作列 + * + * @param array actions + * @return p + */ +func (p *Column) SetActions(actions interface{}) *Column { + p.Actions = actions + + return p +} + +/** + * 传递给 Form.Item 的配置,可以配置 rules,但是默认的查询表单 rules 是不生效的。需要配置 ignoreRules + * + * @param formItemProps + * @return p + */ +func (p *Column) SetFormItemProps(formItemProps interface{}) *Column { + p.FormItemProps = formItemProps + return p +} + +// 组件json序列化 +func (p *Column) JsonSerialize() *Column { + p.Component = "column" + + return p +} diff --git a/pkg/component/admin/table/search.go b/pkg/component/admin/table/search.go new file mode 100644 index 0000000..9fcff0d --- /dev/null +++ b/pkg/component/admin/table/search.go @@ -0,0 +1,263 @@ +package table + +import "github.com/quarkcms/quark-go/pkg/component/admin/component" + +type Search struct { + component.Element + DateFormatter string `json:"dateFormatter"` + LabelAlign string `json:"labelAlign"` + Size string `json:"size"` + DefaultCollapsed bool `json:"defaultCollapsed"` + HideRequiredMark bool `json:"hideRequiredMark"` + DefaultColsNumber int `json:"defaultColsNumber"` + LabelWidth int `json:"labelWidth"` + Span int `json:"span"` + Split bool `json:"split"` + ShowSubmitButton bool `json:"showSubmitButton"` + ShowResetButton bool `json:"showResetButton"` + ShowExportButton bool `json:"showExportButton"` + ResetButton string `json:"resetButton"` + SubmitButton string `json:"submitButton"` + ExportButton string `json:"exportButton"` + ExportApi string `json:"exportApi"` + Items []interface{} `json:"items"` +} + +// 初始化 +func (p *Search) Init() *Search { + p.Component = "search" + p.DateFormatter = "string" + p.LabelAlign = "right" + p.Size = "default" + p.DefaultCollapsed = true + p.HideRequiredMark = true + p.DefaultColsNumber = 2 + p.LabelWidth = 98 + p.ShowSubmitButton = true + p.ShowResetButton = true + p.ResetButton = "重置" + p.SubmitButton = "查询" + p.ExportButton = "导出数据" + + p.SetKey(component.DEFAULT_KEY, component.DEFAULT_CRYPT) + + return p +} + +// Set style. +func (p *Search) SetStyle(style map[string]interface{}) *Search { + p.Style = style + + return p +} + +/** + * 自动格式数据,例如 moment 的表单,支持 string 和 number 两种模式 + * + * @param string dateFormatter + * @return p + */ +func (p *Search) SetDateFormatter(dateFormatter string) *Search { + p.DateFormatter = dateFormatter + + return p +} + +/** + * 默认状态下是否折叠超出的表单项 + * + * @param bool collapsed + * @return p + */ +func (p *Search) SetCollapsed(collapsed bool) *Search { + p.DefaultCollapsed = collapsed + + return p +} + +/** + * label 标签的文本对齐方式,left | right + * + * @param string labelAlign + * @return p + */ +func (p *Search) SetLabelAlign(labelAlign string) *Search { + p.LabelAlign = labelAlign + + return p +} + +/** + * 设置字段组件的尺寸(仅限 antd 组件),small | middle | large + * + * @param string size + * @return p + */ +func (p *Search) SetSize(size string) *Search { + p.Size = size + + return p +} + +/** + * 隐藏所有表单项的必选标记,默认隐藏 + * + * @param bool hideRequiredMark + * @return p + */ +func (p *Search) SetHideRequiredMark(hideRequiredMark bool) *Search { + p.HideRequiredMark = hideRequiredMark + + return p +} + +/** + * 自定义折叠状态下默认显示的表单控件数量,没有设置或小于 0,则显示一行控件 数量大于等于控件数量则隐藏展开按钮 + * + * @param number defaultColsNumber + * @return p + */ +func (p *Search) SetDefaultColsNumber(defaultColsNumber int) *Search { + p.DefaultColsNumber = defaultColsNumber + + return p +} + +/** + * label 宽度,number | 'auto' + * + * @param number|string labelWidth + * @return p + */ +func (p *Search) SetLabelWidth(labelWidth int) *Search { + p.LabelWidth = labelWidth + + return p +} + +/** + * 表单项宽度,number[0 - 24] + * + * @param number span + * @return p + */ +func (p *Search) SetSpan(span int) *Search { + p.Span = span + + return p +} + +/** + * 每一行是否有分割线 + * + * @param bool split + * @return p + */ +func (p *Search) SetSplit(split bool) *Search { + p.Split = split + + return p +} + +/** + * 是否显示提交按钮 + * + * @param bool showSubmitButton + * @return p + */ +func (p *Search) SetShowSubmitButton(showSubmitButton bool) *Search { + p.ShowSubmitButton = showSubmitButton + + return p +} + +/** + * 是否显示重置按钮 + * + * @param bool showResetButton + * @return p + */ +func (p *Search) SetShowResetButton(showResetButton bool) *Search { + p.ShowResetButton = showResetButton + + return p +} + +/** + * 是否显示导出按钮 + * + * @param bool showExportButton + * @return p + */ +func (p *Search) SetShowExportButton(showExportButton bool) *Search { + p.ShowExportButton = showExportButton + + return p +} + +/** + * 提交按钮文字 + * + * @param string submitButton + * @return p + */ +func (p *Search) SetSubmitButton(submitButton string) *Search { + p.SubmitButton = submitButton + + return p +} + +/** + * 重置按钮文字 + * + * @param string resetButton + * @return p + */ +func (p *Search) SetResetButton(resetButton string) *Search { + p.ResetButton = resetButton + + return p +} + +/** + * 导出按钮文字 + * + * @param string exportButton + * @return p + */ +func (p *Search) SetExportButton(exportButton string) *Search { + p.ExportButton = exportButton + + return p +} + +/** + * 导出数据接口 + * + * @param string exportApi + * @return p + */ +func (p *Search) SetExportApi(exportApi string) *Search { + p.ExportApi = exportApi + + return p +} + +/** + * 设置搜索表单项 + * + * @param string exportApi + * @return p + */ +func (p *Search) SetItems(item interface{}) *Search { + p.Items = append(p.Items, item) + + return p +} + +// 组件json序列化 +func (p *Search) JsonSerialize() *Search { + p.Component = "search" + + return p +} diff --git a/pkg/component/admin/table/search_item.go b/pkg/component/admin/table/search_item.go new file mode 100644 index 0000000..e3a1a3a --- /dev/null +++ b/pkg/component/admin/table/search_item.go @@ -0,0 +1,292 @@ +package table + +import "github.com/quarkcms/quark-go/pkg/component/admin/component" + +type SearchItem struct { + component.Element + Value interface{} `json:"value"` + DefaultValue interface{} `json:"defaultValue"` + Label string `json:"label"` + Name string `json:"name"` + Options interface{} `json:"options"` + Api string `json:"api"` + Rules interface{} `json:"rules"` + RuleMessages interface{} `json:"ruleMessages"` + Operator string `json:"operator"` + Placeholder interface{} `json:"placeholder"` + Load interface{} `json:"load"` +} + +// 初始化 +func (p *SearchItem) Init() *SearchItem { + p.Component = "input" + p.SetKey(component.DEFAULT_KEY, component.DEFAULT_CRYPT) + + return p +} + +// Set style. +func (p *SearchItem) SetStyle(style map[string]interface{}) *SearchItem { + p.Style = style + + return p +} + +/** + * label 标签的文本 + * + * @param string label + * @return p + */ +func (p *SearchItem) SetLabel(label string) *SearchItem { + p.Label = label + p.Placeholder = "请输入" + p.Label + + return p +} + +/** + * 字段名,支持数组 + * + * @param string name + * @return p + */ +func (p *SearchItem) SetName(name string) *SearchItem { + p.Name = name + + return p +} + +/** + * 校验规则,设置字段的校验逻辑 + * + * @param array|p rules + * @return p + */ +func (p *SearchItem) SetRules(rules interface{}, messages interface{}) *SearchItem { + p.Rules = rules + p.RuleMessages = messages + + return p +} + +/** + * 设置保存值。 + * + * @param array|string + * @return p + */ +func (p *SearchItem) SetValue(value interface{}) *SearchItem { + p.Value = value + + return p +} + +/** + * 设置默认值。 + * + * @param array|string + * @return p + */ +func (p *SearchItem) SetDefault(value interface{}) *SearchItem { + p.DefaultValue = value + + return p +} + +/** + * 操作符 + * + * @param string + * @return p + */ +func (p *SearchItem) SetOperator(operator string) *SearchItem { + p.Operator = operator + + if p.Operator == "between" { + p.Placeholder = []string{"开始" + p.Label, "结束" + p.Label} + } + + return p +} + +/** + * placeholder + * + * @param string placeholder + * @return object + */ +func (p *SearchItem) SetPlaceholder(placeholder interface{}) *SearchItem { + + p.Placeholder = placeholder + + return p +} + +/** + * 控件宽度 + * + * @param number|string value + * @return object + */ +func (p *SearchItem) SetWidth(value int) *SearchItem { + p.Style = map[string]interface{}{ + "width": value, + } + + return p +} + +/** + * 级联菜单接口 + * + * @param string api + * @return object + */ +func (p *SearchItem) SetApi(api string) *SearchItem { + p.Api = api + + return p +} + +/** + * 单向联动 + * + * @param string field + * @param string api + * @return p + */ +func (p *SearchItem) SetLoad(field string, api string) *SearchItem { + p.Load = map[string]string{ + "field": field, + "api": api, + } + + return p +} + +/** + * 输入框控件 + * + * @param string options + * @return object + */ +func (p *SearchItem) Input(options map[interface{}]interface{}) *SearchItem { + p.Component = "input" + + return p +} + +/** + * 下拉菜单控件 + * + * @param array options + * @return object + */ +func (p *SearchItem) Select(options map[interface{}]interface{}) *SearchItem { + p.Component = "select" + + var data []map[string]interface{} + + for k, v := range options { + option := map[string]interface{}{ + "label": v, + "value": k, + } + + data = append(data, option) + } + + p.Options = data + + if p.Operator == "between" { + p.Placeholder = []string{"开始" + p.Label, "结束" + p.Label} + } else { + p.Placeholder = "请选择" + p.Label + } + + return p +} + +/** + * 多选下拉菜单控件 + * + * @param array options + * @return object + */ +func (p *SearchItem) MultipleSelect(options map[interface{}]interface{}) *SearchItem { + p.Component = "multipleSelect" + + var data []map[string]interface{} + + for k, v := range options { + option := map[string]interface{}{ + "label": v, + "value": k, + } + + data = append(data, option) + } + + p.Options = data + p.Placeholder = "请选择" + p.Label + + return p +} + +/** + * 时间控件 + * + * @param string options + * @return object + */ +func (p *SearchItem) Datetime(options map[interface{}]interface{}) *SearchItem { + p.Component = "datetime" + + return p +} + +/** + * 日期控件 + * + * @param string options + * @return object + */ +func (p *SearchItem) Date(options map[interface{}]interface{}) *SearchItem { + p.Component = "date" + + return p +} + +/** + * 级联菜单 + * + * @param array options + * @return object + */ +func (p *SearchItem) Cascader(options map[interface{}]interface{}) *SearchItem { + p.Component = "cascader" + + var data []map[string]interface{} + + for k, v := range options { + option := map[string]interface{}{ + "label": v, + "value": k, + } + + data = append(data, option) + } + + p.Options = data + p.Placeholder = "请选择" + p.Label + + return p +} + +// 组件json序列化 +func (p *SearchItem) JsonSerialize() *SearchItem { + p.Component = "input" + + return p +} diff --git a/pkg/component/admin/table/table.go b/pkg/component/admin/table/table.go new file mode 100644 index 0000000..39bdb1c --- /dev/null +++ b/pkg/component/admin/table/table.go @@ -0,0 +1,312 @@ +package table + +import "github.com/quarkcms/quark-go/pkg/component/admin/component" + +type Component struct { + component.Element + RowKey string `json:"rowKey"` + Api string `json:"api"` + ApiType string `json:"apiType"` + TableLayout string `json:"tableLayout"` + HeaderTitle string `json:"headerTitle"` + Columns interface{} `json:"columns"` + RowSelection interface{} `json:"rowSelection"` + Options map[string]bool `json:"options"` + AutoBuildSearchFrom bool `json:"autoBuildSearchFrom"` + Search interface{} `json:"search"` + BatchActions interface{} `json:"batchActions"` + DateFormatter string `json:"dateFormatter"` + ColumnEmptyText string `json:"columnEmptyText"` + ToolBar interface{} `json:"toolBar"` + TableExtraRender interface{} `json:"tableExtraRender"` + Scroll interface{} `json:"scroll"` + Striped bool `json:"striped"` + Datasource interface{} `json:"datasource"` + Pagination interface{} `json:"pagination"` + Polling int `json:"polling"` +} + +// 初始化 +func (p *Component) Init() *Component { + p.Component = "table" + p.RowKey = "id" + p.Api = "" + p.ApiType = "GET" + p.ColumnEmptyText = "-" + p.DateFormatter = "string" + p.Options = map[string]bool{ + "fullScreen": true, "reload": true, "setting": true, + } + p.RowSelection = []interface{}{} + p.SetKey("table", false) + + return p +} + +// Set style. +func (p *Component) SetStyle(style map[string]interface{}) *Component { + p.Style = style + + return p +} + +// layout 的左上角 的 title +func (p *Component) SetRowKey(rowKey string) *Component { + p.RowKey = rowKey + return p +} + +/** + * 获取表格数据接口 + * + * @param string api + * @return p + */ +func (p *Component) SetApi(api string) *Component { + p.Api = api + + return p +} + +/** + * 获取表格数据接口类型 + * + * @param string apiType + * @return p + */ +func (p *Component) SetApiType(apiType string) *Component { + p.ApiType = apiType + + return p +} + +/** + * 表格元素的 table-layout 属性,设为 fixed 表示内容不会影响列的布局,- | auto | fixed + * + * @param string tableLayout + * @return p + */ +func (p *Component) SetTableLayout(tableLayout string) *Component { + p.TableLayout = tableLayout + + return p +} + +/** + * 表头标题 + * + * @param string title + * @return p + */ +func (p *Component) SetTitle(title string) *Component { + p.HeaderTitle = title + + return p +} + +/** + * 表头标题 + * + * @param string headerTitle + * @return p + */ +func (p *Component) SetHeaderTitle(headerTitle string) *Component { + p.HeaderTitle = headerTitle + + return p +} + +/** + * 是否显示搜索表单,传入对象时为搜索表单的配置 + * + * @param Closure callback + * @return p + */ +func (p *Component) SetSearch(callback interface{}) interface{} { + // callback(p.Search) + + return p.Search +} + +/** + * 搜索表单的配置 + * + * @param array search + * @return p + */ +func (p *Component) SetSearches(search interface{}) *Component { + p.Search = search + + return p +} + +/** + * 批量设置表格列 + * + * @param array columns + * @return p + */ +func (p *Component) SetColumns(columns interface{}) *Component { + p.Columns = columns + + return p +} + +/** + * 批量操作选择项 + * + * @param array rowSelection + * @return p + */ +func (p *Component) SetRowSelection(rowSelection interface{}) *Component { + p.RowSelection = rowSelection + + return p +} + +/** + * table 工具栏,设为 false 时不显示,{ fullScreen: true, reload: true ,setting: true} + * + * @param array|bool options + * @return p + */ +func (p *Component) SetOptions(options map[string]bool) *Component { + p.Options = options + + return p +} + +/** + * 转化 moment 格式数据为特定类型,false 不做转化,"string" | "number" | false + * + * @param string dateFormatter + * @return p + */ +func (p *Component) SetDateFormatter(dateFormatter string) *Component { + p.DateFormatter = dateFormatter + + return p +} + +/** + * 空值时的显示,不设置 则默认显示 - + * + * @param string columnEmptyText + * @return p + */ +func (p *Component) SetColumnEmptyText(columnEmptyText string) *Component { + p.ColumnEmptyText = columnEmptyText + + return p +} + +/** + * 透传 ProUtils 中的 ListToolBar 配置项 + * + * @param void + * @return p + */ +func (p *Component) SetToolBar(toolBar interface{}) *Component { + p.ToolBar = toolBar + + return p +} + +/** + * 表格的批量操作 + * + * @param array batchActions + * @return p + */ +func (p *Component) SetBatchActions(batchActions interface{}) *Component { + p.BatchActions = batchActions + + return p +} + +/** + * 自定义表格的主体函数 + * + * @param array tableExtraRender + * @return p + */ +func (p *Component) SetTableExtraRender(tableExtraRender interface{}) *Component { + p.TableExtraRender = tableExtraRender + + return p +} + +/** + * 设置表格滚动 + * + * @param array scroll + * @return p + */ +func (p *Component) scroll(scroll interface{}) *Component { + p.Scroll = scroll + + return p +} + +/** + * 设置表格滚动 + * + * @param bool striped + * @return p + */ +func (p *Component) striped(striped bool) *Component { + p.Striped = striped + + return p +} + +/** + * 表格数据 + * + * @param array|string datasource + * @return p + */ +func (p *Component) SetDatasource(datasource interface{}) *Component { + p.Datasource = datasource + + return p +} + +/** + * 表格分页 + * + * @param number current + * @param number pageSize + * @param number total + * @param number defaultCurrent + * @return p + */ +func (p *Component) SetPagination(current int, pageSize int, total int, defaultCurrent int) *Component { + p.Pagination = map[string]int{ + "current": current, + "pageSize": pageSize, + "total": total, + "defaultCurrent": defaultCurrent, + } + + return p +} + +/** + * 是否轮询 + * + * @param null|number polling + * @return p + */ +func (p *Component) SetPolling(polling int) *Component { + p.Polling = polling + + return p +} + +// 组件json序列化 +func (p *Component) JsonSerialize() *Component { + p.Component = "table" + + return p +} diff --git a/pkg/component/admin/table/tool_bar.go b/pkg/component/admin/table/tool_bar.go new file mode 100644 index 0000000..aa5fc32 --- /dev/null +++ b/pkg/component/admin/table/tool_bar.go @@ -0,0 +1,147 @@ +package table + +import "github.com/quarkcms/quark-go/pkg/component/admin/component" + +type ToolBar struct { + component.Element + Title string `json:"title"` + SubTitle string `json:"subTitle"` + Description string `json:"description"` + Search interface{} `json:"search"` + Actions interface{} `json:"actions"` + Filter interface{} `json:"filter"` + MultipleLine bool `json:"multipleLine"` + Menu interface{} `json:"menu"` + Tabs interface{} `json:"tabs"` +} + +// 初始化 +func (p *ToolBar) Init() *ToolBar { + p.Component = "toolBar" + + p.SetKey("toolBar", component.DEFAULT_CRYPT) + + return p +} + +// Set style. +func (p *ToolBar) SetStyle(style map[string]interface{}) *ToolBar { + p.Style = style + + return p +} + +// 标题 +func (p *ToolBar) SetTitle(title string) *ToolBar { + p.Title = title + return p +} + +// 子标题 +func (p *ToolBar) SetSubTitle(subTitle string) *ToolBar { + p.SubTitle = subTitle + return p +} + +/** + * 描述 + * + * @param string description + * @return p + */ +func (p *ToolBar) SetDescription(description string) *ToolBar { + p.Description = description + + return p +} + +/** + * 查询区 + * + * @param array search + * @return p + */ +func (p *ToolBar) SetSearch(search interface{}) *ToolBar { + p.Search = search + + return p +} + +/** + * 操作区 + * + * @param Closure callback + * @return p + */ +func (p *ToolBar) SetAction(callback interface{}) *ToolBar { + // p.actions = callback(p.action); + + return p +} + +/** + * 批量设置操作区 + * + * @param array actions + * @return p + */ +func (p *ToolBar) SetActions(actions interface{}) *ToolBar { + p.Actions = actions + + return p +} + +/** + * 过滤区,通常配合 LightFilter 使用 + * + * @param array filter + * @return p + */ +func (p *ToolBar) filter(filter interface{}) *ToolBar { + p.Filter = filter + + return p +} + +/** + * 是否多行展示 + * + * @param array multipleLine + * @return p + */ +func (p *ToolBar) multipleLine(multipleLine bool) *ToolBar { + p.MultipleLine = multipleLine + + return p +} + +/** + * 菜单配置 + * + * @param array menu + * @return p + */ +func (p *ToolBar) menu(menu interface{}) *ToolBar { + p.Menu = menu + + return p +} + +/** + * 标签页配置,仅当 multipleLine 为 true 时有效 + * + * @param array tabs + * @return p + */ +func (p *ToolBar) tabs(tabs interface{}) *ToolBar { + p.Tabs = tabs + + return p +} + +// 组件json序列化 +func (p *ToolBar) JsonSerialize() *ToolBar { + p.Component = "toolBar" + + return p +} diff --git a/pkg/component/admin/tabs/tab_pane.go b/pkg/component/admin/tabs/tab_pane.go new file mode 100644 index 0000000..6d6a973 --- /dev/null +++ b/pkg/component/admin/tabs/tab_pane.go @@ -0,0 +1,38 @@ +package tabs + +import "github.com/quarkcms/quark-go/pkg/component/admin/component" + +type TabPane struct { + component.Element + Title string `json:"title"` + Body interface{} `json:"body"` +} + +// 初始化 +func (p *TabPane) Init() *TabPane { + p.Component = "tabPane" + p.SetKey(component.DEFAULT_KEY, component.DEFAULT_CRYPT) + + return p +} + +// Set style. +func (p *TabPane) SetStyle(style map[string]interface{}) *TabPane { + p.Style = style + + return p +} + +// 标签标题 +func (p *TabPane) SetTitle(title string) *TabPane { + p.Title = title + + return p +} + +// 内容 +func (p *TabPane) SetBody(body interface{}) *TabPane { + p.Body = body + + return p +} diff --git a/pkg/component/admin/tabs/tabs.go b/pkg/component/admin/tabs/tabs.go new file mode 100644 index 0000000..55ff3c2 --- /dev/null +++ b/pkg/component/admin/tabs/tabs.go @@ -0,0 +1,98 @@ +package tabs + +import "github.com/quarkcms/quark-go/pkg/component/admin/component" + +type Component struct { + component.Element + Centered bool `json:"centered"` + DefaultActiveKey string `json:"defaultActiveKey"` + Size string `json:"size"` + TabBarExtraContent interface{} `json:"tabBarExtraContent"` + TabBarGutter int `json:"tabBarGutter"` + TabBarStyle interface{} `json:"tabBarStyle"` + TabPosition string `json:"tabPosition"` + Type string `json:"type"` + TabPanes interface{} `json:"tabPanes"` +} + +// 初始化 +func (p *Component) Init() *Component { + p.Component = "tabs" + p.Size = "default" + p.TabPosition = "top" + p.Type = "line" + p.TabBarGutter = 35 + p.SetKey(component.DEFAULT_KEY, component.DEFAULT_CRYPT) + + return p +} + +// Set style. +func (p *Component) SetStyle(style map[string]interface{}) *Component { + p.Style = style + + return p +} + +// 标签居中展示 +func (p *Component) SetCentered(centered bool) *Component { + p.Centered = centered + + return p +} + +// 初始化选中面板的 key,如果没有设置 activeKey +func (p *Component) SetDefaultActiveKey(defaultActiveKey string) *Component { + p.DefaultActiveKey = defaultActiveKey + + return p +} + +// 大小,提供 large default 和 small 三种大小 +func (p *Component) SetSize(size string) *Component { + p.Size = size + + return p +} + +// tab bar 上额外的元素 +func (p *Component) SetTabBarExtraContent(tabBarExtraContent interface{}) *Component { + p.TabBarExtraContent = tabBarExtraContent + + return p +} + +// tabs 之间的间隙 +func (p *Component) SetTabBarGutter(tabBarGutter int) *Component { + p.TabBarGutter = tabBarGutter + + return p +} + +// tab bar 的样式对象 +func (p *Component) SetTabBarStyle(style map[string]interface{}) *Component { + p.TabBarStyle = style + + return p +} + +// 页签位置,可选值有 top right bottom left +func (p *Component) SetTabPosition(tabPosition string) *Component { + p.TabPosition = tabPosition + + return p +} + +// 页签的基本样式,可选 line、card editable-card 类型 +func (p *Component) SetType(tabType string) *Component { + p.Type = tabType + + return p +} + +// tab 的内容 +func (p *Component) SetTabPanes(tabPanes interface{}) *Component { + p.TabPanes = tabPanes + + return p +} diff --git a/pkg/component/admin/tpl/tpl.go b/pkg/component/admin/tpl/tpl.go new file mode 100644 index 0000000..2910afd --- /dev/null +++ b/pkg/component/admin/tpl/tpl.go @@ -0,0 +1,30 @@ +package tpl + +import "github.com/quarkcms/quark-go/pkg/component/admin/component" + +type Component struct { + component.Element + Body interface{} `json:"body"` +} + +// 初始化 +func (p *Component) Init() *Component { + p.Component = "tpl" + p.SetKey(component.DEFAULT_KEY, component.DEFAULT_CRYPT) + + return p +} + +// Set style. +func (p *Component) SetStyle(style map[string]interface{}) *Component { + p.Style = style + + return p +} + +// 容器控件里面的内容 +func (p *Component) SetBody(body interface{}) *Component { + p.Body = body + + return p +} diff --git a/pkg/component/admin/view/view.go b/pkg/component/admin/view/view.go new file mode 100644 index 0000000..e35e60b --- /dev/null +++ b/pkg/component/admin/view/view.go @@ -0,0 +1,30 @@ +package view + +import "github.com/quarkcms/quark-go/pkg/component/admin/component" + +type Component struct { + component.Element + Body interface{} `json:"body"` +} + +// 初始化 +func (p *Component) Init() *Component { + p.Component = "view" + p.SetKey(component.DEFAULT_KEY, component.DEFAULT_CRYPT) + + return p +} + +// Set style. +func (p *Component) SetStyle(style map[string]interface{}) *Component { + p.Style = style + + return p +} + +// 容器控件里面的内容 +func (p *Component) SetBody(body interface{}) *Component { + p.Body = body + + return p +} diff --git a/pkg/component/mix/.keep b/pkg/component/mix/.keep new file mode 100644 index 0000000..e69de29 diff --git a/pkg/dal/db/init.go b/pkg/dal/db/init.go new file mode 100644 index 0000000..6cd7924 --- /dev/null +++ b/pkg/dal/db/init.go @@ -0,0 +1,16 @@ +package db + +import ( + "gorm.io/gorm" +) + +var Client *gorm.DB + +// Init init DB +func Init(dialector gorm.Dialector, opts gorm.Option) { + var err error + Client, err = gorm.Open(dialector, opts) + if err != nil { + panic(err) + } +} diff --git a/pkg/dal/init.go b/pkg/dal/init.go new file mode 100644 index 0000000..a80902d --- /dev/null +++ b/pkg/dal/init.go @@ -0,0 +1,17 @@ +package dal + +import ( + "github.com/quarkcms/quark-go/pkg/dal/db" + "github.com/quarkcms/quark-go/pkg/dal/redis" + "gorm.io/gorm" +) + +// Init init DB +func InitDB(dialector gorm.Dialector, opts gorm.Option) { + db.Init(dialector, opts) +} + +// Init init redis +func InitRedis(addr string, password string) { + redis.Init(addr, password) +} diff --git a/pkg/dal/redis/init.go b/pkg/dal/redis/init.go new file mode 100644 index 0000000..0deb20b --- /dev/null +++ b/pkg/dal/redis/init.go @@ -0,0 +1,19 @@ +package redis + +import ( + "context" + + "github.com/go-redis/redis/v8" +) + +var Client *redis.Client + +func Init(addr string, password string) { + Client = redis.NewClient(&redis.Options{ + Addr: addr, + Password: password, + }) + if err := Client.Ping(context.Background()).Err(); err != nil { + panic(err) + } +} diff --git a/pkg/github/github.go b/pkg/github/github.go new file mode 100644 index 0000000..3e2e8c8 --- /dev/null +++ b/pkg/github/github.go @@ -0,0 +1,142 @@ +package github + +import ( + "bytes" + "fmt" + "io" + "io/ioutil" + "net/http" + "os" + "path/filepath" + "regexp" + "strings" + "sync" + "time" +) + +const GITHUB = "https://github.com" +const CONTENT = "https://raw.githubusercontent.com" + +var urlPattern = regexp.MustCompile(``) +var repositoryPattern = regexp.MustCompile(`(/.*?/.*?/)blob/(.*$)`) + +func Download(respositoryURL string, path string) { + if respositoryURL == "" { + fmt.Println("please specify the github url!") + return + } + if path == "" { + path = getPath(respositoryURL) + } + if isExist(path + "/install.lock") { + // 锁定文件存在,则不再下载 + return + } + var client http.Client + var wg sync.WaitGroup + start := time.Now() + fmt.Println("start to download static files, please waiting...") + handle(client, respositoryURL, path, &wg) + wg.Wait() + + // 创建锁定文件 + file, _ := os.Create(path + "/install.lock") + file.Close() + + // 打印用时 + fmt.Printf("total time: %.2f s\n", float64(time.Since(start))/float64(time.Second)) +} + +// get all file link and download it +func handle(client http.Client, url, path string, wg *sync.WaitGroup) { + // if the path is not existed, then create it + if !isExist(path) { + os.MkdirAll(path, 0775) + } + // get html source + html, err := getHtml(client, url) + if err != nil { + panic(err) + } + // find all file and directory link + links := urlPattern.FindAllSubmatch(html, -1) + for _, link := range links { + // if is directory, we can do it recursively + if isDir(link[2]) { + handle(client, GITHUB+string(link[2]), filepath.Join(path, getPath(string(link[2]))), wg) + } else { + // download it if it is file + rep := repositoryPattern.FindSubmatch(link[2]) + // rep[1] is the repositoryPattern path + // rep[2] is the file path in the repositoryPattern + wg.Add(1) + go getFile(client, CONTENT+string(rep[1])+string(rep[2]), path, string(link[1]), wg) + } + } +} + +// download file +func getFile(client http.Client, fileURL, path, filename string, wg *sync.WaitGroup) { + defer wg.Done() + + resp, err := client.Get(fileURL) + if err != nil { + panic(err) + } + defer resp.Body.Close() + var buff [1024]byte + // 创建文件 + file, err := os.Create(filepath.Join(path, filename)) + if err != nil { + panic(err) + } + defer file.Close() + // 写入文件 + for { + n, err := resp.Body.Read(buff[:]) + if err != nil { + if err == io.EOF { + file.Write(buff[:n]) + break + } + // if failed delete this file + os.Remove(filepath.Join(path, filename)) + panic(err) + } + file.Write(buff[:n]) + } +} + +// get html source +func getHtml(client http.Client, url string) ([]byte, error) { + resp, err := client.Get(url) + if err != nil { + return nil, err + } + defer resp.Body.Close() + data, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + return data, nil +} + +// if is a directory +func isDir(link []byte) bool { + return bytes.Contains(link, []byte("tree")) +} + +// if file or directory exits +func isExist(path string) bool { + _, err := os.Stat(path) + if os.IsNotExist(err) { + return false + } + return true +} + +func getPath(responsitoryUrl string) string { + tmp := strings.TrimRight(responsitoryUrl, "/") + i := strings.LastIndex(tmp, "/") + return tmp[i+1:] +} diff --git a/pkg/hash/hash.go b/pkg/hash/hash.go new file mode 100644 index 0000000..a0bd8d1 --- /dev/null +++ b/pkg/hash/hash.go @@ -0,0 +1,30 @@ +package hash + +import ( + "fmt" + + "golang.org/x/crypto/bcrypt" +) + +// 哈希加密 +func Make(password string) string { + + bytePassword := []byte(password) + + hash, err := bcrypt.GenerateFromPassword(bytePassword, bcrypt.MinCost) + if err != nil { + fmt.Println(err) + } + + return string(hash) +} + +// 哈希验证 +func Check(hashedPassword string, password string) bool { + byteHashedPassword := []byte(hashedPassword) + bytePassword := []byte(password) + + err := bcrypt.CompareHashAndPassword(byteHashedPassword, bytePassword) + + return err == nil +} diff --git a/pkg/lister/lister.go b/pkg/lister/lister.go new file mode 100644 index 0000000..cd95f8d --- /dev/null +++ b/pkg/lister/lister.go @@ -0,0 +1,60 @@ +package lister + +import ( + "encoding/json" + "errors" + "strings" +) + +// 数据集转换成Tree +func ListToTree(list interface{}, pk string, pid string, child string, root int) (treeList []interface{}, Error error) { + result := []map[string]interface{}{} + jsonBytes, err := json.Marshal(list) + if err != nil { + return treeList, err + } + err = json.Unmarshal(jsonBytes, &result) + if err != nil { + return treeList, err + } + + for _, v := range result { + if int(v[pid].(float64)) == root { + childNode, err := ListToTree(list, pk, pid, child, int(v[pk].(float64))) + if err != nil { + return treeList, err + } + if childNode != nil { + v[child] = childNode + } + treeList = append(treeList, v) + } + } + + return treeList, nil +} + +// Tree转换为有序列表 +func TreeToOrderedList(tree []interface{}, level int, field string, child string) (list []interface{}, Error error) { + for _, v := range tree { + if value, ok := v.(map[string]interface{}); ok { + value[field] = strings.Repeat("—", level) + value[field].(string) + list = append(list, value) + if value[child] != nil { + if childValue, ok := value[child].([]interface{}); ok { + children, err := TreeToOrderedList(childValue, level+1, field, child) + if err != nil { + return list, err + } + list = append(list, children...) + } else { + return list, errors.New("格式错误") + } + } + } else { + return list, errors.New("格式错误") + } + } + + return list, nil +} diff --git a/pkg/msg/msg.go b/pkg/msg/msg.go new file mode 100644 index 0000000..473ef96 --- /dev/null +++ b/pkg/msg/msg.go @@ -0,0 +1,28 @@ +package msg + +const DEFAULT_MSG string = "" +const DEFAULT_URL string = "" +const DEFAULT_DATA string = "" + +// 返回错误信息 +func Error(msg string, url string) map[string]interface{} { + + return map[string]interface{}{ + "component": "message", + "status": "error", + "msg": msg, + "url": url, + } +} + +// 返回正确信息 +func Success(msg string, url string, data interface{}) map[string]interface{} { + + return map[string]interface{}{ + "component": "message", + "status": "success", + "msg": msg, + "url": url, + "data": data, + } +} diff --git a/pkg/rand/rand.go b/pkg/rand/rand.go new file mode 100644 index 0000000..8736213 --- /dev/null +++ b/pkg/rand/rand.go @@ -0,0 +1,59 @@ +package rand + +import ( + "math/rand" + "strings" + "time" +) + +// 生成随机字符串 +func Make(strtype string, length int) string { + var result string + switch strtype { + case "numeric": + result = MakeNumeric(length) + case "letter": + result = MakeLetter(length) + case "alphanumeric": + result = MakeAlphanumeric(length) + default: + result = MakeAlphanumeric(length) + } + + return result +} + +// 生成字母类型字符串 +func MakeLetter(length int) string { + seed := "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" + return makeRand(seed, length) +} + +// 生成数字类型字符串 +func MakeNumeric(length int) string { + seed := "1234567890" + return makeRand(seed, length) +} + +// 生成数字类型字符串 +func MakeAlphanumeric(length int) string { + seed := "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890" + return makeRand(seed, length) +} + +// 随机函数 +func makeRand(seed string, length int) string { + if length < 1 { + return "" + } + charArr := strings.Split(seed, "") + charlen := len(charArr) + ran := rand.New(rand.NewSource(time.Now().Unix())) + + var rchar string = "" + for i := 1; i <= length; i++ { + rchar = rchar + charArr[ran.Intn(charlen)] + } + + return rchar +} diff --git a/scripts/README.md b/scripts/README.md new file mode 100644 index 0000000..edb724e --- /dev/null +++ b/scripts/README.md @@ -0,0 +1,11 @@ +# `/scripts` + +Scripts to perform various build, install, analysis, etc operations. + +These scripts keep the root level Makefile small and simple. + +Examples: + +* https://github.com/kubernetes/helm/tree/master/scripts +* https://github.com/cockroachdb/cockroach/tree/master/scripts +* https://github.com/hashicorp/terraform/tree/master/scripts \ No newline at end of file diff --git a/scripts/start_service.sh b/scripts/start_service.sh new file mode 100644 index 0000000..37ca4aa --- /dev/null +++ b/scripts/start_service.sh @@ -0,0 +1,44 @@ +#!/bin/sh +PROJECT_PATH=./ +PROJECT_NAME=main +PROJECT_LOG_NAME=storage/logs/app.log + +# 判断logs文件夹下是否有日志文件,没有则创建,用于记录日志 +if [ ! -f $PROJECT_PATH$PROJECT_LOG_NAME ]; then + touch $PROJECT_PATH$PROJECT_LOG_NAME +fi + +# stop process +tpid=`ps -ef|grep $PROJECT_PATH$PROJECT_NAME|grep -v grep|grep -v kill|awk '{print $2}'` +if [[ ${tpid} ]]; then + echo 'Stop Process...' + # 是先关闭和其有关的程序,再将其关闭 + kill -15 $tpid +fi + +sleep 5 + +tpid=`ps -ef|grep $PROJECT_PATH$PROJECT_NAME|grep -v grep|grep -v kill|awk '{print $2}'` +if [[ ${tpid} ]]; then + echo 'Kill Process!' + kill -9 $tpid +else + echo 'Stop Success!' +fi + +# start process +tpid=`ps -ef|grep $PROJECT_PATH$PROJECT_NAME|grep -v grep|grep -v kill|awk '{print $2}'` +if [[ ${tpid} ]]; then + echo 'App is already running.' +else + echo 'App is NOT running.' + + nohup $PROJECT_PATH$PROJECT_NAME >$PROJECT_PATH$PROJECT_LOG_NAME 2>&1 & + + echo Start Success! + + if [ $1 ]; then + sleep 2 + tail -f $PROJECT_PATH$PROJECT_LOG_NAME + fi +fi diff --git a/scripts/stop_service.sh b/scripts/stop_service.sh new file mode 100644 index 0000000..4a51355 --- /dev/null +++ b/scripts/stop_service.sh @@ -0,0 +1,21 @@ +#!/bin/sh +PROJECT_PATH=./ +PROJECT_NAME=main + +# stop process +tpid=`ps -ef|grep $PROJECT_PATH$PROJECT_NAME|grep -v grep|grep -v kill|awk '{print $2}'` +if [[ ${tpid} ]]; then + echo 'Stop Process...' + # 是先关闭和其有关的程序,再将其关闭 + kill -15 $tpid +fi + +sleep 5 + +tpid=`ps -ef|grep $PROJECT_PATH$PROJECT_NAME|grep -v grep|grep -v kill|awk '{print $2}'` +if [[ ${tpid} ]]; then + echo 'Kill Process!' + kill -9 $tpid +else + echo 'Stop Success!' +fi \ No newline at end of file diff --git a/website/admin/apps/app.html b/website/admin/apps/app.html new file mode 100644 index 0000000..bf53267 --- /dev/null +++ b/website/admin/apps/app.html @@ -0,0 +1,9 @@ + + + + 这是APP1 + + + 这是微前端测试页,我是APP1! + + diff --git a/website/admin/config.json b/website/admin/config.json new file mode 100644 index 0000000..9ea86dc --- /dev/null +++ b/website/admin/config.json @@ -0,0 +1,9 @@ +{ + "api": "/api/admin/login/index/index", + "apps": [ + { + "name": "app", + "entry": "/apps/app.html" + } + ] +} diff --git a/website/admin/default.png b/website/admin/default.png new file mode 100644 index 0000000000000000000000000000000000000000..a4798123a69910666afce14595742ab9b2eb2ee0 GIT binary patch literal 6230 zcmb_>`8(8a)IVb^qi7iWQZtM}`Pj21jO-0+>`SsUb}Czlw>{g$#2~VlHA_f#P1(kh zecwV^6NyN^({p{V>-h(sAKu$J_j%ptKIdM}>w3rEG0I$ux7GJ00raXe=Ai8$R`J`K3Uf%l>GqZsUU2MR63{*m6R3wiO z3@Va5m(}02c0UWQw`|S%lsHNTAgOfScN=PL-ni>ilU~udl0}c&0pL!#Dm^tu1PNAo9l!E*>a(us%l|U^ zKTP?T+<6J9Ei6Ai+?sq@Ola2?y2ANVzeye%9?^2@=HqA!AY>vVn?Gf-O! z&b}!tyFXPf1co8AkI0`nk*|9klumaJdQx(!_E#Gp<=K;_32YY zShthK?xoK^h$j?<>vhn4?X)wzc<#Pq&`FRi6}W_}Vzkn;Jh zXtOFrp0-0qRV4cNwbg&?vO57t%R!cRPFtBFso1c&+1b-64#Q#s$P*NiIJM|O!<7j) zXTgcc3p7?_u>IPj1U}cTa*?G(#Y!dtqK;=3Q4(m}j-NQW<9_yxht;0kagHr%GZzbc z;SePO10#e4{rc(Bx^htCp0C4_mh9yFC@(r6*dv?5pLwx=s6oyWc1Z zV!!+kFosR@F5f!ip`Yv^WHFtmfc2v>?_`#?I-wq& zx!PHp7Q}wXbF8g&s9MdJMfJLby&QJ5)=D}*fsM%$>^C$`cKfY|`5zFk!K^jKJX+ZxPCWu_2t9^_Tj+^#5FRc$FJ`$SceMzQXfF4H^EsP9`^z@((2A%O9Kd)(P zEZbtC)LU1p2tYR5`7PJ|lv=U-u)gn@&qd(;7z6DB*#w#vokXCFezn|Cu1o$pdg*HB z3weT!D4>yRD!OW!SE_Z464dF?74si=4k$~aMY$+$)~gwXUbU+LBlwprVv`l?%?yJ0 z?#*KRVl}ic6z!rO*Xp~6R@MI{?3Wcn@o6kzB{RJZJlg!x!mW#JYap89v1wBX0G<6SvF)-s|W=`w+0H zilgs~PxyJ5^fufXY@3Ew87{8q8T?ZjZI>8`KA&|+4~cH-6amxq+GF&fb(cD0F!ZN` z`dt0@@A^Dg%eiG6_jM^17G-}Dbuvi9TIhe9_^i-jX*#av& z9)D~PLR6oErJOl_Zqp#26pizF*YC2s^sc@IQ@HG!j+!2adV&g>o zO*S1`#7-CyG@t{3aj)jn%5jNY+-PMc06HMH|6eEukHdH6e&mAyt=C^{FFFH~=o58# z6KDBlg|!KvvgQoPNJik#$)Ro8IH|fjDRp-Y$1~w)5U=|;2cE;tWfBO-L*R|u9;aI_ zRbX^`gtqP<7vQJxyU;_~+rS;Hyy&hCO6R`)?0wZbWZZPD?E{VBNporR32d${IO{*O zNJO-gML~;O6U2UzPPBNg)@R4r%}DTzz3Gnh~Z14*NITbz=CuY7A`={&1x)QQFuW>uRu>9 zPvtk|ely`!535gJT|7meDhMc=80tgye)@j6`qIp#e&{q+fpH)Ut|8N(t?@h+&bIF# zN2RzVZSbPREE@t0fqur6zC!90{dz5Q7{dJhaII)<8=~IJ@=3PFe3m`IE0t-Wu(;-v}%iEWoD3L-wBld43x24aSXF9e2GJO2|Wqw+yh=b8zQ+ z+*{N?cQ0PUCRkHWMO)5Gj7csmUG8%MCcyz#GH9`!#Orl4sjsmxQdCxl&8k`1h9qe+ zUFlQFejL5o<42{^XfGJ}x!?#Yq!a?WB~!wYctJn)o)A6x=-an%5JL4pQu>Y|trrF`jYU;`dtjI(C5^zSJ^evB)it)Bn`S{q!ZWap&!29EbrRvS%OAY@nk@(T^*(@c zYAYKIo`mYO&GY0{gkFLctHho(lU3+7^9Z20ryFx5oS3a@>-d0e_ zX_E{n7RMi(1QSX3n_4v*)U;4K7rsp?h@5VH1aGAKYH;aF>iXeWP&)mo(2xVGC(5uQ zt2P!pWG9$K-4TMe10IS&M#wX$yHe6HvBc;vzhsRFpe$_`Xy#b z&E?suWfWvYA8MSe6IwP1Zn}W#G)@xgE(zPDbQ~rJKR;}2192;q3^QLE?)u|zSPY?Kq4g*4a z6&8}ytpO$FTXT2@yh@1@<&AN7EsKlT&eNV|K{6wT+nsWhDiL z@TgZyS72aje)N<9wCT(A5j#j?t5`SyZN=u{h!wwHL zpaVj}aW$vQT{K4p*GWD~33+dI^K?0H$UQvcqNEw!h3R4WQBNem*AHhW+YAK%E|lss zoYuu5G|ZToDLH~x8#+1*A>tk!YZEnnKHr!r`YxHe^z7V9N(BE5qONxH*%Q?)IDhPu zsA(|!yjxm+mkywH=3NY@fFt0!-x9br@z362JBuP2Xtrl}z=Q*KCWxaW0G*`C6dW0M zlSKQI7K8<6ynWr^g0QG}DpSUD$ z+MfM3lwVS|3ecb`*CfJq)aLD3oGEoA^k8f}YatM4?htWP1QfQVuY};G-A>y=@%-_e%!N3Mi(Q5aAF`O7BqeGg*qoJE#uuf)TMa1OK~2 z2ikks@cnK`fulxru59Yl2he$q(c2iT>$uYSDK#lJ7cR zvwWLx0m)JXS_!1NzbbCHrOtWv@Sj|UdfWb4@EGJ?^5O*q=}0tUxj`$k1D;iwdo~CI zqd=TWI-*x@i#~3=t1YMn zFB@r5yGukJ!#0gg9@Sb_E@6|=VTD3*XHShyOxlYk1e{sg-jr=pTmQ0^9si0pjTkP) zZnEbGjuc?~>el==TBR17Ze;$!KYQ>1)fCpJo01COqrLic#arg?NRCbwRc5xqQo`Hc zxXR`BY%kT{#_4MgoYr66iL9qp4VLZi^+e|<;XEg3$Tb*pnQ?k^jMY9+xFGD>in(6U z?v`JZwF)2|0eXmtQV{Ro&z~JqlkaV0v|suYvS)Wb2<{YkUS?gE@VdWt&h^&q@WCjk z&ns4Ze?vq{dD#qfcWJ4^9h*di+t^({eRsdVHsng34M)j>$^cJ?Q&_!dT$w{kioV!| zB=5zxv%MkJa}WKz0uidYbD}`|WY@OUlI2w8M@(&vyy1TxTiR1sh~Dj4UAzNPm9Dtq zFAYhersmX><>lq=QPA+6|Iee3+*V3z>`yDUYU4HU`8o!D?XO|q3%wMh;^?M`X9qZ6kEyl=yP5ra<(?Qv!pkj*+_Me` zPrdrN{8+EqpXRZ`Cgt_R#UIzI6jR%oG*N4I|*JbSYiMjO8K@(fgV+PK3xq-d@D z9GfbxV&E&X7Sj4yC~jJ!liF(M)2^&Gf8ti?l|SFDP~0$N{agCCoEvR(AwO6HNq6KL zTrRym3x1y^NtJ%XWG3oStBoqXQD0SFy^3|E=}^d7)#O$Hwr_^Tx7J+j@(k~Z4uF68 zWy11<=h;2b>2cc;q7=xgs&%E>P%Gf5bDVAPKBq{SS{4B8yu2XY8bO*gG-wC8Ei4f$}D zSapUhCU6j?EEA4WC@tHp@pPU-MjUX7uGO`+wvKLXZJAkac~a#~oOqh4*&@*@CMJ*i ze_qIJd@~rZ7#hGAJUBZ3YYCOkzh!JPehJ%$>Wuj~=b>Coc*(m``WKH48?%he<|03x zpzVetJ8eES<`UW$XTHfpt|d0=tMM!l=mWf4<5kPcHcKT6;HmIles;D!`+jBvJX=1W ztqZTc=eC#VT9{SbAsb{w2>givgihwDVGtyD@_IUi^>$s{$$w#|FxV}V#*6;@{%OqF z8`;^}J9I4~jK=~KZRZAtY%y@H*Xm@@aM+d%cm2!x0KRLy2U=+A zV3D$6?9Mb8{iQ%8dES*4^D>#+{bgh|9mF!os5JTGCidXoV<_wanDVQ@3x z|Ju^Y^z(LbZ8E#53nr%yTsy{{sZU!II`L>HMI96(<1)fFnN#%fI-;(Id+2S-2v=g74E0+GvZm0L2X*-_IE6T}p6i1Ik8Y?MPTU)<8& zZ-ndTJvQ1vR{35R4Bj6=vaH5@G#IIZZTfcir_GYO!nn5mJ|V#c9)BZlO;pY5fnmjddg5as3I7z&b$LnO(cW`E-JqU3|^#7@)Id%`qqBvumBej?M+rB3Es%6ggihT)y} zgHvwmdrcChpa=Cy-fpZS&5L-=UB>YaM)%RVoB>5Xy7!kWtumZsw`Y~~QQdYd{Q6LU zU-MYXDHF~`h=Q({Uld>2DS@S7d24(8SIj=pav(Fxy@Q!?@Xy-@gQ_tEui?_~AC`GD zK3h8;u#JirUxa}p(tD5SI;T@OcS7)JL)$&`ZHCnL#1>)&1M>cBa&uxTXQcl{2P%;wK|CW^$!h&d=zb-!rfAQjE zAsWjFVia8{9w1~Dq;+dSzjiTj`F|}{cB&-8`CTo5JNMP~I~&S9b_Q@lI=8YmotHTi zJ{n<+D`uN&4wl8}*K|QJ+I@ND(+K@cjWinma1=bvTt&K$C*V{daJ5+f~+PcUr7lfLXW6XO2lCa?~&P#T5ze6ZME&>TJ;Wv zsZ!Y7&%bAX%P2VH;c<+|N u`N(6s!6z=@6SZ*22z}pN_n^R@YVKX}9<6>KDCK_vm9D0NMwPlP@c#fNrf}u} literal 0 HcmV?d00001 diff --git a/website/admin/favicon.ico b/website/admin/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..f1635bed467f2db7456f9132b42db6c717bd1e16 GIT binary patch literal 4286 zcmb`LS!`8B7{{kux`4E{3Mk9Hr7j2}`rryi4dR1KB)%YtK`fF`ji3?nfy7kNwo(Ox z7U99BMiNDAdy5f^1;iF?aY2P>P!TR|RNw(yG!da@{Qc*gxxKxXqy;be^_%m}e9O#y zGv@?j()bsR8vQlz78ocnRY0I;d|59tS^EenS=@kHZ|h^%7&7#!G(>bU_)oafA0fxRIgXamf8p zV;duxJ{B?!v=-mP1Q?vtL5`BYkj2POn4)L@3;T+Z2Vj|dZtUy#;|3$`dzYL45X8R# zzn?-ab5B@;iu)mx$6 zRATJ*5wh3WyBn16U!ZgOGkgZ}(+I8bD|`*Ng3H0lSR@zuA$$T;S>HVJ%Y-bRhlBRE z1>|!#XdT+&8CU{}Bc1wGgS(&vhJ|&i{Zfo;L3uQTJF7_LKN^03Mee!guEg59=U8L} z@^h%bpZv^&-@t|_b}4;1$Y)_cTm*f7f^(`^Pk`p3z1Fkv{#V#0txJ+!&_97OaZrA$ zgMA<$RZtPO6;pks&a`ZBb~mCs0f#|zT?>=gpEQTs z!JT*v`4jvO(;?N5)Rx$V530STc5|X8rPn^a0KK5|cPC`p2JEyK zqTcz?eKZqVL1UMLY=b!lav{&k@iwPVoB=l`9bF}Kfy*5^7IY5JfcAR|_?#Z2y*;E1 zsk%_#WY9chQwQ=P{Wb6-tR?3x>5_kXhEcE$I^bT=c~D)(K(@YS6#EqT`cqpu$cM&g z>}HVd4$zu?40|8~$)R04e2>UpbNmkEb1x|G$3ec7UkbD$lxx1%8uR}DRb>aPkqVH!v`9yY)k(B0|lFPFCB z$)8YLI@xHwRDYVY^1cG3zZv3C%|2yF=VCV`)?NLI@s!=nH-*k-U^fh@vm}2yTQlKo z=WhmmJK-OwhJ5gTBo~2V+~V{;cJS`2LH7k*tUmv9<6@B;kSE|U9D}uR74NR(`$xK? za0t3#I(Roe2i-q=;0;?J-akQpx(oGQdLH`Kr+W_GKXKa1e?F)_55kL30lJH&dlbr` z3$BFJ_{yUk`rp679U&jGHMXH7)ouiO_Yk!Yb+=qkq6D7{nb4@oHLT;2;RR@bX!4l))=jG2P}nUuosk%#^~Hqa zQv?5c2Pf_i>D0H_^(B47oJ-798|O24x9RMxV-2!Go#w9gde{f9u2b#L_Zh#6Bj&*| zc*t&??COBF_Er1-2)J?Q8*d={(02}U4d@=%vmRIh z1u*0|_7rzmcfPeftE@dzX>C`#J=NA3iD$>Ncbf8ya{l{ZRe4&EXfIDY(r!#wYfiz8 lcuqlfw=wxbZRylk$rwLgwmXfXx|{VyVPlB@s# literal 0 HcmV?d00001 diff --git a/website/admin/index.html b/website/admin/index.html new file mode 100644 index 0000000..e7ddf75 --- /dev/null +++ b/website/admin/index.html @@ -0,0 +1,204 @@ + + + + + + + + + loading + + + + + + + + + +
+ +
+
+
+ +
+
+
+
+ + + + diff --git a/website/admin/tinymce/icons/default/icons.min.js b/website/admin/tinymce/icons/default/icons.min.js new file mode 100644 index 0000000..2cf9ef8 --- /dev/null +++ b/website/admin/tinymce/icons/default/icons.min.js @@ -0,0 +1 @@ +tinymce.IconManager.add("default",{icons:{"accessibility-check":'',"action-next":'',"action-prev":'',"align-center":'',"align-justify":'',"align-left":'',"align-none":'',"align-right":'',"arrow-left":'',"arrow-right":'',bold:'',bookmark:'',"border-style":'',"border-width":'',brightness:'',browse:'',cancel:'',"cell-background-color":'',"cell-border-color":'',"change-case":'',"character-count":'',"checklist-rtl":'',checklist:'',checkmark:'',"chevron-down":'',"chevron-left":'',"chevron-right":'',"chevron-up":'',close:'',"code-sample":'',"color-levels":'',"color-picker":'',"color-swatch-remove-color":'',"color-swatch":'',"comment-add":'',comment:'',contrast:'',copy:'',crop:'',"cut-column":'',"cut-row":'',cut:'',"document-properties":'',drag:'',"duplicate-column":'',"duplicate-row":'',duplicate:'',"edit-block":'',"edit-image":'',"embed-page":'',embed:'',emoji:'',export:'',fill:'',"flip-horizontally":'',"flip-vertically":'',"format-painter":'',format:'',fullscreen:'',gallery:'',gamma:'',help:'',"highlight-bg-color":'',home:'',"horizontal-rule":'',"image-options":'',image:'',indent:'',info:'',"insert-character":'',"insert-time":'',invert:'',italic:'',language:'',"line-height":'',line:'',link:'',"list-bull-circle":'',"list-bull-default":'',"list-bull-square":'',"list-num-default-rtl":'',"list-num-default":'',"list-num-lower-alpha-rtl":'',"list-num-lower-alpha":'',"list-num-lower-greek-rtl":'',"list-num-lower-greek":'',"list-num-lower-roman-rtl":'',"list-num-lower-roman":'',"list-num-upper-alpha-rtl":'',"list-num-upper-alpha":'',"list-num-upper-roman-rtl":'',"list-num-upper-roman":'',lock:'',ltr:'',"more-drawer":'',"new-document":'',"new-tab":'',"non-breaking":'',notice:'',"ordered-list-rtl":'',"ordered-list":'',orientation:'',outdent:'',"page-break":'',paragraph:'',"paste-column-after":'',"paste-column-before":'',"paste-row-after":'',"paste-row-before":'',"paste-text":'',paste:'',"permanent-pen":'',plus:'',preferences:'',preview:'',print:'',quote:'',redo:'',reload:'',"remove-formatting":'',remove:'',"resize-handle":'',resize:'',"restore-draft":'',"rotate-left":'',"rotate-right":'',rtl:'',save:'',search:'',"select-all":'',selected:'',settings:'',sharpen:'',sourcecode:'',"spell-check":'',"strike-through":'',subscript:'',superscript:'',"table-caption":'',"table-cell-classes":'',"table-cell-properties":'',"table-cell-select-all":'',"table-cell-select-inner":'',"table-classes":'',"table-delete-column":'',"table-delete-row":'',"table-delete-table":'',"table-insert-column-after":'',"table-insert-column-before":'',"table-insert-row-above":'',"table-insert-row-after":'',"table-left-header":'',"table-merge-cells":'',"table-row-numbering-rtl":'',"table-row-numbering":'',"table-row-properties":'',"table-split-cells":'',"table-top-header":'',table:'',template:'',"temporary-placeholder":'',"text-color":'',toc:'',translate:'',underline:'',undo:'',unlink:'',unlock:'',"unordered-list":'',unselected:'',upload:'',user:'',"vertical-align":'',visualblocks:'',visualchars:'',warning:'',"zoom-in":'',"zoom-out":''}}); \ No newline at end of file diff --git a/website/admin/tinymce/langs/readme.md b/website/admin/tinymce/langs/readme.md new file mode 100644 index 0000000..a52bf03 --- /dev/null +++ b/website/admin/tinymce/langs/readme.md @@ -0,0 +1,3 @@ +This is where language files should be placed. + +Please DO NOT translate these directly use this service: https://www.transifex.com/projects/p/tinymce/ diff --git a/website/admin/tinymce/langs/zh_CN.js b/website/admin/tinymce/langs/zh_CN.js new file mode 100644 index 0000000..7ed089e --- /dev/null +++ b/website/admin/tinymce/langs/zh_CN.js @@ -0,0 +1 @@ +tinymce.addI18n("zh_CN",{Redo:"\u91cd\u505a",Undo:"\u64a4\u9500",Cut:"\u526a\u5207",Copy:"\u590d\u5236",Paste:"\u7c98\u8d34","Select all":"\u5168\u9009","New document":"\u65b0\u6587\u4ef6",Ok:"\u786e\u5b9a",Cancel:"\u53d6\u6d88","Visual aids":"\u7f51\u683c\u7ebf",Bold:"\u7c97\u4f53",Italic:"\u659c\u4f53",Underline:"\u4e0b\u5212\u7ebf",Strikethrough:"\u5220\u9664\u7ebf",Superscript:"\u4e0a\u6807",Subscript:"\u4e0b\u6807","Clear formatting":"\u6e05\u9664\u683c\u5f0f","Align left":"\u5de6\u8fb9\u5bf9\u9f50","Align center":"\u4e2d\u95f4\u5bf9\u9f50","Align right":"\u53f3\u8fb9\u5bf9\u9f50",Justify:"\u4e24\u7aef\u5bf9\u9f50","Bullet list":"\u9879\u76ee\u7b26\u53f7","Numbered list":"\u7f16\u53f7\u5217\u8868","Decrease indent":"\u51cf\u5c11\u7f29\u8fdb","Increase indent":"\u589e\u52a0\u7f29\u8fdb","Line height":"\u884c\u9ad8",Close:"\u5173\u95ed",Formats:"\u683c\u5f0f","Your browser doesn't support direct access to the clipboard. Please use the Ctrl+X/C/V keyboard shortcuts instead.":"\u4f60\u7684\u6d4f\u89c8\u5668\u4e0d\u652f\u6301\u6253\u5f00\u526a\u8d34\u677f\uff0c\u8bf7\u4f7f\u7528Ctrl+X/C/V\u7b49\u5feb\u6377\u952e\u3002",Headers:"\u6807\u9898","Header 1":"\u6807\u98981","Header 2":"\u6807\u98982","Header 3":"\u6807\u98983","Header 4":"\u6807\u98984","Header 5":"\u6807\u98985","Header 6":"\u6807\u98986",Headings:"\u6807\u9898","Heading 1":"\u6807\u98981","Heading 2":"\u6807\u98982","Heading 3":"\u6807\u98983","Heading 4":"\u6807\u98984","Heading 5":"\u6807\u98985","Heading 6":"\u6807\u98986",Preformatted:"\u9884\u5148\u683c\u5f0f\u5316\u7684",Div:"Div",Pre:"Pre",Code:"\u4ee3\u7801",Paragraph:"\u6bb5\u843d",Blockquote:"\u5f15\u6587\u533a\u5757",Inline:"\u6587\u672c",Blocks:"\u57fa\u5757","Paste is now in plain text mode. Contents will now be pasted as plain text until you toggle this option off.":"\u5f53\u524d\u4e3a\u7eaf\u6587\u672c\u7c98\u8d34\u6a21\u5f0f\uff0c\u518d\u6b21\u70b9\u51fb\u53ef\u4ee5\u56de\u5230\u666e\u901a\u7c98\u8d34\u6a21\u5f0f\u3002",Fonts:"\u5b57\u4f53","Font Sizes":"\u5b57\u53f7",Class:"\u7c7b\u578b","Browse for an image":"\u6d4f\u89c8\u56fe\u50cf",OR:"\u6216","Drop an image here":"\u62d6\u653e\u4e00\u5f20\u56fe\u50cf\u81f3\u6b64",Upload:"\u4e0a\u4f20",Block:"\u5757",Align:"\u5bf9\u9f50",Default:"\u9ed8\u8ba4",Circle:"\u7a7a\u5fc3\u5706",Disc:"\u5b9e\u5fc3\u5706",Square:"\u65b9\u5757","Lower Alpha":"\u5c0f\u5199\u82f1\u6587\u5b57\u6bcd","Lower Greek":"\u5c0f\u5199\u5e0c\u814a\u5b57\u6bcd","Lower Roman":"\u5c0f\u5199\u7f57\u9a6c\u5b57\u6bcd","Upper Alpha":"\u5927\u5199\u82f1\u6587\u5b57\u6bcd","Upper Roman":"\u5927\u5199\u7f57\u9a6c\u5b57\u6bcd","Anchor...":"\u951a\u70b9...",Name:"\u540d\u79f0",Id:"\u6807\u8bc6\u7b26","Id should start with a letter, followed only by letters, numbers, dashes, dots, colons or underscores.":"\u6807\u8bc6\u7b26\u5e94\u8be5\u4ee5\u5b57\u6bcd\u5f00\u5934\uff0c\u540e\u8ddf\u5b57\u6bcd\u3001\u6570\u5b57\u3001\u7834\u6298\u53f7\u3001\u70b9\u3001\u5192\u53f7\u6216\u4e0b\u5212\u7ebf\u3002","You have unsaved changes are you sure you want to navigate away?":"\u4f60\u8fd8\u6709\u6587\u6863\u5c1a\u672a\u4fdd\u5b58\uff0c\u786e\u5b9a\u8981\u79bb\u5f00\uff1f","Restore last draft":"\u6062\u590d\u4e0a\u6b21\u7684\u8349\u7a3f","Special character...":"\u7279\u6b8a\u5b57\u7b26...","Source code":"\u6e90\u4ee3\u7801","Insert/Edit code sample":"\u63d2\u5165/\u7f16\u8f91\u4ee3\u7801\u793a\u4f8b",Language:"\u8bed\u8a00","Code sample...":"\u793a\u4f8b\u4ee3\u7801...","Color Picker":"\u9009\u8272\u5668",R:"R",G:"G",B:"B","Left to right":"\u4ece\u5de6\u5230\u53f3","Right to left":"\u4ece\u53f3\u5230\u5de6","Emoticons...":"\u8868\u60c5\u7b26\u53f7...","Metadata and Document Properties":"\u5143\u6570\u636e\u548c\u6587\u6863\u5c5e\u6027",Title:"\u6807\u9898",Keywords:"\u5173\u952e\u8bcd",Description:"\u63cf\u8ff0",Robots:"\u673a\u5668\u4eba",Author:"\u4f5c\u8005",Encoding:"\u7f16\u7801",Fullscreen:"\u5168\u5c4f",Action:"\u64cd\u4f5c",Shortcut:"\u5feb\u6377\u952e",Help:"\u5e2e\u52a9",Address:"\u5730\u5740","Focus to menubar":"\u79fb\u52a8\u7126\u70b9\u5230\u83dc\u5355\u680f","Focus to toolbar":"\u79fb\u52a8\u7126\u70b9\u5230\u5de5\u5177\u680f","Focus to element path":"\u79fb\u52a8\u7126\u70b9\u5230\u5143\u7d20\u8def\u5f84","Focus to contextual toolbar":"\u79fb\u52a8\u7126\u70b9\u5230\u4e0a\u4e0b\u6587\u83dc\u5355","Insert link (if link plugin activated)":"\u63d2\u5165\u94fe\u63a5 (\u5982\u679c\u94fe\u63a5\u63d2\u4ef6\u5df2\u6fc0\u6d3b)","Save (if save plugin activated)":"\u4fdd\u5b58(\u5982\u679c\u4fdd\u5b58\u63d2\u4ef6\u5df2\u6fc0\u6d3b)","Find (if searchreplace plugin activated)":"\u67e5\u627e(\u5982\u679c\u67e5\u627e\u66ff\u6362\u63d2\u4ef6\u5df2\u6fc0\u6d3b)","Plugins installed ({0}):":"\u5df2\u5b89\u88c5\u63d2\u4ef6 ({0}):","Premium plugins:":"\u4f18\u79c0\u63d2\u4ef6\uff1a","Learn more...":"\u4e86\u89e3\u66f4\u591a...","You are using {0}":"\u4f60\u6b63\u5728\u4f7f\u7528 {0}",Plugins:"\u63d2\u4ef6","Handy Shortcuts":"\u5feb\u6377\u952e","Horizontal line":"\u6c34\u5e73\u5206\u5272\u7ebf","Insert/edit image":"\u63d2\u5165/\u7f16\u8f91\u56fe\u7247","Image description":"\u56fe\u7247\u63cf\u8ff0",Source:"\u5730\u5740",Dimensions:"\u5927\u5c0f","Constrain proportions":"\u4fdd\u6301\u7eb5\u6a2a\u6bd4",General:"\u666e\u901a",Advanced:"\u9ad8\u7ea7",Style:"\u6837\u5f0f","Vertical space":"\u5782\u76f4\u8fb9\u8ddd","Horizontal space":"\u6c34\u5e73\u8fb9\u8ddd",Border:"\u8fb9\u6846","Insert image":"\u63d2\u5165\u56fe\u7247","Image...":"\u56fe\u7247...","Image list":"\u56fe\u7247\u5217\u8868","Rotate counterclockwise":"\u9006\u65f6\u9488\u65cb\u8f6c","Rotate clockwise":"\u987a\u65f6\u9488\u65cb\u8f6c","Flip vertically":"\u5782\u76f4\u7ffb\u8f6c","Flip horizontally":"\u6c34\u5e73\u7ffb\u8f6c","Edit image":"\u7f16\u8f91\u56fe\u7247","Image options":"\u56fe\u7247\u9009\u9879","Zoom in":"\u653e\u5927","Zoom out":"\u7f29\u5c0f",Crop:"\u88c1\u526a",Resize:"\u8c03\u6574\u5927\u5c0f",Orientation:"\u65b9\u5411",Brightness:"\u4eae\u5ea6",Sharpen:"\u9510\u5316",Contrast:"\u5bf9\u6bd4\u5ea6","Color levels":"\u989c\u8272\u5c42\u6b21",Gamma:"\u4f3d\u9a6c\u503c",Invert:"\u53cd\u8f6c",Apply:"\u5e94\u7528",Back:"\u540e\u9000","Insert date/time":"\u63d2\u5165\u65e5\u671f/\u65f6\u95f4","Date/time":"\u65e5\u671f/\u65f6\u95f4","Insert/Edit Link":"\u63d2\u5165/\u7f16\u8f91\u94fe\u63a5","Insert/edit link":"\u63d2\u5165/\u7f16\u8f91\u94fe\u63a5","Text to display":"\u663e\u793a\u6587\u5b57",Url:"\u5730\u5740","Open link in...":"\u94fe\u63a5\u6253\u5f00\u4f4d\u7f6e...","Current window":"\u5f53\u524d\u7a97\u53e3",None:"\u65e0","New window":"\u5728\u65b0\u7a97\u53e3\u6253\u5f00","Remove link":"\u5220\u9664\u94fe\u63a5",Anchors:"\u951a\u70b9","Link...":"\u94fe\u63a5...","Paste or type a link":"\u7c98\u8d34\u6216\u8f93\u5165\u94fe\u63a5","The URL you entered seems to be an email address. Do you want to add the required mailto: prefix?":"\u4f60\u6240\u586b\u5199\u7684URL\u5730\u5740\u4e3a\u90ae\u4ef6\u5730\u5740\uff0c\u9700\u8981\u52a0\u4e0amailto:\u524d\u7f00\u5417\uff1f","The URL you entered seems to be an external link. Do you want to add the required http:// prefix?":"\u4f60\u6240\u586b\u5199\u7684URL\u5730\u5740\u5c5e\u4e8e\u5916\u90e8\u94fe\u63a5\uff0c\u9700\u8981\u52a0\u4e0ahttp://:\u524d\u7f00\u5417\uff1f","Link list":"\u94fe\u63a5\u5217\u8868","Insert video":"\u63d2\u5165\u89c6\u9891","Insert/edit video":"\u63d2\u5165/\u7f16\u8f91\u89c6\u9891","Insert/edit media":"\u63d2\u5165/\u7f16\u8f91\u5a92\u4f53","Alternative source":"\u955c\u50cf","Alternative source URL":"\u66ff\u4ee3\u6765\u6e90\u7f51\u5740","Media poster (Image URL)":"\u5c01\u9762(\u56fe\u7247\u5730\u5740)","Paste your embed code below:":"\u5c06\u5185\u5d4c\u4ee3\u7801\u7c98\u8d34\u5728\u4e0b\u9762:",Embed:"\u5185\u5d4c","Media...":"\u591a\u5a92\u4f53...","Nonbreaking space":"\u4e0d\u95f4\u65ad\u7a7a\u683c","Page break":"\u5206\u9875\u7b26","Paste as text":"\u7c98\u8d34\u4e3a\u6587\u672c",Preview:"\u9884\u89c8","Print...":"\u6253\u5370...",Save:"\u4fdd\u5b58",Find:"\u67e5\u627e","Replace with":"\u66ff\u6362\u4e3a",Replace:"\u66ff\u6362","Replace all":"\u5168\u90e8\u66ff\u6362",Previous:"\u4e0a\u4e00\u4e2a",Next:"\u4e0b\u4e00\u4e2a","Find and replace...":"\u67e5\u627e\u5e76\u66ff\u6362...","Could not find the specified string.":"\u672a\u627e\u5230\u641c\u7d22\u5185\u5bb9.","Match case":"\u533a\u5206\u5927\u5c0f\u5199","Find whole words only":"\u5168\u5b57\u5339\u914d","Spell check":"\u62fc\u5199\u68c0\u67e5",Ignore:"\u5ffd\u7565","Ignore all":"\u5168\u90e8\u5ffd\u7565",Finish:"\u5b8c\u6210","Add to Dictionary":"\u6dfb\u52a0\u5230\u5b57\u5178","Insert table":"\u63d2\u5165\u8868\u683c","Table properties":"\u8868\u683c\u5c5e\u6027","Delete table":"\u5220\u9664\u8868\u683c",Cell:"\u5355\u5143\u683c",Row:"\u884c",Column:"\u5217","Cell properties":"\u5355\u5143\u683c\u5c5e\u6027","Merge cells":"\u5408\u5e76\u5355\u5143\u683c","Split cell":"\u62c6\u5206\u5355\u5143\u683c","Insert row before":"\u5728\u4e0a\u65b9\u63d2\u5165","Insert row after":"\u5728\u4e0b\u65b9\u63d2\u5165","Delete row":"\u5220\u9664\u884c","Row properties":"\u884c\u5c5e\u6027","Cut row":"\u526a\u5207\u884c","Copy row":"\u590d\u5236\u884c","Paste row before":"\u7c98\u8d34\u5230\u4e0a\u65b9","Paste row after":"\u7c98\u8d34\u5230\u4e0b\u65b9","Insert column before":"\u5728\u5de6\u4fa7\u63d2\u5165","Insert column after":"\u5728\u53f3\u4fa7\u63d2\u5165","Delete column":"\u5220\u9664\u5217",Cols:"\u5217",Rows:"\u884c",Width:"\u5bbd",Height:"\u9ad8","Cell spacing":"\u5355\u5143\u683c\u5916\u95f4\u8ddd","Cell padding":"\u5355\u5143\u683c\u5185\u8fb9\u8ddd","Show caption":"\u663e\u793a\u6807\u9898",Left:"\u5de6\u5bf9\u9f50",Center:"\u5c45\u4e2d",Right:"\u53f3\u5bf9\u9f50","Cell type":"\u5355\u5143\u683c\u7c7b\u578b",Scope:"\u8303\u56f4",Alignment:"\u5bf9\u9f50\u65b9\u5f0f","H Align":"\u6c34\u5e73\u5bf9\u9f50","V Align":"\u5782\u76f4\u5bf9\u9f50",Top:"\u9876\u90e8\u5bf9\u9f50",Middle:"\u5782\u76f4\u5c45\u4e2d",Bottom:"\u5e95\u90e8\u5bf9\u9f50","Header cell":"\u8868\u5934\u5355\u5143\u683c","Row group":"\u884c\u7ec4","Column group":"\u5217\u7ec4","Row type":"\u884c\u7c7b\u578b",Header:"\u8868\u5934",Body:"\u8868\u4f53",Footer:"\u8868\u5c3e","Border color":"\u8fb9\u6846\u989c\u8272","Insert template...":"\u63d2\u5165\u6a21\u677f...",Templates:"\u6a21\u677f",Template:"\u6a21\u677f","Text color":"\u6587\u5b57\u989c\u8272","Background color":"\u80cc\u666f\u8272","Custom...":"\u81ea\u5b9a\u4e49...","Custom color":"\u81ea\u5b9a\u4e49\u989c\u8272","No color":"\u65e0","Remove color":"\u79fb\u9664\u989c\u8272","Table of Contents":"\u5185\u5bb9\u5217\u8868","Show blocks":"\u663e\u793a\u533a\u5757\u8fb9\u6846","Show invisible characters":"\u663e\u793a\u4e0d\u53ef\u89c1\u5b57\u7b26","Word count":"\u5b57\u6570",Count:"\u8ba1\u6570",Document:"\u6587\u6863",Selection:"\u9009\u62e9",Words:"\u5355\u8bcd","Words: {0}":"\u5b57\u6570\uff1a{0}","{0} words":"{0} \u5b57",File:"\u6587\u4ef6",Edit:"\u7f16\u8f91",Insert:"\u63d2\u5165",View:"\u89c6\u56fe",Format:"\u683c\u5f0f",Table:"\u8868\u683c",Tools:"\u5de5\u5177","Powered by {0}":"\u7531{0}\u9a71\u52a8","Rich Text Area. Press ALT-F9 for menu. Press ALT-F10 for toolbar. Press ALT-0 for help":"\u5728\u7f16\u8f91\u533a\u6309ALT-F9\u6253\u5f00\u83dc\u5355\uff0c\u6309ALT-F10\u6253\u5f00\u5de5\u5177\u680f\uff0c\u6309ALT-0\u67e5\u770b\u5e2e\u52a9","Image title":"\u56fe\u7247\u6807\u9898","Border width":"\u8fb9\u6846\u5bbd\u5ea6","Border style":"\u8fb9\u6846\u6837\u5f0f",Error:"\u9519\u8bef",Warn:"\u8b66\u544a",Valid:"\u6709\u6548","To open the popup, press Shift+Enter":"\u6309Shitf+Enter\u952e\u6253\u5f00\u5bf9\u8bdd\u6846","Rich Text Area. Press ALT-0 for help.":"\u7f16\u8f91\u533a\u3002\u6309Alt+0\u952e\u6253\u5f00\u5e2e\u52a9\u3002","System Font":"\u7cfb\u7edf\u5b57\u4f53","Failed to upload image: {0}":"\u56fe\u7247\u4e0a\u4f20\u5931\u8d25: {0}","Failed to load plugin: {0} from url {1}":"\u63d2\u4ef6\u52a0\u8f7d\u5931\u8d25: {0} \u6765\u81ea\u94fe\u63a5 {1}","Failed to load plugin url: {0}":"\u63d2\u4ef6\u52a0\u8f7d\u5931\u8d25 \u94fe\u63a5: {0}","Failed to initialize plugin: {0}":"\u63d2\u4ef6\u521d\u59cb\u5316\u5931\u8d25: {0}",example:"\u793a\u4f8b",Search:"\u641c\u7d22",All:"\u5168\u90e8",Currency:"\u8d27\u5e01",Text:"\u6587\u5b57",Quotations:"\u5f15\u7528",Mathematical:"\u6570\u5b66","Extended Latin":"\u62c9\u4e01\u8bed\u6269\u5145",Symbols:"\u7b26\u53f7",Arrows:"\u7bad\u5934","User Defined":"\u81ea\u5b9a\u4e49","dollar sign":"\u7f8e\u5143\u7b26\u53f7","currency sign":"\u8d27\u5e01\u7b26\u53f7","euro-currency sign":"\u6b27\u5143\u7b26\u53f7","colon sign":"\u5192\u53f7","cruzeiro sign":"\u514b\u9c81\u8d5b\u7f57\u5e01\u7b26\u53f7","french franc sign":"\u6cd5\u90ce\u7b26\u53f7","lira sign":"\u91cc\u62c9\u7b26\u53f7","mill sign":"\u5bc6\u5c14\u7b26\u53f7","naira sign":"\u5948\u62c9\u7b26\u53f7","peseta sign":"\u6bd4\u585e\u5854\u7b26\u53f7","rupee sign":"\u5362\u6bd4\u7b26\u53f7","won sign":"\u97e9\u5143\u7b26\u53f7","new sheqel sign":"\u65b0\u8c22\u514b\u5c14\u7b26\u53f7","dong sign":"\u8d8a\u5357\u76fe\u7b26\u53f7","kip sign":"\u8001\u631d\u57fa\u666e\u7b26\u53f7","tugrik sign":"\u56fe\u683c\u91cc\u514b\u7b26\u53f7","drachma sign":"\u5fb7\u62c9\u514b\u9a6c\u7b26\u53f7","german penny symbol":"\u5fb7\u56fd\u4fbf\u58eb\u7b26\u53f7","peso sign":"\u6bd4\u7d22\u7b26\u53f7","guarani sign":"\u74dc\u62c9\u5c3c\u7b26\u53f7","austral sign":"\u6fb3\u5143\u7b26\u53f7","hryvnia sign":"\u683c\u91cc\u592b\u5c3c\u4e9a\u7b26\u53f7","cedi sign":"\u585e\u5730\u7b26\u53f7","livre tournois sign":"\u91cc\u5f17\u5f17\u5c14\u7b26\u53f7","spesmilo sign":"spesmilo\u7b26\u53f7","tenge sign":"\u575a\u6208\u7b26\u53f7","indian rupee sign":"\u5370\u5ea6\u5362\u6bd4","turkish lira sign":"\u571f\u8033\u5176\u91cc\u62c9","nordic mark sign":"\u5317\u6b27\u9a6c\u514b","manat sign":"\u9a6c\u7eb3\u7279\u7b26\u53f7","ruble sign":"\u5362\u5e03\u7b26\u53f7","yen character":"\u65e5\u5143\u5b57\u6837","yuan character":"\u4eba\u6c11\u5e01\u5143\u5b57\u6837","yuan character, in hong kong and taiwan":"\u5143\u5b57\u6837\uff08\u6e2f\u53f0\u5730\u533a\uff09","yen/yuan character variant one":"\u5143\u5b57\u6837\uff08\u5927\u5199\uff09","Loading emoticons...":"\u52a0\u8f7d\u8868\u60c5\u7b26\u53f7...","Could not load emoticons":"\u4e0d\u80fd\u52a0\u8f7d\u8868\u60c5\u7b26\u53f7",People:"\u4eba\u7c7b","Animals and Nature":"\u52a8\u7269\u548c\u81ea\u7136","Food and Drink":"\u98df\u7269\u548c\u996e\u54c1",Activity:"\u6d3b\u52a8","Travel and Places":"\u65c5\u6e38\u548c\u5730\u70b9",Objects:"\u7269\u4ef6",Flags:"\u65d7\u5e1c",Characters:"\u5b57\u7b26","Characters (no spaces)":"\u5b57\u7b26(\u65e0\u7a7a\u683c)","{0} characters":"{0} \u4e2a\u5b57\u7b26","Error: Form submit field collision.":"\u9519\u8bef: \u8868\u5355\u63d0\u4ea4\u5b57\u6bb5\u51b2\u7a81\u3002","Error: No form element found.":"\u9519\u8bef: \u6ca1\u6709\u8868\u5355\u63a7\u4ef6\u3002",Update:"\u66f4\u65b0","Color swatch":"\u989c\u8272\u6837\u672c",Turquoise:"\u9752\u7eff\u8272",Green:"\u7eff\u8272",Blue:"\u84dd\u8272",Purple:"\u7d2b\u8272","Navy Blue":"\u6d77\u519b\u84dd","Dark Turquoise":"\u6df1\u84dd\u7eff\u8272","Dark Green":"\u6df1\u7eff\u8272","Medium Blue":"\u4e2d\u84dd\u8272","Medium Purple":"\u4e2d\u7d2b\u8272","Midnight Blue":"\u6df1\u84dd\u8272",Yellow:"\u9ec4\u8272",Orange:"\u6a59\u8272",Red:"\u7ea2\u8272","Light Gray":"\u6d45\u7070\u8272",Gray:"\u7070\u8272","Dark Yellow":"\u6697\u9ec4\u8272","Dark Orange":"\u6df1\u6a59\u8272","Dark Red":"\u6df1\u7ea2\u8272","Medium Gray":"\u4e2d\u7070\u8272","Dark Gray":"\u6df1\u7070\u8272","Light Green":"\u6d45\u7eff\u8272","Light Yellow":"\u6d45\u9ec4\u8272","Light Red":"\u6d45\u7ea2\u8272","Light Purple":"\u6d45\u7d2b\u8272","Light Blue":"\u6d45\u84dd\u8272","Dark Purple":"\u6df1\u7d2b\u8272","Dark Blue":"\u6df1\u84dd\u8272",Black:"\u9ed1\u8272",White:"\u767d\u8272","Switch to or from fullscreen mode":"\u5207\u6362\u5168\u5c4f\u6a21\u5f0f","Open help dialog":"\u6253\u5f00\u5e2e\u52a9\u5bf9\u8bdd\u6846",history:"\u5386\u53f2",styles:"\u6837\u5f0f",formatting:"\u683c\u5f0f\u5316",alignment:"\u5bf9\u9f50",indentation:"\u7f29\u8fdb","permanent pen":"\u8bb0\u53f7\u7b14",comments:"\u5907\u6ce8","Format Painter":"\u683c\u5f0f\u5237","Insert/edit iframe":"\u63d2\u5165/\u7f16\u8f91\u6846\u67b6",Capitalization:"\u5927\u5199",lowercase:"\u5c0f\u5199",UPPERCASE:"\u5927\u5199","Title Case":"\u9996\u5b57\u6bcd\u5927\u5199","Permanent Pen Properties":"\u6c38\u4e45\u7b14\u5c5e\u6027","Permanent pen properties...":"\u6c38\u4e45\u7b14\u5c5e\u6027...",Font:"\u5b57\u4f53",Size:"\u5b57\u53f7","More...":"\u66f4\u591a...","Spellcheck Language":"\u62fc\u5199\u68c0\u67e5\u8bed\u8a00","Select...":"\u9009\u62e9...",Preferences:"\u9996\u9009\u9879",Yes:"\u662f",No:"\u5426","Keyboard Navigation":"\u952e\u76d8\u6307\u5f15",Version:"\u7248\u672c",Anchor:"\u951a\u70b9","Special character":"\u7279\u6b8a\u7b26\u53f7","Code sample":"\u4ee3\u7801\u793a\u4f8b",Color:"\u989c\u8272",Emoticons:"\u8868\u60c5","Document properties":"\u6587\u6863\u5c5e\u6027",Image:"\u56fe\u7247","Insert link":"\u63d2\u5165\u94fe\u63a5",Target:"\u6253\u5f00\u65b9\u5f0f",Link:"\u94fe\u63a5",Poster:"\u5c01\u9762",Media:"\u5a92\u4f53",Print:"\u6253\u5370",Prev:"\u4e0a\u4e00\u4e2a","Find and replace":"\u67e5\u627e\u548c\u66ff\u6362","Whole words":"\u5168\u5b57\u5339\u914d",Spellcheck:"\u62fc\u5199\u68c0\u67e5",Caption:"\u6807\u9898","Insert template":"\u63d2\u5165\u6a21\u677f"}); \ No newline at end of file diff --git a/website/admin/tinymce/license.txt b/website/admin/tinymce/license.txt new file mode 100644 index 0000000..b17fc90 --- /dev/null +++ b/website/admin/tinymce/license.txt @@ -0,0 +1,504 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 + + Copyright (C) 1991, 1999 Free Software Foundation, Inc. + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the Lesser GPL. It also counts + as the successor of the GNU Library Public License, version 2, hence + the version number 2.1.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Lesser General Public License, applies to some +specially designated software packages--typically libraries--of the +Free Software Foundation and other authors who decide to use it. You +can use it too, but we suggest you first think carefully about whether +this license or the ordinary General Public License is the better +strategy to use in any particular case, based on the explanations below. + + When we speak of free software, we are referring to freedom of use, +not price. Our General Public Licenses are designed to make sure that +you have the freedom to distribute copies of free software (and charge +for this service if you wish); that you receive source code or can get +it if you want it; that you can change the software and use pieces of +it in new free programs; and that you are informed that you can do +these things. + + To protect your rights, we need to make restrictions that forbid +distributors to deny you these rights or to ask you to surrender these +rights. These restrictions translate to certain responsibilities for +you if you distribute copies of the library or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link other code with the library, you must provide +complete object files to the recipients, so that they can relink them +with the library after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + We protect your rights with a two-step method: (1) we copyright the +library, and (2) we offer you this license, which gives you legal +permission to copy, distribute and/or modify the library. + + To protect each distributor, we want to make it very clear that +there is no warranty for the free library. Also, if the library is +modified by someone else and passed on, the recipients should know +that what they have is not the original version, so that the original +author's reputation will not be affected by problems that might be +introduced by others. + + Finally, software patents pose a constant threat to the existence of +any free program. We wish to make sure that a company cannot +effectively restrict the users of a free program by obtaining a +restrictive license from a patent holder. Therefore, we insist that +any patent license obtained for a version of the library must be +consistent with the full freedom of use specified in this license. + + Most GNU software, including some libraries, is covered by the +ordinary GNU General Public License. This license, the GNU Lesser +General Public License, applies to certain designated libraries, and +is quite different from the ordinary General Public License. We use +this license for certain libraries in order to permit linking those +libraries into non-free programs. + + When a program is linked with a library, whether statically or using +a shared library, the combination of the two is legally speaking a +combined work, a derivative of the original library. The ordinary +General Public License therefore permits such linking only if the +entire combination fits its criteria of freedom. The Lesser General +Public License permits more lax criteria for linking other code with +the library. + + We call this license the "Lesser" General Public License because it +does Less to protect the user's freedom than the ordinary General +Public License. It also provides other free software developers Less +of an advantage over competing non-free programs. These disadvantages +are the reason we use the ordinary General Public License for many +libraries. However, the Lesser license provides advantages in certain +special circumstances. + + For example, on rare occasions, there may be a special need to +encourage the widest possible use of a certain library, so that it becomes +a de-facto standard. To achieve this, non-free programs must be +allowed to use the library. A more frequent case is that a free +library does the same job as widely used non-free libraries. In this +case, there is little to gain by limiting the free library to free +software only, so we use the Lesser General Public License. + + In other cases, permission to use a particular library in non-free +programs enables a greater number of people to use a large body of +free software. For example, permission to use the GNU C Library in +non-free programs enables many more people to use the whole GNU +operating system, as well as its variant, the GNU/Linux operating +system. + + Although the Lesser General Public License is Less protective of the +users' freedom, it does ensure that the user of a program that is +linked with the Library has the freedom and the wherewithal to run +that program using a modified version of the Library. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, whereas the latter must +be combined with the library in order to run. + + GNU LESSER GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library or other +program which contains a notice placed by the copyright holder or +other authorized party saying it may be distributed under the terms of +this Lesser General Public License (also called "this License"). +Each licensee is addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control compilation +and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also combine or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (1) uses at run time a + copy of the library already present on the user's computer system, + rather than copying library functions into the executable, and (2) + will operate properly with a modified version of the library, if + the user installs one, as long as the modified version is + interface-compatible with the version that the work was made with. + + c) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + d) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + e) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the materials to be distributed need not include anything that is +normally distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties with +this License. + + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Lesser General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms of the +ordinary General Public License). + + To apply these terms, attach the following notices to the library. It is +safest to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least the +"copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the library, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James Random Hacker. + + , 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! + + diff --git a/website/admin/tinymce/plugins/advlist/plugin.min.js b/website/admin/tinymce/plugins/advlist/plugin.min.js new file mode 100644 index 0000000..bc52917 --- /dev/null +++ b/website/admin/tinymce/plugins/advlist/plugin.min.js @@ -0,0 +1 @@ +!function(){"use strict";function t(t,e,n){t.execCommand("UL"===e?"InsertUnorderedList":"InsertOrderedList",!1,!1===n?null:{"list-style-type":n})}function e(t){return function(){return t}}function n(t){return t}function r(){return s}var o=tinymce.util.Tools.resolve("tinymce.PluginManager"),i=tinymce.util.Tools.resolve("tinymce.util.Tools"),u=e(!1),l=e(!0),s={fold:function(t,e){return t()},isSome:u,isNone:l,getOr:n,getOrThunk:c,getOrDie:function(t){throw new Error(t||"error: getOrDie called on none.")},getOrNull:e(null),getOrUndefined:e(void 0),or:n,orThunk:c,map:r,each:function(){},bind:r,exists:u,forall:l,filter:function(){return s},toArray:function(){return[]},toString:e("none()")};function c(t){return t()}function a(t){return t&&/^(TH|TD)$/.test(t.nodeName)}function d(t,e){return function(n){function r(r){var o,u,l,s,c,d,f;n.setActive((o=t,l=e,c=-1!==(s=function(t,e){for(var n=0;n=(y="www.").length&&w.substr(0,0+y.length)===y?k=A+"://"+k:-1===k.indexOf("@")||/^([A-Za-z][A-Za-z\d.+-]*:\/\/)|mailto:/.test(k)||(k="mailto:"+k),s=n.selection.getBookmark(),n.selection.setRng(h),n.execCommand("createlink",!1,k),!1!==g&&n.dom.setAttrib(n.selection.getNode(),"target",g),n.selection.moveToBookmark(s),n.nodeChanged())}}var f=tinymce.util.Tools.resolve("tinymce.PluginManager"),s=tinymce.util.Tools.resolve("tinymce.Env"),d=new RegExp("^"+/(?:[A-Za-z][A-Za-z\d.+-]{0,14}:\/\/(?:[-.~*+=!&;:'%@?^${}(),\w]+@)?|www\.|[-;:&=+$,.\w]+@)[A-Za-z\d-]+(?:\.[A-Za-z\d-]+)*(?::\d+)?(?:\/(?:[-+~=.,%()\/\w]*[-+~=%()\/\w])?)?(?:\?(?:[-.~*+=!&;:'%@?^${}(),\/\w]+))?(?:#(?:[-.~*+=!&;:'%@?^${}(),\/\w]+))?/g.source+"$","i");f.add("autolink",(function(e){var t,n;(t=e).on("keydown",(function(e){if(13===e.keyCode)return a(t,-1)})),s.browser.isIE()?t.on("focus",(function(){if(!n){n=!0;try{t.execCommand("AutoUrlDetect",!1,!0)}catch(e){}}})):(t.on("keypress",(function(e){if(41===e.keyCode||93===e.keyCode||125===e.keyCode)return a(t,-1)})),t.on("keyup",(function(e){if(32===e.keyCode)return a(t,0)})))}))}(); \ No newline at end of file diff --git a/website/admin/tinymce/plugins/autoresize/plugin.min.js b/website/admin/tinymce/plugins/autoresize/plugin.min.js new file mode 100644 index 0000000..f91ec2c --- /dev/null +++ b/website/admin/tinymce/plugins/autoresize/plugin.min.js @@ -0,0 +1 @@ +!function(){"use strict";function e(e){return e.getParam("min_height",e.getElement().offsetHeight,"number")}function t(e,t){var n=e.getBody();n&&(n.style.overflowY=t?"":"hidden",t||(n.scrollTop=0))}function n(e,t,n,i){var o=parseInt(e.getStyle(t,n,i),10);return isNaN(o)?0:o}var i=Object.hasOwnProperty,o=tinymce.util.Tools.resolve("tinymce.PluginManager"),r=tinymce.util.Tools.resolve("tinymce.Env"),s=tinymce.util.Tools.resolve("tinymce.util.Delay"),a=function(e,t,n,i,o){s.setEditorTimeout(e,(function(){l(e,t),n--?a(e,t,n,i,o):o&&o()}),i)},l=function(i,o,s){var a,u,g,c,m,f,d,h,y,p,v,b=i.dom,C=i.getDoc();C&&(i.plugins.fullscreen&&i.plugins.fullscreen.isFullscreen()?t(i,!0):(a=C.documentElement,u=i.getParam("autoresize_bottom_margin",50,"number"),g=e(i),c=n(b,a,"margin-top",!0),m=n(b,a,"margin-bottom",!0),(f=(f=a.offsetHeight+c+m+u)<0?0:f)+(d=i.getContainer().offsetHeight-i.getContentAreaContainer().offsetHeight)>e(i)&&(g=f+d),(h=i.getParam("max_height",0,"number"))&&ht(r.getParam("autosave_retention"),"20m")&&(v(r,!1),1))}function a(t){var n=e(t);!r(t)&&t.isDirty()&&(m.setItem(n+"draft",t.getContent({format:"raw",no_events:!0})),m.setItem(n+"time",(new Date).getTime().toString()),t.fire("StoreDraft"))}function o(t){var r=e(t);n(t)&&(t.setContent(m.getItem(r+"draft"),{format:"raw"}),t.fire("RestoreDraft"))}function i(t){t.undoManager.transact((function(){o(t),v(t)})),t.focus()}function u(t){return function(e){function r(){return e.setDisabled(!n(t))}return e.setDisabled(!n(t)),t.on("StoreDraft RestoreDraft RemoveDraft",r),function(){return t.off("StoreDraft RestoreDraft RemoveDraft",r)}}}var s=tinymce.util.Tools.resolve("tinymce.PluginManager"),f=function(t){return void 0===t},c=tinymce.util.Tools.resolve("tinymce.util.Delay"),m=tinymce.util.Tools.resolve("tinymce.util.LocalStorage"),l=tinymce.util.Tools.resolve("tinymce.util.Tools"),v=function(t,r){var n=e(t);m.removeItem(n+"draft"),m.removeItem(n+"time"),!1!==r&&t.fire("RemoveDraft")},d=tinymce.util.Tools.resolve("tinymce.EditorManager");s.add("autosave",(function(e){var s,f,m,g;return e.editorManager.on("BeforeUnload",(function(t){var e;l.each(d.get(),(function(t){t.plugins.autosave&&t.plugins.autosave.storeDraft(),!e&&t.isDirty()&&t.getParam("autosave_ask_before_unload",!0)&&(e=t.translate("You have unsaved changes are you sure you want to navigate away?"))})),e&&(t.preventDefault(),t.returnValue=e)})),m=s=e,g=t(m.getParam("autosave_interval"),"30s"),c.setEditorInterval(m,(function(){a(m)}),g),s.ui.registry.addButton("restoredraft",{tooltip:"Restore last draft",icon:"restore-draft",onAction:function(){i(s)},onSetup:u(s)}),s.ui.registry.addMenuItem("restoredraft",{text:"Restore last draft",icon:"restore-draft",onAction:function(){i(s)},onSetup:u(s)}),e.on("init",(function(){e.getParam("autosave_restore_when_empty",!1)&&e.dom.isEmpty(e.getBody())&&o(e)})),f=e,{hasDraft:function(){return n(f)},storeDraft:function(){return a(f)},restoreDraft:function(){return o(f)},removeDraft:function(t){return v(f,t)},isEmpty:function(t){return r(f,t)}}}))}(); \ No newline at end of file diff --git a/website/admin/tinymce/plugins/bbcode/plugin.min.js b/website/admin/tinymce/plugins/bbcode/plugin.min.js new file mode 100644 index 0000000..4feac64 --- /dev/null +++ b/website/admin/tinymce/plugins/bbcode/plugin.min.js @@ -0,0 +1 @@ +!function(){"use strict";function o(o){function e(e,t){o=o.replace(e,t)}return o=t.trim(o),e(/\n/gi,"
"),e(/\[b\]/gi,""),e(/\[\/b\]/gi,""),e(/\[i\]/gi,""),e(/\[\/i\]/gi,""),e(/\[u\]/gi,""),e(/\[\/u\]/gi,""),e(/\[url=([^\]]+)\](.*?)\[\/url\]/gi,'
$2'),e(/\[url\](.*?)\[\/url\]/gi,'$1'),e(/\[img\](.*?)\[\/img\]/gi,''),e(/\[color=(.*?)\](.*?)\[\/color\]/gi,'$2'),e(/\[code\](.*?)\[\/code\]/gi,'$1 '),e(/\[quote.*?\](.*?)\[\/quote\]/gi,'$1 '),o}var e=tinymce.util.Tools.resolve("tinymce.PluginManager"),t=tinymce.util.Tools.resolve("tinymce.util.Tools");e.add("bbcode",(function(e){e.on("BeforeSetContent",(function(e){e.content=o(e.content)})),e.on("PostProcess",(function(e){function i(o,e){n=n.replace(o,e)}var n;e.set&&(e.content=o(e.content)),e.get&&(e.content=(n=e.content,n=t.trim(n),i(/(.*?)<\/a>/gi,"[url=$1]$2[/url]"),i(/(.*?)<\/font>/gi,"[code][color=$1]$2[/color][/code]"),i(/(.*?)<\/font>/gi,"[quote][color=$1]$2[/color][/quote]"),i(/(.*?)<\/font>/gi,"[code][color=$1]$2[/color][/code]"),i(/(.*?)<\/font>/gi,"[quote][color=$1]$2[/color][/quote]"),i(/(.*?)<\/span>/gi,"[color=$1]$2[/color]"),i(/(.*?)<\/font>/gi,"[color=$1]$2[/color]"),i(/(.*?)<\/span>/gi,"[size=$1]$2[/size]"),i(/(.*?)<\/font>/gi,"$1"),i(//gi,"[img]$1[/img]"),i(/(.*?)<\/span>/gi,"[code]$1[/code]"),i(/(.*?)<\/span>/gi,"[quote]$1[/quote]"),i(/(.*?)<\/strong>/gi,"[code][b]$1[/b][/code]"),i(/(.*?)<\/strong>/gi,"[quote][b]$1[/b][/quote]"),i(/(.*?)<\/em>/gi,"[code][i]$1[/i][/code]"),i(/(.*?)<\/em>/gi,"[quote][i]$1[/i][/quote]"),i(/(.*?)<\/u>/gi,"[code][u]$1[/u][/code]"),i(/(.*?)<\/u>/gi,"[quote][u]$1[/u][/quote]"),i(/<\/(strong|b)>/gi,"[/b]"),i(/<(strong|b)>/gi,"[b]"),i(/<\/(em|i)>/gi,"[/i]"),i(/<(em|i)>/gi,"[i]"),i(/<\/u>/gi,"[/u]"),i(/(.*?)<\/span>/gi,"[u]$1[/u]"),i(//gi,"[u]"),i(/]*>/gi,"[quote]"),i(/<\/blockquote>/gi,"[/quote]"),i(/
/gi,"\n"),i(//gi,"\n"),i(/
/gi,"\n"),i(/

/gi,""),i(/<\/p>/gi,"\n"),i(/ |\u00a0/gi," "),i(/"/gi,'"'),i(/</gi,"<"),i(/>/gi,">"),i(/&/gi,"&"),n))}))}))}(); \ No newline at end of file diff --git a/website/admin/tinymce/plugins/charmap/plugin.min.js b/website/admin/tinymce/plugins/charmap/plugin.min.js new file mode 100644 index 0000000..8ee70b5 --- /dev/null +++ b/website/admin/tinymce/plugins/charmap/plugin.min.js @@ -0,0 +1 @@ +!function(){"use strict";function e(e,r){var n=e.fire("insertCustomChar",{chr:r}).chr;e.execCommand("mceInsertContent",!1,n)}function r(e){return function(){return e}}function n(e){return e}function t(){return l}var a,i,o=tinymce.util.Tools.resolve("tinymce.PluginManager"),c=function(e){return n=typeof(r=e),(null===r?"null":"object"==n&&(Array.prototype.isPrototypeOf(r)||r.constructor&&"Array"===r.constructor.name)?"array":"object"==n&&(String.prototype.isPrototypeOf(r)||r.constructor&&"String"===r.constructor.name)?"string":n)===a;var r,n},u=r(!(a="array")),s=r(!(i=null)),l={fold:function(e,r){return e()},isSome:u,isNone:s,getOr:n,getOrThunk:g,getOrDie:function(e){throw new Error(e||"error: getOrDie called on none.")},getOrNull:r(null),getOrUndefined:r(void 0),or:n,orThunk:g,map:t,each:function(){},bind:t,exists:u,forall:s,filter:function(){return l},toArray:function(){return[]},toString:r("none()")};function g(e){return e()}function m(e,r){for(var n=e.length,t=new Array(n),a=0;a>>0===o))throw RangeError("Invalid code point: "+o);16383<=(o<=65535?n.push(o):(o-=65536,n.push(55296+(o>>10),o%1024+56320)))&&(t+=String.fromCharCode.apply(null,n),n.length=0)}return t+String.fromCharCode.apply(null,n)}function v(e,r){var n=[],t=r.toLowerCase();return function(e){for(var r,a,i,o,c=0,u=e.length;c'+s+""),a.selection.select(a.$("#__new").removeAttr("id")[0])}),(function(e){a.dom.setAttrib(e,"class","language-"+r),e.innerHTML=s,h(a).highlightElement(e),a.selection.select(e)}))})),e.close()}})}!function(e,n){var t,a,r=window.Prism;window.Prism={manual:!0},t=this,a=function(){var e,n,t,a,r,s,i,o,l,u,c="undefined"!=typeof globalThis?globalThis:"undefined"!=typeof window?window:f,d={exports:{}};function p(e,n){return"___"+e.toUpperCase()+n+"___"}return e=d,n=function(e){var n=/\blang(?:uage)?-([\w-]+)\b/i,t=0,a={},r={manual:e.Prism&&e.Prism.manual,disableWorkerMessageHandler:e.Prism&&e.Prism.disableWorkerMessageHandler,util:{encode:function e(n){return n instanceof s?new s(n.type,e(n.content),n.alias):Array.isArray(n)?n.map(e):n.replace(/&/g,"&").replace(/=c.reach);_+=v.value.length,v=v.next){var x=v.value;if(t.length>n.length)return;if(!(x instanceof s)){var F,P=1;if(y){if(!(F=i(k,_,n,h)))break;var A=F.index,S=F.index+F[0].length,$=_;for($+=v.value.length;$<=A;)$+=(v=v.next).value.length;if(_=$-=v.value.length,v.value instanceof s)continue;for(var z=v;z!==t.tail&&($c.reach&&(c.reach=T);var O=v.prev;C&&(O=l(t,O,C),_+=C.length),function(e,n,t){for(var a=n.next,r=0;rc.reach&&(c.reach=N.reach))}}}}(e,u,n,u.head,0),function(e){for(var n=[],t=e.head.next;t!==e.tail;)n.push(t.value),t=t.next;return n}(u)},hooks:{all:{},add:function(e,n){var t=r.hooks.all;t[e]=t[e]||[],t[e].push(n)},run:function(e,n){var t=r.hooks.all[e];if(t&&t.length)for(var a,s=0;a=t[s++];)a(n)}},Token:s};function s(e,n,t,a){this.type=e,this.content=n,this.alias=t,this.length=0|(a||"").length}function i(e,n,t,a){e.lastIndex=n;var r,s=e.exec(t);return s&&a&&s[1]&&(r=s[1].length,s.index+=r,s[0]=s[0].slice(r)),s}function o(){var e={value:null,prev:null,next:null},n={value:null,prev:e,next:null};e.next=n,this.head=e,this.tail=n,this.length=0}function l(e,n,t){var a=n.next,r={value:t,prev:n,next:a};return n.next=r,a.prev=r,e.length++,r}if(e.Prism=r,s.stringify=function e(n,t){if("string"==typeof n)return n;if(Array.isArray(n)){var a="";return n.forEach((function(n){a+=e(n,t)})),a}var s={type:n.type,content:e(n.content,t),tag:"span",classes:["token",n.type],attributes:{},language:t},i=n.alias;i&&(Array.isArray(i)?Array.prototype.push.apply(s.classes,i):s.classes.push(i)),r.hooks.run("wrap",s);var o,l="";for(o in s.attributes)l+=" "+o+'="'+(s.attributes[o]||"").replace(/"/g,""")+'"';return"<"+s.tag+' class="'+s.classes.join(" ")+'"'+l+">"+s.content+""},!e.document)return e.addEventListener&&(r.disableWorkerMessageHandler||e.addEventListener("message",(function(n){var t=JSON.parse(n.data),a=t.language,s=t.code,i=t.immediateClose;e.postMessage(r.highlight(s,r.languages[a],a)),i&&e.close()}),!1)),r;var u,c=r.util.currentScript();function d(){r.manual||r.highlightAll()}return c&&(r.filename=c.src,c.hasAttribute("data-manual")&&(r.manual=!0)),r.manual||("loading"===(u=document.readyState)||"interactive"===u&&c&&c.defer?document.addEventListener("DOMContentLoaded",d):window.requestAnimationFrame?window.requestAnimationFrame(d):window.setTimeout(d,16)),r}("undefined"!=typeof window?window:"undefined"!=typeof WorkerGlobalScope&&self instanceof WorkerGlobalScope?self:{}),e.exports&&(e.exports=n),void 0!==c&&(c.Prism=n),Prism.languages.clike={comment:[{pattern:/(^|[^\\])\/\*[\s\S]*?(?:\*\/|$)/,lookbehind:!0,greedy:!0},{pattern:/(^|[^\\:])\/\/.*/,lookbehind:!0,greedy:!0}],string:{pattern:/(["'])(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/,greedy:!0},"class-name":{pattern:/(\b(?:class|interface|extends|implements|trait|instanceof|new)\s+|\bcatch\s+\()[\w.\\]+/i,lookbehind:!0,inside:{punctuation:/[.\\]/}},keyword:/\b(?:if|else|while|do|for|return|in|instanceof|function|new|try|throw|catch|finally|null|break|continue)\b/,boolean:/\b(?:true|false)\b/,function:/\b\w+(?=\()/,number:/\b0x[\da-f]+\b|(?:\b\d+(?:\.\d*)?|\B\.\d+)(?:e[+-]?\d+)?/i,operator:/[<>]=?|[!=]=?=?|--?|\+\+?|&&?|\|\|?|[?*/~^%]/,punctuation:/[{}[\];(),.:]/},t=Prism,Object.defineProperties(t.languages["markup-templating"]={},{buildPlaceholders:{value:function(e,n,a,r){var s;e.language===n&&(s=e.tokenStack=[],e.code=e.code.replace(a,(function(t){if("function"==typeof r&&!r(t))return t;for(var a,i=s.length;-1!==e.code.indexOf(a=p(n,i));)++i;return s[i]=t,a})),e.grammar=t.languages.markup)}},tokenizePlaceholders:{value:function(e,n){var a,r;e.language===n&&e.tokenStack&&(e.grammar=t.languages[n],a=0,r=Object.keys(e.tokenStack),function s(i){for(var o=0;o=r.length);o++){var l,u,c,d,g,b,m,f,h,y=i[o];"string"==typeof y||y.content&&"string"==typeof y.content?(l=r[a],u=e.tokenStack[l],c="string"==typeof y?y:y.content,d=p(n,l),-1<(g=c.indexOf(d))&&(++a,b=c.substring(0,g),m=new t.Token(n,t.tokenize(u,e.grammar),"language-"+n,u),f=c.substring(g+d.length),h=[],b&&h.push.apply(h,s([b])),h.push(m),f&&h.push.apply(h,s([f])),"string"==typeof y?i.splice.apply(i,[o,1].concat(h)):y.content=h)):y.content&&s(y.content)}return i}(e.tokens))}}}),Prism.languages.c=Prism.languages.extend("clike",{comment:{pattern:/\/\/(?:[^\r\n\\]|\\(?:\r\n?|\n|(?![\r\n])))*|\/\*[\s\S]*?(?:\*\/|$)/,greedy:!0},"class-name":{pattern:/(\b(?:enum|struct)\s+(?:__attribute__\s*\(\([\s\S]*?\)\)\s*)?)\w+|\b[a-z]\w*_t\b/,lookbehind:!0},keyword:/\b(?:__attribute__|_Alignas|_Alignof|_Atomic|_Bool|_Complex|_Generic|_Imaginary|_Noreturn|_Static_assert|_Thread_local|asm|typeof|inline|auto|break|case|char|const|continue|default|do|double|else|enum|extern|float|for|goto|if|int|long|register|return|short|signed|sizeof|static|struct|switch|typedef|union|unsigned|void|volatile|while)\b/,function:/\b[a-z_]\w*(?=\s*\()/i,number:/(?:\b0x(?:[\da-f]+(?:\.[\da-f]*)?|\.[\da-f]+)(?:p[+-]?\d+)?|(?:\b\d+(?:\.\d*)?|\B\.\d+)(?:e[+-]?\d+)?)[ful]{0,4}/i,operator:/>>=?|<<=?|->|([-+&|:])\1|[?:~]|[-+*/%&|^!=<>]=?/}),Prism.languages.insertBefore("c","string",{macro:{pattern:/(^[\t ]*)#\s*[a-z](?:[^\r\n\\/]|\/(?!\*)|\/\*(?:[^*]|\*(?!\/))*\*\/|\\(?:\r\n|[\s\S]))*/im,lookbehind:!0,greedy:!0,alias:"property",inside:{string:[{pattern:/^(#\s*include\s*)<[^>]+>/,lookbehind:!0},Prism.languages.c.string],comment:Prism.languages.c.comment,"macro-name":[{pattern:/(^#\s*define\s+)\w+\b(?!\()/i,lookbehind:!0},{pattern:/(^#\s*define\s+)\w+\b(?=\()/i,lookbehind:!0,alias:"function"}],directive:{pattern:/^(#\s*)[a-z]+/,lookbehind:!0,alias:"keyword"},"directive-hash":/^#/,punctuation:/##|\\(?=[\r\n])/,expression:{pattern:/\S[\s\S]*/,inside:Prism.languages.c}}},constant:/\b(?:__FILE__|__LINE__|__DATE__|__TIME__|__TIMESTAMP__|__func__|EOF|NULL|SEEK_CUR|SEEK_END|SEEK_SET|stdin|stdout|stderr)\b/}),delete Prism.languages.c.boolean,a=Prism,r=/\b(?:alignas|alignof|asm|auto|bool|break|case|catch|char|char8_t|char16_t|char32_t|class|compl|concept|const|consteval|constexpr|constinit|const_cast|continue|co_await|co_return|co_yield|decltype|default|delete|do|double|dynamic_cast|else|enum|explicit|export|extern|final|float|for|friend|goto|if|import|inline|int|int8_t|int16_t|int32_t|int64_t|uint8_t|uint16_t|uint32_t|uint64_t|long|module|mutable|namespace|new|noexcept|nullptr|operator|override|private|protected|public|register|reinterpret_cast|requires|return|short|signed|sizeof|static|static_assert|static_cast|struct|switch|template|this|thread_local|throw|try|typedef|typeid|typename|union|unsigned|using|virtual|void|volatile|wchar_t|while)\b/,s=/\b(?!)\w+(?:\s*\.\s*\w+)*\b/.source.replace(//g,(function(){return r.source})),a.languages.cpp=a.languages.extend("c",{"class-name":[{pattern:RegExp(/(\b(?:class|concept|enum|struct|typename)\s+)(?!)\w+/.source.replace(//g,(function(){return r.source}))),lookbehind:!0},/\b[A-Z]\w*(?=\s*::\s*\w+\s*\()/,/\b[A-Z_]\w*(?=\s*::\s*~\w+\s*\()/i,/\b\w+(?=\s*<(?:[^<>]|<(?:[^<>]|<[^<>]*>)*>)*>\s*::\s*\w+\s*\()/],keyword:r,number:{pattern:/(?:\b0b[01']+|\b0x(?:[\da-f']+(?:\.[\da-f']*)?|\.[\da-f']+)(?:p[+-]?[\d']+)?|(?:\b[\d']+(?:\.[\d']*)?|\B\.[\d']+)(?:e[+-]?[\d']+)?)[ful]{0,4}/i,greedy:!0},operator:/>>=?|<<=?|->|--|\+\+|&&|\|\||[?:~]|<=>|[-+*/%&|^!=<>]=?|\b(?:and|and_eq|bitand|bitor|not|not_eq|or|or_eq|xor|xor_eq)\b/,boolean:/\b(?:true|false)\b/}),a.languages.insertBefore("cpp","string",{module:{pattern:RegExp(/(\b(?:module|import)\s+)/.source+"(?:"+/"(?:\\(?:\r\n|[\s\S])|[^"\\\r\n])*"|<[^<>\r\n]*>/.source+"|"+/(?:\s*:\s*)?|:\s*/.source.replace(//g,(function(){return s}))+")"),lookbehind:!0,greedy:!0,inside:{string:/^[<"][\s\S]+/,operator:/:/,punctuation:/\./}},"raw-string":{pattern:/R"([^()\\ ]{0,16})\([\s\S]*?\)\1"/,alias:"string",greedy:!0}}),a.languages.insertBefore("cpp","keyword",{"generic-function":{pattern:/\b(?!operator\b)[a-z_]\w*\s*<(?:[^<>]|<[^<>]*>)*>(?=\s*\()/i,inside:{function:/^\w+/,generic:{pattern:/<[\s\S]+/,alias:"class-name",inside:a.languages.cpp}}}}),a.languages.insertBefore("cpp","operator",{"double-colon":{pattern:/::/,alias:"punctuation"}}),a.languages.insertBefore("cpp","class-name",{"base-clause":{pattern:/(\b(?:class|struct)\s+\w+\s*:\s*)[^;{}"'\s]+(?:\s+[^;{}"'\s]+)*(?=\s*[;{])/,lookbehind:!0,greedy:!0,inside:a.languages.extend("cpp",{})}}),a.languages.insertBefore("inside","double-colon",{"class-name":/\b[a-z_]\w*\b(?!\s*::)/i},a.languages.cpp["base-clause"]),function(e){function n(e,n){return e.replace(/<<(\d+)>>/g,(function(e,t){return"(?:"+n[+t]+")"}))}function t(e,t,a){return RegExp(n(e,t),a||"")}function a(e,n){for(var t=0;t>/g,(function(){return"(?:"+e+")"}));return e.replace(/<>/g,"[^\\s\\S]")}var r="bool byte char decimal double dynamic float int long object sbyte short string uint ulong ushort var void",s="class enum interface record struct",i="add alias and ascending async await by descending from(?=\\s*(?:\\w|$)) get global group into init(?=\\s*;) join let nameof not notnull on or orderby partial remove select set unmanaged value when where with(?=\\s*{)",o="abstract as base break case catch checked const continue default delegate do else event explicit extern finally fixed for foreach goto if implicit in internal is lock namespace new null operator out override params private protected public readonly ref return sealed sizeof stackalloc static switch this throw try typeof unchecked unsafe using virtual volatile while yield";function l(e){return"\\b(?:"+e.trim().replace(/ /g,"|")+")\\b"}var u=l(s),c=RegExp(l(r+" "+s+" "+i+" "+o)),d=l(s+" "+i+" "+o),p=l(r+" "+s+" "+o),g=a(/<(?:[^<>;=+\-*/%&|^]|<>)*>/.source,2),b=a(/\((?:[^()]|<>)*\)/.source,2),m=/@?\b[A-Za-z_]\w*\b/.source,f=n(/<<0>>(?:\s*<<1>>)?/.source,[m,g]),h=n(/(?!<<0>>)<<1>>(?:\s*\.\s*<<1>>)*/.source,[d,f]),y=/\[\s*(?:,\s*)*\]/.source,w=n(/<<0>>(?:\s*(?:\?\s*)?<<1>>)*(?:\s*\?)?/.source,[h,y]),k=n(/[^,()<>[\];=+\-*/%&|^]|<<0>>|<<1>>|<<2>>/.source,[g,b,y]),v=n(/\(<<0>>+(?:,<<0>>+)+\)/.source,[k]),_=n(/(?:<<0>>|<<1>>)(?:\s*(?:\?\s*)?<<2>>)*(?:\s*\?)?/.source,[v,h,y]),x={keyword:c,punctuation:/[<>()?,.:[\]]/},F=/'(?:[^\r\n'\\]|\\.|\\[Uux][\da-fA-F]{1,8})'/.source,P=/"(?:\\.|[^\\"\r\n])*"/.source;e.languages.csharp=e.languages.extend("clike",{string:[{pattern:t(/(^|[^$\\])<<0>>/.source,[/@"(?:""|\\[\s\S]|[^\\"])*"(?!")/.source]),lookbehind:!0,greedy:!0},{pattern:t(/(^|[^@$\\])<<0>>/.source,[P]),lookbehind:!0,greedy:!0},{pattern:RegExp(F),greedy:!0,alias:"character"}],"class-name":[{pattern:t(/(\busing\s+static\s+)<<0>>(?=\s*;)/.source,[h]),lookbehind:!0,inside:x},{pattern:t(/(\busing\s+<<0>>\s*=\s*)<<1>>(?=\s*;)/.source,[m,_]),lookbehind:!0,inside:x},{pattern:t(/(\busing\s+)<<0>>(?=\s*=)/.source,[m]),lookbehind:!0},{pattern:t(/(\b<<0>>\s+)<<1>>/.source,[u,f]),lookbehind:!0,inside:x},{pattern:t(/(\bcatch\s*\(\s*)<<0>>/.source,[h]),lookbehind:!0,inside:x},{pattern:t(/(\bwhere\s+)<<0>>/.source,[m]),lookbehind:!0},{pattern:t(/(\b(?:is(?:\s+not)?|as)\s+)<<0>>/.source,[w]),lookbehind:!0,inside:x},{pattern:t(/\b<<0>>(?=\s+(?!<<1>>|with\s*\{)<<2>>(?:\s*[=,;:{)\]]|\s+(?:in|when)\b))/.source,[_,p,m]),inside:x}],keyword:c,number:/(?:\b0(?:x[\da-f_]*[\da-f]|b[01_]*[01])|(?:\B\.\d+(?:_+\d+)*|\b\d+(?:_+\d+)*(?:\.\d+(?:_+\d+)*)?)(?:e[-+]?\d+(?:_+\d+)*)?)(?:ul|lu|[dflmu])?\b/i,operator:/>>=?|<<=?|[-=]>|([-+&|])\1|~|\?\?=?|[-+*/%&|^!=<>]=?/,punctuation:/\?\.?|::|[{}[\];(),.:]/}),e.languages.insertBefore("csharp","number",{range:{pattern:/\.\./,alias:"operator"}}),e.languages.insertBefore("csharp","punctuation",{"named-parameter":{pattern:t(/([(,]\s*)<<0>>(?=\s*:)/.source,[m]),lookbehind:!0,alias:"punctuation"}}),e.languages.insertBefore("csharp","class-name",{namespace:{pattern:t(/(\b(?:namespace|using)\s+)<<0>>(?:\s*\.\s*<<0>>)*(?=\s*[;{])/.source,[m]),lookbehind:!0,inside:{punctuation:/\./}},"type-expression":{pattern:t(/(\b(?:default|typeof|sizeof)\s*\(\s*(?!\s))(?:[^()\s]|\s(?!\s)|<<0>>)*(?=\s*\))/.source,[b]),lookbehind:!0,alias:"class-name",inside:x},"return-type":{pattern:t(/<<0>>(?=\s+(?:<<1>>\s*(?:=>|[({]|\.\s*this\s*\[)|this\s*\[))/.source,[_,h]),inside:x,alias:"class-name"},"constructor-invocation":{pattern:t(/(\bnew\s+)<<0>>(?=\s*[[({])/.source,[_]),lookbehind:!0,inside:x,alias:"class-name"},"generic-method":{pattern:t(/<<0>>\s*<<1>>(?=\s*\()/.source,[m,g]),inside:{function:t(/^<<0>>/.source,[m]),generic:{pattern:RegExp(g),alias:"class-name",inside:x}}},"type-list":{pattern:t(/\b((?:<<0>>\s+<<1>>|record\s+<<1>>\s*<<5>>|where\s+<<2>>)\s*:\s*)(?:<<3>>|<<4>>|<<1>>\s*<<5>>|<<6>>)(?:\s*,\s*(?:<<3>>|<<4>>|<<6>>))*(?=\s*(?:where|[{;]|=>|$))/.source,[u,f,m,_,c.source,b,/\bnew\s*\(\s*\)/.source]),lookbehind:!0,inside:{"record-arguments":{pattern:t(/(^(?!new\s*\()<<0>>\s*)<<1>>/.source,[f,b]),lookbehind:!0,greedy:!0,inside:e.languages.csharp},keyword:c,"class-name":{pattern:RegExp(_),greedy:!0,inside:x},punctuation:/[,()]/}},preprocessor:{pattern:/(^[\t ]*)#.*/m,lookbehind:!0,alias:"property",inside:{directive:{pattern:/(#)\b(?:define|elif|else|endif|endregion|error|if|line|nullable|pragma|region|undef|warning)\b/,lookbehind:!0,alias:"keyword"}}}});var A=P+"|"+F,S=n(/\/(?![*/])|\/\/[^\r\n]*[\r\n]|\/\*(?:[^*]|\*(?!\/))*\*\/|<<0>>/.source,[A]),$=a(n(/[^"'/()]|<<0>>|\(<>*\)/.source,[S]),2),z=/\b(?:assembly|event|field|method|module|param|property|return|type)\b/.source,E=n(/<<0>>(?:\s*\(<<1>>*\))?/.source,[h,$]);e.languages.insertBefore("csharp","class-name",{attribute:{pattern:t(/((?:^|[^\s\w>)?])\s*\[\s*)(?:<<0>>\s*:\s*)?<<1>>(?:\s*,\s*<<1>>)*(?=\s*\])/.source,[z,E]),lookbehind:!0,greedy:!0,inside:{target:{pattern:t(/^<<0>>(?=\s*:)/.source,[z]),alias:"keyword"},"attribute-arguments":{pattern:t(/\(<<0>>*\)/.source,[$]),inside:e.languages.csharp},"class-name":{pattern:RegExp(h),inside:{punctuation:/\./}},punctuation:/[:,]/}}});var C=/:[^}\r\n]+/.source,j=a(n(/[^"'/()]|<<0>>|\(<>*\)/.source,[S]),2),T=n(/\{(?!\{)(?:(?![}:])<<0>>)*<<1>>?\}/.source,[j,C]),O=a(n(/[^"'/()]|\/(?!\*)|\/\*(?:[^*]|\*(?!\/))*\*\/|<<0>>|\(<>*\)/.source,[A]),2),N=n(/\{(?!\{)(?:(?![}:])<<0>>)*<<1>>?\}/.source,[O,C]);function B(n,a){return{interpolation:{pattern:t(/((?:^|[^{])(?:\{\{)*)<<0>>/.source,[n]),lookbehind:!0,inside:{"format-string":{pattern:t(/(^\{(?:(?![}:])<<0>>)*)<<1>>(?=\}$)/.source,[a,C]),lookbehind:!0,inside:{punctuation:/^:/}},punctuation:/^\{|\}$/,expression:{pattern:/[\s\S]+/,alias:"language-csharp",inside:e.languages.csharp}}},string:/[\s\S]+/}}e.languages.insertBefore("csharp","string",{"interpolation-string":[{pattern:t(/(^|[^\\])(?:\$@|@\$)"(?:""|\\[\s\S]|\{\{|<<0>>|[^\\{"])*"/.source,[T]),lookbehind:!0,greedy:!0,inside:B(T,j)},{pattern:t(/(^|[^@\\])\$"(?:\\.|\{\{|<<0>>|[^\\"{])*"/.source,[N]),lookbehind:!0,greedy:!0,inside:B(N,O)}]})}(Prism),Prism.languages.dotnet=Prism.languages.cs=Prism.languages.csharp,function(e){var n=/(?:"(?:\\(?:\r\n|[\s\S])|[^"\\\r\n])*"|'(?:\\(?:\r\n|[\s\S])|[^'\\\r\n])*')/;e.languages.css={comment:/\/\*[\s\S]*?\*\//,atrule:{pattern:/@[\w-](?:[^;{\s]|\s+(?![\s{]))*(?:;|(?=\s*\{))/,inside:{rule:/^@[\w-]+/,"selector-function-argument":{pattern:/(\bselector\s*\(\s*(?![\s)]))(?:[^()\s]|\s+(?![\s)])|\((?:[^()]|\([^()]*\))*\))+(?=\s*\))/,lookbehind:!0,alias:"selector"},keyword:{pattern:/(^|[^\w-])(?:and|not|only|or)(?![\w-])/,lookbehind:!0}}},url:{pattern:RegExp("\\burl\\((?:"+n.source+"|"+/(?:[^\\\r\n()"']|\\[\s\S])*/.source+")\\)","i"),greedy:!0,inside:{function:/^url/i,punctuation:/^\(|\)$/,string:{pattern:RegExp("^"+n.source+"$"),alias:"url"}}},selector:{pattern:RegExp("(^|[{}\\s])[^{}\\s](?:[^{};\"'\\s]|\\s+(?![\\s{])|"+n.source+")*(?=\\s*\\{)"),lookbehind:!0},string:{pattern:n,greedy:!0},property:{pattern:/(^|[^-\w\xA0-\uFFFF])(?!\s)[-_a-z\xA0-\uFFFF](?:(?!\s)[-\w\xA0-\uFFFF])*(?=\s*:)/i,lookbehind:!0},important:/!important\b/i,function:{pattern:/(^|[^-a-z0-9])[-a-z0-9]+(?=\()/i,lookbehind:!0},punctuation:/[(){};:,]/},e.languages.css.atrule.inside.rest=e.languages.css;var t=e.languages.markup;t&&(t.tag.addInlined("style","css"),t.tag.addAttribute("style","css"))}(Prism),i=Prism,o=/\b(?:abstract|assert|boolean|break|byte|case|catch|char|class|const|continue|default|do|double|else|enum|exports|extends|final|finally|float|for|goto|if|implements|import|instanceof|int|interface|long|module|native|new|non-sealed|null|open|opens|package|permits|private|protected|provides|public|record|requires|return|sealed|short|static|strictfp|super|switch|synchronized|this|throw|throws|to|transient|transitive|try|uses|var|void|volatile|while|with|yield)\b/,l=/(^|[^\w.])(?:[a-z]\w*\s*\.\s*)*(?:[A-Z]\w*\s*\.\s*)*/.source,u={pattern:RegExp(l+/[A-Z](?:[\d_A-Z]*[a-z]\w*)?\b/.source),lookbehind:!0,inside:{namespace:{pattern:/^[a-z]\w*(?:\s*\.\s*[a-z]\w*)*(?:\s*\.)?/,inside:{punctuation:/\./}},punctuation:/\./}},i.languages.java=i.languages.extend("clike",{"class-name":[u,{pattern:RegExp(l+/[A-Z]\w*(?=\s+\w+\s*[;,=()])/.source),lookbehind:!0,inside:u.inside}],keyword:o,function:[i.languages.clike.function,{pattern:/(::\s*)[a-z_]\w*/,lookbehind:!0}],number:/\b0b[01][01_]*L?\b|\b0x(?:\.[\da-f_p+-]+|[\da-f_]+(?:\.[\da-f_p+-]+)?)\b|(?:\b\d[\d_]*(?:\.[\d_]*)?|\B\.\d[\d_]*)(?:e[+-]?\d[\d_]*)?[dfl]?/i,operator:{pattern:/(^|[^.])(?:<<=?|>>>?=?|->|--|\+\+|&&|\|\||::|[?:~]|[-+*/%&|^!=<>]=?)/m,lookbehind:!0}}),i.languages.insertBefore("java","string",{"triple-quoted-string":{pattern:/"""[ \t]*[\r\n](?:(?:"|"")?(?:\\.|[^"\\]))*"""/,greedy:!0,alias:"string"}}),i.languages.insertBefore("java","class-name",{annotation:{pattern:/(^|[^.])@\w+(?:\s*\.\s*\w+)*/,lookbehind:!0,alias:"punctuation"},generics:{pattern:/<(?:[\w\s,.?]|&(?!&)|<(?:[\w\s,.?]|&(?!&)|<(?:[\w\s,.?]|&(?!&)|<(?:[\w\s,.?]|&(?!&))*>)*>)*>)*>/,inside:{"class-name":u,keyword:o,punctuation:/[<>(),.:]/,operator:/[?&|]/}},namespace:{pattern:RegExp(/(\b(?:exports|import(?:\s+static)?|module|open|opens|package|provides|requires|to|transitive|uses|with)\s+)(?!)[a-z]\w*(?:\.[a-z]\w*)*\.?/.source.replace(//g,(function(){return o.source}))),lookbehind:!0,inside:{punctuation:/\./}}}),Prism.languages.javascript=Prism.languages.extend("clike",{"class-name":[Prism.languages.clike["class-name"],{pattern:/(^|[^$\w\xA0-\uFFFF])(?!\s)[_$A-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\.(?:prototype|constructor))/,lookbehind:!0}],keyword:[{pattern:/((?:^|\})\s*)catch\b/,lookbehind:!0},{pattern:/(^|[^.]|\.\.\.\s*)\b(?:as|assert(?=\s*\{)|async(?=\s*(?:function\b|\(|[$\w\xA0-\uFFFF]|$))|await|break|case|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally(?=\s*(?:\{|$))|for|from(?=\s*(?:['"]|$))|function|(?:get|set)(?=\s*(?:[#\[$\w\xA0-\uFFFF]|$))|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|static|super|switch|this|throw|try|typeof|undefined|var|void|while|with|yield)\b/,lookbehind:!0}],function:/#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*(?:\.\s*(?:apply|bind|call)\s*)?\()/,number:/\b(?:(?:0[xX](?:[\dA-Fa-f](?:_[\dA-Fa-f])?)+|0[bB](?:[01](?:_[01])?)+|0[oO](?:[0-7](?:_[0-7])?)+)n?|(?:\d(?:_\d)?)+n|NaN|Infinity)\b|(?:\b(?:\d(?:_\d)?)+\.?(?:\d(?:_\d)?)*|\B\.(?:\d(?:_\d)?)+)(?:[Ee][+-]?(?:\d(?:_\d)?)+)?/,operator:/--|\+\+|\*\*=?|=>|&&=?|\|\|=?|[!=]==|<<=?|>>>?=?|[-+*/%&|^!=<>]=?|\.{3}|\?\?=?|\?\.?|[~:]/}),Prism.languages.javascript["class-name"][0].pattern=/(\b(?:class|interface|extends|implements|instanceof|new)\s+)[\w.\\]+/,Prism.languages.insertBefore("javascript","keyword",{regex:{pattern:/((?:^|[^$\w\xA0-\uFFFF."'\])\s]|\b(?:return|yield))\s*)\/(?:\[(?:[^\]\\\r\n]|\\.)*\]|\\.|[^/\\\[\r\n])+\/[dgimyus]{0,7}(?=(?:\s|\/\*(?:[^*]|\*(?!\/))*\*\/)*(?:$|[\r\n,.;:})\]]|\/\/))/,lookbehind:!0,greedy:!0,inside:{"regex-source":{pattern:/^(\/)[\s\S]+(?=\/[a-z]*$)/,lookbehind:!0,alias:"language-regex",inside:Prism.languages.regex},"regex-delimiter":/^\/|\/$/,"regex-flags":/^[a-z]+$/}},"function-variable":{pattern:/#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*[=:]\s*(?:async\s*)?(?:\bfunction\b|(?:\((?:[^()]|\([^()]*\))*\)|(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*)\s*=>))/,alias:"function"},parameter:[{pattern:/(function(?:\s+(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*)?\s*\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\))/,lookbehind:!0,inside:Prism.languages.javascript},{pattern:/(^|[^$\w\xA0-\uFFFF])(?!\s)[_$a-z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*=>)/i,lookbehind:!0,inside:Prism.languages.javascript},{pattern:/(\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\)\s*=>)/,lookbehind:!0,inside:Prism.languages.javascript},{pattern:/((?:\b|\s|^)(?!(?:as|async|await|break|case|catch|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally|for|from|function|get|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|set|static|super|switch|this|throw|try|typeof|undefined|var|void|while|with|yield)(?![$\w\xA0-\uFFFF]))(?:(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*\s*)\(\s*|\]\s*\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\)\s*\{)/,lookbehind:!0,inside:Prism.languages.javascript}],constant:/\b[A-Z](?:[A-Z_]|\dx?)*\b/}),Prism.languages.insertBefore("javascript","string",{hashbang:{pattern:/^#!.*/,greedy:!0,alias:"comment"},"template-string":{pattern:/`(?:\\[\s\S]|\$\{(?:[^{}]|\{(?:[^{}]|\{[^}]*\})*\})+\}|(?!\$\{)[^\\`])*`/,greedy:!0,inside:{"template-punctuation":{pattern:/^`|`$/,alias:"string"},interpolation:{pattern:/((?:^|[^\\])(?:\\{2})*)\$\{(?:[^{}]|\{(?:[^{}]|\{[^}]*\})*\})+\}/,lookbehind:!0,inside:{"interpolation-punctuation":{pattern:/^\$\{|\}$/,alias:"punctuation"},rest:Prism.languages.javascript}},string:/[\s\S]+/}}}),Prism.languages.markup&&(Prism.languages.markup.tag.addInlined("script","javascript"),Prism.languages.markup.tag.addAttribute(/on(?:abort|blur|change|click|composition(?:end|start|update)|dblclick|error|focus(?:in|out)?|key(?:down|up)|load|mouse(?:down|enter|leave|move|out|over|up)|reset|resize|scroll|select|slotchange|submit|unload|wheel)/.source,"javascript")),Prism.languages.js=Prism.languages.javascript,Prism.languages.markup={comment:{pattern://,greedy:!0},prolog:{pattern:/<\?[\s\S]+?\?>/,greedy:!0},doctype:{pattern:/"'[\]]|"[^"]*"|'[^']*')+(?:\[(?:[^<"'\]]|"[^"]*"|'[^']*'|<(?!!--)|)*\]\s*)?>/i,greedy:!0,inside:{"internal-subset":{pattern:/(^[^\[]*\[)[\s\S]+(?=\]>$)/,lookbehind:!0,greedy:!0,inside:null},string:{pattern:/"[^"]*"|'[^']*'/,greedy:!0},punctuation:/^$|[[\]]/,"doctype-tag":/^DOCTYPE/i,name:/[^\s<>'"]+/}},cdata:{pattern://i,greedy:!0},tag:{pattern:/<\/?(?!\d)[^\s>\/=$<%]+(?:\s(?:\s*[^\s>\/=]+(?:\s*=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+(?=[\s>]))|(?=[\s/>])))+)?\s*\/?>/,greedy:!0,inside:{tag:{pattern:/^<\/?[^\s>\/]+/,inside:{punctuation:/^<\/?/,namespace:/^[^\s>\/:]+:/}},"special-attr":[],"attr-value":{pattern:/=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+)/,inside:{punctuation:[{pattern:/^=/,alias:"attr-equals"},/"|'/]}},punctuation:/\/?>/,"attr-name":{pattern:/[^\s>\/]+/,inside:{namespace:/^[^\s>\/:]+:/}}}},entity:[{pattern:/&[\da-z]{1,8};/i,alias:"named-entity"},/&#x?[\da-f]{1,8};/i]},Prism.languages.markup.tag.inside["attr-value"].inside.entity=Prism.languages.markup.entity,Prism.languages.markup.doctype.inside["internal-subset"].inside=Prism.languages.markup,Prism.hooks.add("wrap",(function(e){"entity"===e.type&&(e.attributes.title=e.content.replace(/&/,"&"))})),Object.defineProperty(Prism.languages.markup.tag,"addInlined",{value:function(e,n){var t={};t["language-"+n]={pattern:/(^$)/i,lookbehind:!0,inside:Prism.languages[n]},t.cdata=/^$/i;var a={"included-cdata":{pattern://i,inside:t}};a["language-"+n]={pattern:/[\s\S]+/,inside:Prism.languages[n]};var r={};r[e]={pattern:RegExp(/(<__[^>]*>)(?:))*\]\]>|(?!)/.source.replace(/__/g,(function(){return e})),"i"),lookbehind:!0,greedy:!0,inside:a},Prism.languages.insertBefore("markup","cdata",r)}}),Object.defineProperty(Prism.languages.markup.tag,"addAttribute",{value:function(e,n){Prism.languages.markup.tag.inside["special-attr"].push({pattern:RegExp(/(^|["'\s])/.source+"(?:"+e+")"+/\s*=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+(?=[\s>]))/.source,"i"),lookbehind:!0,inside:{"attr-name":/^[^\s=]+/,"attr-value":{pattern:/=[\s\S]+/,inside:{value:{pattern:/(^=\s*(["']|(?!["'])))\S[\s\S]*(?=\2$)/,lookbehind:!0,alias:[n,"language-"+n],inside:Prism.languages[n]},punctuation:[{pattern:/^=/,alias:"attr-equals"},/"|'/]}}}})}}),Prism.languages.html=Prism.languages.markup,Prism.languages.mathml=Prism.languages.markup,Prism.languages.svg=Prism.languages.markup,Prism.languages.xml=Prism.languages.extend("markup",{}),Prism.languages.ssml=Prism.languages.xml,Prism.languages.atom=Prism.languages.xml,Prism.languages.rss=Prism.languages.xml,function(e){var n=/\/\*[\s\S]*?\*\/|\/\/.*|#(?!\[).*/,t=[{pattern:/\b(?:false|true)\b/i,alias:"boolean"},{pattern:/(::\s*)\b[a-z_]\w*\b(?!\s*\()/i,greedy:!0,lookbehind:!0},{pattern:/(\b(?:case|const)\s+)\b[a-z_]\w*(?=\s*[;=])/i,greedy:!0,lookbehind:!0},/\b(?:null)\b/i,/\b[A-Z_][A-Z0-9_]*\b(?!\s*\()/],a=/\b0b[01]+(?:_[01]+)*\b|\b0o[0-7]+(?:_[0-7]+)*\b|\b0x[\da-f]+(?:_[\da-f]+)*\b|(?:\b\d+(?:_\d+)*\.?(?:\d+(?:_\d+)*)?|\B\.\d+)(?:e[+-]?\d+)?/i,r=/|\?\?=?|\.{3}|\??->|[!=]=?=?|::|\*\*=?|--|\+\+|&&|\|\||<<|>>|[?~]|[/^|%*&<>.+-]=?/,s=/[{}\[\](),:;]/;e.languages.php={delimiter:{pattern:/\?>$|^<\?(?:php(?=\s)|=)?/i,alias:"important"},comment:n,variable:/\$+(?:\w+\b|(?=\{))/i,package:{pattern:/(namespace\s+|use\s+(?:function\s+)?)(?:\\?\b[a-z_]\w*)+\b(?!\\)/i,lookbehind:!0,inside:{punctuation:/\\/}},"class-name-definition":{pattern:/(\b(?:class|enum|interface|trait)\s+)\b[a-z_]\w*(?!\\)\b/i,lookbehind:!0,alias:"class-name"},"function-definition":{pattern:/(\bfunction\s+)[a-z_]\w*(?=\s*\()/i,lookbehind:!0,alias:"function"},keyword:[{pattern:/(\(\s*)\b(?:bool|boolean|int|integer|float|string|object|array)\b(?=\s*\))/i,alias:"type-casting",greedy:!0,lookbehind:!0},{pattern:/([(,?]\s*)\b(?:bool|int|float|string|object|array(?!\s*\()|mixed|self|static|callable|iterable|(?:null|false)(?=\s*\|))\b(?=\s*\$)/i,alias:"type-hint",greedy:!0,lookbehind:!0},{pattern:/([(,?]\s*[\w|]\|\s*)(?:null|false)\b(?=\s*\$)/i,alias:"type-hint",greedy:!0,lookbehind:!0},{pattern:/(\)\s*:\s*(?:\?\s*)?)\b(?:bool|int|float|string|object|void|array(?!\s*\()|mixed|self|static|callable|iterable|(?:null|false)(?=\s*\|))\b/i,alias:"return-type",greedy:!0,lookbehind:!0},{pattern:/(\)\s*:\s*(?:\?\s*)?[\w|]\|\s*)(?:null|false)\b/i,alias:"return-type",greedy:!0,lookbehind:!0},{pattern:/\b(?:bool|int|float|string|object|void|array(?!\s*\()|mixed|iterable|(?:null|false)(?=\s*\|))\b/i,alias:"type-declaration",greedy:!0},{pattern:/(\|\s*)(?:null|false)\b/i,alias:"type-declaration",greedy:!0,lookbehind:!0},{pattern:/\b(?:parent|self|static)(?=\s*::)/i,alias:"static-context",greedy:!0},{pattern:/(\byield\s+)from\b/i,lookbehind:!0},/\bclass\b/i,{pattern:/((?:^|[^\s>:]|(?:^|[^-])>|(?:^|[^:]):)\s*)\b(?:__halt_compiler|abstract|and|array|as|break|callable|case|catch|clone|const|continue|declare|default|die|do|echo|else|elseif|empty|enddeclare|endfor|endforeach|endif|endswitch|endwhile|enum|eval|exit|extends|final|finally|fn|for|foreach|function|global|goto|if|implements|include|include_once|instanceof|insteadof|interface|isset|list|namespace|match|new|or|parent|print|private|protected|public|require|require_once|return|self|static|switch|throw|trait|try|unset|use|var|while|xor|yield)\b/i,lookbehind:!0}],"argument-name":{pattern:/([(,]\s+)\b[a-z_]\w*(?=\s*:(?!:))/i,lookbehind:!0},"class-name":[{pattern:/(\b(?:extends|implements|instanceof|new(?!\s+self|\s+static))\s+|\bcatch\s*\()\b[a-z_]\w*(?!\\)\b/i,greedy:!0,lookbehind:!0},{pattern:/(\|\s*)\b[a-z_]\w*(?!\\)\b/i,greedy:!0,lookbehind:!0},{pattern:/\b[a-z_]\w*(?!\\)\b(?=\s*\|)/i,greedy:!0},{pattern:/(\|\s*)(?:\\?\b[a-z_]\w*)+\b/i,alias:"class-name-fully-qualified",greedy:!0,lookbehind:!0,inside:{punctuation:/\\/}},{pattern:/(?:\\?\b[a-z_]\w*)+\b(?=\s*\|)/i,alias:"class-name-fully-qualified",greedy:!0,inside:{punctuation:/\\/}},{pattern:/(\b(?:extends|implements|instanceof|new(?!\s+self\b|\s+static\b))\s+|\bcatch\s*\()(?:\\?\b[a-z_]\w*)+\b(?!\\)/i,alias:"class-name-fully-qualified",greedy:!0,lookbehind:!0,inside:{punctuation:/\\/}},{pattern:/\b[a-z_]\w*(?=\s*\$)/i,alias:"type-declaration",greedy:!0},{pattern:/(?:\\?\b[a-z_]\w*)+(?=\s*\$)/i,alias:["class-name-fully-qualified","type-declaration"],greedy:!0,inside:{punctuation:/\\/}},{pattern:/\b[a-z_]\w*(?=\s*::)/i,alias:"static-context",greedy:!0},{pattern:/(?:\\?\b[a-z_]\w*)+(?=\s*::)/i,alias:["class-name-fully-qualified","static-context"],greedy:!0,inside:{punctuation:/\\/}},{pattern:/([(,?]\s*)[a-z_]\w*(?=\s*\$)/i,alias:"type-hint",greedy:!0,lookbehind:!0},{pattern:/([(,?]\s*)(?:\\?\b[a-z_]\w*)+(?=\s*\$)/i,alias:["class-name-fully-qualified","type-hint"],greedy:!0,lookbehind:!0,inside:{punctuation:/\\/}},{pattern:/(\)\s*:\s*(?:\?\s*)?)\b[a-z_]\w*(?!\\)\b/i,alias:"return-type",greedy:!0,lookbehind:!0},{pattern:/(\)\s*:\s*(?:\?\s*)?)(?:\\?\b[a-z_]\w*)+\b(?!\\)/i,alias:["class-name-fully-qualified","return-type"],greedy:!0,lookbehind:!0,inside:{punctuation:/\\/}}],constant:t,function:{pattern:/(^|[^\\\w])\\?[a-z_](?:[\w\\]*\w)?(?=\s*\()/i,lookbehind:!0,inside:{punctuation:/\\/}},property:{pattern:/(->\s*)\w+/,lookbehind:!0},number:a,operator:r,punctuation:s};var i={pattern:/\{\$(?:\{(?:\{[^{}]+\}|[^{}]+)\}|[^{}])+\}|(^|[^\\{])\$+(?:\w+(?:\[[^\r\n\[\]]+\]|->\w+)?)/,lookbehind:!0,inside:e.languages.php},o=[{pattern:/<<<'([^']+)'[\r\n](?:.*[\r\n])*?\1;/,alias:"nowdoc-string",greedy:!0,inside:{delimiter:{pattern:/^<<<'[^']+'|[a-z_]\w*;$/i,alias:"symbol",inside:{punctuation:/^<<<'?|[';]$/}}}},{pattern:/<<<(?:"([^"]+)"[\r\n](?:.*[\r\n])*?\1;|([a-z_]\w*)[\r\n](?:.*[\r\n])*?\2;)/i,alias:"heredoc-string",greedy:!0,inside:{delimiter:{pattern:/^<<<(?:"[^"]+"|[a-z_]\w*)|[a-z_]\w*;$/i,alias:"symbol",inside:{punctuation:/^<<<"?|[";]$/}},interpolation:i}},{pattern:/`(?:\\[\s\S]|[^\\`])*`/,alias:"backtick-quoted-string",greedy:!0},{pattern:/'(?:\\[\s\S]|[^\\'])*'/,alias:"single-quoted-string",greedy:!0},{pattern:/"(?:\\[\s\S]|[^\\"])*"/,alias:"double-quoted-string",greedy:!0,inside:{interpolation:i}}];e.languages.insertBefore("php","variable",{string:o,attribute:{pattern:/#\[(?:[^"'\/#]|\/(?![*/])|\/\/.*$|#(?!\[).*$|\/\*(?:[^*]|\*(?!\/))*\*\/|"(?:\\[\s\S]|[^\\"])*"|'(?:\\[\s\S]|[^\\'])*')+\](?=\s*[a-z$#])/im,greedy:!0,inside:{"attribute-content":{pattern:/^(#\[)[\s\S]+(?=\]$)/,lookbehind:!0,inside:{comment:n,string:o,"attribute-class-name":[{pattern:/([^:]|^)\b[a-z_]\w*(?!\\)\b/i,alias:"class-name",greedy:!0,lookbehind:!0},{pattern:/([^:]|^)(?:\\?\b[a-z_]\w*)+/i,alias:["class-name","class-name-fully-qualified"],greedy:!0,lookbehind:!0,inside:{punctuation:/\\/}}],constant:t,number:a,operator:r,punctuation:s}},delimiter:{pattern:/^#\[|\]$/,alias:"punctuation"}}}}),e.hooks.add("before-tokenize",(function(n){/<\?/.test(n.code)&&e.languages["markup-templating"].buildPlaceholders(n,"php",/<\?(?:[^"'/#]|\/(?![*/])|("|')(?:\\[\s\S]|(?!\1)[^\\])*\1|(?:\/\/|#(?!\[))(?:[^?\n\r]|\?(?!>))*(?=$|\?>|[\r\n])|#\[|\/\*(?:[^*]|\*(?!\/))*(?:\*\/|$))*?(?:\?>|$)/gi)})),e.hooks.add("after-tokenize",(function(n){e.languages["markup-templating"].tokenizePlaceholders(n,"php")}))}(Prism),Prism.languages.python={comment:{pattern:/(^|[^\\])#.*/,lookbehind:!0},"string-interpolation":{pattern:/(?:f|rf|fr)(?:("""|''')[\s\S]*?\1|("|')(?:\\.|(?!\2)[^\\\r\n])*\2)/i,greedy:!0,inside:{interpolation:{pattern:/((?:^|[^{])(?:\{\{)*)\{(?!\{)(?:[^{}]|\{(?!\{)(?:[^{}]|\{(?!\{)(?:[^{}])+\})+\})+\}/,lookbehind:!0,inside:{"format-spec":{pattern:/(:)[^:(){}]+(?=\}$)/,lookbehind:!0},"conversion-option":{pattern:/![sra](?=[:}]$)/,alias:"punctuation"},rest:null}},string:/[\s\S]+/}},"triple-quoted-string":{pattern:/(?:[rub]|rb|br)?("""|''')[\s\S]*?\1/i,greedy:!0,alias:"string"},string:{pattern:/(?:[rub]|rb|br)?("|')(?:\\.|(?!\1)[^\\\r\n])*\1/i,greedy:!0},function:{pattern:/((?:^|\s)def[ \t]+)[a-zA-Z_]\w*(?=\s*\()/g,lookbehind:!0},"class-name":{pattern:/(\bclass\s+)\w+/i,lookbehind:!0},decorator:{pattern:/(^[\t ]*)@\w+(?:\.\w+)*/im,lookbehind:!0,alias:["annotation","punctuation"],inside:{punctuation:/\./}},keyword:/\b(?:and|as|assert|async|await|break|class|continue|def|del|elif|else|except|exec|finally|for|from|global|if|import|in|is|lambda|nonlocal|not|or|pass|print|raise|return|try|while|with|yield)\b/,builtin:/\b(?:__import__|abs|all|any|apply|ascii|basestring|bin|bool|buffer|bytearray|bytes|callable|chr|classmethod|cmp|coerce|compile|complex|delattr|dict|dir|divmod|enumerate|eval|execfile|file|filter|float|format|frozenset|getattr|globals|hasattr|hash|help|hex|id|input|int|intern|isinstance|issubclass|iter|len|list|locals|long|map|max|memoryview|min|next|object|oct|open|ord|pow|property|range|raw_input|reduce|reload|repr|reversed|round|set|setattr|slice|sorted|staticmethod|str|sum|super|tuple|type|unichr|unicode|vars|xrange|zip)\b/,boolean:/\b(?:True|False|None)\b/,number:/\b0(?:b(?:_?[01])+|o(?:_?[0-7])+|x(?:_?[a-f0-9])+)\b|(?:\b\d+(?:_\d+)*(?:\.(?:\d+(?:_\d+)*)?)?|\B\.\d+(?:_\d+)*)(?:e[+-]?\d+(?:_\d+)*)?j?\b/i,operator:/[-+%=]=?|!=|\*\*?=?|\/\/?=?|<[<=>]?|>[=>]?|[&|^~]/,punctuation:/[{}[\];(),.:]/},Prism.languages.python["string-interpolation"].inside.interpolation.inside.rest=Prism.languages.python,Prism.languages.py=Prism.languages.python,function(e){e.languages.ruby=e.languages.extend("clike",{comment:[/#.*/,{pattern:/^=begin\s[\s\S]*?^=end/m,greedy:!0}],"class-name":{pattern:/(\b(?:class)\s+|\bcatch\s+\()[\w.\\]+/i,lookbehind:!0,inside:{punctuation:/[.\\]/}},keyword:/\b(?:alias|and|BEGIN|begin|break|case|class|def|define_method|defined|do|each|else|elsif|END|end|ensure|extend|for|if|in|include|module|new|next|nil|not|or|prepend|protected|private|public|raise|redo|require|rescue|retry|return|self|super|then|throw|undef|unless|until|when|while|yield)\b/});var n={pattern:/#\{[^}]+\}/,inside:{delimiter:{pattern:/^#\{|\}$/,alias:"tag"},rest:e.languages.ruby}};delete e.languages.ruby.function,e.languages.insertBefore("ruby","keyword",{regex:[{pattern:RegExp(/%r/.source+"(?:"+[/([^a-zA-Z0-9\s{(\[<])(?:(?!\1)[^\\]|\\[\s\S])*\1/.source,/\((?:[^()\\]|\\[\s\S])*\)/.source,/\{(?:[^#{}\\]|#(?:\{[^}]+\})?|\\[\s\S])*\}/.source,/\[(?:[^\[\]\\]|\\[\s\S])*\]/.source,/<(?:[^<>\\]|\\[\s\S])*>/.source].join("|")+")"+/[egimnosux]{0,6}/.source),greedy:!0,inside:{interpolation:n}},{pattern:/(^|[^/])\/(?!\/)(?:\[[^\r\n\]]+\]|\\.|[^[/\\\r\n])+\/[egimnosux]{0,6}(?=\s*(?:$|[\r\n,.;})#]))/,lookbehind:!0,greedy:!0,inside:{interpolation:n}}],variable:/[@$]+[a-zA-Z_]\w*(?:[?!]|\b)/,symbol:{pattern:/(^|[^:]):[a-zA-Z_]\w*(?:[?!]|\b)/,lookbehind:!0},"method-definition":{pattern:/(\bdef\s+)[\w.]+/,lookbehind:!0,inside:{function:/\w+$/,rest:e.languages.ruby}}}),e.languages.insertBefore("ruby","number",{builtin:/\b(?:Array|Bignum|Binding|Class|Continuation|Dir|Exception|FalseClass|File|Stat|Fixnum|Float|Hash|Integer|IO|MatchData|Method|Module|NilClass|Numeric|Object|Proc|Range|Regexp|String|Struct|TMS|Symbol|ThreadGroup|Thread|Time|TrueClass)\b/,constant:/\b[A-Z]\w*(?:[?!]|\b)/}),e.languages.ruby.string=[{pattern:RegExp(/%[qQiIwWxs]?/.source+"(?:"+[/([^a-zA-Z0-9\s{(\[<])(?:(?!\1)[^\\]|\\[\s\S])*\1/.source,/\((?:[^()\\]|\\[\s\S])*\)/.source,/\{(?:[^#{}\\]|#(?:\{[^}]+\})?|\\[\s\S])*\}/.source,/\[(?:[^\[\]\\]|\\[\s\S])*\]/.source,/<(?:[^<>\\]|\\[\s\S])*>/.source].join("|")+")"),greedy:!0,inside:{interpolation:n}},{pattern:/("|')(?:#\{[^}]+\}|#(?!\{)|\\(?:\r\n|[\s\S])|(?!\1)[^\\#\r\n])*\1/,greedy:!0,inside:{interpolation:n}},{pattern:/<<[-~]?([a-z_]\w*)[\r\n](?:.*[\r\n])*?[\t ]*\1/i,alias:"heredoc-string",greedy:!0,inside:{delimiter:{pattern:/^<<[-~]?[a-z_]\w*|[a-z_]\w*$/i,alias:"symbol",inside:{punctuation:/^<<[-~]?/}},interpolation:n}},{pattern:/<<[-~]?'([a-z_]\w*)'[\r\n](?:.*[\r\n])*?[\t ]*\1/i,alias:"heredoc-string",greedy:!0,inside:{delimiter:{pattern:/^<<[-~]?'[a-z_]\w*'|[a-z_]\w*$/i,alias:"symbol",inside:{punctuation:/^<<[-~]?'|'$/}}}}],e.languages.rb=e.languages.ruby}(Prism),{boltExport:d.exports}},"object"==typeof e&&void 0!==n?n.exports=a():(t="undefined"!=typeof globalThis?globalThis:t||self).EphoxContactWrapper=a(),window.Prism,window.Prism=r}(b,m);var k=m.exports.boltExport;a.add("codesample",(function(e){var n,t,a,r;function s(){return r.execCommand("codesample")}t=(n=e).$,n.on("PreProcess",(function(e){t("pre[contenteditable=false]",e.node).filter(u(l)).each((function(e,n){var a=t(n),r=n.textContent;a.attr("class",t.trim(a.attr("class"))),a.removeAttr("contentEditable"),a.empty().append(t("").each((function(){this.textContent=r})))}))})),n.on("SetContent",(function(){var e=t("pre").filter(u(l)).filter((function(e,n){return"false"!==n.contentEditable}));e.length&&n.undoManager.transact((function(){e.each((function(e,a){t(a).find("br").each((function(e,t){t.parentNode.replaceChild(n.getDoc().createTextNode("\n"),t)})),a.contentEditable="false",a.innerHTML=n.dom.encode(a.textContent),h(n).highlightElement(a),a.className=t.trim(a.className)}))}))})),(r=e).ui.registry.addToggleButton("codesample",{icon:"code-sample",tooltip:"Insert/edit code sample",onAction:s,onSetup:function(e){function n(){var n,t;e.setActive((t=(n=r).selection.getStart(),n.dom.is(t,'pre[class*="language-"]')))}return r.on("NodeChange",n),function(){return r.off("NodeChange",n)}}}),r.ui.registry.addMenuItem("codesample",{text:"Code sample...",icon:"code-sample",onAction:s}),(a=e).addCommand("codesample",(function(){var e=a.selection.getNode();a.selection.isCollapsed()||l(e)?w(a):a.formatter.toggle("code")})),e.on("dblclick",(function(n){l(n.target)&&w(e)}))}))}(); \ No newline at end of file diff --git a/website/admin/tinymce/plugins/colorpicker/plugin.min.js b/website/admin/tinymce/plugins/colorpicker/plugin.min.js new file mode 100644 index 0000000..113c0c1 --- /dev/null +++ b/website/admin/tinymce/plugins/colorpicker/plugin.min.js @@ -0,0 +1 @@ +!function(){"use strict";tinymce.util.Tools.resolve("tinymce.PluginManager").add("colorpicker",(function(){}))}(); \ No newline at end of file diff --git a/website/admin/tinymce/plugins/contextmenu/plugin.min.js b/website/admin/tinymce/plugins/contextmenu/plugin.min.js new file mode 100644 index 0000000..ab06407 --- /dev/null +++ b/website/admin/tinymce/plugins/contextmenu/plugin.min.js @@ -0,0 +1 @@ +!function(){"use strict";tinymce.util.Tools.resolve("tinymce.PluginManager").add("contextmenu",(function(){}))}(); \ No newline at end of file diff --git a/website/admin/tinymce/plugins/directionality/plugin.min.js b/website/admin/tinymce/plugins/directionality/plugin.min.js new file mode 100644 index 0000000..d1a2921 --- /dev/null +++ b/website/admin/tinymce/plugins/directionality/plugin.min.js @@ -0,0 +1 @@ +!function(){"use strict";function n(n){return function(t){return typeof t===n}}function t(n){return function(){return n}}function r(n){return n}function o(){return d}var e,u=tinymce.util.Tools.resolve("tinymce.PluginManager"),i=function(n){return r=typeof(t=n),(null===t?"null":"object"==r&&(Array.prototype.isPrototypeOf(t)||t.constructor&&"Array"===t.constructor.name)?"array":"object"==r&&(String.prototype.isPrototypeOf(t)||t.constructor&&"String"===t.constructor.name)?"string":r)===e;var t,r},c=n("boolean"),f=n("function"),l=n("number"),a=t(!(e="string")),m=t(!0),d={fold:function(n,t){return n()},isSome:a,isNone:m,getOr:r,getOrThunk:s,getOrDie:function(n){throw new Error(n||"error: getOrDie called on none.")},getOrNull:t(null),getOrUndefined:t(void 0),or:r,orThunk:s,map:o,each:function(){},bind:o,exists:a,forall:m,filter:function(){return d},toArray:function(){return[]},toString:t("none()")};function s(n){return n()}function g(n,t){for(var r=0,o=n.length;r',fitzpatrick_scale:!1,category:"symbols"},1234:{keywords:["numbers","blue-square"],char:'\ud83d\udd22',fitzpatrick_scale:!1,category:"symbols"},grinning:{keywords:["face","smile","happy","joy",":D","grin"],char:'\ud83d\ude00',fitzpatrick_scale:!1,category:"people"},grimacing:{keywords:["face","grimace","teeth"],char:'\ud83d\ude2c',fitzpatrick_scale:!1,category:"people"},grin:{keywords:["face","happy","smile","joy","kawaii"],char:'\ud83d\ude01',fitzpatrick_scale:!1,category:"people"},joy:{keywords:["face","cry","tears","weep","happy","happytears","haha"],char:'\ud83d\ude02',fitzpatrick_scale:!1,category:"people"},rofl:{keywords:["face","rolling","floor","laughing","lol","haha"],char:'\ud83e\udd23',fitzpatrick_scale:!1,category:"people"},partying:{keywords:["face","celebration","woohoo"],char:'\ud83e\udd73',fitzpatrick_scale:!1,category:"people"},smiley:{keywords:["face","happy","joy","haha",":D",":)","smile","funny"],char:'\ud83d\ude03',fitzpatrick_scale:!1,category:"people"},smile:{keywords:["face","happy","joy","funny","haha","laugh","like",":D",":)"],char:'\ud83d\ude04',fitzpatrick_scale:!1,category:"people"},sweat_smile:{keywords:["face","hot","happy","laugh","sweat","smile","relief"],char:'\ud83d\ude05',fitzpatrick_scale:!1,category:"people"},laughing:{keywords:["happy","joy","lol","satisfied","haha","face","glad","XD","laugh"],char:'\ud83d\ude06',fitzpatrick_scale:!1,category:"people"},innocent:{keywords:["face","angel","heaven","halo"],char:'\ud83d\ude07',fitzpatrick_scale:!1,category:"people"},wink:{keywords:["face","happy","mischievous","secret",";)","smile","eye"],char:'\ud83d\ude09',fitzpatrick_scale:!1,category:"people"},blush:{keywords:["face","smile","happy","flushed","crush","embarrassed","shy","joy"],char:'\ud83d\ude0a',fitzpatrick_scale:!1,category:"people"},slightly_smiling_face:{keywords:["face","smile"],char:'\ud83d\ude42',fitzpatrick_scale:!1,category:"people"},upside_down_face:{keywords:["face","flipped","silly","smile"],char:'\ud83d\ude43',fitzpatrick_scale:!1,category:"people"},relaxed:{keywords:["face","blush","massage","happiness"],char:'\u263a\ufe0f',fitzpatrick_scale:!1,category:"people"},yum:{keywords:["happy","joy","tongue","smile","face","silly","yummy","nom","delicious","savouring"],char:'\ud83d\ude0b',fitzpatrick_scale:!1,category:"people"},relieved:{keywords:["face","relaxed","phew","massage","happiness"],char:'\ud83d\ude0c',fitzpatrick_scale:!1,category:"people"},heart_eyes:{keywords:["face","love","like","affection","valentines","infatuation","crush","heart"],char:'\ud83d\ude0d',fitzpatrick_scale:!1,category:"people"},smiling_face_with_three_hearts:{keywords:["face","love","like","affection","valentines","infatuation","crush","hearts","adore"],char:'\ud83e\udd70',fitzpatrick_scale:!1,category:"people"},kissing_heart:{keywords:["face","love","like","affection","valentines","infatuation","kiss"],char:'\ud83d\ude18',fitzpatrick_scale:!1,category:"people"},kissing:{keywords:["love","like","face","3","valentines","infatuation","kiss"],char:'\ud83d\ude17',fitzpatrick_scale:!1,category:"people"},kissing_smiling_eyes:{keywords:["face","affection","valentines","infatuation","kiss"],char:'\ud83d\ude19',fitzpatrick_scale:!1,category:"people"},kissing_closed_eyes:{keywords:["face","love","like","affection","valentines","infatuation","kiss"],char:'\ud83d\ude1a',fitzpatrick_scale:!1,category:"people"},stuck_out_tongue_winking_eye:{keywords:["face","prank","childish","playful","mischievous","smile","wink","tongue"],char:'\ud83d\ude1c',fitzpatrick_scale:!1,category:"people"},zany:{keywords:["face","goofy","crazy"],char:'\ud83e\udd2a',fitzpatrick_scale:!1,category:"people"},raised_eyebrow:{keywords:["face","distrust","scepticism","disapproval","disbelief","surprise"],char:'\ud83e\udd28',fitzpatrick_scale:!1,category:"people"},monocle:{keywords:["face","stuffy","wealthy"],char:'\ud83e\uddd0',fitzpatrick_scale:!1,category:"people"},stuck_out_tongue_closed_eyes:{keywords:["face","prank","playful","mischievous","smile","tongue"],char:'\ud83d\ude1d',fitzpatrick_scale:!1,category:"people"},stuck_out_tongue:{keywords:["face","prank","childish","playful","mischievous","smile","tongue"],char:'\ud83d\ude1b',fitzpatrick_scale:!1,category:"people"},money_mouth_face:{keywords:["face","rich","dollar","money"],char:'\ud83e\udd11',fitzpatrick_scale:!1,category:"people"},nerd_face:{keywords:["face","nerdy","geek","dork"],char:'\ud83e\udd13',fitzpatrick_scale:!1,category:"people"},sunglasses:{keywords:["face","cool","smile","summer","beach","sunglass"],char:'\ud83d\ude0e',fitzpatrick_scale:!1,category:"people"},star_struck:{keywords:["face","smile","starry","eyes","grinning"],char:'\ud83e\udd29',fitzpatrick_scale:!1,category:"people"},clown_face:{keywords:["face"],char:'\ud83e\udd21',fitzpatrick_scale:!1,category:"people"},cowboy_hat_face:{keywords:["face","cowgirl","hat"],char:'\ud83e\udd20',fitzpatrick_scale:!1,category:"people"},hugs:{keywords:["face","smile","hug"],char:'\ud83e\udd17',fitzpatrick_scale:!1,category:"people"},smirk:{keywords:["face","smile","mean","prank","smug","sarcasm"],char:'\ud83d\ude0f',fitzpatrick_scale:!1,category:"people"},no_mouth:{keywords:["face","hellokitty"],char:'\ud83d\ude36',fitzpatrick_scale:!1,category:"people"},neutral_face:{keywords:["indifference","meh",":|","neutral"],char:'\ud83d\ude10',fitzpatrick_scale:!1,category:"people"},expressionless:{keywords:["face","indifferent","-_-","meh","deadpan"],char:'\ud83d\ude11',fitzpatrick_scale:!1,category:"people"},unamused:{keywords:["indifference","bored","straight face","serious","sarcasm","unimpressed","skeptical","dubious","side_eye"],char:'\ud83d\ude12',fitzpatrick_scale:!1,category:"people"},roll_eyes:{keywords:["face","eyeroll","frustrated"],char:'\ud83d\ude44',fitzpatrick_scale:!1,category:"people"},thinking:{keywords:["face","hmmm","think","consider"],char:'\ud83e\udd14',fitzpatrick_scale:!1,category:"people"},lying_face:{keywords:["face","lie","pinocchio"],char:'\ud83e\udd25',fitzpatrick_scale:!1,category:"people"},hand_over_mouth:{keywords:["face","whoops","shock","surprise"],char:'\ud83e\udd2d',fitzpatrick_scale:!1,category:"people"},shushing:{keywords:["face","quiet","shhh"],char:'\ud83e\udd2b',fitzpatrick_scale:!1,category:"people"},symbols_over_mouth:{keywords:["face","swearing","cursing","cussing","profanity","expletive"],char:'\ud83e\udd2c',fitzpatrick_scale:!1,category:"people"},exploding_head:{keywords:["face","shocked","mind","blown"],char:'\ud83e\udd2f',fitzpatrick_scale:!1,category:"people"},flushed:{keywords:["face","blush","shy","flattered"],char:'\ud83d\ude33',fitzpatrick_scale:!1,category:"people"},disappointed:{keywords:["face","sad","upset","depressed",":("],char:'\ud83d\ude1e',fitzpatrick_scale:!1,category:"people"},worried:{keywords:["face","concern","nervous",":("],char:'\ud83d\ude1f',fitzpatrick_scale:!1,category:"people"},angry:{keywords:["mad","face","annoyed","frustrated"],char:'\ud83d\ude20',fitzpatrick_scale:!1,category:"people"},rage:{keywords:["angry","mad","hate","despise"],char:'\ud83d\ude21',fitzpatrick_scale:!1,category:"people"},pensive:{keywords:["face","sad","depressed","upset"],char:'\ud83d\ude14',fitzpatrick_scale:!1,category:"people"},confused:{keywords:["face","indifference","huh","weird","hmmm",":/"],char:'\ud83d\ude15',fitzpatrick_scale:!1,category:"people"},slightly_frowning_face:{keywords:["face","frowning","disappointed","sad","upset"],char:'\ud83d\ude41',fitzpatrick_scale:!1,category:"people"},frowning_face:{keywords:["face","sad","upset","frown"],char:'\u2639',fitzpatrick_scale:!1,category:"people"},persevere:{keywords:["face","sick","no","upset","oops"],char:'\ud83d\ude23',fitzpatrick_scale:!1,category:"people"},confounded:{keywords:["face","confused","sick","unwell","oops",":S"],char:'\ud83d\ude16',fitzpatrick_scale:!1,category:"people"},tired_face:{keywords:["sick","whine","upset","frustrated"],char:'\ud83d\ude2b',fitzpatrick_scale:!1,category:"people"},weary:{keywords:["face","tired","sleepy","sad","frustrated","upset"],char:'\ud83d\ude29',fitzpatrick_scale:!1,category:"people"},pleading:{keywords:["face","begging","mercy"],char:'\ud83e\udd7a',fitzpatrick_scale:!1,category:"people"},triumph:{keywords:["face","gas","phew","proud","pride"],char:'\ud83d\ude24',fitzpatrick_scale:!1,category:"people"},open_mouth:{keywords:["face","surprise","impressed","wow","whoa",":O"],char:'\ud83d\ude2e',fitzpatrick_scale:!1,category:"people"},scream:{keywords:["face","munch","scared","omg"],char:'\ud83d\ude31',fitzpatrick_scale:!1,category:"people"},fearful:{keywords:["face","scared","terrified","nervous","oops","huh"],char:'\ud83d\ude28',fitzpatrick_scale:!1,category:"people"},cold_sweat:{keywords:["face","nervous","sweat"],char:'\ud83d\ude30',fitzpatrick_scale:!1,category:"people"},hushed:{keywords:["face","woo","shh"],char:'\ud83d\ude2f',fitzpatrick_scale:!1,category:"people"},frowning:{keywords:["face","aw","what"],char:'\ud83d\ude26',fitzpatrick_scale:!1,category:"people"},anguished:{keywords:["face","stunned","nervous"],char:'\ud83d\ude27',fitzpatrick_scale:!1,category:"people"},cry:{keywords:["face","tears","sad","depressed","upset",":'("],char:'\ud83d\ude22',fitzpatrick_scale:!1,category:"people"},disappointed_relieved:{keywords:["face","phew","sweat","nervous"],char:'\ud83d\ude25',fitzpatrick_scale:!1,category:"people"},drooling_face:{keywords:["face"],char:'\ud83e\udd24',fitzpatrick_scale:!1,category:"people"},sleepy:{keywords:["face","tired","rest","nap"],char:'\ud83d\ude2a',fitzpatrick_scale:!1,category:"people"},sweat:{keywords:["face","hot","sad","tired","exercise"],char:'\ud83d\ude13',fitzpatrick_scale:!1,category:"people"},hot:{keywords:["face","feverish","heat","red","sweating"],char:'\ud83e\udd75',fitzpatrick_scale:!1,category:"people"},cold:{keywords:["face","blue","freezing","frozen","frostbite","icicles"],char:'\ud83e\udd76',fitzpatrick_scale:!1,category:"people"},sob:{keywords:["face","cry","tears","sad","upset","depressed"],char:'\ud83d\ude2d',fitzpatrick_scale:!1,category:"people"},dizzy_face:{keywords:["spent","unconscious","xox","dizzy"],char:'\ud83d\ude35',fitzpatrick_scale:!1,category:"people"},astonished:{keywords:["face","xox","surprised","poisoned"],char:'\ud83d\ude32',fitzpatrick_scale:!1,category:"people"},zipper_mouth_face:{keywords:["face","sealed","zipper","secret"],char:'\ud83e\udd10',fitzpatrick_scale:!1,category:"people"},nauseated_face:{keywords:["face","vomit","gross","green","sick","throw up","ill"],char:'\ud83e\udd22',fitzpatrick_scale:!1,category:"people"},sneezing_face:{keywords:["face","gesundheit","sneeze","sick","allergy"],char:'\ud83e\udd27',fitzpatrick_scale:!1,category:"people"},vomiting:{keywords:["face","sick"],char:'\ud83e\udd2e',fitzpatrick_scale:!1,category:"people"},mask:{keywords:["face","sick","ill","disease"],char:'\ud83d\ude37',fitzpatrick_scale:!1,category:"people"},face_with_thermometer:{keywords:["sick","temperature","thermometer","cold","fever"],char:'\ud83e\udd12',fitzpatrick_scale:!1,category:"people"},face_with_head_bandage:{keywords:["injured","clumsy","bandage","hurt"],char:'\ud83e\udd15',fitzpatrick_scale:!1,category:"people"},woozy:{keywords:["face","dizzy","intoxicated","tipsy","wavy"],char:'\ud83e\udd74',fitzpatrick_scale:!1,category:"people"},sleeping:{keywords:["face","tired","sleepy","night","zzz"],char:'\ud83d\ude34',fitzpatrick_scale:!1,category:"people"},zzz:{keywords:["sleepy","tired","dream"],char:'\ud83d\udca4',fitzpatrick_scale:!1,category:"people"},poop:{keywords:["hankey","shitface","fail","turd","shit"],char:'\ud83d\udca9',fitzpatrick_scale:!1,category:"people"},smiling_imp:{keywords:["devil","horns"],char:'\ud83d\ude08',fitzpatrick_scale:!1,category:"people"},imp:{keywords:["devil","angry","horns"],char:'\ud83d\udc7f',fitzpatrick_scale:!1,category:"people"},japanese_ogre:{keywords:["monster","red","mask","halloween","scary","creepy","devil","demon","japanese","ogre"],char:'\ud83d\udc79',fitzpatrick_scale:!1,category:"people"},japanese_goblin:{keywords:["red","evil","mask","monster","scary","creepy","japanese","goblin"],char:'\ud83d\udc7a',fitzpatrick_scale:!1,category:"people"},skull:{keywords:["dead","skeleton","creepy","death"],char:'\ud83d\udc80',fitzpatrick_scale:!1,category:"people"},ghost:{keywords:["halloween","spooky","scary"],char:'\ud83d\udc7b',fitzpatrick_scale:!1,category:"people"},alien:{keywords:["UFO","paul","weird","outer_space"],char:'\ud83d\udc7d',fitzpatrick_scale:!1,category:"people"},robot:{keywords:["computer","machine","bot"],char:'\ud83e\udd16',fitzpatrick_scale:!1,category:"people"},smiley_cat:{keywords:["animal","cats","happy","smile"],char:'\ud83d\ude3a',fitzpatrick_scale:!1,category:"people"},smile_cat:{keywords:["animal","cats","smile"],char:'\ud83d\ude38',fitzpatrick_scale:!1,category:"people"},joy_cat:{keywords:["animal","cats","haha","happy","tears"],char:'\ud83d\ude39',fitzpatrick_scale:!1,category:"people"},heart_eyes_cat:{keywords:["animal","love","like","affection","cats","valentines","heart"],char:'\ud83d\ude3b',fitzpatrick_scale:!1,category:"people"},smirk_cat:{keywords:["animal","cats","smirk"],char:'\ud83d\ude3c',fitzpatrick_scale:!1,category:"people"},kissing_cat:{keywords:["animal","cats","kiss"],char:'\ud83d\ude3d',fitzpatrick_scale:!1,category:"people"},scream_cat:{keywords:["animal","cats","munch","scared","scream"],char:'\ud83d\ude40',fitzpatrick_scale:!1,category:"people"},crying_cat_face:{keywords:["animal","tears","weep","sad","cats","upset","cry"],char:'\ud83d\ude3f',fitzpatrick_scale:!1,category:"people"},pouting_cat:{keywords:["animal","cats"],char:'\ud83d\ude3e',fitzpatrick_scale:!1,category:"people"},palms_up:{keywords:["hands","gesture","cupped","prayer"],char:'\ud83e\udd32',fitzpatrick_scale:!0,category:"people"},raised_hands:{keywords:["gesture","hooray","yea","celebration","hands"],char:'\ud83d\ude4c',fitzpatrick_scale:!0,category:"people"},clap:{keywords:["hands","praise","applause","congrats","yay"],char:'\ud83d\udc4f',fitzpatrick_scale:!0,category:"people"},wave:{keywords:["hands","gesture","goodbye","solong","farewell","hello","hi","palm"],char:'\ud83d\udc4b',fitzpatrick_scale:!0,category:"people"},call_me_hand:{keywords:["hands","gesture"],char:'\ud83e\udd19',fitzpatrick_scale:!0,category:"people"},"+1":{keywords:["thumbsup","yes","awesome","good","agree","accept","cool","hand","like"],char:'\ud83d\udc4d',fitzpatrick_scale:!0,category:"people"},"-1":{keywords:["thumbsdown","no","dislike","hand"],char:'\ud83d\udc4e',fitzpatrick_scale:!0,category:"people"},facepunch:{keywords:["angry","violence","fist","hit","attack","hand"],char:'\ud83d\udc4a',fitzpatrick_scale:!0,category:"people"},fist:{keywords:["fingers","hand","grasp"],char:'\u270a',fitzpatrick_scale:!0,category:"people"},fist_left:{keywords:["hand","fistbump"],char:'\ud83e\udd1b',fitzpatrick_scale:!0,category:"people"},fist_right:{keywords:["hand","fistbump"],char:'\ud83e\udd1c',fitzpatrick_scale:!0,category:"people"},v:{keywords:["fingers","ohyeah","hand","peace","victory","two"],char:'\u270c',fitzpatrick_scale:!0,category:"people"},ok_hand:{keywords:["fingers","limbs","perfect","ok","okay"],char:'\ud83d\udc4c',fitzpatrick_scale:!0,category:"people"},raised_hand:{keywords:["fingers","stop","highfive","palm","ban"],char:'\u270b',fitzpatrick_scale:!0,category:"people"},raised_back_of_hand:{keywords:["fingers","raised","backhand"],char:'\ud83e\udd1a',fitzpatrick_scale:!0,category:"people"},open_hands:{keywords:["fingers","butterfly","hands","open"],char:'\ud83d\udc50',fitzpatrick_scale:!0,category:"people"},muscle:{keywords:["arm","flex","hand","summer","strong","biceps"],char:'\ud83d\udcaa',fitzpatrick_scale:!0,category:"people"},pray:{keywords:["please","hope","wish","namaste","highfive"],char:'\ud83d\ude4f',fitzpatrick_scale:!0,category:"people"},foot:{keywords:["kick","stomp"],char:'\ud83e\uddb6',fitzpatrick_scale:!0,category:"people"},leg:{keywords:["kick","limb"],char:'\ud83e\uddb5',fitzpatrick_scale:!0,category:"people"},handshake:{keywords:["agreement","shake"],char:'\ud83e\udd1d',fitzpatrick_scale:!1,category:"people"},point_up:{keywords:["hand","fingers","direction","up"],char:'\u261d',fitzpatrick_scale:!0,category:"people"},point_up_2:{keywords:["fingers","hand","direction","up"],char:'\ud83d\udc46',fitzpatrick_scale:!0,category:"people"},point_down:{keywords:["fingers","hand","direction","down"],char:'\ud83d\udc47',fitzpatrick_scale:!0,category:"people"},point_left:{keywords:["direction","fingers","hand","left"],char:'\ud83d\udc48',fitzpatrick_scale:!0,category:"people"},point_right:{keywords:["fingers","hand","direction","right"],char:'\ud83d\udc49',fitzpatrick_scale:!0,category:"people"},fu:{keywords:["hand","fingers","rude","middle","flipping"],char:'\ud83d\udd95',fitzpatrick_scale:!0,category:"people"},raised_hand_with_fingers_splayed:{keywords:["hand","fingers","palm"],char:'\ud83d\udd90',fitzpatrick_scale:!0,category:"people"},love_you:{keywords:["hand","fingers","gesture"],char:'\ud83e\udd1f',fitzpatrick_scale:!0,category:"people"},metal:{keywords:["hand","fingers","evil_eye","sign_of_horns","rock_on"],char:'\ud83e\udd18',fitzpatrick_scale:!0,category:"people"},crossed_fingers:{keywords:["good","lucky"],char:'\ud83e\udd1e',fitzpatrick_scale:!0,category:"people"},vulcan_salute:{keywords:["hand","fingers","spock","star trek"],char:'\ud83d\udd96',fitzpatrick_scale:!0,category:"people"},writing_hand:{keywords:["lower_left_ballpoint_pen","stationery","write","compose"],char:'\u270d',fitzpatrick_scale:!0,category:"people"},selfie:{keywords:["camera","phone"],char:'\ud83e\udd33',fitzpatrick_scale:!0,category:"people"},nail_care:{keywords:["beauty","manicure","finger","fashion","nail"],char:'\ud83d\udc85',fitzpatrick_scale:!0,category:"people"},lips:{keywords:["mouth","kiss"],char:'\ud83d\udc44',fitzpatrick_scale:!1,category:"people"},tooth:{keywords:["teeth","dentist"],char:'\ud83e\uddb7',fitzpatrick_scale:!1,category:"people"},tongue:{keywords:["mouth","playful"],char:'\ud83d\udc45',fitzpatrick_scale:!1,category:"people"},ear:{keywords:["face","hear","sound","listen"],char:'\ud83d\udc42',fitzpatrick_scale:!0,category:"people"},nose:{keywords:["smell","sniff"],char:'\ud83d\udc43',fitzpatrick_scale:!0,category:"people"},eye:{keywords:["face","look","see","watch","stare"],char:'\ud83d\udc41',fitzpatrick_scale:!1,category:"people"},eyes:{keywords:["look","watch","stalk","peek","see"],char:'\ud83d\udc40',fitzpatrick_scale:!1,category:"people"},brain:{keywords:["smart","intelligent"],char:'\ud83e\udde0',fitzpatrick_scale:!1,category:"people"},bust_in_silhouette:{keywords:["user","person","human"],char:'\ud83d\udc64',fitzpatrick_scale:!1,category:"people"},busts_in_silhouette:{keywords:["user","person","human","group","team"],char:'\ud83d\udc65',fitzpatrick_scale:!1,category:"people"},speaking_head:{keywords:["user","person","human","sing","say","talk"],char:'\ud83d\udde3',fitzpatrick_scale:!1,category:"people"},baby:{keywords:["child","boy","girl","toddler"],char:'\ud83d\udc76',fitzpatrick_scale:!0,category:"people"},child:{keywords:["gender-neutral","young"],char:'\ud83e\uddd2',fitzpatrick_scale:!0,category:"people"},boy:{keywords:["man","male","guy","teenager"],char:'\ud83d\udc66',fitzpatrick_scale:!0,category:"people"},girl:{keywords:["female","woman","teenager"],char:'\ud83d\udc67',fitzpatrick_scale:!0,category:"people"},adult:{keywords:["gender-neutral","person"],char:'\ud83e\uddd1',fitzpatrick_scale:!0,category:"people"},man:{keywords:["mustache","father","dad","guy","classy","sir","moustache"],char:'\ud83d\udc68',fitzpatrick_scale:!0,category:"people"},woman:{keywords:["female","girls","lady"],char:'\ud83d\udc69',fitzpatrick_scale:!0,category:"people"},blonde_woman:{keywords:["woman","female","girl","blonde","person"],char:'\ud83d\udc71\u200d\u2640\ufe0f',fitzpatrick_scale:!0,category:"people"},blonde_man:{keywords:["man","male","boy","blonde","guy","person"],char:'\ud83d\udc71',fitzpatrick_scale:!0,category:"people"},bearded_person:{keywords:["person","bewhiskered"],char:'\ud83e\uddd4',fitzpatrick_scale:!0,category:"people"},older_adult:{keywords:["human","elder","senior","gender-neutral"],char:'\ud83e\uddd3',fitzpatrick_scale:!0,category:"people"},older_man:{keywords:["human","male","men","old","elder","senior"],char:'\ud83d\udc74',fitzpatrick_scale:!0,category:"people"},older_woman:{keywords:["human","female","women","lady","old","elder","senior"],char:'\ud83d\udc75',fitzpatrick_scale:!0,category:"people"},man_with_gua_pi_mao:{keywords:["male","boy","chinese"],char:'\ud83d\udc72',fitzpatrick_scale:!0,category:"people"},woman_with_headscarf:{keywords:["female","hijab","mantilla","tichel"],char:'\ud83e\uddd5',fitzpatrick_scale:!0,category:"people"},woman_with_turban:{keywords:["female","indian","hinduism","arabs","woman"],char:'\ud83d\udc73\u200d\u2640\ufe0f',fitzpatrick_scale:!0,category:"people"},man_with_turban:{keywords:["male","indian","hinduism","arabs"],char:'\ud83d\udc73',fitzpatrick_scale:!0,category:"people"},policewoman:{keywords:["woman","police","law","legal","enforcement","arrest","911","female"],char:'\ud83d\udc6e\u200d\u2640\ufe0f',fitzpatrick_scale:!0,category:"people"},policeman:{keywords:["man","police","law","legal","enforcement","arrest","911"],char:'\ud83d\udc6e',fitzpatrick_scale:!0,category:"people"},construction_worker_woman:{keywords:["female","human","wip","build","construction","worker","labor","woman"],char:'\ud83d\udc77\u200d\u2640\ufe0f',fitzpatrick_scale:!0,category:"people"},construction_worker_man:{keywords:["male","human","wip","guy","build","construction","worker","labor"],char:'\ud83d\udc77',fitzpatrick_scale:!0,category:"people"},guardswoman:{keywords:["uk","gb","british","female","royal","woman"],char:'\ud83d\udc82\u200d\u2640\ufe0f',fitzpatrick_scale:!0,category:"people"},guardsman:{keywords:["uk","gb","british","male","guy","royal"],char:'\ud83d\udc82',fitzpatrick_scale:!0,category:"people"},female_detective:{keywords:["human","spy","detective","female","woman"],char:'\ud83d\udd75\ufe0f\u200d\u2640\ufe0f',fitzpatrick_scale:!0,category:"people"},male_detective:{keywords:["human","spy","detective"],char:'\ud83d\udd75',fitzpatrick_scale:!0,category:"people"},woman_health_worker:{keywords:["doctor","nurse","therapist","healthcare","woman","human"],char:'\ud83d\udc69\u200d\u2695\ufe0f',fitzpatrick_scale:!0,category:"people"},man_health_worker:{keywords:["doctor","nurse","therapist","healthcare","man","human"],char:'\ud83d\udc68\u200d\u2695\ufe0f',fitzpatrick_scale:!0,category:"people"},woman_farmer:{keywords:["rancher","gardener","woman","human"],char:'\ud83d\udc69\u200d\ud83c\udf3e',fitzpatrick_scale:!0,category:"people"},man_farmer:{keywords:["rancher","gardener","man","human"],char:'\ud83d\udc68\u200d\ud83c\udf3e',fitzpatrick_scale:!0,category:"people"},woman_cook:{keywords:["chef","woman","human"],char:'\ud83d\udc69\u200d\ud83c\udf73',fitzpatrick_scale:!0,category:"people"},man_cook:{keywords:["chef","man","human"],char:'\ud83d\udc68\u200d\ud83c\udf73',fitzpatrick_scale:!0,category:"people"},woman_student:{keywords:["graduate","woman","human"],char:'\ud83d\udc69\u200d\ud83c\udf93',fitzpatrick_scale:!0,category:"people"},man_student:{keywords:["graduate","man","human"],char:'\ud83d\udc68\u200d\ud83c\udf93',fitzpatrick_scale:!0,category:"people"},woman_singer:{keywords:["rockstar","entertainer","woman","human"],char:'\ud83d\udc69\u200d\ud83c\udfa4',fitzpatrick_scale:!0,category:"people"},man_singer:{keywords:["rockstar","entertainer","man","human"],char:'\ud83d\udc68\u200d\ud83c\udfa4',fitzpatrick_scale:!0,category:"people"},woman_teacher:{keywords:["instructor","professor","woman","human"],char:'\ud83d\udc69\u200d\ud83c\udfeb',fitzpatrick_scale:!0,category:"people"},man_teacher:{keywords:["instructor","professor","man","human"],char:'\ud83d\udc68\u200d\ud83c\udfeb',fitzpatrick_scale:!0,category:"people"},woman_factory_worker:{keywords:["assembly","industrial","woman","human"],char:'\ud83d\udc69\u200d\ud83c\udfed',fitzpatrick_scale:!0,category:"people"},man_factory_worker:{keywords:["assembly","industrial","man","human"],char:'\ud83d\udc68\u200d\ud83c\udfed',fitzpatrick_scale:!0,category:"people"},woman_technologist:{keywords:["coder","developer","engineer","programmer","software","woman","human","laptop","computer"],char:'\ud83d\udc69\u200d\ud83d\udcbb',fitzpatrick_scale:!0,category:"people"},man_technologist:{keywords:["coder","developer","engineer","programmer","software","man","human","laptop","computer"],char:'\ud83d\udc68\u200d\ud83d\udcbb',fitzpatrick_scale:!0,category:"people"},woman_office_worker:{keywords:["business","manager","woman","human"],char:'\ud83d\udc69\u200d\ud83d\udcbc',fitzpatrick_scale:!0,category:"people"},man_office_worker:{keywords:["business","manager","man","human"],char:'\ud83d\udc68\u200d\ud83d\udcbc',fitzpatrick_scale:!0,category:"people"},woman_mechanic:{keywords:["plumber","woman","human","wrench"],char:'\ud83d\udc69\u200d\ud83d\udd27',fitzpatrick_scale:!0,category:"people"},man_mechanic:{keywords:["plumber","man","human","wrench"],char:'\ud83d\udc68\u200d\ud83d\udd27',fitzpatrick_scale:!0,category:"people"},woman_scientist:{keywords:["biologist","chemist","engineer","physicist","woman","human"],char:'\ud83d\udc69\u200d\ud83d\udd2c',fitzpatrick_scale:!0,category:"people"},man_scientist:{keywords:["biologist","chemist","engineer","physicist","man","human"],char:'\ud83d\udc68\u200d\ud83d\udd2c',fitzpatrick_scale:!0,category:"people"},woman_artist:{keywords:["painter","woman","human"],char:'\ud83d\udc69\u200d\ud83c\udfa8',fitzpatrick_scale:!0,category:"people"},man_artist:{keywords:["painter","man","human"],char:'\ud83d\udc68\u200d\ud83c\udfa8',fitzpatrick_scale:!0,category:"people"},woman_firefighter:{keywords:["fireman","woman","human"],char:'\ud83d\udc69\u200d\ud83d\ude92',fitzpatrick_scale:!0,category:"people"},man_firefighter:{keywords:["fireman","man","human"],char:'\ud83d\udc68\u200d\ud83d\ude92',fitzpatrick_scale:!0,category:"people"},woman_pilot:{keywords:["aviator","plane","woman","human"],char:'\ud83d\udc69\u200d\u2708\ufe0f',fitzpatrick_scale:!0,category:"people"},man_pilot:{keywords:["aviator","plane","man","human"],char:'\ud83d\udc68\u200d\u2708\ufe0f',fitzpatrick_scale:!0,category:"people"},woman_astronaut:{keywords:["space","rocket","woman","human"],char:'\ud83d\udc69\u200d\ud83d\ude80',fitzpatrick_scale:!0,category:"people"},man_astronaut:{keywords:["space","rocket","man","human"],char:'\ud83d\udc68\u200d\ud83d\ude80',fitzpatrick_scale:!0,category:"people"},woman_judge:{keywords:["justice","court","woman","human"],char:'\ud83d\udc69\u200d\u2696\ufe0f',fitzpatrick_scale:!0,category:"people"},man_judge:{keywords:["justice","court","man","human"],char:'\ud83d\udc68\u200d\u2696\ufe0f',fitzpatrick_scale:!0,category:"people"},woman_superhero:{keywords:["woman","female","good","heroine","superpowers"],char:'\ud83e\uddb8\u200d\u2640\ufe0f',fitzpatrick_scale:!0,category:"people"},man_superhero:{keywords:["man","male","good","hero","superpowers"],char:'\ud83e\uddb8\u200d\u2642\ufe0f',fitzpatrick_scale:!0,category:"people"},woman_supervillain:{keywords:["woman","female","evil","bad","criminal","heroine","superpowers"],char:'\ud83e\uddb9\u200d\u2640\ufe0f',fitzpatrick_scale:!0,category:"people"},man_supervillain:{keywords:["man","male","evil","bad","criminal","hero","superpowers"],char:'\ud83e\uddb9\u200d\u2642\ufe0f',fitzpatrick_scale:!0,category:"people"},mrs_claus:{keywords:["woman","female","xmas","mother christmas"],char:'\ud83e\udd36',fitzpatrick_scale:!0,category:"people"},santa:{keywords:["festival","man","male","xmas","father christmas"],char:'\ud83c\udf85',fitzpatrick_scale:!0,category:"people"},sorceress:{keywords:["woman","female","mage","witch"],char:'\ud83e\uddd9\u200d\u2640\ufe0f',fitzpatrick_scale:!0,category:"people"},wizard:{keywords:["man","male","mage","sorcerer"],char:'\ud83e\uddd9\u200d\u2642\ufe0f',fitzpatrick_scale:!0,category:"people"},woman_elf:{keywords:["woman","female"],char:'\ud83e\udddd\u200d\u2640\ufe0f',fitzpatrick_scale:!0,category:"people"},man_elf:{keywords:["man","male"],char:'\ud83e\udddd\u200d\u2642\ufe0f',fitzpatrick_scale:!0,category:"people"},woman_vampire:{keywords:["woman","female"],char:'\ud83e\udddb\u200d\u2640\ufe0f',fitzpatrick_scale:!0,category:"people"},man_vampire:{keywords:["man","male","dracula"],char:'\ud83e\udddb\u200d\u2642\ufe0f',fitzpatrick_scale:!0,category:"people"},woman_zombie:{keywords:["woman","female","undead","walking dead"],char:'\ud83e\udddf\u200d\u2640\ufe0f',fitzpatrick_scale:!1,category:"people"},man_zombie:{keywords:["man","male","dracula","undead","walking dead"],char:'\ud83e\udddf\u200d\u2642\ufe0f',fitzpatrick_scale:!1,category:"people"},woman_genie:{keywords:["woman","female"],char:'\ud83e\uddde\u200d\u2640\ufe0f',fitzpatrick_scale:!1,category:"people"},man_genie:{keywords:["man","male"],char:'\ud83e\uddde\u200d\u2642\ufe0f',fitzpatrick_scale:!1,category:"people"},mermaid:{keywords:["woman","female","merwoman","ariel"],char:'\ud83e\udddc\u200d\u2640\ufe0f',fitzpatrick_scale:!0,category:"people"},merman:{keywords:["man","male","triton"],char:'\ud83e\udddc\u200d\u2642\ufe0f',fitzpatrick_scale:!0,category:"people"},woman_fairy:{keywords:["woman","female"],char:'\ud83e\uddda\u200d\u2640\ufe0f',fitzpatrick_scale:!0,category:"people"},man_fairy:{keywords:["man","male"],char:'\ud83e\uddda\u200d\u2642\ufe0f',fitzpatrick_scale:!0,category:"people"},angel:{keywords:["heaven","wings","halo"],char:'\ud83d\udc7c',fitzpatrick_scale:!0,category:"people"},pregnant_woman:{keywords:["baby"],char:'\ud83e\udd30',fitzpatrick_scale:!0,category:"people"},breastfeeding:{keywords:["nursing","baby"],char:'\ud83e\udd31',fitzpatrick_scale:!0,category:"people"},princess:{keywords:["girl","woman","female","blond","crown","royal","queen"],char:'\ud83d\udc78',fitzpatrick_scale:!0,category:"people"},prince:{keywords:["boy","man","male","crown","royal","king"],char:'\ud83e\udd34',fitzpatrick_scale:!0,category:"people"},bride_with_veil:{keywords:["couple","marriage","wedding","woman","bride"],char:'\ud83d\udc70',fitzpatrick_scale:!0,category:"people"},man_in_tuxedo:{keywords:["couple","marriage","wedding","groom"],char:'\ud83e\udd35',fitzpatrick_scale:!0,category:"people"},running_woman:{keywords:["woman","walking","exercise","race","running","female"],char:'\ud83c\udfc3\u200d\u2640\ufe0f',fitzpatrick_scale:!0,category:"people"},running_man:{keywords:["man","walking","exercise","race","running"],char:'\ud83c\udfc3',fitzpatrick_scale:!0,category:"people"},walking_woman:{keywords:["human","feet","steps","woman","female"],char:'\ud83d\udeb6\u200d\u2640\ufe0f',fitzpatrick_scale:!0,category:"people"},walking_man:{keywords:["human","feet","steps"],char:'\ud83d\udeb6',fitzpatrick_scale:!0,category:"people"},dancer:{keywords:["female","girl","woman","fun"],char:'\ud83d\udc83',fitzpatrick_scale:!0,category:"people"},man_dancing:{keywords:["male","boy","fun","dancer"],char:'\ud83d\udd7a',fitzpatrick_scale:!0,category:"people"},dancing_women:{keywords:["female","bunny","women","girls"],char:'\ud83d\udc6f',fitzpatrick_scale:!1,category:"people"},dancing_men:{keywords:["male","bunny","men","boys"],char:'\ud83d\udc6f\u200d\u2642\ufe0f',fitzpatrick_scale:!1,category:"people"},couple:{keywords:["pair","people","human","love","date","dating","like","affection","valentines","marriage"],char:'\ud83d\udc6b',fitzpatrick_scale:!1,category:"people"},two_men_holding_hands:{keywords:["pair","couple","love","like","bromance","friendship","people","human"],char:'\ud83d\udc6c',fitzpatrick_scale:!1,category:"people"},two_women_holding_hands:{keywords:["pair","friendship","couple","love","like","female","people","human"],char:'\ud83d\udc6d',fitzpatrick_scale:!1,category:"people"},bowing_woman:{keywords:["woman","female","girl"],char:'\ud83d\ude47\u200d\u2640\ufe0f',fitzpatrick_scale:!0,category:"people"},bowing_man:{keywords:["man","male","boy"],char:'\ud83d\ude47',fitzpatrick_scale:!0,category:"people"},man_facepalming:{keywords:["man","male","boy","disbelief"],char:'\ud83e\udd26\u200d\u2642\ufe0f',fitzpatrick_scale:!0,category:"people"},woman_facepalming:{keywords:["woman","female","girl","disbelief"],char:'\ud83e\udd26\u200d\u2640\ufe0f',fitzpatrick_scale:!0,category:"people"},woman_shrugging:{keywords:["woman","female","girl","confused","indifferent","doubt"],char:'\ud83e\udd37',fitzpatrick_scale:!0,category:"people"},man_shrugging:{keywords:["man","male","boy","confused","indifferent","doubt"],char:'\ud83e\udd37\u200d\u2642\ufe0f',fitzpatrick_scale:!0,category:"people"},tipping_hand_woman:{keywords:["female","girl","woman","human","information"],char:'\ud83d\udc81',fitzpatrick_scale:!0,category:"people"},tipping_hand_man:{keywords:["male","boy","man","human","information"],char:'\ud83d\udc81\u200d\u2642\ufe0f',fitzpatrick_scale:!0,category:"people"},no_good_woman:{keywords:["female","girl","woman","nope"],char:'\ud83d\ude45',fitzpatrick_scale:!0,category:"people"},no_good_man:{keywords:["male","boy","man","nope"],char:'\ud83d\ude45\u200d\u2642\ufe0f',fitzpatrick_scale:!0,category:"people"},ok_woman:{keywords:["women","girl","female","pink","human","woman"],char:'\ud83d\ude46',fitzpatrick_scale:!0,category:"people"},ok_man:{keywords:["men","boy","male","blue","human","man"],char:'\ud83d\ude46\u200d\u2642\ufe0f',fitzpatrick_scale:!0,category:"people"},raising_hand_woman:{keywords:["female","girl","woman"],char:'\ud83d\ude4b',fitzpatrick_scale:!0,category:"people"},raising_hand_man:{keywords:["male","boy","man"],char:'\ud83d\ude4b\u200d\u2642\ufe0f',fitzpatrick_scale:!0,category:"people"},pouting_woman:{keywords:["female","girl","woman"],char:'\ud83d\ude4e',fitzpatrick_scale:!0,category:"people"},pouting_man:{keywords:["male","boy","man"],char:'\ud83d\ude4e\u200d\u2642\ufe0f',fitzpatrick_scale:!0,category:"people"},frowning_woman:{keywords:["female","girl","woman","sad","depressed","discouraged","unhappy"],char:'\ud83d\ude4d',fitzpatrick_scale:!0,category:"people"},frowning_man:{keywords:["male","boy","man","sad","depressed","discouraged","unhappy"],char:'\ud83d\ude4d\u200d\u2642\ufe0f',fitzpatrick_scale:!0,category:"people"},haircut_woman:{keywords:["female","girl","woman"],char:'\ud83d\udc87',fitzpatrick_scale:!0,category:"people"},haircut_man:{keywords:["male","boy","man"],char:'\ud83d\udc87\u200d\u2642\ufe0f',fitzpatrick_scale:!0,category:"people"},massage_woman:{keywords:["female","girl","woman","head"],char:'\ud83d\udc86',fitzpatrick_scale:!0,category:"people"},massage_man:{keywords:["male","boy","man","head"],char:'\ud83d\udc86\u200d\u2642\ufe0f',fitzpatrick_scale:!0,category:"people"},woman_in_steamy_room:{keywords:["female","woman","spa","steamroom","sauna"],char:'\ud83e\uddd6\u200d\u2640\ufe0f',fitzpatrick_scale:!0,category:"people"},man_in_steamy_room:{keywords:["male","man","spa","steamroom","sauna"],char:'\ud83e\uddd6\u200d\u2642\ufe0f',fitzpatrick_scale:!0,category:"people"},couple_with_heart_woman_man:{keywords:["pair","love","like","affection","human","dating","valentines","marriage"],char:'\ud83d\udc91',fitzpatrick_scale:!1,category:"people"},couple_with_heart_woman_woman:{keywords:["pair","love","like","affection","human","dating","valentines","marriage"],char:'\ud83d\udc69\u200d\u2764\ufe0f\u200d\ud83d\udc69',fitzpatrick_scale:!1,category:"people"},couple_with_heart_man_man:{keywords:["pair","love","like","affection","human","dating","valentines","marriage"],char:'\ud83d\udc68\u200d\u2764\ufe0f\u200d\ud83d\udc68',fitzpatrick_scale:!1,category:"people"},couplekiss_man_woman:{keywords:["pair","valentines","love","like","dating","marriage"],char:'\ud83d\udc8f',fitzpatrick_scale:!1,category:"people"},couplekiss_woman_woman:{keywords:["pair","valentines","love","like","dating","marriage"],char:'\ud83d\udc69\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc69',fitzpatrick_scale:!1,category:"people"},couplekiss_man_man:{keywords:["pair","valentines","love","like","dating","marriage"],char:'\ud83d\udc68\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68',fitzpatrick_scale:!1,category:"people"},family_man_woman_boy:{keywords:["home","parents","child","mom","dad","father","mother","people","human"],char:'\ud83d\udc6a',fitzpatrick_scale:!1,category:"people"},family_man_woman_girl:{keywords:["home","parents","people","human","child"],char:'\ud83d\udc68\u200d\ud83d\udc69\u200d\ud83d\udc67',fitzpatrick_scale:!1,category:"people"},family_man_woman_girl_boy:{keywords:["home","parents","people","human","children"],char:'\ud83d\udc68\u200d\ud83d\udc69\u200d\ud83d\udc67\u200d\ud83d\udc66',fitzpatrick_scale:!1,category:"people"},family_man_woman_boy_boy:{keywords:["home","parents","people","human","children"],char:'\ud83d\udc68\u200d\ud83d\udc69\u200d\ud83d\udc66\u200d\ud83d\udc66',fitzpatrick_scale:!1,category:"people"},family_man_woman_girl_girl:{keywords:["home","parents","people","human","children"],char:'\ud83d\udc68\u200d\ud83d\udc69\u200d\ud83d\udc67\u200d\ud83d\udc67',fitzpatrick_scale:!1,category:"people"},family_woman_woman_boy:{keywords:["home","parents","people","human","children"],char:'\ud83d\udc69\u200d\ud83d\udc69\u200d\ud83d\udc66',fitzpatrick_scale:!1,category:"people"},family_woman_woman_girl:{keywords:["home","parents","people","human","children"],char:'\ud83d\udc69\u200d\ud83d\udc69\u200d\ud83d\udc67',fitzpatrick_scale:!1,category:"people"},family_woman_woman_girl_boy:{keywords:["home","parents","people","human","children"],char:'\ud83d\udc69\u200d\ud83d\udc69\u200d\ud83d\udc67\u200d\ud83d\udc66',fitzpatrick_scale:!1,category:"people"},family_woman_woman_boy_boy:{keywords:["home","parents","people","human","children"],char:'\ud83d\udc69\u200d\ud83d\udc69\u200d\ud83d\udc66\u200d\ud83d\udc66',fitzpatrick_scale:!1,category:"people"},family_woman_woman_girl_girl:{keywords:["home","parents","people","human","children"],char:'\ud83d\udc69\u200d\ud83d\udc69\u200d\ud83d\udc67\u200d\ud83d\udc67',fitzpatrick_scale:!1,category:"people"},family_man_man_boy:{keywords:["home","parents","people","human","children"],char:'\ud83d\udc68\u200d\ud83d\udc68\u200d\ud83d\udc66',fitzpatrick_scale:!1,category:"people"},family_man_man_girl:{keywords:["home","parents","people","human","children"],char:'\ud83d\udc68\u200d\ud83d\udc68\u200d\ud83d\udc67',fitzpatrick_scale:!1,category:"people"},family_man_man_girl_boy:{keywords:["home","parents","people","human","children"],char:'\ud83d\udc68\u200d\ud83d\udc68\u200d\ud83d\udc67\u200d\ud83d\udc66',fitzpatrick_scale:!1,category:"people"},family_man_man_boy_boy:{keywords:["home","parents","people","human","children"],char:'\ud83d\udc68\u200d\ud83d\udc68\u200d\ud83d\udc66\u200d\ud83d\udc66',fitzpatrick_scale:!1,category:"people"},family_man_man_girl_girl:{keywords:["home","parents","people","human","children"],char:'\ud83d\udc68\u200d\ud83d\udc68\u200d\ud83d\udc67\u200d\ud83d\udc67',fitzpatrick_scale:!1,category:"people"},family_woman_boy:{keywords:["home","parent","people","human","child"],char:'\ud83d\udc69\u200d\ud83d\udc66',fitzpatrick_scale:!1,category:"people"},family_woman_girl:{keywords:["home","parent","people","human","child"],char:'\ud83d\udc69\u200d\ud83d\udc67',fitzpatrick_scale:!1,category:"people"},family_woman_girl_boy:{keywords:["home","parent","people","human","children"],char:'\ud83d\udc69\u200d\ud83d\udc67\u200d\ud83d\udc66',fitzpatrick_scale:!1,category:"people"},family_woman_boy_boy:{keywords:["home","parent","people","human","children"],char:'\ud83d\udc69\u200d\ud83d\udc66\u200d\ud83d\udc66',fitzpatrick_scale:!1,category:"people"},family_woman_girl_girl:{keywords:["home","parent","people","human","children"],char:'\ud83d\udc69\u200d\ud83d\udc67\u200d\ud83d\udc67',fitzpatrick_scale:!1,category:"people"},family_man_boy:{keywords:["home","parent","people","human","child"],char:'\ud83d\udc68\u200d\ud83d\udc66',fitzpatrick_scale:!1,category:"people"},family_man_girl:{keywords:["home","parent","people","human","child"],char:'\ud83d\udc68\u200d\ud83d\udc67',fitzpatrick_scale:!1,category:"people"},family_man_girl_boy:{keywords:["home","parent","people","human","children"],char:'\ud83d\udc68\u200d\ud83d\udc67\u200d\ud83d\udc66',fitzpatrick_scale:!1,category:"people"},family_man_boy_boy:{keywords:["home","parent","people","human","children"],char:'\ud83d\udc68\u200d\ud83d\udc66\u200d\ud83d\udc66',fitzpatrick_scale:!1,category:"people"},family_man_girl_girl:{keywords:["home","parent","people","human","children"],char:'\ud83d\udc68\u200d\ud83d\udc67\u200d\ud83d\udc67',fitzpatrick_scale:!1,category:"people"},yarn:{keywords:["ball","crochet","knit"],char:'\ud83e\uddf6',fitzpatrick_scale:!1,category:"people"},thread:{keywords:["needle","sewing","spool","string"],char:'\ud83e\uddf5',fitzpatrick_scale:!1,category:"people"},coat:{keywords:["jacket"],char:'\ud83e\udde5',fitzpatrick_scale:!1,category:"people"},labcoat:{keywords:["doctor","experiment","scientist","chemist"],char:'\ud83e\udd7c',fitzpatrick_scale:!1,category:"people"},womans_clothes:{keywords:["fashion","shopping_bags","female"],char:'\ud83d\udc5a',fitzpatrick_scale:!1,category:"people"},tshirt:{keywords:["fashion","cloth","casual","shirt","tee"],char:'\ud83d\udc55',fitzpatrick_scale:!1,category:"people"},jeans:{keywords:["fashion","shopping"],char:'\ud83d\udc56',fitzpatrick_scale:!1,category:"people"},necktie:{keywords:["shirt","suitup","formal","fashion","cloth","business"],char:'\ud83d\udc54',fitzpatrick_scale:!1,category:"people"},dress:{keywords:["clothes","fashion","shopping"],char:'\ud83d\udc57',fitzpatrick_scale:!1,category:"people"},bikini:{keywords:["swimming","female","woman","girl","fashion","beach","summer"],char:'\ud83d\udc59',fitzpatrick_scale:!1,category:"people"},kimono:{keywords:["dress","fashion","women","female","japanese"],char:'\ud83d\udc58',fitzpatrick_scale:!1,category:"people"},lipstick:{keywords:["female","girl","fashion","woman"],char:'\ud83d\udc84',fitzpatrick_scale:!1,category:"people"},kiss:{keywords:["face","lips","love","like","affection","valentines"],char:'\ud83d\udc8b',fitzpatrick_scale:!1,category:"people"},footprints:{keywords:["feet","tracking","walking","beach"],char:'\ud83d\udc63',fitzpatrick_scale:!1,category:"people"},flat_shoe:{keywords:["ballet","slip-on","slipper"],char:'\ud83e\udd7f',fitzpatrick_scale:!1,category:"people"},high_heel:{keywords:["fashion","shoes","female","pumps","stiletto"],char:'\ud83d\udc60',fitzpatrick_scale:!1,category:"people"},sandal:{keywords:["shoes","fashion","flip flops"],char:'\ud83d\udc61',fitzpatrick_scale:!1,category:"people"},boot:{keywords:["shoes","fashion"],char:'\ud83d\udc62',fitzpatrick_scale:!1,category:"people"},mans_shoe:{keywords:["fashion","male"],char:'\ud83d\udc5e',fitzpatrick_scale:!1,category:"people"},athletic_shoe:{keywords:["shoes","sports","sneakers"],char:'\ud83d\udc5f',fitzpatrick_scale:!1,category:"people"},hiking_boot:{keywords:["backpacking","camping","hiking"],char:'\ud83e\udd7e',fitzpatrick_scale:!1,category:"people"},socks:{keywords:["stockings","clothes"],char:'\ud83e\udde6',fitzpatrick_scale:!1,category:"people"},gloves:{keywords:["hands","winter","clothes"],char:'\ud83e\udde4',fitzpatrick_scale:!1,category:"people"},scarf:{keywords:["neck","winter","clothes"],char:'\ud83e\udde3',fitzpatrick_scale:!1,category:"people"},womans_hat:{keywords:["fashion","accessories","female","lady","spring"],char:'\ud83d\udc52',fitzpatrick_scale:!1,category:"people"},tophat:{keywords:["magic","gentleman","classy","circus"],char:'\ud83c\udfa9',fitzpatrick_scale:!1,category:"people"},billed_hat:{keywords:["cap","baseball"],char:'\ud83e\udde2',fitzpatrick_scale:!1,category:"people"},rescue_worker_helmet:{keywords:["construction","build"],char:'\u26d1',fitzpatrick_scale:!1,category:"people"},mortar_board:{keywords:["school","college","degree","university","graduation","cap","hat","legal","learn","education"],char:'\ud83c\udf93',fitzpatrick_scale:!1,category:"people"},crown:{keywords:["king","kod","leader","royalty","lord"],char:'\ud83d\udc51',fitzpatrick_scale:!1,category:"people"},school_satchel:{keywords:["student","education","bag","backpack"],char:'\ud83c\udf92',fitzpatrick_scale:!1,category:"people"},luggage:{keywords:["packing","travel"],char:'\ud83e\uddf3',fitzpatrick_scale:!1,category:"people"},pouch:{keywords:["bag","accessories","shopping"],char:'\ud83d\udc5d',fitzpatrick_scale:!1,category:"people"},purse:{keywords:["fashion","accessories","money","sales","shopping"],char:'\ud83d\udc5b',fitzpatrick_scale:!1,category:"people"},handbag:{keywords:["fashion","accessory","accessories","shopping"],char:'\ud83d\udc5c',fitzpatrick_scale:!1,category:"people"},briefcase:{keywords:["business","documents","work","law","legal","job","career"],char:'\ud83d\udcbc',fitzpatrick_scale:!1,category:"people"},eyeglasses:{keywords:["fashion","accessories","eyesight","nerdy","dork","geek"],char:'\ud83d\udc53',fitzpatrick_scale:!1,category:"people"},dark_sunglasses:{keywords:["face","cool","accessories"],char:'\ud83d\udd76',fitzpatrick_scale:!1,category:"people"},goggles:{keywords:["eyes","protection","safety"],char:'\ud83e\udd7d',fitzpatrick_scale:!1,category:"people"},ring:{keywords:["wedding","propose","marriage","valentines","diamond","fashion","jewelry","gem","engagement"],char:'\ud83d\udc8d',fitzpatrick_scale:!1,category:"people"},closed_umbrella:{keywords:["weather","rain","drizzle"],char:'\ud83c\udf02',fitzpatrick_scale:!1,category:"people"},dog:{keywords:["animal","friend","nature","woof","puppy","pet","faithful"],char:'\ud83d\udc36',fitzpatrick_scale:!1,category:"animals_and_nature"},cat:{keywords:["animal","meow","nature","pet","kitten"],char:'\ud83d\udc31',fitzpatrick_scale:!1,category:"animals_and_nature"},mouse:{keywords:["animal","nature","cheese_wedge","rodent"],char:'\ud83d\udc2d',fitzpatrick_scale:!1,category:"animals_and_nature"},hamster:{keywords:["animal","nature"],char:'\ud83d\udc39',fitzpatrick_scale:!1,category:"animals_and_nature"},rabbit:{keywords:["animal","nature","pet","spring","magic","bunny"],char:'\ud83d\udc30',fitzpatrick_scale:!1,category:"animals_and_nature"},fox_face:{keywords:["animal","nature","face"],char:'\ud83e\udd8a',fitzpatrick_scale:!1,category:"animals_and_nature"},bear:{keywords:["animal","nature","wild"],char:'\ud83d\udc3b',fitzpatrick_scale:!1,category:"animals_and_nature"},panda_face:{keywords:["animal","nature","panda"],char:'\ud83d\udc3c',fitzpatrick_scale:!1,category:"animals_and_nature"},koala:{keywords:["animal","nature"],char:'\ud83d\udc28',fitzpatrick_scale:!1,category:"animals_and_nature"},tiger:{keywords:["animal","cat","danger","wild","nature","roar"],char:'\ud83d\udc2f',fitzpatrick_scale:!1,category:"animals_and_nature"},lion:{keywords:["animal","nature"],char:'\ud83e\udd81',fitzpatrick_scale:!1,category:"animals_and_nature"},cow:{keywords:["beef","ox","animal","nature","moo","milk"],char:'\ud83d\udc2e',fitzpatrick_scale:!1,category:"animals_and_nature"},pig:{keywords:["animal","oink","nature"],char:'\ud83d\udc37',fitzpatrick_scale:!1,category:"animals_and_nature"},pig_nose:{keywords:["animal","oink"],char:'\ud83d\udc3d',fitzpatrick_scale:!1,category:"animals_and_nature"},frog:{keywords:["animal","nature","croak","toad"],char:'\ud83d\udc38',fitzpatrick_scale:!1,category:"animals_and_nature"},squid:{keywords:["animal","nature","ocean","sea"],char:'\ud83e\udd91',fitzpatrick_scale:!1,category:"animals_and_nature"},octopus:{keywords:["animal","creature","ocean","sea","nature","beach"],char:'\ud83d\udc19',fitzpatrick_scale:!1,category:"animals_and_nature"},shrimp:{keywords:["animal","ocean","nature","seafood"],char:'\ud83e\udd90',fitzpatrick_scale:!1,category:"animals_and_nature"},monkey_face:{keywords:["animal","nature","circus"],char:'\ud83d\udc35',fitzpatrick_scale:!1,category:"animals_and_nature"},gorilla:{keywords:["animal","nature","circus"],char:'\ud83e\udd8d',fitzpatrick_scale:!1,category:"animals_and_nature"},see_no_evil:{keywords:["monkey","animal","nature","haha"],char:'\ud83d\ude48',fitzpatrick_scale:!1,category:"animals_and_nature"},hear_no_evil:{keywords:["animal","monkey","nature"],char:'\ud83d\ude49',fitzpatrick_scale:!1,category:"animals_and_nature"},speak_no_evil:{keywords:["monkey","animal","nature","omg"],char:'\ud83d\ude4a',fitzpatrick_scale:!1,category:"animals_and_nature"},monkey:{keywords:["animal","nature","banana","circus"],char:'\ud83d\udc12',fitzpatrick_scale:!1,category:"animals_and_nature"},chicken:{keywords:["animal","cluck","nature","bird"],char:'\ud83d\udc14',fitzpatrick_scale:!1,category:"animals_and_nature"},penguin:{keywords:["animal","nature"],char:'\ud83d\udc27',fitzpatrick_scale:!1,category:"animals_and_nature"},bird:{keywords:["animal","nature","fly","tweet","spring"],char:'\ud83d\udc26',fitzpatrick_scale:!1,category:"animals_and_nature"},baby_chick:{keywords:["animal","chicken","bird"],char:'\ud83d\udc24',fitzpatrick_scale:!1,category:"animals_and_nature"},hatching_chick:{keywords:["animal","chicken","egg","born","baby","bird"],char:'\ud83d\udc23',fitzpatrick_scale:!1,category:"animals_and_nature"},hatched_chick:{keywords:["animal","chicken","baby","bird"],char:'\ud83d\udc25',fitzpatrick_scale:!1,category:"animals_and_nature"},duck:{keywords:["animal","nature","bird","mallard"],char:'\ud83e\udd86',fitzpatrick_scale:!1,category:"animals_and_nature"},eagle:{keywords:["animal","nature","bird"],char:'\ud83e\udd85',fitzpatrick_scale:!1,category:"animals_and_nature"},owl:{keywords:["animal","nature","bird","hoot"],char:'\ud83e\udd89',fitzpatrick_scale:!1,category:"animals_and_nature"},bat:{keywords:["animal","nature","blind","vampire"],char:'\ud83e\udd87',fitzpatrick_scale:!1,category:"animals_and_nature"},wolf:{keywords:["animal","nature","wild"],char:'\ud83d\udc3a',fitzpatrick_scale:!1,category:"animals_and_nature"},boar:{keywords:["animal","nature"],char:'\ud83d\udc17',fitzpatrick_scale:!1,category:"animals_and_nature"},horse:{keywords:["animal","brown","nature"],char:'\ud83d\udc34',fitzpatrick_scale:!1,category:"animals_and_nature"},unicorn:{keywords:["animal","nature","mystical"],char:'\ud83e\udd84',fitzpatrick_scale:!1,category:"animals_and_nature"},honeybee:{keywords:["animal","insect","nature","bug","spring","honey"],char:'\ud83d\udc1d',fitzpatrick_scale:!1,category:"animals_and_nature"},bug:{keywords:["animal","insect","nature","worm"],char:'\ud83d\udc1b',fitzpatrick_scale:!1,category:"animals_and_nature"},butterfly:{keywords:["animal","insect","nature","caterpillar"],char:'\ud83e\udd8b',fitzpatrick_scale:!1,category:"animals_and_nature"},snail:{keywords:["slow","animal","shell"],char:'\ud83d\udc0c',fitzpatrick_scale:!1,category:"animals_and_nature"},beetle:{keywords:["animal","insect","nature","ladybug"],char:'\ud83d\udc1e',fitzpatrick_scale:!1,category:"animals_and_nature"},ant:{keywords:["animal","insect","nature","bug"],char:'\ud83d\udc1c',fitzpatrick_scale:!1,category:"animals_and_nature"},grasshopper:{keywords:["animal","cricket","chirp"],char:'\ud83e\udd97',fitzpatrick_scale:!1,category:"animals_and_nature"},spider:{keywords:["animal","arachnid"],char:'\ud83d\udd77',fitzpatrick_scale:!1,category:"animals_and_nature"},scorpion:{keywords:["animal","arachnid"],char:'\ud83e\udd82',fitzpatrick_scale:!1,category:"animals_and_nature"},crab:{keywords:["animal","crustacean"],char:'\ud83e\udd80',fitzpatrick_scale:!1,category:"animals_and_nature"},snake:{keywords:["animal","evil","nature","hiss","python"],char:'\ud83d\udc0d',fitzpatrick_scale:!1,category:"animals_and_nature"},lizard:{keywords:["animal","nature","reptile"],char:'\ud83e\udd8e',fitzpatrick_scale:!1,category:"animals_and_nature"},"t-rex":{keywords:["animal","nature","dinosaur","tyrannosaurus","extinct"],char:'\ud83e\udd96',fitzpatrick_scale:!1,category:"animals_and_nature"},sauropod:{keywords:["animal","nature","dinosaur","brachiosaurus","brontosaurus","diplodocus","extinct"],char:'\ud83e\udd95',fitzpatrick_scale:!1,category:"animals_and_nature"},turtle:{keywords:["animal","slow","nature","tortoise"],char:'\ud83d\udc22',fitzpatrick_scale:!1,category:"animals_and_nature"},tropical_fish:{keywords:["animal","swim","ocean","beach","nemo"],char:'\ud83d\udc20',fitzpatrick_scale:!1,category:"animals_and_nature"},fish:{keywords:["animal","food","nature"],char:'\ud83d\udc1f',fitzpatrick_scale:!1,category:"animals_and_nature"},blowfish:{keywords:["animal","nature","food","sea","ocean"],char:'\ud83d\udc21',fitzpatrick_scale:!1,category:"animals_and_nature"},dolphin:{keywords:["animal","nature","fish","sea","ocean","flipper","fins","beach"],char:'\ud83d\udc2c',fitzpatrick_scale:!1,category:"animals_and_nature"},shark:{keywords:["animal","nature","fish","sea","ocean","jaws","fins","beach"],char:'\ud83e\udd88',fitzpatrick_scale:!1,category:"animals_and_nature"},whale:{keywords:["animal","nature","sea","ocean"],char:'\ud83d\udc33',fitzpatrick_scale:!1,category:"animals_and_nature"},whale2:{keywords:["animal","nature","sea","ocean"],char:'\ud83d\udc0b',fitzpatrick_scale:!1,category:"animals_and_nature"},crocodile:{keywords:["animal","nature","reptile","lizard","alligator"],char:'\ud83d\udc0a',fitzpatrick_scale:!1,category:"animals_and_nature"},leopard:{keywords:["animal","nature"],char:'\ud83d\udc06',fitzpatrick_scale:!1,category:"animals_and_nature"},zebra:{keywords:["animal","nature","stripes","safari"],char:'\ud83e\udd93',fitzpatrick_scale:!1,category:"animals_and_nature"},tiger2:{keywords:["animal","nature","roar"],char:'\ud83d\udc05',fitzpatrick_scale:!1,category:"animals_and_nature"},water_buffalo:{keywords:["animal","nature","ox","cow"],char:'\ud83d\udc03',fitzpatrick_scale:!1,category:"animals_and_nature"},ox:{keywords:["animal","cow","beef"],char:'\ud83d\udc02',fitzpatrick_scale:!1,category:"animals_and_nature"},cow2:{keywords:["beef","ox","animal","nature","moo","milk"],char:'\ud83d\udc04',fitzpatrick_scale:!1,category:"animals_and_nature"},deer:{keywords:["animal","nature","horns","venison"],char:'\ud83e\udd8c',fitzpatrick_scale:!1,category:"animals_and_nature"},dromedary_camel:{keywords:["animal","hot","desert","hump"],char:'\ud83d\udc2a',fitzpatrick_scale:!1,category:"animals_and_nature"},camel:{keywords:["animal","nature","hot","desert","hump"],char:'\ud83d\udc2b',fitzpatrick_scale:!1,category:"animals_and_nature"},giraffe:{keywords:["animal","nature","spots","safari"],char:'\ud83e\udd92',fitzpatrick_scale:!1,category:"animals_and_nature"},elephant:{keywords:["animal","nature","nose","th","circus"],char:'\ud83d\udc18',fitzpatrick_scale:!1,category:"animals_and_nature"},rhinoceros:{keywords:["animal","nature","horn"],char:'\ud83e\udd8f',fitzpatrick_scale:!1,category:"animals_and_nature"},goat:{keywords:["animal","nature"],char:'\ud83d\udc10',fitzpatrick_scale:!1,category:"animals_and_nature"},ram:{keywords:["animal","sheep","nature"],char:'\ud83d\udc0f',fitzpatrick_scale:!1,category:"animals_and_nature"},sheep:{keywords:["animal","nature","wool","shipit"],char:'\ud83d\udc11',fitzpatrick_scale:!1,category:"animals_and_nature"},racehorse:{keywords:["animal","gamble","luck"],char:'\ud83d\udc0e',fitzpatrick_scale:!1,category:"animals_and_nature"},pig2:{keywords:["animal","nature"],char:'\ud83d\udc16',fitzpatrick_scale:!1,category:"animals_and_nature"},rat:{keywords:["animal","mouse","rodent"],char:'\ud83d\udc00',fitzpatrick_scale:!1,category:"animals_and_nature"},mouse2:{keywords:["animal","nature","rodent"],char:'\ud83d\udc01',fitzpatrick_scale:!1,category:"animals_and_nature"},rooster:{keywords:["animal","nature","chicken"],char:'\ud83d\udc13',fitzpatrick_scale:!1,category:"animals_and_nature"},turkey:{keywords:["animal","bird"],char:'\ud83e\udd83',fitzpatrick_scale:!1,category:"animals_and_nature"},dove:{keywords:["animal","bird"],char:'\ud83d\udd4a',fitzpatrick_scale:!1,category:"animals_and_nature"},dog2:{keywords:["animal","nature","friend","doge","pet","faithful"],char:'\ud83d\udc15',fitzpatrick_scale:!1,category:"animals_and_nature"},poodle:{keywords:["dog","animal","101","nature","pet"],char:'\ud83d\udc29',fitzpatrick_scale:!1,category:"animals_and_nature"},cat2:{keywords:["animal","meow","pet","cats"],char:'\ud83d\udc08',fitzpatrick_scale:!1,category:"animals_and_nature"},rabbit2:{keywords:["animal","nature","pet","magic","spring"],char:'\ud83d\udc07',fitzpatrick_scale:!1,category:"animals_and_nature"},chipmunk:{keywords:["animal","nature","rodent","squirrel"],char:'\ud83d\udc3f',fitzpatrick_scale:!1,category:"animals_and_nature"},hedgehog:{keywords:["animal","nature","spiny"],char:'\ud83e\udd94',fitzpatrick_scale:!1,category:"animals_and_nature"},raccoon:{keywords:["animal","nature"],char:'\ud83e\udd9d',fitzpatrick_scale:!1,category:"animals_and_nature"},llama:{keywords:["animal","nature","alpaca"],char:'\ud83e\udd99',fitzpatrick_scale:!1,category:"animals_and_nature"},hippopotamus:{keywords:["animal","nature"],char:'\ud83e\udd9b',fitzpatrick_scale:!1,category:"animals_and_nature"},kangaroo:{keywords:["animal","nature","australia","joey","hop","marsupial"],char:'\ud83e\udd98',fitzpatrick_scale:!1,category:"animals_and_nature"},badger:{keywords:["animal","nature","honey"],char:'\ud83e\udda1',fitzpatrick_scale:!1,category:"animals_and_nature"},swan:{keywords:["animal","nature","bird"],char:'\ud83e\udda2',fitzpatrick_scale:!1,category:"animals_and_nature"},peacock:{keywords:["animal","nature","peahen","bird"],char:'\ud83e\udd9a',fitzpatrick_scale:!1,category:"animals_and_nature"},parrot:{keywords:["animal","nature","bird","pirate","talk"],char:'\ud83e\udd9c',fitzpatrick_scale:!1,category:"animals_and_nature"},lobster:{keywords:["animal","nature","bisque","claws","seafood"],char:'\ud83e\udd9e',fitzpatrick_scale:!1,category:"animals_and_nature"},mosquito:{keywords:["animal","nature","insect","malaria"],char:'\ud83e\udd9f',fitzpatrick_scale:!1,category:"animals_and_nature"},paw_prints:{keywords:["animal","tracking","footprints","dog","cat","pet","feet"],char:'\ud83d\udc3e',fitzpatrick_scale:!1,category:"animals_and_nature"},dragon:{keywords:["animal","myth","nature","chinese","green"],char:'\ud83d\udc09',fitzpatrick_scale:!1,category:"animals_and_nature"},dragon_face:{keywords:["animal","myth","nature","chinese","green"],char:'\ud83d\udc32',fitzpatrick_scale:!1,category:"animals_and_nature"},cactus:{keywords:["vegetable","plant","nature"],char:'\ud83c\udf35',fitzpatrick_scale:!1,category:"animals_and_nature"},christmas_tree:{keywords:["festival","vacation","december","xmas","celebration"],char:'\ud83c\udf84',fitzpatrick_scale:!1,category:"animals_and_nature"},evergreen_tree:{keywords:["plant","nature"],char:'\ud83c\udf32',fitzpatrick_scale:!1,category:"animals_and_nature"},deciduous_tree:{keywords:["plant","nature"],char:'\ud83c\udf33',fitzpatrick_scale:!1,category:"animals_and_nature"},palm_tree:{keywords:["plant","vegetable","nature","summer","beach","mojito","tropical"],char:'\ud83c\udf34',fitzpatrick_scale:!1,category:"animals_and_nature"},seedling:{keywords:["plant","nature","grass","lawn","spring"],char:'\ud83c\udf31',fitzpatrick_scale:!1,category:"animals_and_nature"},herb:{keywords:["vegetable","plant","medicine","weed","grass","lawn"],char:'\ud83c\udf3f',fitzpatrick_scale:!1,category:"animals_and_nature"},shamrock:{keywords:["vegetable","plant","nature","irish","clover"],char:'\u2618',fitzpatrick_scale:!1,category:"animals_and_nature"},four_leaf_clover:{keywords:["vegetable","plant","nature","lucky","irish"],char:'\ud83c\udf40',fitzpatrick_scale:!1,category:"animals_and_nature"},bamboo:{keywords:["plant","nature","vegetable","panda","pine_decoration"],char:'\ud83c\udf8d',fitzpatrick_scale:!1,category:"animals_and_nature"},tanabata_tree:{keywords:["plant","nature","branch","summer"],char:'\ud83c\udf8b',fitzpatrick_scale:!1,category:"animals_and_nature"},leaves:{keywords:["nature","plant","tree","vegetable","grass","lawn","spring"],char:'\ud83c\udf43',fitzpatrick_scale:!1,category:"animals_and_nature"},fallen_leaf:{keywords:["nature","plant","vegetable","leaves"],char:'\ud83c\udf42',fitzpatrick_scale:!1,category:"animals_and_nature"},maple_leaf:{keywords:["nature","plant","vegetable","ca","fall"],char:'\ud83c\udf41',fitzpatrick_scale:!1,category:"animals_and_nature"},ear_of_rice:{keywords:["nature","plant"],char:'\ud83c\udf3e',fitzpatrick_scale:!1,category:"animals_and_nature"},hibiscus:{keywords:["plant","vegetable","flowers","beach"],char:'\ud83c\udf3a',fitzpatrick_scale:!1,category:"animals_and_nature"},sunflower:{keywords:["nature","plant","fall"],char:'\ud83c\udf3b',fitzpatrick_scale:!1,category:"animals_and_nature"},rose:{keywords:["flowers","valentines","love","spring"],char:'\ud83c\udf39',fitzpatrick_scale:!1,category:"animals_and_nature"},wilted_flower:{keywords:["plant","nature","flower"],char:'\ud83e\udd40',fitzpatrick_scale:!1,category:"animals_and_nature"},tulip:{keywords:["flowers","plant","nature","summer","spring"],char:'\ud83c\udf37',fitzpatrick_scale:!1,category:"animals_and_nature"},blossom:{keywords:["nature","flowers","yellow"],char:'\ud83c\udf3c',fitzpatrick_scale:!1,category:"animals_and_nature"},cherry_blossom:{keywords:["nature","plant","spring","flower"],char:'\ud83c\udf38',fitzpatrick_scale:!1,category:"animals_and_nature"},bouquet:{keywords:["flowers","nature","spring"],char:'\ud83d\udc90',fitzpatrick_scale:!1,category:"animals_and_nature"},mushroom:{keywords:["plant","vegetable"],char:'\ud83c\udf44',fitzpatrick_scale:!1,category:"animals_and_nature"},chestnut:{keywords:["food","squirrel"],char:'\ud83c\udf30',fitzpatrick_scale:!1,category:"animals_and_nature"},jack_o_lantern:{keywords:["halloween","light","pumpkin","creepy","fall"],char:'\ud83c\udf83',fitzpatrick_scale:!1,category:"animals_and_nature"},shell:{keywords:["nature","sea","beach"],char:'\ud83d\udc1a',fitzpatrick_scale:!1,category:"animals_and_nature"},spider_web:{keywords:["animal","insect","arachnid","silk"],char:'\ud83d\udd78',fitzpatrick_scale:!1,category:"animals_and_nature"},earth_americas:{keywords:["globe","world","USA","international"],char:'\ud83c\udf0e',fitzpatrick_scale:!1,category:"animals_and_nature"},earth_africa:{keywords:["globe","world","international"],char:'\ud83c\udf0d',fitzpatrick_scale:!1,category:"animals_and_nature"},earth_asia:{keywords:["globe","world","east","international"],char:'\ud83c\udf0f',fitzpatrick_scale:!1,category:"animals_and_nature"},full_moon:{keywords:["nature","yellow","twilight","planet","space","night","evening","sleep"],char:'\ud83c\udf15',fitzpatrick_scale:!1,category:"animals_and_nature"},waning_gibbous_moon:{keywords:["nature","twilight","planet","space","night","evening","sleep","waxing_gibbous_moon"],char:'\ud83c\udf16',fitzpatrick_scale:!1,category:"animals_and_nature"},last_quarter_moon:{keywords:["nature","twilight","planet","space","night","evening","sleep"],char:'\ud83c\udf17',fitzpatrick_scale:!1,category:"animals_and_nature"},waning_crescent_moon:{keywords:["nature","twilight","planet","space","night","evening","sleep"],char:'\ud83c\udf18',fitzpatrick_scale:!1,category:"animals_and_nature"},new_moon:{keywords:["nature","twilight","planet","space","night","evening","sleep"],char:'\ud83c\udf11',fitzpatrick_scale:!1,category:"animals_and_nature"},waxing_crescent_moon:{keywords:["nature","twilight","planet","space","night","evening","sleep"],char:'\ud83c\udf12',fitzpatrick_scale:!1,category:"animals_and_nature"},first_quarter_moon:{keywords:["nature","twilight","planet","space","night","evening","sleep"],char:'\ud83c\udf13',fitzpatrick_scale:!1,category:"animals_and_nature"},waxing_gibbous_moon:{keywords:["nature","night","sky","gray","twilight","planet","space","evening","sleep"],char:'\ud83c\udf14',fitzpatrick_scale:!1,category:"animals_and_nature"},new_moon_with_face:{keywords:["nature","twilight","planet","space","night","evening","sleep"],char:'\ud83c\udf1a',fitzpatrick_scale:!1,category:"animals_and_nature"},full_moon_with_face:{keywords:["nature","twilight","planet","space","night","evening","sleep"],char:'\ud83c\udf1d',fitzpatrick_scale:!1,category:"animals_and_nature"},first_quarter_moon_with_face:{keywords:["nature","twilight","planet","space","night","evening","sleep"],char:'\ud83c\udf1b',fitzpatrick_scale:!1,category:"animals_and_nature"},last_quarter_moon_with_face:{keywords:["nature","twilight","planet","space","night","evening","sleep"],char:'\ud83c\udf1c',fitzpatrick_scale:!1,category:"animals_and_nature"},sun_with_face:{keywords:["nature","morning","sky"],char:'\ud83c\udf1e',fitzpatrick_scale:!1,category:"animals_and_nature"},crescent_moon:{keywords:["night","sleep","sky","evening","magic"],char:'\ud83c\udf19',fitzpatrick_scale:!1,category:"animals_and_nature"},star:{keywords:["night","yellow"],char:'\u2b50',fitzpatrick_scale:!1,category:"animals_and_nature"},star2:{keywords:["night","sparkle","awesome","good","magic"],char:'\ud83c\udf1f',fitzpatrick_scale:!1,category:"animals_and_nature"},dizzy:{keywords:["star","sparkle","shoot","magic"],char:'\ud83d\udcab',fitzpatrick_scale:!1,category:"animals_and_nature"},sparkles:{keywords:["stars","shine","shiny","cool","awesome","good","magic"],char:'\u2728',fitzpatrick_scale:!1,category:"animals_and_nature"},comet:{keywords:["space"],char:'\u2604',fitzpatrick_scale:!1,category:"animals_and_nature"},sunny:{keywords:["weather","nature","brightness","summer","beach","spring"],char:'\u2600\ufe0f',fitzpatrick_scale:!1,category:"animals_and_nature"},sun_behind_small_cloud:{keywords:["weather"],char:'\ud83c\udf24',fitzpatrick_scale:!1,category:"animals_and_nature"},partly_sunny:{keywords:["weather","nature","cloudy","morning","fall","spring"],char:'\u26c5',fitzpatrick_scale:!1,category:"animals_and_nature"},sun_behind_large_cloud:{keywords:["weather"],char:'\ud83c\udf25',fitzpatrick_scale:!1,category:"animals_and_nature"},sun_behind_rain_cloud:{keywords:["weather"],char:'\ud83c\udf26',fitzpatrick_scale:!1,category:"animals_and_nature"},cloud:{keywords:["weather","sky"],char:'\u2601\ufe0f',fitzpatrick_scale:!1,category:"animals_and_nature"},cloud_with_rain:{keywords:["weather"],char:'\ud83c\udf27',fitzpatrick_scale:!1,category:"animals_and_nature"},cloud_with_lightning_and_rain:{keywords:["weather","lightning"],char:'\u26c8',fitzpatrick_scale:!1,category:"animals_and_nature"},cloud_with_lightning:{keywords:["weather","thunder"],char:'\ud83c\udf29',fitzpatrick_scale:!1,category:"animals_and_nature"},zap:{keywords:["thunder","weather","lightning bolt","fast"],char:'\u26a1',fitzpatrick_scale:!1,category:"animals_and_nature"},fire:{keywords:["hot","cook","flame"],char:'\ud83d\udd25',fitzpatrick_scale:!1,category:"animals_and_nature"},boom:{keywords:["bomb","explode","explosion","collision","blown"],char:'\ud83d\udca5',fitzpatrick_scale:!1,category:"animals_and_nature"},snowflake:{keywords:["winter","season","cold","weather","christmas","xmas"],char:'\u2744\ufe0f',fitzpatrick_scale:!1,category:"animals_and_nature"},cloud_with_snow:{keywords:["weather"],char:'\ud83c\udf28',fitzpatrick_scale:!1,category:"animals_and_nature"},snowman:{keywords:["winter","season","cold","weather","christmas","xmas","frozen","without_snow"],char:'\u26c4',fitzpatrick_scale:!1,category:"animals_and_nature"},snowman_with_snow:{keywords:["winter","season","cold","weather","christmas","xmas","frozen"],char:'\u2603',fitzpatrick_scale:!1,category:"animals_and_nature"},wind_face:{keywords:["gust","air"],char:'\ud83c\udf2c',fitzpatrick_scale:!1,category:"animals_and_nature"},dash:{keywords:["wind","air","fast","shoo","fart","smoke","puff"],char:'\ud83d\udca8',fitzpatrick_scale:!1,category:"animals_and_nature"},tornado:{keywords:["weather","cyclone","twister"],char:'\ud83c\udf2a',fitzpatrick_scale:!1,category:"animals_and_nature"},fog:{keywords:["weather"],char:'\ud83c\udf2b',fitzpatrick_scale:!1,category:"animals_and_nature"},open_umbrella:{keywords:["weather","spring"],char:'\u2602',fitzpatrick_scale:!1,category:"animals_and_nature"},umbrella:{keywords:["rainy","weather","spring"],char:'\u2614',fitzpatrick_scale:!1,category:"animals_and_nature"},droplet:{keywords:["water","drip","faucet","spring"],char:'\ud83d\udca7',fitzpatrick_scale:!1,category:"animals_and_nature"},sweat_drops:{keywords:["water","drip","oops"],char:'\ud83d\udca6',fitzpatrick_scale:!1,category:"animals_and_nature"},ocean:{keywords:["sea","water","wave","nature","tsunami","disaster"],char:'\ud83c\udf0a',fitzpatrick_scale:!1,category:"animals_and_nature"},green_apple:{keywords:["fruit","nature"],char:'\ud83c\udf4f',fitzpatrick_scale:!1,category:"food_and_drink"},apple:{keywords:["fruit","mac","school"],char:'\ud83c\udf4e',fitzpatrick_scale:!1,category:"food_and_drink"},pear:{keywords:["fruit","nature","food"],char:'\ud83c\udf50',fitzpatrick_scale:!1,category:"food_and_drink"},tangerine:{keywords:["food","fruit","nature","orange"],char:'\ud83c\udf4a',fitzpatrick_scale:!1,category:"food_and_drink"},lemon:{keywords:["fruit","nature"],char:'\ud83c\udf4b',fitzpatrick_scale:!1,category:"food_and_drink"},banana:{keywords:["fruit","food","monkey"],char:'\ud83c\udf4c',fitzpatrick_scale:!1,category:"food_and_drink"},watermelon:{keywords:["fruit","food","picnic","summer"],char:'\ud83c\udf49',fitzpatrick_scale:!1,category:"food_and_drink"},grapes:{keywords:["fruit","food","wine"],char:'\ud83c\udf47',fitzpatrick_scale:!1,category:"food_and_drink"},strawberry:{keywords:["fruit","food","nature"],char:'\ud83c\udf53',fitzpatrick_scale:!1,category:"food_and_drink"},melon:{keywords:["fruit","nature","food"],char:'\ud83c\udf48',fitzpatrick_scale:!1,category:"food_and_drink"},cherries:{keywords:["food","fruit"],char:'\ud83c\udf52',fitzpatrick_scale:!1,category:"food_and_drink"},peach:{keywords:["fruit","nature","food"],char:'\ud83c\udf51',fitzpatrick_scale:!1,category:"food_and_drink"},pineapple:{keywords:["fruit","nature","food"],char:'\ud83c\udf4d',fitzpatrick_scale:!1,category:"food_and_drink"},coconut:{keywords:["fruit","nature","food","palm"],char:'\ud83e\udd65',fitzpatrick_scale:!1,category:"food_and_drink"},kiwi_fruit:{keywords:["fruit","food"],char:'\ud83e\udd5d',fitzpatrick_scale:!1,category:"food_and_drink"},mango:{keywords:["fruit","food","tropical"],char:'\ud83e\udd6d',fitzpatrick_scale:!1,category:"food_and_drink"},avocado:{keywords:["fruit","food"],char:'\ud83e\udd51',fitzpatrick_scale:!1,category:"food_and_drink"},broccoli:{keywords:["fruit","food","vegetable"],char:'\ud83e\udd66',fitzpatrick_scale:!1,category:"food_and_drink"},tomato:{keywords:["fruit","vegetable","nature","food"],char:'\ud83c\udf45',fitzpatrick_scale:!1,category:"food_and_drink"},eggplant:{keywords:["vegetable","nature","food","aubergine"],char:'\ud83c\udf46',fitzpatrick_scale:!1,category:"food_and_drink"},cucumber:{keywords:["fruit","food","pickle"],char:'\ud83e\udd52',fitzpatrick_scale:!1,category:"food_and_drink"},carrot:{keywords:["vegetable","food","orange"],char:'\ud83e\udd55',fitzpatrick_scale:!1,category:"food_and_drink"},hot_pepper:{keywords:["food","spicy","chilli","chili"],char:'\ud83c\udf36',fitzpatrick_scale:!1,category:"food_and_drink"},potato:{keywords:["food","tuber","vegatable","starch"],char:'\ud83e\udd54',fitzpatrick_scale:!1,category:"food_and_drink"},corn:{keywords:["food","vegetable","plant"],char:'\ud83c\udf3d',fitzpatrick_scale:!1,category:"food_and_drink"},leafy_greens:{keywords:["food","vegetable","plant","bok choy","cabbage","kale","lettuce"],char:'\ud83e\udd6c',fitzpatrick_scale:!1,category:"food_and_drink"},sweet_potato:{keywords:["food","nature"],char:'\ud83c\udf60',fitzpatrick_scale:!1,category:"food_and_drink"},peanuts:{keywords:["food","nut"],char:'\ud83e\udd5c',fitzpatrick_scale:!1,category:"food_and_drink"},honey_pot:{keywords:["bees","sweet","kitchen"],char:'\ud83c\udf6f',fitzpatrick_scale:!1,category:"food_and_drink"},croissant:{keywords:["food","bread","french"],char:'\ud83e\udd50',fitzpatrick_scale:!1,category:"food_and_drink"},bread:{keywords:["food","wheat","breakfast","toast"],char:'\ud83c\udf5e',fitzpatrick_scale:!1,category:"food_and_drink"},baguette_bread:{keywords:["food","bread","french"],char:'\ud83e\udd56',fitzpatrick_scale:!1,category:"food_and_drink"},bagel:{keywords:["food","bread","bakery","schmear"],char:'\ud83e\udd6f',fitzpatrick_scale:!1,category:"food_and_drink"},pretzel:{keywords:["food","bread","twisted"],char:'\ud83e\udd68',fitzpatrick_scale:!1,category:"food_and_drink"},cheese:{keywords:["food","chadder"],char:'\ud83e\uddc0',fitzpatrick_scale:!1,category:"food_and_drink"},egg:{keywords:["food","chicken","breakfast"],char:'\ud83e\udd5a',fitzpatrick_scale:!1,category:"food_and_drink"},bacon:{keywords:["food","breakfast","pork","pig","meat"],char:'\ud83e\udd53',fitzpatrick_scale:!1,category:"food_and_drink"},steak:{keywords:["food","cow","meat","cut","chop","lambchop","porkchop"],char:'\ud83e\udd69',fitzpatrick_scale:!1,category:"food_and_drink"},pancakes:{keywords:["food","breakfast","flapjacks","hotcakes"],char:'\ud83e\udd5e',fitzpatrick_scale:!1,category:"food_and_drink"},poultry_leg:{keywords:["food","meat","drumstick","bird","chicken","turkey"],char:'\ud83c\udf57',fitzpatrick_scale:!1,category:"food_and_drink"},meat_on_bone:{keywords:["good","food","drumstick"],char:'\ud83c\udf56',fitzpatrick_scale:!1,category:"food_and_drink"},bone:{keywords:["skeleton"],char:'\ud83e\uddb4',fitzpatrick_scale:!1,category:"food_and_drink"},fried_shrimp:{keywords:["food","animal","appetizer","summer"],char:'\ud83c\udf64',fitzpatrick_scale:!1,category:"food_and_drink"},fried_egg:{keywords:["food","breakfast","kitchen","egg"],char:'\ud83c\udf73',fitzpatrick_scale:!1,category:"food_and_drink"},hamburger:{keywords:["meat","fast food","beef","cheeseburger","mcdonalds","burger king"],char:'\ud83c\udf54',fitzpatrick_scale:!1,category:"food_and_drink"},fries:{keywords:["chips","snack","fast food"],char:'\ud83c\udf5f',fitzpatrick_scale:!1,category:"food_and_drink"},stuffed_flatbread:{keywords:["food","flatbread","stuffed","gyro"],char:'\ud83e\udd59',fitzpatrick_scale:!1,category:"food_and_drink"},hotdog:{keywords:["food","frankfurter"],char:'\ud83c\udf2d',fitzpatrick_scale:!1,category:"food_and_drink"},pizza:{keywords:["food","party"],char:'\ud83c\udf55',fitzpatrick_scale:!1,category:"food_and_drink"},sandwich:{keywords:["food","lunch","bread"],char:'\ud83e\udd6a',fitzpatrick_scale:!1,category:"food_and_drink"},canned_food:{keywords:["food","soup"],char:'\ud83e\udd6b',fitzpatrick_scale:!1,category:"food_and_drink"},spaghetti:{keywords:["food","italian","noodle"],char:'\ud83c\udf5d',fitzpatrick_scale:!1,category:"food_and_drink"},taco:{keywords:["food","mexican"],char:'\ud83c\udf2e',fitzpatrick_scale:!1,category:"food_and_drink"},burrito:{keywords:["food","mexican"],char:'\ud83c\udf2f',fitzpatrick_scale:!1,category:"food_and_drink"},green_salad:{keywords:["food","healthy","lettuce"],char:'\ud83e\udd57',fitzpatrick_scale:!1,category:"food_and_drink"},shallow_pan_of_food:{keywords:["food","cooking","casserole","paella"],char:'\ud83e\udd58',fitzpatrick_scale:!1,category:"food_and_drink"},ramen:{keywords:["food","japanese","noodle","chopsticks"],char:'\ud83c\udf5c',fitzpatrick_scale:!1,category:"food_and_drink"},stew:{keywords:["food","meat","soup"],char:'\ud83c\udf72',fitzpatrick_scale:!1,category:"food_and_drink"},fish_cake:{keywords:["food","japan","sea","beach","narutomaki","pink","swirl","kamaboko","surimi","ramen"],char:'\ud83c\udf65',fitzpatrick_scale:!1,category:"food_and_drink"},fortune_cookie:{keywords:["food","prophecy"],char:'\ud83e\udd60',fitzpatrick_scale:!1,category:"food_and_drink"},sushi:{keywords:["food","fish","japanese","rice"],char:'\ud83c\udf63',fitzpatrick_scale:!1,category:"food_and_drink"},bento:{keywords:["food","japanese","box"],char:'\ud83c\udf71',fitzpatrick_scale:!1,category:"food_and_drink"},curry:{keywords:["food","spicy","hot","indian"],char:'\ud83c\udf5b',fitzpatrick_scale:!1,category:"food_and_drink"},rice_ball:{keywords:["food","japanese"],char:'\ud83c\udf59',fitzpatrick_scale:!1,category:"food_and_drink"},rice:{keywords:["food","china","asian"],char:'\ud83c\udf5a',fitzpatrick_scale:!1,category:"food_and_drink"},rice_cracker:{keywords:["food","japanese"],char:'\ud83c\udf58',fitzpatrick_scale:!1,category:"food_and_drink"},oden:{keywords:["food","japanese"],char:'\ud83c\udf62',fitzpatrick_scale:!1,category:"food_and_drink"},dango:{keywords:["food","dessert","sweet","japanese","barbecue","meat"],char:'\ud83c\udf61',fitzpatrick_scale:!1,category:"food_and_drink"},shaved_ice:{keywords:["hot","dessert","summer"],char:'\ud83c\udf67',fitzpatrick_scale:!1,category:"food_and_drink"},ice_cream:{keywords:["food","hot","dessert"],char:'\ud83c\udf68',fitzpatrick_scale:!1,category:"food_and_drink"},icecream:{keywords:["food","hot","dessert","summer"],char:'\ud83c\udf66',fitzpatrick_scale:!1,category:"food_and_drink"},pie:{keywords:["food","dessert","pastry"],char:'\ud83e\udd67',fitzpatrick_scale:!1,category:"food_and_drink"},cake:{keywords:["food","dessert"],char:'\ud83c\udf70',fitzpatrick_scale:!1,category:"food_and_drink"},cupcake:{keywords:["food","dessert","bakery","sweet"],char:'\ud83e\uddc1',fitzpatrick_scale:!1,category:"food_and_drink"},moon_cake:{keywords:["food","autumn"],char:'\ud83e\udd6e',fitzpatrick_scale:!1,category:"food_and_drink"},birthday:{keywords:["food","dessert","cake"],char:'\ud83c\udf82',fitzpatrick_scale:!1,category:"food_and_drink"},custard:{keywords:["dessert","food"],char:'\ud83c\udf6e',fitzpatrick_scale:!1,category:"food_and_drink"},candy:{keywords:["snack","dessert","sweet","lolly"],char:'\ud83c\udf6c',fitzpatrick_scale:!1,category:"food_and_drink"},lollipop:{keywords:["food","snack","candy","sweet"],char:'\ud83c\udf6d',fitzpatrick_scale:!1,category:"food_and_drink"},chocolate_bar:{keywords:["food","snack","dessert","sweet"],char:'\ud83c\udf6b',fitzpatrick_scale:!1,category:"food_and_drink"},popcorn:{keywords:["food","movie theater","films","snack"],char:'\ud83c\udf7f',fitzpatrick_scale:!1,category:"food_and_drink"},dumpling:{keywords:["food","empanada","pierogi","potsticker"],char:'\ud83e\udd5f',fitzpatrick_scale:!1,category:"food_and_drink"},doughnut:{keywords:["food","dessert","snack","sweet","donut"],char:'\ud83c\udf69',fitzpatrick_scale:!1,category:"food_and_drink"},cookie:{keywords:["food","snack","oreo","chocolate","sweet","dessert"],char:'\ud83c\udf6a',fitzpatrick_scale:!1,category:"food_and_drink"},milk_glass:{keywords:["beverage","drink","cow"],char:'\ud83e\udd5b',fitzpatrick_scale:!1,category:"food_and_drink"},beer:{keywords:["relax","beverage","drink","drunk","party","pub","summer","alcohol","booze"],char:'\ud83c\udf7a',fitzpatrick_scale:!1,category:"food_and_drink"},beers:{keywords:["relax","beverage","drink","drunk","party","pub","summer","alcohol","booze"],char:'\ud83c\udf7b',fitzpatrick_scale:!1,category:"food_and_drink"},clinking_glasses:{keywords:["beverage","drink","party","alcohol","celebrate","cheers","wine","champagne","toast"],char:'\ud83e\udd42',fitzpatrick_scale:!1,category:"food_and_drink"},wine_glass:{keywords:["drink","beverage","drunk","alcohol","booze"],char:'\ud83c\udf77',fitzpatrick_scale:!1,category:"food_and_drink"},tumbler_glass:{keywords:["drink","beverage","drunk","alcohol","liquor","booze","bourbon","scotch","whisky","glass","shot"],char:'\ud83e\udd43',fitzpatrick_scale:!1,category:"food_and_drink"},cocktail:{keywords:["drink","drunk","alcohol","beverage","booze","mojito"],char:'\ud83c\udf78',fitzpatrick_scale:!1,category:"food_and_drink"},tropical_drink:{keywords:["beverage","cocktail","summer","beach","alcohol","booze","mojito"],char:'\ud83c\udf79',fitzpatrick_scale:!1,category:"food_and_drink"},champagne:{keywords:["drink","wine","bottle","celebration"],char:'\ud83c\udf7e',fitzpatrick_scale:!1,category:"food_and_drink"},sake:{keywords:["wine","drink","drunk","beverage","japanese","alcohol","booze"],char:'\ud83c\udf76',fitzpatrick_scale:!1,category:"food_and_drink"},tea:{keywords:["drink","bowl","breakfast","green","british"],char:'\ud83c\udf75',fitzpatrick_scale:!1,category:"food_and_drink"},cup_with_straw:{keywords:["drink","soda"],char:'\ud83e\udd64',fitzpatrick_scale:!1,category:"food_and_drink"},coffee:{keywords:["beverage","caffeine","latte","espresso"],char:'\u2615',fitzpatrick_scale:!1,category:"food_and_drink"},baby_bottle:{keywords:["food","container","milk"],char:'\ud83c\udf7c',fitzpatrick_scale:!1,category:"food_and_drink"},salt:{keywords:["condiment","shaker"],char:'\ud83e\uddc2',fitzpatrick_scale:!1,category:"food_and_drink"},spoon:{keywords:["cutlery","kitchen","tableware"],char:'\ud83e\udd44',fitzpatrick_scale:!1,category:"food_and_drink"},fork_and_knife:{keywords:["cutlery","kitchen"],char:'\ud83c\udf74',fitzpatrick_scale:!1,category:"food_and_drink"},plate_with_cutlery:{keywords:["food","eat","meal","lunch","dinner","restaurant"],char:'\ud83c\udf7d',fitzpatrick_scale:!1,category:"food_and_drink"},bowl_with_spoon:{keywords:["food","breakfast","cereal","oatmeal","porridge"],char:'\ud83e\udd63',fitzpatrick_scale:!1,category:"food_and_drink"},takeout_box:{keywords:["food","leftovers"],char:'\ud83e\udd61',fitzpatrick_scale:!1,category:"food_and_drink"},chopsticks:{keywords:["food"],char:'\ud83e\udd62',fitzpatrick_scale:!1,category:"food_and_drink"},soccer:{keywords:["sports","football"],char:'\u26bd',fitzpatrick_scale:!1,category:"activity"},basketball:{keywords:["sports","balls","NBA"],char:'\ud83c\udfc0',fitzpatrick_scale:!1,category:"activity"},football:{keywords:["sports","balls","NFL"],char:'\ud83c\udfc8',fitzpatrick_scale:!1,category:"activity"},baseball:{keywords:["sports","balls"],char:'\u26be',fitzpatrick_scale:!1,category:"activity"},softball:{keywords:["sports","balls"],char:'\ud83e\udd4e',fitzpatrick_scale:!1,category:"activity"},tennis:{keywords:["sports","balls","green"],char:'\ud83c\udfbe',fitzpatrick_scale:!1,category:"activity"},volleyball:{keywords:["sports","balls"],char:'\ud83c\udfd0',fitzpatrick_scale:!1,category:"activity"},rugby_football:{keywords:["sports","team"],char:'\ud83c\udfc9',fitzpatrick_scale:!1,category:"activity"},flying_disc:{keywords:["sports","frisbee","ultimate"],char:'\ud83e\udd4f',fitzpatrick_scale:!1,category:"activity"},"8ball":{keywords:["pool","hobby","game","luck","magic"],char:'\ud83c\udfb1',fitzpatrick_scale:!1,category:"activity"},golf:{keywords:["sports","business","flag","hole","summer"],char:'\u26f3',fitzpatrick_scale:!1,category:"activity"},golfing_woman:{keywords:["sports","business","woman","female"],char:'\ud83c\udfcc\ufe0f\u200d\u2640\ufe0f',fitzpatrick_scale:!1,category:"activity"},golfing_man:{keywords:["sports","business"],char:'\ud83c\udfcc',fitzpatrick_scale:!0,category:"activity"},ping_pong:{keywords:["sports","pingpong"],char:'\ud83c\udfd3',fitzpatrick_scale:!1,category:"activity"},badminton:{keywords:["sports"],char:'\ud83c\udff8',fitzpatrick_scale:!1,category:"activity"},goal_net:{keywords:["sports"],char:'\ud83e\udd45',fitzpatrick_scale:!1,category:"activity"},ice_hockey:{keywords:["sports"],char:'\ud83c\udfd2',fitzpatrick_scale:!1,category:"activity"},field_hockey:{keywords:["sports"],char:'\ud83c\udfd1',fitzpatrick_scale:!1,category:"activity"},lacrosse:{keywords:["sports","ball","stick"],char:'\ud83e\udd4d',fitzpatrick_scale:!1,category:"activity"},cricket:{keywords:["sports"],char:'\ud83c\udfcf',fitzpatrick_scale:!1,category:"activity"},ski:{keywords:["sports","winter","cold","snow"],char:'\ud83c\udfbf',fitzpatrick_scale:!1,category:"activity"},skier:{keywords:["sports","winter","snow"],char:'\u26f7',fitzpatrick_scale:!1,category:"activity"},snowboarder:{keywords:["sports","winter"],char:'\ud83c\udfc2',fitzpatrick_scale:!0,category:"activity"},person_fencing:{keywords:["sports","fencing","sword"],char:'\ud83e\udd3a',fitzpatrick_scale:!1,category:"activity"},women_wrestling:{keywords:["sports","wrestlers"],char:'\ud83e\udd3c\u200d\u2640\ufe0f',fitzpatrick_scale:!1,category:"activity"},men_wrestling:{keywords:["sports","wrestlers"],char:'\ud83e\udd3c\u200d\u2642\ufe0f',fitzpatrick_scale:!1,category:"activity"},woman_cartwheeling:{keywords:["gymnastics"],char:'\ud83e\udd38\u200d\u2640\ufe0f',fitzpatrick_scale:!0,category:"activity"},man_cartwheeling:{keywords:["gymnastics"],char:'\ud83e\udd38\u200d\u2642\ufe0f',fitzpatrick_scale:!0,category:"activity"},woman_playing_handball:{keywords:["sports"],char:'\ud83e\udd3e\u200d\u2640\ufe0f',fitzpatrick_scale:!0,category:"activity"},man_playing_handball:{keywords:["sports"],char:'\ud83e\udd3e\u200d\u2642\ufe0f',fitzpatrick_scale:!0,category:"activity"},ice_skate:{keywords:["sports"],char:'\u26f8',fitzpatrick_scale:!1,category:"activity"},curling_stone:{keywords:["sports"],char:'\ud83e\udd4c',fitzpatrick_scale:!1,category:"activity"},skateboard:{keywords:["board"],char:'\ud83d\udef9',fitzpatrick_scale:!1,category:"activity"},sled:{keywords:["sleigh","luge","toboggan"],char:'\ud83d\udef7',fitzpatrick_scale:!1,category:"activity"},bow_and_arrow:{keywords:["sports"],char:'\ud83c\udff9',fitzpatrick_scale:!1,category:"activity"},fishing_pole_and_fish:{keywords:["food","hobby","summer"],char:'\ud83c\udfa3',fitzpatrick_scale:!1,category:"activity"},boxing_glove:{keywords:["sports","fighting"],char:'\ud83e\udd4a',fitzpatrick_scale:!1,category:"activity"},martial_arts_uniform:{keywords:["judo","karate","taekwondo"],char:'\ud83e\udd4b',fitzpatrick_scale:!1,category:"activity"},rowing_woman:{keywords:["sports","hobby","water","ship","woman","female"],char:'\ud83d\udea3\u200d\u2640\ufe0f',fitzpatrick_scale:!0,category:"activity"},rowing_man:{keywords:["sports","hobby","water","ship"],char:'\ud83d\udea3',fitzpatrick_scale:!0,category:"activity"},climbing_woman:{keywords:["sports","hobby","woman","female","rock"],char:'\ud83e\uddd7\u200d\u2640\ufe0f',fitzpatrick_scale:!0,category:"activity"},climbing_man:{keywords:["sports","hobby","man","male","rock"],char:'\ud83e\uddd7\u200d\u2642\ufe0f',fitzpatrick_scale:!0,category:"activity"},swimming_woman:{keywords:["sports","exercise","human","athlete","water","summer","woman","female"],char:'\ud83c\udfca\u200d\u2640\ufe0f',fitzpatrick_scale:!0,category:"activity"},swimming_man:{keywords:["sports","exercise","human","athlete","water","summer"],char:'\ud83c\udfca',fitzpatrick_scale:!0,category:"activity"},woman_playing_water_polo:{keywords:["sports","pool"],char:'\ud83e\udd3d\u200d\u2640\ufe0f',fitzpatrick_scale:!0,category:"activity"},man_playing_water_polo:{keywords:["sports","pool"],char:'\ud83e\udd3d\u200d\u2642\ufe0f',fitzpatrick_scale:!0,category:"activity"},woman_in_lotus_position:{keywords:["woman","female","meditation","yoga","serenity","zen","mindfulness"],char:'\ud83e\uddd8\u200d\u2640\ufe0f',fitzpatrick_scale:!0,category:"activity"},man_in_lotus_position:{keywords:["man","male","meditation","yoga","serenity","zen","mindfulness"],char:'\ud83e\uddd8\u200d\u2642\ufe0f',fitzpatrick_scale:!0,category:"activity"},surfing_woman:{keywords:["sports","ocean","sea","summer","beach","woman","female"],char:'\ud83c\udfc4\u200d\u2640\ufe0f',fitzpatrick_scale:!0,category:"activity"},surfing_man:{keywords:["sports","ocean","sea","summer","beach"],char:'\ud83c\udfc4',fitzpatrick_scale:!0,category:"activity"},bath:{keywords:["clean","shower","bathroom"],char:'\ud83d\udec0',fitzpatrick_scale:!0,category:"activity"},basketball_woman:{keywords:["sports","human","woman","female"],char:'\u26f9\ufe0f\u200d\u2640\ufe0f',fitzpatrick_scale:!0,category:"activity"},basketball_man:{keywords:["sports","human"],char:'\u26f9',fitzpatrick_scale:!0,category:"activity"},weight_lifting_woman:{keywords:["sports","training","exercise","woman","female"],char:'\ud83c\udfcb\ufe0f\u200d\u2640\ufe0f',fitzpatrick_scale:!0,category:"activity"},weight_lifting_man:{keywords:["sports","training","exercise"],char:'\ud83c\udfcb',fitzpatrick_scale:!0,category:"activity"},biking_woman:{keywords:["sports","bike","exercise","hipster","woman","female"],char:'\ud83d\udeb4\u200d\u2640\ufe0f',fitzpatrick_scale:!0,category:"activity"},biking_man:{keywords:["sports","bike","exercise","hipster"],char:'\ud83d\udeb4',fitzpatrick_scale:!0,category:"activity"},mountain_biking_woman:{keywords:["transportation","sports","human","race","bike","woman","female"],char:'\ud83d\udeb5\u200d\u2640\ufe0f',fitzpatrick_scale:!0,category:"activity"},mountain_biking_man:{keywords:["transportation","sports","human","race","bike"],char:'\ud83d\udeb5',fitzpatrick_scale:!0,category:"activity"},horse_racing:{keywords:["animal","betting","competition","gambling","luck"],char:'\ud83c\udfc7',fitzpatrick_scale:!0,category:"activity"},business_suit_levitating:{keywords:["suit","business","levitate","hover","jump"],char:'\ud83d\udd74',fitzpatrick_scale:!0,category:"activity"},trophy:{keywords:["win","award","contest","place","ftw","ceremony"],char:'\ud83c\udfc6',fitzpatrick_scale:!1,category:"activity"},running_shirt_with_sash:{keywords:["play","pageant"],char:'\ud83c\udfbd',fitzpatrick_scale:!1,category:"activity"},medal_sports:{keywords:["award","winning"],char:'\ud83c\udfc5',fitzpatrick_scale:!1,category:"activity"},medal_military:{keywords:["award","winning","army"],char:'\ud83c\udf96',fitzpatrick_scale:!1,category:"activity"},"1st_place_medal":{keywords:["award","winning","first"],char:'\ud83e\udd47',fitzpatrick_scale:!1,category:"activity"},"2nd_place_medal":{keywords:["award","second"],char:'\ud83e\udd48',fitzpatrick_scale:!1,category:"activity"},"3rd_place_medal":{keywords:["award","third"],char:'\ud83e\udd49',fitzpatrick_scale:!1,category:"activity"},reminder_ribbon:{keywords:["sports","cause","support","awareness"],char:'\ud83c\udf97',fitzpatrick_scale:!1,category:"activity"},rosette:{keywords:["flower","decoration","military"],char:'\ud83c\udff5',fitzpatrick_scale:!1,category:"activity"},ticket:{keywords:["event","concert","pass"],char:'\ud83c\udfab',fitzpatrick_scale:!1,category:"activity"},tickets:{keywords:["sports","concert","entrance"],char:'\ud83c\udf9f',fitzpatrick_scale:!1,category:"activity"},performing_arts:{keywords:["acting","theater","drama"],char:'\ud83c\udfad',fitzpatrick_scale:!1,category:"activity"},art:{keywords:["design","paint","draw","colors"],char:'\ud83c\udfa8',fitzpatrick_scale:!1,category:"activity"},circus_tent:{keywords:["festival","carnival","party"],char:'\ud83c\udfaa',fitzpatrick_scale:!1,category:"activity"},woman_juggling:{keywords:["juggle","balance","skill","multitask"],char:'\ud83e\udd39\u200d\u2640\ufe0f',fitzpatrick_scale:!0,category:"activity"},man_juggling:{keywords:["juggle","balance","skill","multitask"],char:'\ud83e\udd39\u200d\u2642\ufe0f',fitzpatrick_scale:!0,category:"activity"},microphone:{keywords:["sound","music","PA","sing","talkshow"],char:'\ud83c\udfa4',fitzpatrick_scale:!1,category:"activity"},headphones:{keywords:["music","score","gadgets"],char:'\ud83c\udfa7',fitzpatrick_scale:!1,category:"activity"},musical_score:{keywords:["treble","clef","compose"],char:'\ud83c\udfbc',fitzpatrick_scale:!1,category:"activity"},musical_keyboard:{keywords:["piano","instrument","compose"],char:'\ud83c\udfb9',fitzpatrick_scale:!1,category:"activity"},drum:{keywords:["music","instrument","drumsticks","snare"],char:'\ud83e\udd41',fitzpatrick_scale:!1,category:"activity"},saxophone:{keywords:["music","instrument","jazz","blues"],char:'\ud83c\udfb7',fitzpatrick_scale:!1,category:"activity"},trumpet:{keywords:["music","brass"],char:'\ud83c\udfba',fitzpatrick_scale:!1,category:"activity"},guitar:{keywords:["music","instrument"],char:'\ud83c\udfb8',fitzpatrick_scale:!1,category:"activity"},violin:{keywords:["music","instrument","orchestra","symphony"],char:'\ud83c\udfbb',fitzpatrick_scale:!1,category:"activity"},clapper:{keywords:["movie","film","record"],char:'\ud83c\udfac',fitzpatrick_scale:!1,category:"activity"},video_game:{keywords:["play","console","PS4","controller"],char:'\ud83c\udfae',fitzpatrick_scale:!1,category:"activity"},space_invader:{keywords:["game","arcade","play"],char:'\ud83d\udc7e',fitzpatrick_scale:!1,category:"activity"},dart:{keywords:["game","play","bar","target","bullseye"],char:'\ud83c\udfaf',fitzpatrick_scale:!1,category:"activity"},game_die:{keywords:["dice","random","tabletop","play","luck"],char:'\ud83c\udfb2',fitzpatrick_scale:!1,category:"activity"},chess_pawn:{keywords:["expendable"],char:"\u265f",fitzpatrick_scale:!1,category:"activity"},slot_machine:{keywords:["bet","gamble","vegas","fruit machine","luck","casino"],char:'\ud83c\udfb0',fitzpatrick_scale:!1,category:"activity"},jigsaw:{keywords:["interlocking","puzzle","piece"],char:'\ud83e\udde9',fitzpatrick_scale:!1,category:"activity"},bowling:{keywords:["sports","fun","play"],char:'\ud83c\udfb3',fitzpatrick_scale:!1,category:"activity"},red_car:{keywords:["red","transportation","vehicle"],char:'\ud83d\ude97',fitzpatrick_scale:!1,category:"travel_and_places"},taxi:{keywords:["uber","vehicle","cars","transportation"],char:'\ud83d\ude95',fitzpatrick_scale:!1,category:"travel_and_places"},blue_car:{keywords:["transportation","vehicle"],char:'\ud83d\ude99',fitzpatrick_scale:!1,category:"travel_and_places"},bus:{keywords:["car","vehicle","transportation"],char:'\ud83d\ude8c',fitzpatrick_scale:!1,category:"travel_and_places"},trolleybus:{keywords:["bart","transportation","vehicle"],char:'\ud83d\ude8e',fitzpatrick_scale:!1,category:"travel_and_places"},racing_car:{keywords:["sports","race","fast","formula","f1"],char:'\ud83c\udfce',fitzpatrick_scale:!1,category:"travel_and_places"},police_car:{keywords:["vehicle","cars","transportation","law","legal","enforcement"],char:'\ud83d\ude93',fitzpatrick_scale:!1,category:"travel_and_places"},ambulance:{keywords:["health","911","hospital"],char:'\ud83d\ude91',fitzpatrick_scale:!1,category:"travel_and_places"},fire_engine:{keywords:["transportation","cars","vehicle"],char:'\ud83d\ude92',fitzpatrick_scale:!1,category:"travel_and_places"},minibus:{keywords:["vehicle","car","transportation"],char:'\ud83d\ude90',fitzpatrick_scale:!1,category:"travel_and_places"},truck:{keywords:["cars","transportation"],char:'\ud83d\ude9a',fitzpatrick_scale:!1,category:"travel_and_places"},articulated_lorry:{keywords:["vehicle","cars","transportation","express"],char:'\ud83d\ude9b',fitzpatrick_scale:!1,category:"travel_and_places"},tractor:{keywords:["vehicle","car","farming","agriculture"],char:'\ud83d\ude9c',fitzpatrick_scale:!1,category:"travel_and_places"},kick_scooter:{keywords:["vehicle","kick","razor"],char:'\ud83d\udef4',fitzpatrick_scale:!1,category:"travel_and_places"},motorcycle:{keywords:["race","sports","fast"],char:'\ud83c\udfcd',fitzpatrick_scale:!1,category:"travel_and_places"},bike:{keywords:["sports","bicycle","exercise","hipster"],char:'\ud83d\udeb2',fitzpatrick_scale:!1,category:"travel_and_places"},motor_scooter:{keywords:["vehicle","vespa","sasha"],char:'\ud83d\udef5',fitzpatrick_scale:!1,category:"travel_and_places"},rotating_light:{keywords:["police","ambulance","911","emergency","alert","error","pinged","law","legal"],char:'\ud83d\udea8',fitzpatrick_scale:!1,category:"travel_and_places"},oncoming_police_car:{keywords:["vehicle","law","legal","enforcement","911"],char:'\ud83d\ude94',fitzpatrick_scale:!1,category:"travel_and_places"},oncoming_bus:{keywords:["vehicle","transportation"],char:'\ud83d\ude8d',fitzpatrick_scale:!1,category:"travel_and_places"},oncoming_automobile:{keywords:["car","vehicle","transportation"],char:'\ud83d\ude98',fitzpatrick_scale:!1,category:"travel_and_places"},oncoming_taxi:{keywords:["vehicle","cars","uber"],char:'\ud83d\ude96',fitzpatrick_scale:!1,category:"travel_and_places"},aerial_tramway:{keywords:["transportation","vehicle","ski"],char:'\ud83d\udea1',fitzpatrick_scale:!1,category:"travel_and_places"},mountain_cableway:{keywords:["transportation","vehicle","ski"],char:'\ud83d\udea0',fitzpatrick_scale:!1,category:"travel_and_places"},suspension_railway:{keywords:["vehicle","transportation"],char:'\ud83d\ude9f',fitzpatrick_scale:!1,category:"travel_and_places"},railway_car:{keywords:["transportation","vehicle"],char:'\ud83d\ude83',fitzpatrick_scale:!1,category:"travel_and_places"},train:{keywords:["transportation","vehicle","carriage","public","travel"],char:'\ud83d\ude8b',fitzpatrick_scale:!1,category:"travel_and_places"},monorail:{keywords:["transportation","vehicle"],char:'\ud83d\ude9d',fitzpatrick_scale:!1,category:"travel_and_places"},bullettrain_side:{keywords:["transportation","vehicle"],char:'\ud83d\ude84',fitzpatrick_scale:!1,category:"travel_and_places"},bullettrain_front:{keywords:["transportation","vehicle","speed","fast","public","travel"],char:'\ud83d\ude85',fitzpatrick_scale:!1,category:"travel_and_places"},light_rail:{keywords:["transportation","vehicle"],char:'\ud83d\ude88',fitzpatrick_scale:!1,category:"travel_and_places"},mountain_railway:{keywords:["transportation","vehicle"],char:'\ud83d\ude9e',fitzpatrick_scale:!1,category:"travel_and_places"},steam_locomotive:{keywords:["transportation","vehicle","train"],char:'\ud83d\ude82',fitzpatrick_scale:!1,category:"travel_and_places"},train2:{keywords:["transportation","vehicle"],char:'\ud83d\ude86',fitzpatrick_scale:!1,category:"travel_and_places"},metro:{keywords:["transportation","blue-square","mrt","underground","tube"],char:'\ud83d\ude87',fitzpatrick_scale:!1,category:"travel_and_places"},tram:{keywords:["transportation","vehicle"],char:'\ud83d\ude8a',fitzpatrick_scale:!1,category:"travel_and_places"},station:{keywords:["transportation","vehicle","public"],char:'\ud83d\ude89',fitzpatrick_scale:!1,category:"travel_and_places"},flying_saucer:{keywords:["transportation","vehicle","ufo"],char:'\ud83d\udef8',fitzpatrick_scale:!1,category:"travel_and_places"},helicopter:{keywords:["transportation","vehicle","fly"],char:'\ud83d\ude81',fitzpatrick_scale:!1,category:"travel_and_places"},small_airplane:{keywords:["flight","transportation","fly","vehicle"],char:'\ud83d\udee9',fitzpatrick_scale:!1,category:"travel_and_places"},airplane:{keywords:["vehicle","transportation","flight","fly"],char:'\u2708\ufe0f',fitzpatrick_scale:!1,category:"travel_and_places"},flight_departure:{keywords:["airport","flight","landing"],char:'\ud83d\udeeb',fitzpatrick_scale:!1,category:"travel_and_places"},flight_arrival:{keywords:["airport","flight","boarding"],char:'\ud83d\udeec',fitzpatrick_scale:!1,category:"travel_and_places"},sailboat:{keywords:["ship","summer","transportation","water","sailing"],char:'\u26f5',fitzpatrick_scale:!1,category:"travel_and_places"},motor_boat:{keywords:["ship"],char:'\ud83d\udee5',fitzpatrick_scale:!1,category:"travel_and_places"},speedboat:{keywords:["ship","transportation","vehicle","summer"],char:'\ud83d\udea4',fitzpatrick_scale:!1,category:"travel_and_places"},ferry:{keywords:["boat","ship","yacht"],char:'\u26f4',fitzpatrick_scale:!1,category:"travel_and_places"},passenger_ship:{keywords:["yacht","cruise","ferry"],char:'\ud83d\udef3',fitzpatrick_scale:!1,category:"travel_and_places"},rocket:{keywords:["launch","ship","staffmode","NASA","outer space","outer_space","fly"],char:'\ud83d\ude80',fitzpatrick_scale:!1,category:"travel_and_places"},artificial_satellite:{keywords:["communication","gps","orbit","spaceflight","NASA","ISS"],char:'\ud83d\udef0',fitzpatrick_scale:!1,category:"travel_and_places"},seat:{keywords:["sit","airplane","transport","bus","flight","fly"],char:'\ud83d\udcba',fitzpatrick_scale:!1,category:"travel_and_places"},canoe:{keywords:["boat","paddle","water","ship"],char:'\ud83d\udef6',fitzpatrick_scale:!1,category:"travel_and_places"},anchor:{keywords:["ship","ferry","sea","boat"],char:'\u2693',fitzpatrick_scale:!1,category:"travel_and_places"},construction:{keywords:["wip","progress","caution","warning"],char:'\ud83d\udea7',fitzpatrick_scale:!1,category:"travel_and_places"},fuelpump:{keywords:["gas station","petroleum"],char:'\u26fd',fitzpatrick_scale:!1,category:"travel_and_places"},busstop:{keywords:["transportation","wait"],char:'\ud83d\ude8f',fitzpatrick_scale:!1,category:"travel_and_places"},vertical_traffic_light:{keywords:["transportation","driving"],char:'\ud83d\udea6',fitzpatrick_scale:!1,category:"travel_and_places"},traffic_light:{keywords:["transportation","signal"],char:'\ud83d\udea5',fitzpatrick_scale:!1,category:"travel_and_places"},checkered_flag:{keywords:["contest","finishline","race","gokart"],char:'\ud83c\udfc1',fitzpatrick_scale:!1,category:"travel_and_places"},ship:{keywords:["transportation","titanic","deploy"],char:'\ud83d\udea2',fitzpatrick_scale:!1,category:"travel_and_places"},ferris_wheel:{keywords:["photo","carnival","londoneye"],char:'\ud83c\udfa1',fitzpatrick_scale:!1,category:"travel_and_places"},roller_coaster:{keywords:["carnival","playground","photo","fun"],char:'\ud83c\udfa2',fitzpatrick_scale:!1,category:"travel_and_places"},carousel_horse:{keywords:["photo","carnival"],char:'\ud83c\udfa0',fitzpatrick_scale:!1,category:"travel_and_places"},building_construction:{keywords:["wip","working","progress"],char:'\ud83c\udfd7',fitzpatrick_scale:!1,category:"travel_and_places"},foggy:{keywords:["photo","mountain"],char:'\ud83c\udf01',fitzpatrick_scale:!1,category:"travel_and_places"},tokyo_tower:{keywords:["photo","japanese"],char:'\ud83d\uddfc',fitzpatrick_scale:!1,category:"travel_and_places"},factory:{keywords:["building","industry","pollution","smoke"],char:'\ud83c\udfed',fitzpatrick_scale:!1,category:"travel_and_places"},fountain:{keywords:["photo","summer","water","fresh"],char:'\u26f2',fitzpatrick_scale:!1,category:"travel_and_places"},rice_scene:{keywords:["photo","japan","asia","tsukimi"],char:'\ud83c\udf91',fitzpatrick_scale:!1,category:"travel_and_places"},mountain:{keywords:["photo","nature","environment"],char:'\u26f0',fitzpatrick_scale:!1,category:"travel_and_places"},mountain_snow:{keywords:["photo","nature","environment","winter","cold"],char:'\ud83c\udfd4',fitzpatrick_scale:!1,category:"travel_and_places"},mount_fuji:{keywords:["photo","mountain","nature","japanese"],char:'\ud83d\uddfb',fitzpatrick_scale:!1,category:"travel_and_places"},volcano:{keywords:["photo","nature","disaster"],char:'\ud83c\udf0b',fitzpatrick_scale:!1,category:"travel_and_places"},japan:{keywords:["nation","country","japanese","asia"],char:'\ud83d\uddfe',fitzpatrick_scale:!1,category:"travel_and_places"},camping:{keywords:["photo","outdoors","tent"],char:'\ud83c\udfd5',fitzpatrick_scale:!1,category:"travel_and_places"},tent:{keywords:["photo","camping","outdoors"],char:'\u26fa',fitzpatrick_scale:!1,category:"travel_and_places"},national_park:{keywords:["photo","environment","nature"],char:'\ud83c\udfde',fitzpatrick_scale:!1,category:"travel_and_places"},motorway:{keywords:["road","cupertino","interstate","highway"],char:'\ud83d\udee3',fitzpatrick_scale:!1,category:"travel_and_places"},railway_track:{keywords:["train","transportation"],char:'\ud83d\udee4',fitzpatrick_scale:!1,category:"travel_and_places"},sunrise:{keywords:["morning","view","vacation","photo"],char:'\ud83c\udf05',fitzpatrick_scale:!1,category:"travel_and_places"},sunrise_over_mountains:{keywords:["view","vacation","photo"],char:'\ud83c\udf04',fitzpatrick_scale:!1,category:"travel_and_places"},desert:{keywords:["photo","warm","saharah"],char:'\ud83c\udfdc',fitzpatrick_scale:!1,category:"travel_and_places"},beach_umbrella:{keywords:["weather","summer","sunny","sand","mojito"],char:'\ud83c\udfd6',fitzpatrick_scale:!1,category:"travel_and_places"},desert_island:{keywords:["photo","tropical","mojito"],char:'\ud83c\udfdd',fitzpatrick_scale:!1,category:"travel_and_places"},city_sunrise:{keywords:["photo","good morning","dawn"],char:'\ud83c\udf07',fitzpatrick_scale:!1,category:"travel_and_places"},city_sunset:{keywords:["photo","evening","sky","buildings"],char:'\ud83c\udf06',fitzpatrick_scale:!1,category:"travel_and_places"},cityscape:{keywords:["photo","night life","urban"],char:'\ud83c\udfd9',fitzpatrick_scale:!1,category:"travel_and_places"},night_with_stars:{keywords:["evening","city","downtown"],char:'\ud83c\udf03',fitzpatrick_scale:!1,category:"travel_and_places"},bridge_at_night:{keywords:["photo","sanfrancisco"],char:'\ud83c\udf09',fitzpatrick_scale:!1,category:"travel_and_places"},milky_way:{keywords:["photo","space","stars"],char:'\ud83c\udf0c',fitzpatrick_scale:!1,category:"travel_and_places"},stars:{keywords:["night","photo"],char:'\ud83c\udf20',fitzpatrick_scale:!1,category:"travel_and_places"},sparkler:{keywords:["stars","night","shine"],char:'\ud83c\udf87',fitzpatrick_scale:!1,category:"travel_and_places"},fireworks:{keywords:["photo","festival","carnival","congratulations"],char:'\ud83c\udf86',fitzpatrick_scale:!1,category:"travel_and_places"},rainbow:{keywords:["nature","happy","unicorn_face","photo","sky","spring"],char:'\ud83c\udf08',fitzpatrick_scale:!1,category:"travel_and_places"},houses:{keywords:["buildings","photo"],char:'\ud83c\udfd8',fitzpatrick_scale:!1,category:"travel_and_places"},european_castle:{keywords:["building","royalty","history"],char:'\ud83c\udff0',fitzpatrick_scale:!1,category:"travel_and_places"},japanese_castle:{keywords:["photo","building"],char:'\ud83c\udfef',fitzpatrick_scale:!1,category:"travel_and_places"},stadium:{keywords:["photo","place","sports","concert","venue"],char:'\ud83c\udfdf',fitzpatrick_scale:!1,category:"travel_and_places"},statue_of_liberty:{keywords:["american","newyork"],char:'\ud83d\uddfd',fitzpatrick_scale:!1,category:"travel_and_places"},house:{keywords:["building","home"],char:'\ud83c\udfe0',fitzpatrick_scale:!1,category:"travel_and_places"},house_with_garden:{keywords:["home","plant","nature"],char:'\ud83c\udfe1',fitzpatrick_scale:!1,category:"travel_and_places"},derelict_house:{keywords:["abandon","evict","broken","building"],char:'\ud83c\udfda',fitzpatrick_scale:!1,category:"travel_and_places"},office:{keywords:["building","bureau","work"],char:'\ud83c\udfe2',fitzpatrick_scale:!1,category:"travel_and_places"},department_store:{keywords:["building","shopping","mall"],char:'\ud83c\udfec',fitzpatrick_scale:!1,category:"travel_and_places"},post_office:{keywords:["building","envelope","communication"],char:'\ud83c\udfe3',fitzpatrick_scale:!1,category:"travel_and_places"},european_post_office:{keywords:["building","email"],char:'\ud83c\udfe4',fitzpatrick_scale:!1,category:"travel_and_places"},hospital:{keywords:["building","health","surgery","doctor"],char:'\ud83c\udfe5',fitzpatrick_scale:!1,category:"travel_and_places"},bank:{keywords:["building","money","sales","cash","business","enterprise"],char:'\ud83c\udfe6',fitzpatrick_scale:!1,category:"travel_and_places"},hotel:{keywords:["building","accomodation","checkin"],char:'\ud83c\udfe8',fitzpatrick_scale:!1,category:"travel_and_places"},convenience_store:{keywords:["building","shopping","groceries"],char:'\ud83c\udfea',fitzpatrick_scale:!1,category:"travel_and_places"},school:{keywords:["building","student","education","learn","teach"],char:'\ud83c\udfeb',fitzpatrick_scale:!1,category:"travel_and_places"},love_hotel:{keywords:["like","affection","dating"],char:'\ud83c\udfe9',fitzpatrick_scale:!1,category:"travel_and_places"},wedding:{keywords:["love","like","affection","couple","marriage","bride","groom"],char:'\ud83d\udc92',fitzpatrick_scale:!1,category:"travel_and_places"},classical_building:{keywords:["art","culture","history"],char:'\ud83c\udfdb',fitzpatrick_scale:!1,category:"travel_and_places"},church:{keywords:["building","religion","christ"],char:'\u26ea',fitzpatrick_scale:!1,category:"travel_and_places"},mosque:{keywords:["islam","worship","minaret"],char:'\ud83d\udd4c',fitzpatrick_scale:!1,category:"travel_and_places"},synagogue:{keywords:["judaism","worship","temple","jewish"],char:'\ud83d\udd4d',fitzpatrick_scale:!1,category:"travel_and_places"},kaaba:{keywords:["mecca","mosque","islam"],char:'\ud83d\udd4b',fitzpatrick_scale:!1,category:"travel_and_places"},shinto_shrine:{keywords:["temple","japan","kyoto"],char:'\u26e9',fitzpatrick_scale:!1,category:"travel_and_places"},watch:{keywords:["time","accessories"],char:'\u231a',fitzpatrick_scale:!1,category:"objects"},iphone:{keywords:["technology","apple","gadgets","dial"],char:'\ud83d\udcf1',fitzpatrick_scale:!1,category:"objects"},calling:{keywords:["iphone","incoming"],char:'\ud83d\udcf2',fitzpatrick_scale:!1,category:"objects"},computer:{keywords:["technology","laptop","screen","display","monitor"],char:'\ud83d\udcbb',fitzpatrick_scale:!1,category:"objects"},keyboard:{keywords:["technology","computer","type","input","text"],char:'\u2328',fitzpatrick_scale:!1,category:"objects"},desktop_computer:{keywords:["technology","computing","screen"],char:'\ud83d\udda5',fitzpatrick_scale:!1,category:"objects"},printer:{keywords:["paper","ink"],char:'\ud83d\udda8',fitzpatrick_scale:!1,category:"objects"},computer_mouse:{keywords:["click"],char:'\ud83d\uddb1',fitzpatrick_scale:!1,category:"objects"},trackball:{keywords:["technology","trackpad"],char:'\ud83d\uddb2',fitzpatrick_scale:!1,category:"objects"},joystick:{keywords:["game","play"],char:'\ud83d\udd79',fitzpatrick_scale:!1,category:"objects"},clamp:{keywords:["tool"],char:'\ud83d\udddc',fitzpatrick_scale:!1,category:"objects"},minidisc:{keywords:["technology","record","data","disk","90s"],char:'\ud83d\udcbd',fitzpatrick_scale:!1,category:"objects"},floppy_disk:{keywords:["oldschool","technology","save","90s","80s"],char:'\ud83d\udcbe',fitzpatrick_scale:!1,category:"objects"},cd:{keywords:["technology","dvd","disk","disc","90s"],char:'\ud83d\udcbf',fitzpatrick_scale:!1,category:"objects"},dvd:{keywords:["cd","disk","disc"],char:'\ud83d\udcc0',fitzpatrick_scale:!1,category:"objects"},vhs:{keywords:["record","video","oldschool","90s","80s"],char:'\ud83d\udcfc',fitzpatrick_scale:!1,category:"objects"},camera:{keywords:["gadgets","photography"],char:'\ud83d\udcf7',fitzpatrick_scale:!1,category:"objects"},camera_flash:{keywords:["photography","gadgets"],char:'\ud83d\udcf8',fitzpatrick_scale:!1,category:"objects"},video_camera:{keywords:["film","record"],char:'\ud83d\udcf9',fitzpatrick_scale:!1,category:"objects"},movie_camera:{keywords:["film","record"],char:'\ud83c\udfa5',fitzpatrick_scale:!1,category:"objects"},film_projector:{keywords:["video","tape","record","movie"],char:'\ud83d\udcfd',fitzpatrick_scale:!1,category:"objects"},film_strip:{keywords:["movie"],char:'\ud83c\udf9e',fitzpatrick_scale:!1,category:"objects"},telephone_receiver:{keywords:["technology","communication","dial"],char:'\ud83d\udcde',fitzpatrick_scale:!1,category:"objects"},phone:{keywords:["technology","communication","dial","telephone"],char:'\u260e\ufe0f',fitzpatrick_scale:!1,category:"objects"},pager:{keywords:["bbcall","oldschool","90s"],char:'\ud83d\udcdf',fitzpatrick_scale:!1,category:"objects"},fax:{keywords:["communication","technology"],char:'\ud83d\udce0',fitzpatrick_scale:!1,category:"objects"},tv:{keywords:["technology","program","oldschool","show","television"],char:'\ud83d\udcfa',fitzpatrick_scale:!1,category:"objects"},radio:{keywords:["communication","music","podcast","program"],char:'\ud83d\udcfb',fitzpatrick_scale:!1,category:"objects"},studio_microphone:{keywords:["sing","recording","artist","talkshow"],char:'\ud83c\udf99',fitzpatrick_scale:!1,category:"objects"},level_slider:{keywords:["scale"],char:'\ud83c\udf9a',fitzpatrick_scale:!1,category:"objects"},control_knobs:{keywords:["dial"],char:'\ud83c\udf9b',fitzpatrick_scale:!1,category:"objects"},compass:{keywords:["magnetic","navigation","orienteering"],char:'\ud83e\udded',fitzpatrick_scale:!1,category:"objects"},stopwatch:{keywords:["time","deadline"],char:'\u23f1',fitzpatrick_scale:!1,category:"objects"},timer_clock:{keywords:["alarm"],char:'\u23f2',fitzpatrick_scale:!1,category:"objects"},alarm_clock:{keywords:["time","wake"],char:'\u23f0',fitzpatrick_scale:!1,category:"objects"},mantelpiece_clock:{keywords:["time"],char:'\ud83d\udd70',fitzpatrick_scale:!1,category:"objects"},hourglass_flowing_sand:{keywords:["oldschool","time","countdown"],char:'\u23f3',fitzpatrick_scale:!1,category:"objects"},hourglass:{keywords:["time","clock","oldschool","limit","exam","quiz","test"],char:'\u231b',fitzpatrick_scale:!1,category:"objects"},satellite:{keywords:["communication","future","radio","space"],char:'\ud83d\udce1',fitzpatrick_scale:!1,category:"objects"},battery:{keywords:["power","energy","sustain"],char:'\ud83d\udd0b',fitzpatrick_scale:!1,category:"objects"},electric_plug:{keywords:["charger","power"],char:'\ud83d\udd0c',fitzpatrick_scale:!1,category:"objects"},bulb:{keywords:["light","electricity","idea"],char:'\ud83d\udca1',fitzpatrick_scale:!1,category:"objects"},flashlight:{keywords:["dark","camping","sight","night"],char:'\ud83d\udd26',fitzpatrick_scale:!1,category:"objects"},candle:{keywords:["fire","wax"],char:'\ud83d\udd6f',fitzpatrick_scale:!1,category:"objects"},fire_extinguisher:{keywords:["quench"],char:'\ud83e\uddef',fitzpatrick_scale:!1,category:"objects"},wastebasket:{keywords:["bin","trash","rubbish","garbage","toss"],char:'\ud83d\uddd1',fitzpatrick_scale:!1,category:"objects"},oil_drum:{keywords:["barrell"],char:'\ud83d\udee2',fitzpatrick_scale:!1,category:"objects"},money_with_wings:{keywords:["dollar","bills","payment","sale"],char:'\ud83d\udcb8',fitzpatrick_scale:!1,category:"objects"},dollar:{keywords:["money","sales","bill","currency"],char:'\ud83d\udcb5',fitzpatrick_scale:!1,category:"objects"},yen:{keywords:["money","sales","japanese","dollar","currency"],char:'\ud83d\udcb4',fitzpatrick_scale:!1,category:"objects"},euro:{keywords:["money","sales","dollar","currency"],char:'\ud83d\udcb6',fitzpatrick_scale:!1,category:"objects"},pound:{keywords:["british","sterling","money","sales","bills","uk","england","currency"],char:'\ud83d\udcb7',fitzpatrick_scale:!1,category:"objects"},moneybag:{keywords:["dollar","payment","coins","sale"],char:'\ud83d\udcb0',fitzpatrick_scale:!1,category:"objects"},credit_card:{keywords:["money","sales","dollar","bill","payment","shopping"],char:'\ud83d\udcb3',fitzpatrick_scale:!1,category:"objects"},gem:{keywords:["blue","ruby","diamond","jewelry"],char:'\ud83d\udc8e',fitzpatrick_scale:!1,category:"objects"},balance_scale:{keywords:["law","fairness","weight"],char:'\u2696',fitzpatrick_scale:!1,category:"objects"},toolbox:{keywords:["tools","diy","fix","maintainer","mechanic"],char:'\ud83e\uddf0',fitzpatrick_scale:!1,category:"objects"},wrench:{keywords:["tools","diy","ikea","fix","maintainer"],char:'\ud83d\udd27',fitzpatrick_scale:!1,category:"objects"},hammer:{keywords:["tools","build","create"],char:'\ud83d\udd28',fitzpatrick_scale:!1,category:"objects"},hammer_and_pick:{keywords:["tools","build","create"],char:'\u2692',fitzpatrick_scale:!1,category:"objects"},hammer_and_wrench:{keywords:["tools","build","create"],char:'\ud83d\udee0',fitzpatrick_scale:!1,category:"objects"},pick:{keywords:["tools","dig"],char:'\u26cf',fitzpatrick_scale:!1,category:"objects"},nut_and_bolt:{keywords:["handy","tools","fix"],char:'\ud83d\udd29',fitzpatrick_scale:!1,category:"objects"},gear:{keywords:["cog"],char:'\u2699',fitzpatrick_scale:!1,category:"objects"},brick:{keywords:["bricks"],char:'\ud83e\uddf1',fitzpatrick_scale:!1,category:"objects"},chains:{keywords:["lock","arrest"],char:'\u26d3',fitzpatrick_scale:!1,category:"objects"},magnet:{keywords:["attraction","magnetic"],char:'\ud83e\uddf2',fitzpatrick_scale:!1,category:"objects"},gun:{keywords:["violence","weapon","pistol","revolver"],char:'\ud83d\udd2b',fitzpatrick_scale:!1,category:"objects"},bomb:{keywords:["boom","explode","explosion","terrorism"],char:'\ud83d\udca3',fitzpatrick_scale:!1,category:"objects"},firecracker:{keywords:["dynamite","boom","explode","explosion","explosive"],char:'\ud83e\udde8',fitzpatrick_scale:!1,category:"objects"},hocho:{keywords:["knife","blade","cutlery","kitchen","weapon"],char:'\ud83d\udd2a',fitzpatrick_scale:!1,category:"objects"},dagger:{keywords:["weapon"],char:'\ud83d\udde1',fitzpatrick_scale:!1,category:"objects"},crossed_swords:{keywords:["weapon"],char:'\u2694',fitzpatrick_scale:!1,category:"objects"},shield:{keywords:["protection","security"],char:'\ud83d\udee1',fitzpatrick_scale:!1,category:"objects"},smoking:{keywords:["kills","tobacco","cigarette","joint","smoke"],char:'\ud83d\udeac',fitzpatrick_scale:!1,category:"objects"},skull_and_crossbones:{keywords:["poison","danger","deadly","scary","death","pirate","evil"],char:'\u2620',fitzpatrick_scale:!1,category:"objects"},coffin:{keywords:["vampire","dead","die","death","rip","graveyard","cemetery","casket","funeral","box"],char:'\u26b0',fitzpatrick_scale:!1,category:"objects"},funeral_urn:{keywords:["dead","die","death","rip","ashes"],char:'\u26b1',fitzpatrick_scale:!1,category:"objects"},amphora:{keywords:["vase","jar"],char:'\ud83c\udffa',fitzpatrick_scale:!1,category:"objects"},crystal_ball:{keywords:["disco","party","magic","circus","fortune_teller"],char:'\ud83d\udd2e',fitzpatrick_scale:!1,category:"objects"},prayer_beads:{keywords:["dhikr","religious"],char:'\ud83d\udcff',fitzpatrick_scale:!1,category:"objects"},nazar_amulet:{keywords:["bead","charm"],char:'\ud83e\uddff',fitzpatrick_scale:!1,category:"objects"},barber:{keywords:["hair","salon","style"],char:'\ud83d\udc88',fitzpatrick_scale:!1,category:"objects"},alembic:{keywords:["distilling","science","experiment","chemistry"],char:'\u2697',fitzpatrick_scale:!1,category:"objects"},telescope:{keywords:["stars","space","zoom","science","astronomy"],char:'\ud83d\udd2d',fitzpatrick_scale:!1,category:"objects"},microscope:{keywords:["laboratory","experiment","zoomin","science","study"],char:'\ud83d\udd2c',fitzpatrick_scale:!1,category:"objects"},hole:{keywords:["embarrassing"],char:'\ud83d\udd73',fitzpatrick_scale:!1,category:"objects"},pill:{keywords:["health","medicine","doctor","pharmacy","drug"],char:'\ud83d\udc8a',fitzpatrick_scale:!1,category:"objects"},syringe:{keywords:["health","hospital","drugs","blood","medicine","needle","doctor","nurse"],char:'\ud83d\udc89',fitzpatrick_scale:!1,category:"objects"},dna:{keywords:["biologist","genetics","life"],char:'\ud83e\uddec',fitzpatrick_scale:!1,category:"objects"},microbe:{keywords:["amoeba","bacteria","germs"],char:'\ud83e\udda0',fitzpatrick_scale:!1,category:"objects"},petri_dish:{keywords:["bacteria","biology","culture","lab"],char:'\ud83e\uddeb',fitzpatrick_scale:!1,category:"objects"},test_tube:{keywords:["chemistry","experiment","lab","science"],char:'\ud83e\uddea',fitzpatrick_scale:!1,category:"objects"},thermometer:{keywords:["weather","temperature","hot","cold"],char:'\ud83c\udf21',fitzpatrick_scale:!1,category:"objects"},broom:{keywords:["cleaning","sweeping","witch"],char:'\ud83e\uddf9',fitzpatrick_scale:!1,category:"objects"},basket:{keywords:["laundry"],char:'\ud83e\uddfa',fitzpatrick_scale:!1,category:"objects"},toilet_paper:{keywords:["roll"],char:'\ud83e\uddfb',fitzpatrick_scale:!1,category:"objects"},label:{keywords:["sale","tag"],char:'\ud83c\udff7',fitzpatrick_scale:!1,category:"objects"},bookmark:{keywords:["favorite","label","save"],char:'\ud83d\udd16',fitzpatrick_scale:!1,category:"objects"},toilet:{keywords:["restroom","wc","washroom","bathroom","potty"],char:'\ud83d\udebd',fitzpatrick_scale:!1,category:"objects"},shower:{keywords:["clean","water","bathroom"],char:'\ud83d\udebf',fitzpatrick_scale:!1,category:"objects"},bathtub:{keywords:["clean","shower","bathroom"],char:'\ud83d\udec1',fitzpatrick_scale:!1,category:"objects"},soap:{keywords:["bar","bathing","cleaning","lather"],char:'\ud83e\uddfc',fitzpatrick_scale:!1,category:"objects"},sponge:{keywords:["absorbing","cleaning","porous"],char:'\ud83e\uddfd',fitzpatrick_scale:!1,category:"objects"},lotion_bottle:{keywords:["moisturizer","sunscreen"],char:'\ud83e\uddf4',fitzpatrick_scale:!1,category:"objects"},key:{keywords:["lock","door","password"],char:'\ud83d\udd11',fitzpatrick_scale:!1,category:"objects"},old_key:{keywords:["lock","door","password"],char:'\ud83d\udddd',fitzpatrick_scale:!1,category:"objects"},couch_and_lamp:{keywords:["read","chill"],char:'\ud83d\udecb',fitzpatrick_scale:!1,category:"objects"},sleeping_bed:{keywords:["bed","rest"],char:'\ud83d\udecc',fitzpatrick_scale:!0,category:"objects"},bed:{keywords:["sleep","rest"],char:'\ud83d\udecf',fitzpatrick_scale:!1,category:"objects"},door:{keywords:["house","entry","exit"],char:'\ud83d\udeaa',fitzpatrick_scale:!1,category:"objects"},bellhop_bell:{keywords:["service"],char:'\ud83d\udece',fitzpatrick_scale:!1,category:"objects"},teddy_bear:{keywords:["plush","stuffed"],char:'\ud83e\uddf8',fitzpatrick_scale:!1,category:"objects"},framed_picture:{keywords:["photography"],char:'\ud83d\uddbc',fitzpatrick_scale:!1,category:"objects"},world_map:{keywords:["location","direction"],char:'\ud83d\uddfa',fitzpatrick_scale:!1,category:"objects"},parasol_on_ground:{keywords:["weather","summer"],char:'\u26f1',fitzpatrick_scale:!1,category:"objects"},moyai:{keywords:["rock","easter island","moai"],char:'\ud83d\uddff',fitzpatrick_scale:!1,category:"objects"},shopping:{keywords:["mall","buy","purchase"],char:'\ud83d\udecd',fitzpatrick_scale:!1,category:"objects"},shopping_cart:{keywords:["trolley"],char:'\ud83d\uded2',fitzpatrick_scale:!1,category:"objects"},balloon:{keywords:["party","celebration","birthday","circus"],char:'\ud83c\udf88',fitzpatrick_scale:!1,category:"objects"},flags:{keywords:["fish","japanese","koinobori","carp","banner"],char:'\ud83c\udf8f',fitzpatrick_scale:!1,category:"objects"},ribbon:{keywords:["decoration","pink","girl","bowtie"],char:'\ud83c\udf80',fitzpatrick_scale:!1,category:"objects"},gift:{keywords:["present","birthday","christmas","xmas"],char:'\ud83c\udf81',fitzpatrick_scale:!1,category:"objects"},confetti_ball:{keywords:["festival","party","birthday","circus"],char:'\ud83c\udf8a',fitzpatrick_scale:!1,category:"objects"},tada:{keywords:["party","congratulations","birthday","magic","circus","celebration"],char:'\ud83c\udf89',fitzpatrick_scale:!1,category:"objects"},dolls:{keywords:["japanese","toy","kimono"],char:'\ud83c\udf8e',fitzpatrick_scale:!1,category:"objects"},wind_chime:{keywords:["nature","ding","spring","bell"],char:'\ud83c\udf90',fitzpatrick_scale:!1,category:"objects"},crossed_flags:{keywords:["japanese","nation","country","border"],char:'\ud83c\udf8c',fitzpatrick_scale:!1,category:"objects"},izakaya_lantern:{keywords:["light","paper","halloween","spooky"],char:'\ud83c\udfee',fitzpatrick_scale:!1,category:"objects"},red_envelope:{keywords:["gift"],char:'\ud83e\udde7',fitzpatrick_scale:!1,category:"objects"},email:{keywords:["letter","postal","inbox","communication"],char:'\u2709\ufe0f',fitzpatrick_scale:!1,category:"objects"},envelope_with_arrow:{keywords:["email","communication"],char:'\ud83d\udce9',fitzpatrick_scale:!1,category:"objects"},incoming_envelope:{keywords:["email","inbox"],char:'\ud83d\udce8',fitzpatrick_scale:!1,category:"objects"},"e-mail":{keywords:["communication","inbox"],char:'\ud83d\udce7',fitzpatrick_scale:!1,category:"objects"},love_letter:{keywords:["email","like","affection","envelope","valentines"],char:'\ud83d\udc8c',fitzpatrick_scale:!1,category:"objects"},postbox:{keywords:["email","letter","envelope"],char:'\ud83d\udcee',fitzpatrick_scale:!1,category:"objects"},mailbox_closed:{keywords:["email","communication","inbox"],char:'\ud83d\udcea',fitzpatrick_scale:!1,category:"objects"},mailbox:{keywords:["email","inbox","communication"],char:'\ud83d\udceb',fitzpatrick_scale:!1,category:"objects"},mailbox_with_mail:{keywords:["email","inbox","communication"],char:'\ud83d\udcec',fitzpatrick_scale:!1,category:"objects"},mailbox_with_no_mail:{keywords:["email","inbox"],char:'\ud83d\udced',fitzpatrick_scale:!1,category:"objects"},package:{keywords:["mail","gift","cardboard","box","moving"],char:'\ud83d\udce6',fitzpatrick_scale:!1,category:"objects"},postal_horn:{keywords:["instrument","music"],char:'\ud83d\udcef',fitzpatrick_scale:!1,category:"objects"},inbox_tray:{keywords:["email","documents"],char:'\ud83d\udce5',fitzpatrick_scale:!1,category:"objects"},outbox_tray:{keywords:["inbox","email"],char:'\ud83d\udce4',fitzpatrick_scale:!1,category:"objects"},scroll:{keywords:["documents","ancient","history","paper"],char:'\ud83d\udcdc',fitzpatrick_scale:!1,category:"objects"},page_with_curl:{keywords:["documents","office","paper"],char:'\ud83d\udcc3',fitzpatrick_scale:!1,category:"objects"},bookmark_tabs:{keywords:["favorite","save","order","tidy"],char:'\ud83d\udcd1',fitzpatrick_scale:!1,category:"objects"},receipt:{keywords:["accounting","expenses"],char:'\ud83e\uddfe',fitzpatrick_scale:!1,category:"objects"},bar_chart:{keywords:["graph","presentation","stats"],char:'\ud83d\udcca',fitzpatrick_scale:!1,category:"objects"},chart_with_upwards_trend:{keywords:["graph","presentation","stats","recovery","business","economics","money","sales","good","success"],char:'\ud83d\udcc8',fitzpatrick_scale:!1,category:"objects"},chart_with_downwards_trend:{keywords:["graph","presentation","stats","recession","business","economics","money","sales","bad","failure"],char:'\ud83d\udcc9',fitzpatrick_scale:!1,category:"objects"},page_facing_up:{keywords:["documents","office","paper","information"],char:'\ud83d\udcc4',fitzpatrick_scale:!1,category:"objects"},date:{keywords:["calendar","schedule"],char:'\ud83d\udcc5',fitzpatrick_scale:!1,category:"objects"},calendar:{keywords:["schedule","date","planning"],char:'\ud83d\udcc6',fitzpatrick_scale:!1,category:"objects"},spiral_calendar:{keywords:["date","schedule","planning"],char:'\ud83d\uddd3',fitzpatrick_scale:!1,category:"objects"},card_index:{keywords:["business","stationery"],char:'\ud83d\udcc7',fitzpatrick_scale:!1,category:"objects"},card_file_box:{keywords:["business","stationery"],char:'\ud83d\uddc3',fitzpatrick_scale:!1,category:"objects"},ballot_box:{keywords:["election","vote"],char:'\ud83d\uddf3',fitzpatrick_scale:!1,category:"objects"},file_cabinet:{keywords:["filing","organizing"],char:'\ud83d\uddc4',fitzpatrick_scale:!1,category:"objects"},clipboard:{keywords:["stationery","documents"],char:'\ud83d\udccb',fitzpatrick_scale:!1,category:"objects"},spiral_notepad:{keywords:["memo","stationery"],char:'\ud83d\uddd2',fitzpatrick_scale:!1,category:"objects"},file_folder:{keywords:["documents","business","office"],char:'\ud83d\udcc1',fitzpatrick_scale:!1,category:"objects"},open_file_folder:{keywords:["documents","load"],char:'\ud83d\udcc2',fitzpatrick_scale:!1,category:"objects"},card_index_dividers:{keywords:["organizing","business","stationery"],char:'\ud83d\uddc2',fitzpatrick_scale:!1,category:"objects"},newspaper_roll:{keywords:["press","headline"],char:'\ud83d\uddde',fitzpatrick_scale:!1,category:"objects"},newspaper:{keywords:["press","headline"],char:'\ud83d\udcf0',fitzpatrick_scale:!1,category:"objects"},notebook:{keywords:["stationery","record","notes","paper","study"],char:'\ud83d\udcd3',fitzpatrick_scale:!1,category:"objects"},closed_book:{keywords:["read","library","knowledge","textbook","learn"],char:'\ud83d\udcd5',fitzpatrick_scale:!1,category:"objects"},green_book:{keywords:["read","library","knowledge","study"],char:'\ud83d\udcd7',fitzpatrick_scale:!1,category:"objects"},blue_book:{keywords:["read","library","knowledge","learn","study"],char:'\ud83d\udcd8',fitzpatrick_scale:!1,category:"objects"},orange_book:{keywords:["read","library","knowledge","textbook","study"],char:'\ud83d\udcd9',fitzpatrick_scale:!1,category:"objects"},notebook_with_decorative_cover:{keywords:["classroom","notes","record","paper","study"],char:'\ud83d\udcd4',fitzpatrick_scale:!1,category:"objects"},ledger:{keywords:["notes","paper"],char:'\ud83d\udcd2',fitzpatrick_scale:!1,category:"objects"},books:{keywords:["literature","library","study"],char:'\ud83d\udcda',fitzpatrick_scale:!1,category:"objects"},open_book:{keywords:["book","read","library","knowledge","literature","learn","study"],char:'\ud83d\udcd6',fitzpatrick_scale:!1,category:"objects"},safety_pin:{keywords:["diaper"],char:'\ud83e\uddf7',fitzpatrick_scale:!1,category:"objects"},link:{keywords:["rings","url"],char:'\ud83d\udd17',fitzpatrick_scale:!1,category:"objects"},paperclip:{keywords:["documents","stationery"],char:'\ud83d\udcce',fitzpatrick_scale:!1,category:"objects"},paperclips:{keywords:["documents","stationery"],char:'\ud83d\udd87',fitzpatrick_scale:!1,category:"objects"},scissors:{keywords:["stationery","cut"],char:'\u2702\ufe0f',fitzpatrick_scale:!1,category:"objects"},triangular_ruler:{keywords:["stationery","math","architect","sketch"],char:'\ud83d\udcd0',fitzpatrick_scale:!1,category:"objects"},straight_ruler:{keywords:["stationery","calculate","length","math","school","drawing","architect","sketch"],char:'\ud83d\udccf',fitzpatrick_scale:!1,category:"objects"},abacus:{keywords:["calculation"],char:'\ud83e\uddee',fitzpatrick_scale:!1,category:"objects"},pushpin:{keywords:["stationery","mark","here"],char:'\ud83d\udccc',fitzpatrick_scale:!1,category:"objects"},round_pushpin:{keywords:["stationery","location","map","here"],char:'\ud83d\udccd',fitzpatrick_scale:!1,category:"objects"},triangular_flag_on_post:{keywords:["mark","milestone","place"],char:'\ud83d\udea9',fitzpatrick_scale:!1,category:"objects"},white_flag:{keywords:["losing","loser","lost","surrender","give up","fail"],char:'\ud83c\udff3',fitzpatrick_scale:!1,category:"objects"},black_flag:{keywords:["pirate"],char:'\ud83c\udff4',fitzpatrick_scale:!1,category:"objects"},rainbow_flag:{keywords:["flag","rainbow","pride","gay","lgbt","glbt","queer","homosexual","lesbian","bisexual","transgender"],char:'\ud83c\udff3\ufe0f\u200d\ud83c\udf08',fitzpatrick_scale:!1,category:"objects"},closed_lock_with_key:{keywords:["security","privacy"],char:'\ud83d\udd10',fitzpatrick_scale:!1,category:"objects"},lock:{keywords:["security","password","padlock"],char:'\ud83d\udd12',fitzpatrick_scale:!1,category:"objects"},unlock:{keywords:["privacy","security"],char:'\ud83d\udd13',fitzpatrick_scale:!1,category:"objects"},lock_with_ink_pen:{keywords:["security","secret"],char:'\ud83d\udd0f',fitzpatrick_scale:!1,category:"objects"},pen:{keywords:["stationery","writing","write"],char:'\ud83d\udd8a',fitzpatrick_scale:!1,category:"objects"},fountain_pen:{keywords:["stationery","writing","write"],char:'\ud83d\udd8b',fitzpatrick_scale:!1,category:"objects"},black_nib:{keywords:["pen","stationery","writing","write"],char:'\u2712\ufe0f',fitzpatrick_scale:!1,category:"objects"},memo:{keywords:["write","documents","stationery","pencil","paper","writing","legal","exam","quiz","test","study","compose"],char:'\ud83d\udcdd',fitzpatrick_scale:!1,category:"objects"},pencil2:{keywords:["stationery","write","paper","writing","school","study"],char:'\u270f\ufe0f',fitzpatrick_scale:!1,category:"objects"},crayon:{keywords:["drawing","creativity"],char:'\ud83d\udd8d',fitzpatrick_scale:!1,category:"objects"},paintbrush:{keywords:["drawing","creativity","art"],char:'\ud83d\udd8c',fitzpatrick_scale:!1,category:"objects"},mag:{keywords:["search","zoom","find","detective"],char:'\ud83d\udd0d',fitzpatrick_scale:!1,category:"objects"},mag_right:{keywords:["search","zoom","find","detective"],char:'\ud83d\udd0e',fitzpatrick_scale:!1,category:"objects"},heart:{keywords:["love","like","valentines"],char:'\u2764\ufe0f',fitzpatrick_scale:!1,category:"symbols"},orange_heart:{keywords:["love","like","affection","valentines"],char:'\ud83e\udde1',fitzpatrick_scale:!1,category:"symbols"},yellow_heart:{keywords:["love","like","affection","valentines"],char:'\ud83d\udc9b',fitzpatrick_scale:!1,category:"symbols"},green_heart:{keywords:["love","like","affection","valentines"],char:'\ud83d\udc9a',fitzpatrick_scale:!1,category:"symbols"},blue_heart:{keywords:["love","like","affection","valentines"],char:'\ud83d\udc99',fitzpatrick_scale:!1,category:"symbols"},purple_heart:{keywords:["love","like","affection","valentines"],char:'\ud83d\udc9c',fitzpatrick_scale:!1,category:"symbols"},black_heart:{keywords:["evil"],char:'\ud83d\udda4',fitzpatrick_scale:!1,category:"symbols"},broken_heart:{keywords:["sad","sorry","break","heart","heartbreak"],char:'\ud83d\udc94',fitzpatrick_scale:!1,category:"symbols"},heavy_heart_exclamation:{keywords:["decoration","love"],char:'\u2763',fitzpatrick_scale:!1,category:"symbols"},two_hearts:{keywords:["love","like","affection","valentines","heart"],char:'\ud83d\udc95',fitzpatrick_scale:!1,category:"symbols"},revolving_hearts:{keywords:["love","like","affection","valentines"],char:'\ud83d\udc9e',fitzpatrick_scale:!1,category:"symbols"},heartbeat:{keywords:["love","like","affection","valentines","pink","heart"],char:'\ud83d\udc93',fitzpatrick_scale:!1,category:"symbols"},heartpulse:{keywords:["like","love","affection","valentines","pink"],char:'\ud83d\udc97',fitzpatrick_scale:!1,category:"symbols"},sparkling_heart:{keywords:["love","like","affection","valentines"],char:'\ud83d\udc96',fitzpatrick_scale:!1,category:"symbols"},cupid:{keywords:["love","like","heart","affection","valentines"],char:'\ud83d\udc98',fitzpatrick_scale:!1,category:"symbols"},gift_heart:{keywords:["love","valentines"],char:'\ud83d\udc9d',fitzpatrick_scale:!1,category:"symbols"},heart_decoration:{keywords:["purple-square","love","like"],char:'\ud83d\udc9f',fitzpatrick_scale:!1,category:"symbols"},peace_symbol:{keywords:["hippie"],char:'\u262e',fitzpatrick_scale:!1,category:"symbols"},latin_cross:{keywords:["christianity"],char:'\u271d',fitzpatrick_scale:!1,category:"symbols"},star_and_crescent:{keywords:["islam"],char:'\u262a',fitzpatrick_scale:!1,category:"symbols"},om:{keywords:["hinduism","buddhism","sikhism","jainism"],char:'\ud83d\udd49',fitzpatrick_scale:!1,category:"symbols"},wheel_of_dharma:{keywords:["hinduism","buddhism","sikhism","jainism"],char:'\u2638',fitzpatrick_scale:!1,category:"symbols"},star_of_david:{keywords:["judaism"],char:'\u2721',fitzpatrick_scale:!1,category:"symbols"},six_pointed_star:{keywords:["purple-square","religion","jewish","hexagram"],char:'\ud83d\udd2f',fitzpatrick_scale:!1,category:"symbols"},menorah:{keywords:["hanukkah","candles","jewish"],char:'\ud83d\udd4e',fitzpatrick_scale:!1,category:"symbols"},yin_yang:{keywords:["balance"],char:'\u262f',fitzpatrick_scale:!1,category:"symbols"},orthodox_cross:{keywords:["suppedaneum","religion"],char:'\u2626',fitzpatrick_scale:!1,category:"symbols"},place_of_worship:{keywords:["religion","church","temple","prayer"],char:'\ud83d\uded0',fitzpatrick_scale:!1,category:"symbols"},ophiuchus:{keywords:["sign","purple-square","constellation","astrology"],char:'\u26ce',fitzpatrick_scale:!1,category:"symbols"},aries:{keywords:["sign","purple-square","zodiac","astrology"],char:'\u2648',fitzpatrick_scale:!1,category:"symbols"},taurus:{keywords:["purple-square","sign","zodiac","astrology"],char:'\u2649',fitzpatrick_scale:!1,category:"symbols"},gemini:{keywords:["sign","zodiac","purple-square","astrology"],char:'\u264a',fitzpatrick_scale:!1,category:"symbols"},cancer:{keywords:["sign","zodiac","purple-square","astrology"],char:'\u264b',fitzpatrick_scale:!1,category:"symbols"},leo:{keywords:["sign","purple-square","zodiac","astrology"],char:'\u264c',fitzpatrick_scale:!1,category:"symbols"},virgo:{keywords:["sign","zodiac","purple-square","astrology"],char:'\u264d',fitzpatrick_scale:!1,category:"symbols"},libra:{keywords:["sign","purple-square","zodiac","astrology"],char:'\u264e',fitzpatrick_scale:!1,category:"symbols"},scorpius:{keywords:["sign","zodiac","purple-square","astrology","scorpio"],char:'\u264f',fitzpatrick_scale:!1,category:"symbols"},sagittarius:{keywords:["sign","zodiac","purple-square","astrology"],char:'\u2650',fitzpatrick_scale:!1,category:"symbols"},capricorn:{keywords:["sign","zodiac","purple-square","astrology"],char:'\u2651',fitzpatrick_scale:!1,category:"symbols"},aquarius:{keywords:["sign","purple-square","zodiac","astrology"],char:'\u2652',fitzpatrick_scale:!1,category:"symbols"},pisces:{keywords:["purple-square","sign","zodiac","astrology"],char:'\u2653',fitzpatrick_scale:!1,category:"symbols"},id:{keywords:["purple-square","words"],char:'\ud83c\udd94',fitzpatrick_scale:!1,category:"symbols"},atom_symbol:{keywords:["science","physics","chemistry"],char:'\u269b',fitzpatrick_scale:!1,category:"symbols"},u7a7a:{keywords:["kanji","japanese","chinese","empty","sky","blue-square"],char:'\ud83c\ude33',fitzpatrick_scale:!1,category:"symbols"},u5272:{keywords:["cut","divide","chinese","kanji","pink-square"],char:'\ud83c\ude39',fitzpatrick_scale:!1,category:"symbols"},radioactive:{keywords:["nuclear","danger"],char:'\u2622',fitzpatrick_scale:!1,category:"symbols"},biohazard:{keywords:["danger"],char:'\u2623',fitzpatrick_scale:!1,category:"symbols"},mobile_phone_off:{keywords:["mute","orange-square","silence","quiet"],char:'\ud83d\udcf4',fitzpatrick_scale:!1,category:"symbols"},vibration_mode:{keywords:["orange-square","phone"],char:'\ud83d\udcf3',fitzpatrick_scale:!1,category:"symbols"},u6709:{keywords:["orange-square","chinese","have","kanji"],char:'\ud83c\ude36',fitzpatrick_scale:!1,category:"symbols"},u7121:{keywords:["nothing","chinese","kanji","japanese","orange-square"],char:'\ud83c\ude1a',fitzpatrick_scale:!1,category:"symbols"},u7533:{keywords:["chinese","japanese","kanji","orange-square"],char:'\ud83c\ude38',fitzpatrick_scale:!1,category:"symbols"},u55b6:{keywords:["japanese","opening hours","orange-square"],char:'\ud83c\ude3a',fitzpatrick_scale:!1,category:"symbols"},u6708:{keywords:["chinese","month","moon","japanese","orange-square","kanji"],char:'\ud83c\ude37\ufe0f',fitzpatrick_scale:!1,category:"symbols"},eight_pointed_black_star:{keywords:["orange-square","shape","polygon"],char:'\u2734\ufe0f',fitzpatrick_scale:!1,category:"symbols"},vs:{keywords:["words","orange-square"],char:'\ud83c\udd9a',fitzpatrick_scale:!1,category:"symbols"},accept:{keywords:["ok","good","chinese","kanji","agree","yes","orange-circle"],char:'\ud83c\ude51',fitzpatrick_scale:!1,category:"symbols"},white_flower:{keywords:["japanese","spring"],char:'\ud83d\udcae',fitzpatrick_scale:!1,category:"symbols"},ideograph_advantage:{keywords:["chinese","kanji","obtain","get","circle"],char:'\ud83c\ude50',fitzpatrick_scale:!1,category:"symbols"},secret:{keywords:["privacy","chinese","sshh","kanji","red-circle"],char:'\u3299\ufe0f',fitzpatrick_scale:!1,category:"symbols"},congratulations:{keywords:["chinese","kanji","japanese","red-circle"],char:'\u3297\ufe0f',fitzpatrick_scale:!1,category:"symbols"},u5408:{keywords:["japanese","chinese","join","kanji","red-square"],char:'\ud83c\ude34',fitzpatrick_scale:!1,category:"symbols"},u6e80:{keywords:["full","chinese","japanese","red-square","kanji"],char:'\ud83c\ude35',fitzpatrick_scale:!1,category:"symbols"},u7981:{keywords:["kanji","japanese","chinese","forbidden","limit","restricted","red-square"],char:'\ud83c\ude32',fitzpatrick_scale:!1,category:"symbols"},a:{keywords:["red-square","alphabet","letter"],char:'\ud83c\udd70\ufe0f',fitzpatrick_scale:!1,category:"symbols"},b:{keywords:["red-square","alphabet","letter"],char:'\ud83c\udd71\ufe0f',fitzpatrick_scale:!1,category:"symbols"},ab:{keywords:["red-square","alphabet"],char:'\ud83c\udd8e',fitzpatrick_scale:!1,category:"symbols"},cl:{keywords:["alphabet","words","red-square"],char:'\ud83c\udd91',fitzpatrick_scale:!1,category:"symbols"},o2:{keywords:["alphabet","red-square","letter"],char:'\ud83c\udd7e\ufe0f',fitzpatrick_scale:!1,category:"symbols"},sos:{keywords:["help","red-square","words","emergency","911"],char:'\ud83c\udd98',fitzpatrick_scale:!1,category:"symbols"},no_entry:{keywords:["limit","security","privacy","bad","denied","stop","circle"],char:'\u26d4',fitzpatrick_scale:!1,category:"symbols"},name_badge:{keywords:["fire","forbid"],char:'\ud83d\udcdb',fitzpatrick_scale:!1,category:"symbols"},no_entry_sign:{keywords:["forbid","stop","limit","denied","disallow","circle"],char:'\ud83d\udeab',fitzpatrick_scale:!1,category:"symbols"},x:{keywords:["no","delete","remove","cancel","red"],char:'\u274c',fitzpatrick_scale:!1,category:"symbols"},o:{keywords:["circle","round"],char:'\u2b55',fitzpatrick_scale:!1,category:"symbols"},stop_sign:{keywords:["stop"],char:'\ud83d\uded1',fitzpatrick_scale:!1,category:"symbols"},anger:{keywords:["angry","mad"],char:'\ud83d\udca2',fitzpatrick_scale:!1,category:"symbols"},hotsprings:{keywords:["bath","warm","relax"],char:'\u2668\ufe0f',fitzpatrick_scale:!1,category:"symbols"},no_pedestrians:{keywords:["rules","crossing","walking","circle"],char:'\ud83d\udeb7',fitzpatrick_scale:!1,category:"symbols"},do_not_litter:{keywords:["trash","bin","garbage","circle"],char:'\ud83d\udeaf',fitzpatrick_scale:!1,category:"symbols"},no_bicycles:{keywords:["cyclist","prohibited","circle"],char:'\ud83d\udeb3',fitzpatrick_scale:!1,category:"symbols"},"non-potable_water":{keywords:["drink","faucet","tap","circle"],char:'\ud83d\udeb1',fitzpatrick_scale:!1,category:"symbols"},underage:{keywords:["18","drink","pub","night","minor","circle"],char:'\ud83d\udd1e',fitzpatrick_scale:!1,category:"symbols"},no_mobile_phones:{keywords:["iphone","mute","circle"],char:'\ud83d\udcf5',fitzpatrick_scale:!1,category:"symbols"},exclamation:{keywords:["heavy_exclamation_mark","danger","surprise","punctuation","wow","warning"],char:'\u2757',fitzpatrick_scale:!1,category:"symbols"},grey_exclamation:{keywords:["surprise","punctuation","gray","wow","warning"],char:'\u2755',fitzpatrick_scale:!1,category:"symbols"},question:{keywords:["doubt","confused"],char:'\u2753',fitzpatrick_scale:!1,category:"symbols"},grey_question:{keywords:["doubts","gray","huh","confused"],char:'\u2754',fitzpatrick_scale:!1,category:"symbols"},bangbang:{keywords:["exclamation","surprise"],char:'\u203c\ufe0f',fitzpatrick_scale:!1,category:"symbols"},interrobang:{keywords:["wat","punctuation","surprise"],char:'\u2049\ufe0f',fitzpatrick_scale:!1,category:"symbols"},low_brightness:{keywords:["sun","afternoon","warm","summer"],char:'\ud83d\udd05',fitzpatrick_scale:!1,category:"symbols"},high_brightness:{keywords:["sun","light"],char:'\ud83d\udd06',fitzpatrick_scale:!1,category:"symbols"},trident:{keywords:["weapon","spear"],char:'\ud83d\udd31',fitzpatrick_scale:!1,category:"symbols"},fleur_de_lis:{keywords:["decorative","scout"],char:'\u269c',fitzpatrick_scale:!1,category:"symbols"},part_alternation_mark:{keywords:["graph","presentation","stats","business","economics","bad"],char:'\u303d\ufe0f',fitzpatrick_scale:!1,category:"symbols"},warning:{keywords:["exclamation","wip","alert","error","problem","issue"],char:'\u26a0\ufe0f',fitzpatrick_scale:!1,category:"symbols"},children_crossing:{keywords:["school","warning","danger","sign","driving","yellow-diamond"],char:'\ud83d\udeb8',fitzpatrick_scale:!1,category:"symbols"},beginner:{keywords:["badge","shield"],char:'\ud83d\udd30',fitzpatrick_scale:!1,category:"symbols"},recycle:{keywords:["arrow","environment","garbage","trash"],char:'\u267b\ufe0f',fitzpatrick_scale:!1,category:"symbols"},u6307:{keywords:["chinese","point","green-square","kanji"],char:'\ud83c\ude2f',fitzpatrick_scale:!1,category:"symbols"},chart:{keywords:["green-square","graph","presentation","stats"],char:'\ud83d\udcb9',fitzpatrick_scale:!1,category:"symbols"},sparkle:{keywords:["stars","green-square","awesome","good","fireworks"],char:'\u2747\ufe0f',fitzpatrick_scale:!1,category:"symbols"},eight_spoked_asterisk:{keywords:["star","sparkle","green-square"],char:'\u2733\ufe0f',fitzpatrick_scale:!1,category:"symbols"},negative_squared_cross_mark:{keywords:["x","green-square","no","deny"],char:'\u274e',fitzpatrick_scale:!1,category:"symbols"},white_check_mark:{keywords:["green-square","ok","agree","vote","election","answer","tick"],char:'\u2705',fitzpatrick_scale:!1,category:"symbols"},diamond_shape_with_a_dot_inside:{keywords:["jewel","blue","gem","crystal","fancy"],char:'\ud83d\udca0',fitzpatrick_scale:!1,category:"symbols"},cyclone:{keywords:["weather","swirl","blue","cloud","vortex","spiral","whirlpool","spin","tornado","hurricane","typhoon"],char:'\ud83c\udf00',fitzpatrick_scale:!1,category:"symbols"},loop:{keywords:["tape","cassette"],char:'\u27bf',fitzpatrick_scale:!1,category:"symbols"},globe_with_meridians:{keywords:["earth","international","world","internet","interweb","i18n"],char:'\ud83c\udf10',fitzpatrick_scale:!1,category:"symbols"},m:{keywords:["alphabet","blue-circle","letter"],char:'\u24c2\ufe0f',fitzpatrick_scale:!1,category:"symbols"},atm:{keywords:["money","sales","cash","blue-square","payment","bank"],char:'\ud83c\udfe7',fitzpatrick_scale:!1,category:"symbols"},sa:{keywords:["japanese","blue-square","katakana"],char:'\ud83c\ude02\ufe0f',fitzpatrick_scale:!1,category:"symbols"},passport_control:{keywords:["custom","blue-square"],char:'\ud83d\udec2',fitzpatrick_scale:!1,category:"symbols"},customs:{keywords:["passport","border","blue-square"],char:'\ud83d\udec3',fitzpatrick_scale:!1,category:"symbols"},baggage_claim:{keywords:["blue-square","airport","transport"],char:'\ud83d\udec4',fitzpatrick_scale:!1,category:"symbols"},left_luggage:{keywords:["blue-square","travel"],char:'\ud83d\udec5',fitzpatrick_scale:!1,category:"symbols"},wheelchair:{keywords:["blue-square","disabled","a11y","accessibility"],char:'\u267f',fitzpatrick_scale:!1,category:"symbols"},no_smoking:{keywords:["cigarette","blue-square","smell","smoke"],char:'\ud83d\udead',fitzpatrick_scale:!1,category:"symbols"},wc:{keywords:["toilet","restroom","blue-square"],char:'\ud83d\udebe',fitzpatrick_scale:!1,category:"symbols"},parking:{keywords:["cars","blue-square","alphabet","letter"],char:'\ud83c\udd7f\ufe0f',fitzpatrick_scale:!1,category:"symbols"},potable_water:{keywords:["blue-square","liquid","restroom","cleaning","faucet"],char:'\ud83d\udeb0',fitzpatrick_scale:!1,category:"symbols"},mens:{keywords:["toilet","restroom","wc","blue-square","gender","male"],char:'\ud83d\udeb9',fitzpatrick_scale:!1,category:"symbols"},womens:{keywords:["purple-square","woman","female","toilet","loo","restroom","gender"],char:'\ud83d\udeba',fitzpatrick_scale:!1,category:"symbols"},baby_symbol:{keywords:["orange-square","child"],char:'\ud83d\udebc',fitzpatrick_scale:!1,category:"symbols"},restroom:{keywords:["blue-square","toilet","refresh","wc","gender"],char:'\ud83d\udebb',fitzpatrick_scale:!1,category:"symbols"},put_litter_in_its_place:{keywords:["blue-square","sign","human","info"],char:'\ud83d\udeae',fitzpatrick_scale:!1,category:"symbols"},cinema:{keywords:["blue-square","record","film","movie","curtain","stage","theater"],char:'\ud83c\udfa6',fitzpatrick_scale:!1,category:"symbols"},signal_strength:{keywords:["blue-square","reception","phone","internet","connection","wifi","bluetooth","bars"],char:'\ud83d\udcf6',fitzpatrick_scale:!1,category:"symbols"},koko:{keywords:["blue-square","here","katakana","japanese","destination"],char:'\ud83c\ude01',fitzpatrick_scale:!1,category:"symbols"},ng:{keywords:["blue-square","words","shape","icon"],char:'\ud83c\udd96',fitzpatrick_scale:!1,category:"symbols"},ok:{keywords:["good","agree","yes","blue-square"],char:'\ud83c\udd97',fitzpatrick_scale:!1,category:"symbols"},up:{keywords:["blue-square","above","high"],char:'\ud83c\udd99',fitzpatrick_scale:!1,category:"symbols"},cool:{keywords:["words","blue-square"],char:'\ud83c\udd92',fitzpatrick_scale:!1,category:"symbols"},new:{keywords:["blue-square","words","start"],char:'\ud83c\udd95',fitzpatrick_scale:!1,category:"symbols"},free:{keywords:["blue-square","words"],char:'\ud83c\udd93',fitzpatrick_scale:!1,category:"symbols"},zero:{keywords:["0","numbers","blue-square","null"],char:'0\ufe0f\u20e3',fitzpatrick_scale:!1,category:"symbols"},one:{keywords:["blue-square","numbers","1"],char:'1\ufe0f\u20e3',fitzpatrick_scale:!1,category:"symbols"},two:{keywords:["numbers","2","prime","blue-square"],char:'2\ufe0f\u20e3',fitzpatrick_scale:!1,category:"symbols"},three:{keywords:["3","numbers","prime","blue-square"],char:'3\ufe0f\u20e3',fitzpatrick_scale:!1,category:"symbols"},four:{keywords:["4","numbers","blue-square"],char:'4\ufe0f\u20e3',fitzpatrick_scale:!1,category:"symbols"},five:{keywords:["5","numbers","blue-square","prime"],char:'5\ufe0f\u20e3',fitzpatrick_scale:!1,category:"symbols"},six:{keywords:["6","numbers","blue-square"],char:'6\ufe0f\u20e3',fitzpatrick_scale:!1,category:"symbols"},seven:{keywords:["7","numbers","blue-square","prime"],char:'7\ufe0f\u20e3',fitzpatrick_scale:!1,category:"symbols"},eight:{keywords:["8","blue-square","numbers"],char:'8\ufe0f\u20e3',fitzpatrick_scale:!1,category:"symbols"},nine:{keywords:["blue-square","numbers","9"],char:'9\ufe0f\u20e3',fitzpatrick_scale:!1,category:"symbols"},keycap_ten:{keywords:["numbers","10","blue-square"],char:'\ud83d\udd1f',fitzpatrick_scale:!1,category:"symbols"},asterisk:{keywords:["star","keycap"],char:'*\u20e3',fitzpatrick_scale:!1,category:"symbols"},eject_button:{keywords:["blue-square"],char:'\u23cf\ufe0f',fitzpatrick_scale:!1,category:"symbols"},arrow_forward:{keywords:["blue-square","right","direction","play"],char:'\u25b6\ufe0f',fitzpatrick_scale:!1,category:"symbols"},pause_button:{keywords:["pause","blue-square"],char:'\u23f8',fitzpatrick_scale:!1,category:"symbols"},next_track_button:{keywords:["forward","next","blue-square"],char:'\u23ed',fitzpatrick_scale:!1,category:"symbols"},stop_button:{keywords:["blue-square"],char:'\u23f9',fitzpatrick_scale:!1,category:"symbols"},record_button:{keywords:["blue-square"],char:'\u23fa',fitzpatrick_scale:!1,category:"symbols"},play_or_pause_button:{keywords:["blue-square","play","pause"],char:'\u23ef',fitzpatrick_scale:!1,category:"symbols"},previous_track_button:{keywords:["backward"],char:'\u23ee',fitzpatrick_scale:!1,category:"symbols"},fast_forward:{keywords:["blue-square","play","speed","continue"],char:'\u23e9',fitzpatrick_scale:!1,category:"symbols"},rewind:{keywords:["play","blue-square"],char:'\u23ea',fitzpatrick_scale:!1,category:"symbols"},twisted_rightwards_arrows:{keywords:["blue-square","shuffle","music","random"],char:'\ud83d\udd00',fitzpatrick_scale:!1,category:"symbols"},repeat:{keywords:["loop","record"],char:'\ud83d\udd01',fitzpatrick_scale:!1,category:"symbols"},repeat_one:{keywords:["blue-square","loop"],char:'\ud83d\udd02',fitzpatrick_scale:!1,category:"symbols"},arrow_backward:{keywords:["blue-square","left","direction"],char:'\u25c0\ufe0f',fitzpatrick_scale:!1,category:"symbols"},arrow_up_small:{keywords:["blue-square","triangle","direction","point","forward","top"],char:'\ud83d\udd3c',fitzpatrick_scale:!1,category:"symbols"},arrow_down_small:{keywords:["blue-square","direction","bottom"],char:'\ud83d\udd3d',fitzpatrick_scale:!1,category:"symbols"},arrow_double_up:{keywords:["blue-square","direction","top"],char:'\u23eb',fitzpatrick_scale:!1,category:"symbols"},arrow_double_down:{keywords:["blue-square","direction","bottom"],char:'\u23ec',fitzpatrick_scale:!1,category:"symbols"},arrow_right:{keywords:["blue-square","next"],char:'\u27a1\ufe0f',fitzpatrick_scale:!1,category:"symbols"},arrow_left:{keywords:["blue-square","previous","back"],char:'\u2b05\ufe0f',fitzpatrick_scale:!1,category:"symbols"},arrow_up:{keywords:["blue-square","continue","top","direction"],char:'\u2b06\ufe0f',fitzpatrick_scale:!1,category:"symbols"},arrow_down:{keywords:["blue-square","direction","bottom"],char:'\u2b07\ufe0f',fitzpatrick_scale:!1,category:"symbols"},arrow_upper_right:{keywords:["blue-square","point","direction","diagonal","northeast"],char:'\u2197\ufe0f',fitzpatrick_scale:!1,category:"symbols"},arrow_lower_right:{keywords:["blue-square","direction","diagonal","southeast"],char:'\u2198\ufe0f',fitzpatrick_scale:!1,category:"symbols"},arrow_lower_left:{keywords:["blue-square","direction","diagonal","southwest"],char:'\u2199\ufe0f',fitzpatrick_scale:!1,category:"symbols"},arrow_upper_left:{keywords:["blue-square","point","direction","diagonal","northwest"],char:'\u2196\ufe0f',fitzpatrick_scale:!1,category:"symbols"},arrow_up_down:{keywords:["blue-square","direction","way","vertical"],char:'\u2195\ufe0f',fitzpatrick_scale:!1,category:"symbols"},left_right_arrow:{keywords:["shape","direction","horizontal","sideways"],char:'\u2194\ufe0f',fitzpatrick_scale:!1,category:"symbols"},arrows_counterclockwise:{keywords:["blue-square","sync","cycle"],char:'\ud83d\udd04',fitzpatrick_scale:!1,category:"symbols"},arrow_right_hook:{keywords:["blue-square","return","rotate","direction"],char:'\u21aa\ufe0f',fitzpatrick_scale:!1,category:"symbols"},leftwards_arrow_with_hook:{keywords:["back","return","blue-square","undo","enter"],char:'\u21a9\ufe0f',fitzpatrick_scale:!1,category:"symbols"},arrow_heading_up:{keywords:["blue-square","direction","top"],char:'\u2934\ufe0f',fitzpatrick_scale:!1,category:"symbols"},arrow_heading_down:{keywords:["blue-square","direction","bottom"],char:'\u2935\ufe0f',fitzpatrick_scale:!1,category:"symbols"},hash:{keywords:["symbol","blue-square","twitter"],char:'#\ufe0f\u20e3',fitzpatrick_scale:!1,category:"symbols"},information_source:{keywords:["blue-square","alphabet","letter"],char:'\u2139\ufe0f',fitzpatrick_scale:!1,category:"symbols"},abc:{keywords:["blue-square","alphabet"],char:'\ud83d\udd24',fitzpatrick_scale:!1,category:"symbols"},abcd:{keywords:["blue-square","alphabet"],char:'\ud83d\udd21',fitzpatrick_scale:!1,category:"symbols"},capital_abcd:{keywords:["alphabet","words","blue-square"],char:'\ud83d\udd20',fitzpatrick_scale:!1,category:"symbols"},symbols:{keywords:["blue-square","music","note","ampersand","percent","glyphs","characters"],char:'\ud83d\udd23',fitzpatrick_scale:!1,category:"symbols"},musical_note:{keywords:["score","tone","sound"],char:'\ud83c\udfb5',fitzpatrick_scale:!1,category:"symbols"},notes:{keywords:["music","score"],char:'\ud83c\udfb6',fitzpatrick_scale:!1,category:"symbols"},wavy_dash:{keywords:["draw","line","moustache","mustache","squiggle","scribble"],char:'\u3030\ufe0f',fitzpatrick_scale:!1,category:"symbols"},curly_loop:{keywords:["scribble","draw","shape","squiggle"],char:'\u27b0',fitzpatrick_scale:!1,category:"symbols"},heavy_check_mark:{keywords:["ok","nike","answer","yes","tick"],char:'\u2714\ufe0f',fitzpatrick_scale:!1,category:"symbols"},arrows_clockwise:{keywords:["sync","cycle","round","repeat"],char:'\ud83d\udd03',fitzpatrick_scale:!1,category:"symbols"},heavy_plus_sign:{keywords:["math","calculation","addition","more","increase"],char:'\u2795',fitzpatrick_scale:!1,category:"symbols"},heavy_minus_sign:{keywords:["math","calculation","subtract","less"],char:'\u2796',fitzpatrick_scale:!1,category:"symbols"},heavy_division_sign:{keywords:["divide","math","calculation"],char:'\u2797',fitzpatrick_scale:!1,category:"symbols"},heavy_multiplication_x:{keywords:["math","calculation"],char:'\u2716\ufe0f',fitzpatrick_scale:!1,category:"symbols"},infinity:{keywords:["forever"],char:'\u267e',fitzpatrick_scale:!1,category:"symbols"},heavy_dollar_sign:{keywords:["money","sales","payment","currency","buck"],char:'\ud83d\udcb2',fitzpatrick_scale:!1,category:"symbols"},currency_exchange:{keywords:["money","sales","dollar","travel"],char:'\ud83d\udcb1',fitzpatrick_scale:!1,category:"symbols"},copyright:{keywords:["ip","license","circle","law","legal"],char:'\xa9\ufe0f',fitzpatrick_scale:!1,category:"symbols"},registered:{keywords:["alphabet","circle"],char:'\xae\ufe0f',fitzpatrick_scale:!1,category:"symbols"},tm:{keywords:["trademark","brand","law","legal"],char:'\u2122\ufe0f',fitzpatrick_scale:!1,category:"symbols"},end:{keywords:["words","arrow"],char:'\ud83d\udd1a',fitzpatrick_scale:!1,category:"symbols"},back:{keywords:["arrow","words","return"],char:'\ud83d\udd19',fitzpatrick_scale:!1,category:"symbols"},on:{keywords:["arrow","words"],char:'\ud83d\udd1b',fitzpatrick_scale:!1,category:"symbols"},top:{keywords:["words","blue-square"],char:'\ud83d\udd1d',fitzpatrick_scale:!1,category:"symbols"},soon:{keywords:["arrow","words"],char:'\ud83d\udd1c',fitzpatrick_scale:!1,category:"symbols"},ballot_box_with_check:{keywords:["ok","agree","confirm","black-square","vote","election","yes","tick"],char:'\u2611\ufe0f',fitzpatrick_scale:!1,category:"symbols"},radio_button:{keywords:["input","old","music","circle"],char:'\ud83d\udd18',fitzpatrick_scale:!1,category:"symbols"},white_circle:{keywords:["shape","round"],char:'\u26aa',fitzpatrick_scale:!1,category:"symbols"},black_circle:{keywords:["shape","button","round"],char:'\u26ab',fitzpatrick_scale:!1,category:"symbols"},red_circle:{keywords:["shape","error","danger"],char:'\ud83d\udd34',fitzpatrick_scale:!1,category:"symbols"},large_blue_circle:{keywords:["shape","icon","button"],char:'\ud83d\udd35',fitzpatrick_scale:!1,category:"symbols"},small_orange_diamond:{keywords:["shape","jewel","gem"],char:'\ud83d\udd38',fitzpatrick_scale:!1,category:"symbols"},small_blue_diamond:{keywords:["shape","jewel","gem"],char:'\ud83d\udd39',fitzpatrick_scale:!1,category:"symbols"},large_orange_diamond:{keywords:["shape","jewel","gem"],char:'\ud83d\udd36',fitzpatrick_scale:!1,category:"symbols"},large_blue_diamond:{keywords:["shape","jewel","gem"],char:'\ud83d\udd37',fitzpatrick_scale:!1,category:"symbols"},small_red_triangle:{keywords:["shape","direction","up","top"],char:'\ud83d\udd3a',fitzpatrick_scale:!1,category:"symbols"},black_small_square:{keywords:["shape","icon"],char:'\u25aa\ufe0f',fitzpatrick_scale:!1,category:"symbols"},white_small_square:{keywords:["shape","icon"],char:'\u25ab\ufe0f',fitzpatrick_scale:!1,category:"symbols"},black_large_square:{keywords:["shape","icon","button"],char:'\u2b1b',fitzpatrick_scale:!1,category:"symbols"},white_large_square:{keywords:["shape","icon","stone","button"],char:'\u2b1c',fitzpatrick_scale:!1,category:"symbols"},small_red_triangle_down:{keywords:["shape","direction","bottom"],char:'\ud83d\udd3b',fitzpatrick_scale:!1,category:"symbols"},black_medium_square:{keywords:["shape","button","icon"],char:'\u25fc\ufe0f',fitzpatrick_scale:!1,category:"symbols"},white_medium_square:{keywords:["shape","stone","icon"],char:'\u25fb\ufe0f',fitzpatrick_scale:!1,category:"symbols"},black_medium_small_square:{keywords:["icon","shape","button"],char:'\u25fe',fitzpatrick_scale:!1,category:"symbols"},white_medium_small_square:{keywords:["shape","stone","icon","button"],char:'\u25fd',fitzpatrick_scale:!1,category:"symbols"},black_square_button:{keywords:["shape","input","frame"],char:'\ud83d\udd32',fitzpatrick_scale:!1,category:"symbols"},white_square_button:{keywords:["shape","input"],char:'\ud83d\udd33',fitzpatrick_scale:!1,category:"symbols"},speaker:{keywords:["sound","volume","silence","broadcast"],char:'\ud83d\udd08',fitzpatrick_scale:!1,category:"symbols"},sound:{keywords:["volume","speaker","broadcast"],char:'\ud83d\udd09',fitzpatrick_scale:!1,category:"symbols"},loud_sound:{keywords:["volume","noise","noisy","speaker","broadcast"],char:'\ud83d\udd0a',fitzpatrick_scale:!1,category:"symbols"},mute:{keywords:["sound","volume","silence","quiet"],char:'\ud83d\udd07',fitzpatrick_scale:!1,category:"symbols"},mega:{keywords:["sound","speaker","volume"],char:'\ud83d\udce3',fitzpatrick_scale:!1,category:"symbols"},loudspeaker:{keywords:["volume","sound"],char:'\ud83d\udce2',fitzpatrick_scale:!1,category:"symbols"},bell:{keywords:["sound","notification","christmas","xmas","chime"],char:'\ud83d\udd14',fitzpatrick_scale:!1,category:"symbols"},no_bell:{keywords:["sound","volume","mute","quiet","silent"],char:'\ud83d\udd15',fitzpatrick_scale:!1,category:"symbols"},black_joker:{keywords:["poker","cards","game","play","magic"],char:'\ud83c\udccf',fitzpatrick_scale:!1,category:"symbols"},mahjong:{keywords:["game","play","chinese","kanji"],char:'\ud83c\udc04',fitzpatrick_scale:!1,category:"symbols"},spades:{keywords:["poker","cards","suits","magic"],char:'\u2660\ufe0f',fitzpatrick_scale:!1,category:"symbols"},clubs:{keywords:["poker","cards","magic","suits"],char:'\u2663\ufe0f',fitzpatrick_scale:!1,category:"symbols"},hearts:{keywords:["poker","cards","magic","suits"],char:'\u2665\ufe0f',fitzpatrick_scale:!1,category:"symbols"},diamonds:{keywords:["poker","cards","magic","suits"],char:'\u2666\ufe0f',fitzpatrick_scale:!1,category:"symbols"},flower_playing_cards:{keywords:["game","sunset","red"],char:'\ud83c\udfb4',fitzpatrick_scale:!1,category:"symbols"},thought_balloon:{keywords:["bubble","cloud","speech","thinking","dream"],char:'\ud83d\udcad',fitzpatrick_scale:!1,category:"symbols"},right_anger_bubble:{keywords:["caption","speech","thinking","mad"],char:'\ud83d\uddef',fitzpatrick_scale:!1,category:"symbols"},speech_balloon:{keywords:["bubble","words","message","talk","chatting"],char:'\ud83d\udcac',fitzpatrick_scale:!1,category:"symbols"},left_speech_bubble:{keywords:["words","message","talk","chatting"],char:'\ud83d\udde8',fitzpatrick_scale:!1,category:"symbols"},clock1:{keywords:["time","late","early","schedule"],char:'\ud83d\udd50',fitzpatrick_scale:!1,category:"symbols"},clock2:{keywords:["time","late","early","schedule"],char:'\ud83d\udd51',fitzpatrick_scale:!1,category:"symbols"},clock3:{keywords:["time","late","early","schedule"],char:'\ud83d\udd52',fitzpatrick_scale:!1,category:"symbols"},clock4:{keywords:["time","late","early","schedule"],char:'\ud83d\udd53',fitzpatrick_scale:!1,category:"symbols"},clock5:{keywords:["time","late","early","schedule"],char:'\ud83d\udd54',fitzpatrick_scale:!1,category:"symbols"},clock6:{keywords:["time","late","early","schedule","dawn","dusk"],char:'\ud83d\udd55',fitzpatrick_scale:!1,category:"symbols"},clock7:{keywords:["time","late","early","schedule"],char:'\ud83d\udd56',fitzpatrick_scale:!1,category:"symbols"},clock8:{keywords:["time","late","early","schedule"],char:'\ud83d\udd57',fitzpatrick_scale:!1,category:"symbols"},clock9:{keywords:["time","late","early","schedule"],char:'\ud83d\udd58',fitzpatrick_scale:!1,category:"symbols"},clock10:{keywords:["time","late","early","schedule"],char:'\ud83d\udd59',fitzpatrick_scale:!1,category:"symbols"},clock11:{keywords:["time","late","early","schedule"],char:'\ud83d\udd5a',fitzpatrick_scale:!1,category:"symbols"},clock12:{keywords:["time","noon","midnight","midday","late","early","schedule"],char:'\ud83d\udd5b',fitzpatrick_scale:!1,category:"symbols"},clock130:{keywords:["time","late","early","schedule"],char:'\ud83d\udd5c',fitzpatrick_scale:!1,category:"symbols"},clock230:{keywords:["time","late","early","schedule"],char:'\ud83d\udd5d',fitzpatrick_scale:!1,category:"symbols"},clock330:{keywords:["time","late","early","schedule"],char:'\ud83d\udd5e',fitzpatrick_scale:!1,category:"symbols"},clock430:{keywords:["time","late","early","schedule"],char:'\ud83d\udd5f',fitzpatrick_scale:!1,category:"symbols"},clock530:{keywords:["time","late","early","schedule"],char:'\ud83d\udd60',fitzpatrick_scale:!1,category:"symbols"},clock630:{keywords:["time","late","early","schedule"],char:'\ud83d\udd61',fitzpatrick_scale:!1,category:"symbols"},clock730:{keywords:["time","late","early","schedule"],char:'\ud83d\udd62',fitzpatrick_scale:!1,category:"symbols"},clock830:{keywords:["time","late","early","schedule"],char:'\ud83d\udd63',fitzpatrick_scale:!1,category:"symbols"},clock930:{keywords:["time","late","early","schedule"],char:'\ud83d\udd64',fitzpatrick_scale:!1,category:"symbols"},clock1030:{keywords:["time","late","early","schedule"],char:'\ud83d\udd65',fitzpatrick_scale:!1,category:"symbols"},clock1130:{keywords:["time","late","early","schedule"],char:'\ud83d\udd66',fitzpatrick_scale:!1,category:"symbols"},clock1230:{keywords:["time","late","early","schedule"],char:'\ud83d\udd67',fitzpatrick_scale:!1,category:"symbols"},afghanistan:{keywords:["af","flag","nation","country","banner"],char:'\ud83c\udde6\ud83c\uddeb',fitzpatrick_scale:!1,category:"flags"},aland_islands:{keywords:["\xc5land","islands","flag","nation","country","banner"],char:'\ud83c\udde6\ud83c\uddfd',fitzpatrick_scale:!1,category:"flags"},albania:{keywords:["al","flag","nation","country","banner"],char:'\ud83c\udde6\ud83c\uddf1',fitzpatrick_scale:!1,category:"flags"},algeria:{keywords:["dz","flag","nation","country","banner"],char:'\ud83c\udde9\ud83c\uddff',fitzpatrick_scale:!1,category:"flags"},american_samoa:{keywords:["american","ws","flag","nation","country","banner"],char:'\ud83c\udde6\ud83c\uddf8',fitzpatrick_scale:!1,category:"flags"},andorra:{keywords:["ad","flag","nation","country","banner"],char:'\ud83c\udde6\ud83c\udde9',fitzpatrick_scale:!1,category:"flags"},angola:{keywords:["ao","flag","nation","country","banner"],char:'\ud83c\udde6\ud83c\uddf4',fitzpatrick_scale:!1,category:"flags"},anguilla:{keywords:["ai","flag","nation","country","banner"],char:'\ud83c\udde6\ud83c\uddee',fitzpatrick_scale:!1,category:"flags"},antarctica:{keywords:["aq","flag","nation","country","banner"],char:'\ud83c\udde6\ud83c\uddf6',fitzpatrick_scale:!1,category:"flags"},antigua_barbuda:{keywords:["antigua","barbuda","flag","nation","country","banner"],char:'\ud83c\udde6\ud83c\uddec',fitzpatrick_scale:!1,category:"flags"},argentina:{keywords:["ar","flag","nation","country","banner"],char:'\ud83c\udde6\ud83c\uddf7',fitzpatrick_scale:!1,category:"flags"},armenia:{keywords:["am","flag","nation","country","banner"],char:'\ud83c\udde6\ud83c\uddf2',fitzpatrick_scale:!1,category:"flags"},aruba:{keywords:["aw","flag","nation","country","banner"],char:'\ud83c\udde6\ud83c\uddfc',fitzpatrick_scale:!1,category:"flags"},australia:{keywords:["au","flag","nation","country","banner"],char:'\ud83c\udde6\ud83c\uddfa',fitzpatrick_scale:!1,category:"flags"},austria:{keywords:["at","flag","nation","country","banner"],char:'\ud83c\udde6\ud83c\uddf9',fitzpatrick_scale:!1,category:"flags"},azerbaijan:{keywords:["az","flag","nation","country","banner"],char:'\ud83c\udde6\ud83c\uddff',fitzpatrick_scale:!1,category:"flags"},bahamas:{keywords:["bs","flag","nation","country","banner"],char:'\ud83c\udde7\ud83c\uddf8',fitzpatrick_scale:!1,category:"flags"},bahrain:{keywords:["bh","flag","nation","country","banner"],char:'\ud83c\udde7\ud83c\udded',fitzpatrick_scale:!1,category:"flags"},bangladesh:{keywords:["bd","flag","nation","country","banner"],char:'\ud83c\udde7\ud83c\udde9',fitzpatrick_scale:!1,category:"flags"},barbados:{keywords:["bb","flag","nation","country","banner"],char:'\ud83c\udde7\ud83c\udde7',fitzpatrick_scale:!1,category:"flags"},belarus:{keywords:["by","flag","nation","country","banner"],char:'\ud83c\udde7\ud83c\uddfe',fitzpatrick_scale:!1,category:"flags"},belgium:{keywords:["be","flag","nation","country","banner"],char:'\ud83c\udde7\ud83c\uddea',fitzpatrick_scale:!1,category:"flags"},belize:{keywords:["bz","flag","nation","country","banner"],char:'\ud83c\udde7\ud83c\uddff',fitzpatrick_scale:!1,category:"flags"},benin:{keywords:["bj","flag","nation","country","banner"],char:'\ud83c\udde7\ud83c\uddef',fitzpatrick_scale:!1,category:"flags"},bermuda:{keywords:["bm","flag","nation","country","banner"],char:'\ud83c\udde7\ud83c\uddf2',fitzpatrick_scale:!1,category:"flags"},bhutan:{keywords:["bt","flag","nation","country","banner"],char:'\ud83c\udde7\ud83c\uddf9',fitzpatrick_scale:!1,category:"flags"},bolivia:{keywords:["bo","flag","nation","country","banner"],char:'\ud83c\udde7\ud83c\uddf4',fitzpatrick_scale:!1,category:"flags"},caribbean_netherlands:{keywords:["bonaire","flag","nation","country","banner"],char:'\ud83c\udde7\ud83c\uddf6',fitzpatrick_scale:!1,category:"flags"},bosnia_herzegovina:{keywords:["bosnia","herzegovina","flag","nation","country","banner"],char:'\ud83c\udde7\ud83c\udde6',fitzpatrick_scale:!1,category:"flags"},botswana:{keywords:["bw","flag","nation","country","banner"],char:'\ud83c\udde7\ud83c\uddfc',fitzpatrick_scale:!1,category:"flags"},brazil:{keywords:["br","flag","nation","country","banner"],char:'\ud83c\udde7\ud83c\uddf7',fitzpatrick_scale:!1,category:"flags"},british_indian_ocean_territory:{keywords:["british","indian","ocean","territory","flag","nation","country","banner"],char:'\ud83c\uddee\ud83c\uddf4',fitzpatrick_scale:!1,category:"flags"},british_virgin_islands:{keywords:["british","virgin","islands","bvi","flag","nation","country","banner"],char:'\ud83c\uddfb\ud83c\uddec',fitzpatrick_scale:!1,category:"flags"},brunei:{keywords:["bn","darussalam","flag","nation","country","banner"],char:'\ud83c\udde7\ud83c\uddf3',fitzpatrick_scale:!1,category:"flags"},bulgaria:{keywords:["bg","flag","nation","country","banner"],char:'\ud83c\udde7\ud83c\uddec',fitzpatrick_scale:!1,category:"flags"},burkina_faso:{keywords:["burkina","faso","flag","nation","country","banner"],char:'\ud83c\udde7\ud83c\uddeb',fitzpatrick_scale:!1,category:"flags"},burundi:{keywords:["bi","flag","nation","country","banner"],char:'\ud83c\udde7\ud83c\uddee',fitzpatrick_scale:!1,category:"flags"},cape_verde:{keywords:["cabo","verde","flag","nation","country","banner"],char:'\ud83c\udde8\ud83c\uddfb',fitzpatrick_scale:!1,category:"flags"},cambodia:{keywords:["kh","flag","nation","country","banner"],char:'\ud83c\uddf0\ud83c\udded',fitzpatrick_scale:!1,category:"flags"},cameroon:{keywords:["cm","flag","nation","country","banner"],char:'\ud83c\udde8\ud83c\uddf2',fitzpatrick_scale:!1,category:"flags"},canada:{keywords:["ca","flag","nation","country","banner"],char:'\ud83c\udde8\ud83c\udde6',fitzpatrick_scale:!1,category:"flags"},canary_islands:{keywords:["canary","islands","flag","nation","country","banner"],char:'\ud83c\uddee\ud83c\udde8',fitzpatrick_scale:!1,category:"flags"},cayman_islands:{keywords:["cayman","islands","flag","nation","country","banner"],char:'\ud83c\uddf0\ud83c\uddfe',fitzpatrick_scale:!1,category:"flags"},central_african_republic:{keywords:["central","african","republic","flag","nation","country","banner"],char:'\ud83c\udde8\ud83c\uddeb',fitzpatrick_scale:!1,category:"flags"},chad:{keywords:["td","flag","nation","country","banner"],char:'\ud83c\uddf9\ud83c\udde9',fitzpatrick_scale:!1,category:"flags"},chile:{keywords:["flag","nation","country","banner"],char:'\ud83c\udde8\ud83c\uddf1',fitzpatrick_scale:!1,category:"flags"},cn:{keywords:["china","chinese","prc","flag","country","nation","banner"],char:'\ud83c\udde8\ud83c\uddf3',fitzpatrick_scale:!1,category:"flags"},christmas_island:{keywords:["christmas","island","flag","nation","country","banner"],char:'\ud83c\udde8\ud83c\uddfd',fitzpatrick_scale:!1,category:"flags"},cocos_islands:{keywords:["cocos","keeling","islands","flag","nation","country","banner"],char:'\ud83c\udde8\ud83c\udde8',fitzpatrick_scale:!1,category:"flags"},colombia:{keywords:["co","flag","nation","country","banner"],char:'\ud83c\udde8\ud83c\uddf4',fitzpatrick_scale:!1,category:"flags"},comoros:{keywords:["km","flag","nation","country","banner"],char:'\ud83c\uddf0\ud83c\uddf2',fitzpatrick_scale:!1,category:"flags"},congo_brazzaville:{keywords:["congo","flag","nation","country","banner"],char:'\ud83c\udde8\ud83c\uddec',fitzpatrick_scale:!1,category:"flags"},congo_kinshasa:{keywords:["congo","democratic","republic","flag","nation","country","banner"],char:'\ud83c\udde8\ud83c\udde9',fitzpatrick_scale:!1,category:"flags"},cook_islands:{keywords:["cook","islands","flag","nation","country","banner"],char:'\ud83c\udde8\ud83c\uddf0',fitzpatrick_scale:!1,category:"flags"},costa_rica:{keywords:["costa","rica","flag","nation","country","banner"],char:'\ud83c\udde8\ud83c\uddf7',fitzpatrick_scale:!1,category:"flags"},croatia:{keywords:["hr","flag","nation","country","banner"],char:'\ud83c\udded\ud83c\uddf7',fitzpatrick_scale:!1,category:"flags"},cuba:{keywords:["cu","flag","nation","country","banner"],char:'\ud83c\udde8\ud83c\uddfa',fitzpatrick_scale:!1,category:"flags"},curacao:{keywords:["cura\xe7ao","flag","nation","country","banner"],char:'\ud83c\udde8\ud83c\uddfc',fitzpatrick_scale:!1,category:"flags"},cyprus:{keywords:["cy","flag","nation","country","banner"],char:'\ud83c\udde8\ud83c\uddfe',fitzpatrick_scale:!1,category:"flags"},czech_republic:{keywords:["cz","flag","nation","country","banner"],char:'\ud83c\udde8\ud83c\uddff',fitzpatrick_scale:!1,category:"flags"},denmark:{keywords:["dk","flag","nation","country","banner"],char:'\ud83c\udde9\ud83c\uddf0',fitzpatrick_scale:!1,category:"flags"},djibouti:{keywords:["dj","flag","nation","country","banner"],char:'\ud83c\udde9\ud83c\uddef',fitzpatrick_scale:!1,category:"flags"},dominica:{keywords:["dm","flag","nation","country","banner"],char:'\ud83c\udde9\ud83c\uddf2',fitzpatrick_scale:!1,category:"flags"},dominican_republic:{keywords:["dominican","republic","flag","nation","country","banner"],char:'\ud83c\udde9\ud83c\uddf4',fitzpatrick_scale:!1,category:"flags"},ecuador:{keywords:["ec","flag","nation","country","banner"],char:'\ud83c\uddea\ud83c\udde8',fitzpatrick_scale:!1,category:"flags"},egypt:{keywords:["eg","flag","nation","country","banner"],char:'\ud83c\uddea\ud83c\uddec',fitzpatrick_scale:!1,category:"flags"},el_salvador:{keywords:["el","salvador","flag","nation","country","banner"],char:'\ud83c\uddf8\ud83c\uddfb',fitzpatrick_scale:!1,category:"flags"},equatorial_guinea:{keywords:["equatorial","gn","flag","nation","country","banner"],char:'\ud83c\uddec\ud83c\uddf6',fitzpatrick_scale:!1,category:"flags"},eritrea:{keywords:["er","flag","nation","country","banner"],char:'\ud83c\uddea\ud83c\uddf7',fitzpatrick_scale:!1,category:"flags"},estonia:{keywords:["ee","flag","nation","country","banner"],char:'\ud83c\uddea\ud83c\uddea',fitzpatrick_scale:!1,category:"flags"},ethiopia:{keywords:["et","flag","nation","country","banner"],char:'\ud83c\uddea\ud83c\uddf9',fitzpatrick_scale:!1,category:"flags"},eu:{keywords:["european","union","flag","banner"],char:'\ud83c\uddea\ud83c\uddfa',fitzpatrick_scale:!1,category:"flags"},falkland_islands:{keywords:["falkland","islands","malvinas","flag","nation","country","banner"],char:'\ud83c\uddeb\ud83c\uddf0',fitzpatrick_scale:!1,category:"flags"},faroe_islands:{keywords:["faroe","islands","flag","nation","country","banner"],char:'\ud83c\uddeb\ud83c\uddf4',fitzpatrick_scale:!1,category:"flags"},fiji:{keywords:["fj","flag","nation","country","banner"],char:'\ud83c\uddeb\ud83c\uddef',fitzpatrick_scale:!1,category:"flags"},finland:{keywords:["fi","flag","nation","country","banner"],char:'\ud83c\uddeb\ud83c\uddee',fitzpatrick_scale:!1,category:"flags"},fr:{keywords:["banner","flag","nation","france","french","country"],char:'\ud83c\uddeb\ud83c\uddf7',fitzpatrick_scale:!1,category:"flags"},french_guiana:{keywords:["french","guiana","flag","nation","country","banner"],char:'\ud83c\uddec\ud83c\uddeb',fitzpatrick_scale:!1,category:"flags"},french_polynesia:{keywords:["french","polynesia","flag","nation","country","banner"],char:'\ud83c\uddf5\ud83c\uddeb',fitzpatrick_scale:!1,category:"flags"},french_southern_territories:{keywords:["french","southern","territories","flag","nation","country","banner"],char:'\ud83c\uddf9\ud83c\uddeb',fitzpatrick_scale:!1,category:"flags"},gabon:{keywords:["ga","flag","nation","country","banner"],char:'\ud83c\uddec\ud83c\udde6',fitzpatrick_scale:!1,category:"flags"},gambia:{keywords:["gm","flag","nation","country","banner"],char:'\ud83c\uddec\ud83c\uddf2',fitzpatrick_scale:!1,category:"flags"},georgia:{keywords:["ge","flag","nation","country","banner"],char:'\ud83c\uddec\ud83c\uddea',fitzpatrick_scale:!1,category:"flags"},de:{keywords:["german","nation","flag","country","banner"],char:'\ud83c\udde9\ud83c\uddea',fitzpatrick_scale:!1,category:"flags"},ghana:{keywords:["gh","flag","nation","country","banner"],char:'\ud83c\uddec\ud83c\udded',fitzpatrick_scale:!1,category:"flags"},gibraltar:{keywords:["gi","flag","nation","country","banner"],char:'\ud83c\uddec\ud83c\uddee',fitzpatrick_scale:!1,category:"flags"},greece:{keywords:["gr","flag","nation","country","banner"],char:'\ud83c\uddec\ud83c\uddf7',fitzpatrick_scale:!1,category:"flags"},greenland:{keywords:["gl","flag","nation","country","banner"],char:'\ud83c\uddec\ud83c\uddf1',fitzpatrick_scale:!1,category:"flags"},grenada:{keywords:["gd","flag","nation","country","banner"],char:'\ud83c\uddec\ud83c\udde9',fitzpatrick_scale:!1,category:"flags"},guadeloupe:{keywords:["gp","flag","nation","country","banner"],char:'\ud83c\uddec\ud83c\uddf5',fitzpatrick_scale:!1,category:"flags"},guam:{keywords:["gu","flag","nation","country","banner"],char:'\ud83c\uddec\ud83c\uddfa',fitzpatrick_scale:!1,category:"flags"},guatemala:{keywords:["gt","flag","nation","country","banner"],char:'\ud83c\uddec\ud83c\uddf9',fitzpatrick_scale:!1,category:"flags"},guernsey:{keywords:["gg","flag","nation","country","banner"],char:'\ud83c\uddec\ud83c\uddec',fitzpatrick_scale:!1,category:"flags"},guinea:{keywords:["gn","flag","nation","country","banner"],char:'\ud83c\uddec\ud83c\uddf3',fitzpatrick_scale:!1,category:"flags"},guinea_bissau:{keywords:["gw","bissau","flag","nation","country","banner"],char:'\ud83c\uddec\ud83c\uddfc',fitzpatrick_scale:!1,category:"flags"},guyana:{keywords:["gy","flag","nation","country","banner"],char:'\ud83c\uddec\ud83c\uddfe',fitzpatrick_scale:!1,category:"flags"},haiti:{keywords:["ht","flag","nation","country","banner"],char:'\ud83c\udded\ud83c\uddf9',fitzpatrick_scale:!1,category:"flags"},honduras:{keywords:["hn","flag","nation","country","banner"],char:'\ud83c\udded\ud83c\uddf3',fitzpatrick_scale:!1,category:"flags"},hong_kong:{keywords:["hong","kong","flag","nation","country","banner"],char:'\ud83c\udded\ud83c\uddf0',fitzpatrick_scale:!1,category:"flags"},hungary:{keywords:["hu","flag","nation","country","banner"],char:'\ud83c\udded\ud83c\uddfa',fitzpatrick_scale:!1,category:"flags"},iceland:{keywords:["is","flag","nation","country","banner"],char:'\ud83c\uddee\ud83c\uddf8',fitzpatrick_scale:!1,category:"flags"},india:{keywords:["in","flag","nation","country","banner"],char:'\ud83c\uddee\ud83c\uddf3',fitzpatrick_scale:!1,category:"flags"},indonesia:{keywords:["flag","nation","country","banner"],char:'\ud83c\uddee\ud83c\udde9',fitzpatrick_scale:!1,category:"flags"},iran:{keywords:["iran,","islamic","republic","flag","nation","country","banner"],char:'\ud83c\uddee\ud83c\uddf7',fitzpatrick_scale:!1,category:"flags"},iraq:{keywords:["iq","flag","nation","country","banner"],char:'\ud83c\uddee\ud83c\uddf6',fitzpatrick_scale:!1,category:"flags"},ireland:{keywords:["ie","flag","nation","country","banner"],char:'\ud83c\uddee\ud83c\uddea',fitzpatrick_scale:!1,category:"flags"},isle_of_man:{keywords:["isle","man","flag","nation","country","banner"],char:'\ud83c\uddee\ud83c\uddf2',fitzpatrick_scale:!1,category:"flags"},israel:{keywords:["il","flag","nation","country","banner"],char:'\ud83c\uddee\ud83c\uddf1',fitzpatrick_scale:!1,category:"flags"},it:{keywords:["italy","flag","nation","country","banner"],char:'\ud83c\uddee\ud83c\uddf9',fitzpatrick_scale:!1,category:"flags"},cote_divoire:{keywords:["ivory","coast","flag","nation","country","banner"],char:'\ud83c\udde8\ud83c\uddee',fitzpatrick_scale:!1,category:"flags"},jamaica:{keywords:["jm","flag","nation","country","banner"],char:'\ud83c\uddef\ud83c\uddf2',fitzpatrick_scale:!1,category:"flags"},jp:{keywords:["japanese","nation","flag","country","banner"],char:'\ud83c\uddef\ud83c\uddf5',fitzpatrick_scale:!1,category:"flags"},jersey:{keywords:["je","flag","nation","country","banner"],char:'\ud83c\uddef\ud83c\uddea',fitzpatrick_scale:!1,category:"flags"},jordan:{keywords:["jo","flag","nation","country","banner"],char:'\ud83c\uddef\ud83c\uddf4',fitzpatrick_scale:!1,category:"flags"},kazakhstan:{keywords:["kz","flag","nation","country","banner"],char:'\ud83c\uddf0\ud83c\uddff',fitzpatrick_scale:!1,category:"flags"},kenya:{keywords:["ke","flag","nation","country","banner"],char:'\ud83c\uddf0\ud83c\uddea',fitzpatrick_scale:!1,category:"flags"},kiribati:{keywords:["ki","flag","nation","country","banner"],char:'\ud83c\uddf0\ud83c\uddee',fitzpatrick_scale:!1,category:"flags"},kosovo:{keywords:["xk","flag","nation","country","banner"],char:'\ud83c\uddfd\ud83c\uddf0',fitzpatrick_scale:!1,category:"flags"},kuwait:{keywords:["kw","flag","nation","country","banner"],char:'\ud83c\uddf0\ud83c\uddfc',fitzpatrick_scale:!1,category:"flags"},kyrgyzstan:{keywords:["kg","flag","nation","country","banner"],char:'\ud83c\uddf0\ud83c\uddec',fitzpatrick_scale:!1,category:"flags"},laos:{keywords:["lao","democratic","republic","flag","nation","country","banner"],char:'\ud83c\uddf1\ud83c\udde6',fitzpatrick_scale:!1,category:"flags"},latvia:{keywords:["lv","flag","nation","country","banner"],char:'\ud83c\uddf1\ud83c\uddfb',fitzpatrick_scale:!1,category:"flags"},lebanon:{keywords:["lb","flag","nation","country","banner"],char:'\ud83c\uddf1\ud83c\udde7',fitzpatrick_scale:!1,category:"flags"},lesotho:{keywords:["ls","flag","nation","country","banner"],char:'\ud83c\uddf1\ud83c\uddf8',fitzpatrick_scale:!1,category:"flags"},liberia:{keywords:["lr","flag","nation","country","banner"],char:'\ud83c\uddf1\ud83c\uddf7',fitzpatrick_scale:!1,category:"flags"},libya:{keywords:["ly","flag","nation","country","banner"],char:'\ud83c\uddf1\ud83c\uddfe',fitzpatrick_scale:!1,category:"flags"},liechtenstein:{keywords:["li","flag","nation","country","banner"],char:'\ud83c\uddf1\ud83c\uddee',fitzpatrick_scale:!1,category:"flags"},lithuania:{keywords:["lt","flag","nation","country","banner"],char:'\ud83c\uddf1\ud83c\uddf9',fitzpatrick_scale:!1,category:"flags"},luxembourg:{keywords:["lu","flag","nation","country","banner"],char:'\ud83c\uddf1\ud83c\uddfa',fitzpatrick_scale:!1,category:"flags"},macau:{keywords:["macao","flag","nation","country","banner"],char:'\ud83c\uddf2\ud83c\uddf4',fitzpatrick_scale:!1,category:"flags"},macedonia:{keywords:["macedonia,","flag","nation","country","banner"],char:'\ud83c\uddf2\ud83c\uddf0',fitzpatrick_scale:!1,category:"flags"},madagascar:{keywords:["mg","flag","nation","country","banner"],char:'\ud83c\uddf2\ud83c\uddec',fitzpatrick_scale:!1,category:"flags"},malawi:{keywords:["mw","flag","nation","country","banner"],char:'\ud83c\uddf2\ud83c\uddfc',fitzpatrick_scale:!1,category:"flags"},malaysia:{keywords:["my","flag","nation","country","banner"],char:'\ud83c\uddf2\ud83c\uddfe',fitzpatrick_scale:!1,category:"flags"},maldives:{keywords:["mv","flag","nation","country","banner"],char:'\ud83c\uddf2\ud83c\uddfb',fitzpatrick_scale:!1,category:"flags"},mali:{keywords:["ml","flag","nation","country","banner"],char:'\ud83c\uddf2\ud83c\uddf1',fitzpatrick_scale:!1,category:"flags"},malta:{keywords:["mt","flag","nation","country","banner"],char:'\ud83c\uddf2\ud83c\uddf9',fitzpatrick_scale:!1,category:"flags"},marshall_islands:{keywords:["marshall","islands","flag","nation","country","banner"],char:'\ud83c\uddf2\ud83c\udded',fitzpatrick_scale:!1,category:"flags"},martinique:{keywords:["mq","flag","nation","country","banner"],char:'\ud83c\uddf2\ud83c\uddf6',fitzpatrick_scale:!1,category:"flags"},mauritania:{keywords:["mr","flag","nation","country","banner"],char:'\ud83c\uddf2\ud83c\uddf7',fitzpatrick_scale:!1,category:"flags"},mauritius:{keywords:["mu","flag","nation","country","banner"],char:'\ud83c\uddf2\ud83c\uddfa',fitzpatrick_scale:!1,category:"flags"},mayotte:{keywords:["yt","flag","nation","country","banner"],char:'\ud83c\uddfe\ud83c\uddf9',fitzpatrick_scale:!1,category:"flags"},mexico:{keywords:["mx","flag","nation","country","banner"],char:'\ud83c\uddf2\ud83c\uddfd',fitzpatrick_scale:!1,category:"flags"},micronesia:{keywords:["micronesia,","federated","states","flag","nation","country","banner"],char:'\ud83c\uddeb\ud83c\uddf2',fitzpatrick_scale:!1,category:"flags"},moldova:{keywords:["moldova,","republic","flag","nation","country","banner"],char:'\ud83c\uddf2\ud83c\udde9',fitzpatrick_scale:!1,category:"flags"},monaco:{keywords:["mc","flag","nation","country","banner"],char:'\ud83c\uddf2\ud83c\udde8',fitzpatrick_scale:!1,category:"flags"},mongolia:{keywords:["mn","flag","nation","country","banner"],char:'\ud83c\uddf2\ud83c\uddf3',fitzpatrick_scale:!1,category:"flags"},montenegro:{keywords:["me","flag","nation","country","banner"],char:'\ud83c\uddf2\ud83c\uddea',fitzpatrick_scale:!1,category:"flags"},montserrat:{keywords:["ms","flag","nation","country","banner"],char:'\ud83c\uddf2\ud83c\uddf8',fitzpatrick_scale:!1,category:"flags"},morocco:{keywords:["ma","flag","nation","country","banner"],char:'\ud83c\uddf2\ud83c\udde6',fitzpatrick_scale:!1,category:"flags"},mozambique:{keywords:["mz","flag","nation","country","banner"],char:'\ud83c\uddf2\ud83c\uddff',fitzpatrick_scale:!1,category:"flags"},myanmar:{keywords:["mm","flag","nation","country","banner"],char:'\ud83c\uddf2\ud83c\uddf2',fitzpatrick_scale:!1,category:"flags"},namibia:{keywords:["na","flag","nation","country","banner"],char:'\ud83c\uddf3\ud83c\udde6',fitzpatrick_scale:!1,category:"flags"},nauru:{keywords:["nr","flag","nation","country","banner"],char:'\ud83c\uddf3\ud83c\uddf7',fitzpatrick_scale:!1,category:"flags"},nepal:{keywords:["np","flag","nation","country","banner"],char:'\ud83c\uddf3\ud83c\uddf5',fitzpatrick_scale:!1,category:"flags"},netherlands:{keywords:["nl","flag","nation","country","banner"],char:'\ud83c\uddf3\ud83c\uddf1',fitzpatrick_scale:!1,category:"flags"},new_caledonia:{keywords:["new","caledonia","flag","nation","country","banner"],char:'\ud83c\uddf3\ud83c\udde8',fitzpatrick_scale:!1,category:"flags"},new_zealand:{keywords:["new","zealand","flag","nation","country","banner"],char:'\ud83c\uddf3\ud83c\uddff',fitzpatrick_scale:!1,category:"flags"},nicaragua:{keywords:["ni","flag","nation","country","banner"],char:'\ud83c\uddf3\ud83c\uddee',fitzpatrick_scale:!1,category:"flags"},niger:{keywords:["ne","flag","nation","country","banner"],char:'\ud83c\uddf3\ud83c\uddea',fitzpatrick_scale:!1,category:"flags"},nigeria:{keywords:["flag","nation","country","banner"],char:'\ud83c\uddf3\ud83c\uddec',fitzpatrick_scale:!1,category:"flags"},niue:{keywords:["nu","flag","nation","country","banner"],char:'\ud83c\uddf3\ud83c\uddfa',fitzpatrick_scale:!1,category:"flags"},norfolk_island:{keywords:["norfolk","island","flag","nation","country","banner"],char:'\ud83c\uddf3\ud83c\uddeb',fitzpatrick_scale:!1,category:"flags"},northern_mariana_islands:{keywords:["northern","mariana","islands","flag","nation","country","banner"],char:'\ud83c\uddf2\ud83c\uddf5',fitzpatrick_scale:!1,category:"flags"},north_korea:{keywords:["north","korea","nation","flag","country","banner"],char:'\ud83c\uddf0\ud83c\uddf5',fitzpatrick_scale:!1,category:"flags"},norway:{keywords:["no","flag","nation","country","banner"],char:'\ud83c\uddf3\ud83c\uddf4',fitzpatrick_scale:!1,category:"flags"},oman:{keywords:["om_symbol","flag","nation","country","banner"],char:'\ud83c\uddf4\ud83c\uddf2',fitzpatrick_scale:!1,category:"flags"},pakistan:{keywords:["pk","flag","nation","country","banner"],char:'\ud83c\uddf5\ud83c\uddf0',fitzpatrick_scale:!1,category:"flags"},palau:{keywords:["pw","flag","nation","country","banner"],char:'\ud83c\uddf5\ud83c\uddfc',fitzpatrick_scale:!1,category:"flags"},palestinian_territories:{keywords:["palestine","palestinian","territories","flag","nation","country","banner"],char:'\ud83c\uddf5\ud83c\uddf8',fitzpatrick_scale:!1,category:"flags"},panama:{keywords:["pa","flag","nation","country","banner"],char:'\ud83c\uddf5\ud83c\udde6',fitzpatrick_scale:!1,category:"flags"},papua_new_guinea:{keywords:["papua","new","guinea","flag","nation","country","banner"],char:'\ud83c\uddf5\ud83c\uddec',fitzpatrick_scale:!1,category:"flags"},paraguay:{keywords:["py","flag","nation","country","banner"],char:'\ud83c\uddf5\ud83c\uddfe',fitzpatrick_scale:!1,category:"flags"},peru:{keywords:["pe","flag","nation","country","banner"],char:'\ud83c\uddf5\ud83c\uddea',fitzpatrick_scale:!1,category:"flags"},philippines:{keywords:["ph","flag","nation","country","banner"],char:'\ud83c\uddf5\ud83c\udded',fitzpatrick_scale:!1,category:"flags"},pitcairn_islands:{keywords:["pitcairn","flag","nation","country","banner"],char:'\ud83c\uddf5\ud83c\uddf3',fitzpatrick_scale:!1,category:"flags"},poland:{keywords:["pl","flag","nation","country","banner"],char:'\ud83c\uddf5\ud83c\uddf1',fitzpatrick_scale:!1,category:"flags"},portugal:{keywords:["pt","flag","nation","country","banner"],char:'\ud83c\uddf5\ud83c\uddf9',fitzpatrick_scale:!1,category:"flags"},puerto_rico:{keywords:["puerto","rico","flag","nation","country","banner"],char:'\ud83c\uddf5\ud83c\uddf7',fitzpatrick_scale:!1,category:"flags"},qatar:{keywords:["qa","flag","nation","country","banner"],char:'\ud83c\uddf6\ud83c\udde6',fitzpatrick_scale:!1,category:"flags"},reunion:{keywords:["r\xe9union","flag","nation","country","banner"],char:'\ud83c\uddf7\ud83c\uddea',fitzpatrick_scale:!1,category:"flags"},romania:{keywords:["ro","flag","nation","country","banner"],char:'\ud83c\uddf7\ud83c\uddf4',fitzpatrick_scale:!1,category:"flags"},ru:{keywords:["russian","federation","flag","nation","country","banner"],char:'\ud83c\uddf7\ud83c\uddfa',fitzpatrick_scale:!1,category:"flags"},rwanda:{keywords:["rw","flag","nation","country","banner"],char:'\ud83c\uddf7\ud83c\uddfc',fitzpatrick_scale:!1,category:"flags"},st_barthelemy:{keywords:["saint","barth\xe9lemy","flag","nation","country","banner"],char:'\ud83c\udde7\ud83c\uddf1',fitzpatrick_scale:!1,category:"flags"},st_helena:{keywords:["saint","helena","ascension","tristan","cunha","flag","nation","country","banner"],char:'\ud83c\uddf8\ud83c\udded',fitzpatrick_scale:!1,category:"flags"},st_kitts_nevis:{keywords:["saint","kitts","nevis","flag","nation","country","banner"],char:'\ud83c\uddf0\ud83c\uddf3',fitzpatrick_scale:!1,category:"flags"},st_lucia:{keywords:["saint","lucia","flag","nation","country","banner"],char:'\ud83c\uddf1\ud83c\udde8',fitzpatrick_scale:!1,category:"flags"},st_pierre_miquelon:{keywords:["saint","pierre","miquelon","flag","nation","country","banner"],char:'\ud83c\uddf5\ud83c\uddf2',fitzpatrick_scale:!1,category:"flags"},st_vincent_grenadines:{keywords:["saint","vincent","grenadines","flag","nation","country","banner"],char:'\ud83c\uddfb\ud83c\udde8',fitzpatrick_scale:!1,category:"flags"},samoa:{keywords:["ws","flag","nation","country","banner"],char:'\ud83c\uddfc\ud83c\uddf8',fitzpatrick_scale:!1,category:"flags"},san_marino:{keywords:["san","marino","flag","nation","country","banner"],char:'\ud83c\uddf8\ud83c\uddf2',fitzpatrick_scale:!1,category:"flags"},sao_tome_principe:{keywords:["sao","tome","principe","flag","nation","country","banner"],char:'\ud83c\uddf8\ud83c\uddf9',fitzpatrick_scale:!1,category:"flags"},saudi_arabia:{keywords:["flag","nation","country","banner"],char:'\ud83c\uddf8\ud83c\udde6',fitzpatrick_scale:!1,category:"flags"},senegal:{keywords:["sn","flag","nation","country","banner"],char:'\ud83c\uddf8\ud83c\uddf3',fitzpatrick_scale:!1,category:"flags"},serbia:{keywords:["rs","flag","nation","country","banner"],char:'\ud83c\uddf7\ud83c\uddf8',fitzpatrick_scale:!1,category:"flags"},seychelles:{keywords:["sc","flag","nation","country","banner"],char:'\ud83c\uddf8\ud83c\udde8',fitzpatrick_scale:!1,category:"flags"},sierra_leone:{keywords:["sierra","leone","flag","nation","country","banner"],char:'\ud83c\uddf8\ud83c\uddf1',fitzpatrick_scale:!1,category:"flags"},singapore:{keywords:["sg","flag","nation","country","banner"],char:'\ud83c\uddf8\ud83c\uddec',fitzpatrick_scale:!1,category:"flags"},sint_maarten:{keywords:["sint","maarten","dutch","flag","nation","country","banner"],char:'\ud83c\uddf8\ud83c\uddfd',fitzpatrick_scale:!1,category:"flags"},slovakia:{keywords:["sk","flag","nation","country","banner"],char:'\ud83c\uddf8\ud83c\uddf0',fitzpatrick_scale:!1,category:"flags"},slovenia:{keywords:["si","flag","nation","country","banner"],char:'\ud83c\uddf8\ud83c\uddee',fitzpatrick_scale:!1,category:"flags"},solomon_islands:{keywords:["solomon","islands","flag","nation","country","banner"],char:'\ud83c\uddf8\ud83c\udde7',fitzpatrick_scale:!1,category:"flags"},somalia:{keywords:["so","flag","nation","country","banner"],char:'\ud83c\uddf8\ud83c\uddf4',fitzpatrick_scale:!1,category:"flags"},south_africa:{keywords:["south","africa","flag","nation","country","banner"],char:'\ud83c\uddff\ud83c\udde6',fitzpatrick_scale:!1,category:"flags"},south_georgia_south_sandwich_islands:{keywords:["south","georgia","sandwich","islands","flag","nation","country","banner"],char:'\ud83c\uddec\ud83c\uddf8',fitzpatrick_scale:!1,category:"flags"},kr:{keywords:["south","korea","nation","flag","country","banner"],char:'\ud83c\uddf0\ud83c\uddf7',fitzpatrick_scale:!1,category:"flags"},south_sudan:{keywords:["south","sd","flag","nation","country","banner"],char:'\ud83c\uddf8\ud83c\uddf8',fitzpatrick_scale:!1,category:"flags"},es:{keywords:["spain","flag","nation","country","banner"],char:'\ud83c\uddea\ud83c\uddf8',fitzpatrick_scale:!1,category:"flags"},sri_lanka:{keywords:["sri","lanka","flag","nation","country","banner"],char:'\ud83c\uddf1\ud83c\uddf0',fitzpatrick_scale:!1,category:"flags"},sudan:{keywords:["sd","flag","nation","country","banner"],char:'\ud83c\uddf8\ud83c\udde9',fitzpatrick_scale:!1,category:"flags"},suriname:{keywords:["sr","flag","nation","country","banner"],char:'\ud83c\uddf8\ud83c\uddf7',fitzpatrick_scale:!1,category:"flags"},swaziland:{keywords:["sz","flag","nation","country","banner"],char:'\ud83c\uddf8\ud83c\uddff',fitzpatrick_scale:!1,category:"flags"},sweden:{keywords:["se","flag","nation","country","banner"],char:'\ud83c\uddf8\ud83c\uddea',fitzpatrick_scale:!1,category:"flags"},switzerland:{keywords:["ch","flag","nation","country","banner"],char:'\ud83c\udde8\ud83c\udded',fitzpatrick_scale:!1,category:"flags"},syria:{keywords:["syrian","arab","republic","flag","nation","country","banner"],char:'\ud83c\uddf8\ud83c\uddfe',fitzpatrick_scale:!1,category:"flags"},taiwan:{keywords:["tw","flag","nation","country","banner"],char:'\ud83c\uddf9\ud83c\uddfc',fitzpatrick_scale:!1,category:"flags"},tajikistan:{keywords:["tj","flag","nation","country","banner"],char:'\ud83c\uddf9\ud83c\uddef',fitzpatrick_scale:!1,category:"flags"},tanzania:{keywords:["tanzania,","united","republic","flag","nation","country","banner"],char:'\ud83c\uddf9\ud83c\uddff',fitzpatrick_scale:!1,category:"flags"},thailand:{keywords:["th","flag","nation","country","banner"],char:'\ud83c\uddf9\ud83c\udded',fitzpatrick_scale:!1,category:"flags"},timor_leste:{keywords:["timor","leste","flag","nation","country","banner"],char:'\ud83c\uddf9\ud83c\uddf1',fitzpatrick_scale:!1,category:"flags"},togo:{keywords:["tg","flag","nation","country","banner"],char:'\ud83c\uddf9\ud83c\uddec',fitzpatrick_scale:!1,category:"flags"},tokelau:{keywords:["tk","flag","nation","country","banner"],char:'\ud83c\uddf9\ud83c\uddf0',fitzpatrick_scale:!1,category:"flags"},tonga:{keywords:["to","flag","nation","country","banner"],char:'\ud83c\uddf9\ud83c\uddf4',fitzpatrick_scale:!1,category:"flags"},trinidad_tobago:{keywords:["trinidad","tobago","flag","nation","country","banner"],char:'\ud83c\uddf9\ud83c\uddf9',fitzpatrick_scale:!1,category:"flags"},tunisia:{keywords:["tn","flag","nation","country","banner"],char:'\ud83c\uddf9\ud83c\uddf3',fitzpatrick_scale:!1,category:"flags"},tr:{keywords:["turkey","flag","nation","country","banner"],char:'\ud83c\uddf9\ud83c\uddf7',fitzpatrick_scale:!1,category:"flags"},turkmenistan:{keywords:["flag","nation","country","banner"],char:'\ud83c\uddf9\ud83c\uddf2',fitzpatrick_scale:!1,category:"flags"},turks_caicos_islands:{keywords:["turks","caicos","islands","flag","nation","country","banner"],char:'\ud83c\uddf9\ud83c\udde8',fitzpatrick_scale:!1,category:"flags"},tuvalu:{keywords:["flag","nation","country","banner"],char:'\ud83c\uddf9\ud83c\uddfb',fitzpatrick_scale:!1,category:"flags"},uganda:{keywords:["ug","flag","nation","country","banner"],char:'\ud83c\uddfa\ud83c\uddec',fitzpatrick_scale:!1,category:"flags"},ukraine:{keywords:["ua","flag","nation","country","banner"],char:'\ud83c\uddfa\ud83c\udde6',fitzpatrick_scale:!1,category:"flags"},united_arab_emirates:{keywords:["united","arab","emirates","flag","nation","country","banner"],char:'\ud83c\udde6\ud83c\uddea',fitzpatrick_scale:!1,category:"flags"},uk:{keywords:["united","kingdom","great","britain","northern","ireland","flag","nation","country","banner","british","UK","english","england","union jack"],char:'\ud83c\uddec\ud83c\udde7',fitzpatrick_scale:!1,category:"flags"},england:{keywords:["flag","english"],char:'\ud83c\udff4\udb40\udc67\udb40\udc62\udb40\udc65\udb40\udc6e\udb40\udc67\udb40\udc7f',fitzpatrick_scale:!1,category:"flags"},scotland:{keywords:["flag","scottish"],char:'\ud83c\udff4\udb40\udc67\udb40\udc62\udb40\udc73\udb40\udc63\udb40\udc74\udb40\udc7f',fitzpatrick_scale:!1,category:"flags"},wales:{keywords:["flag","welsh"],char:'\ud83c\udff4\udb40\udc67\udb40\udc62\udb40\udc77\udb40\udc6c\udb40\udc73\udb40\udc7f',fitzpatrick_scale:!1,category:"flags"},us:{keywords:["united","states","america","flag","nation","country","banner"],char:'\ud83c\uddfa\ud83c\uddf8',fitzpatrick_scale:!1,category:"flags"},us_virgin_islands:{keywords:["virgin","islands","us","flag","nation","country","banner"],char:'\ud83c\uddfb\ud83c\uddee',fitzpatrick_scale:!1,category:"flags"},uruguay:{keywords:["uy","flag","nation","country","banner"],char:'\ud83c\uddfa\ud83c\uddfe',fitzpatrick_scale:!1,category:"flags"},uzbekistan:{keywords:["uz","flag","nation","country","banner"],char:'\ud83c\uddfa\ud83c\uddff',fitzpatrick_scale:!1,category:"flags"},vanuatu:{keywords:["vu","flag","nation","country","banner"],char:'\ud83c\uddfb\ud83c\uddfa',fitzpatrick_scale:!1,category:"flags"},vatican_city:{keywords:["vatican","city","flag","nation","country","banner"],char:'\ud83c\uddfb\ud83c\udde6',fitzpatrick_scale:!1,category:"flags"},venezuela:{keywords:["ve","bolivarian","republic","flag","nation","country","banner"],char:'\ud83c\uddfb\ud83c\uddea',fitzpatrick_scale:!1,category:"flags"},vietnam:{keywords:["viet","nam","flag","nation","country","banner"],char:'\ud83c\uddfb\ud83c\uddf3',fitzpatrick_scale:!1,category:"flags"},wallis_futuna:{keywords:["wallis","futuna","flag","nation","country","banner"],char:'\ud83c\uddfc\ud83c\uddeb',fitzpatrick_scale:!1,category:"flags"},western_sahara:{keywords:["western","sahara","flag","nation","country","banner"],char:'\ud83c\uddea\ud83c\udded',fitzpatrick_scale:!1,category:"flags"},yemen:{keywords:["ye","flag","nation","country","banner"],char:'\ud83c\uddfe\ud83c\uddea',fitzpatrick_scale:!1,category:"flags"},zambia:{keywords:["zm","flag","nation","country","banner"],char:'\ud83c\uddff\ud83c\uddf2',fitzpatrick_scale:!1,category:"flags"},zimbabwe:{keywords:["zw","flag","nation","country","banner"],char:'\ud83c\uddff\ud83c\uddfc',fitzpatrick_scale:!1,category:"flags"},united_nations:{keywords:["un","flag","banner"],char:'\ud83c\uddfa\ud83c\uddf3',fitzpatrick_scale:!1,category:"flags"},pirate_flag:{keywords:["skull","crossbones","flag","banner"],char:'\ud83c\udff4\u200d\u2620\ufe0f',fitzpatrick_scale:!1,category:"flags"}}); \ No newline at end of file diff --git a/website/admin/tinymce/plugins/emoticons/js/emojiimages.min.js b/website/admin/tinymce/plugins/emoticons/js/emojiimages.min.js new file mode 100644 index 0000000..980bc15 --- /dev/null +++ b/website/admin/tinymce/plugins/emoticons/js/emojiimages.min.js @@ -0,0 +1 @@ +window.tinymce.Resource.add("tinymce.plugins.emoticons",{100:{keywords:["score","perfect","numbers","century","exam","quiz","test","pass","hundred"],char:'\ud83d\udcaf',fitzpatrick_scale:!1,category:"symbols"},1234:{keywords:["numbers","blue-square"],char:'\ud83d\udd22',fitzpatrick_scale:!1,category:"symbols"},grinning:{keywords:["face","smile","happy","joy",":D","grin"],char:'\ud83d\ude00',fitzpatrick_scale:!1,category:"people"},grimacing:{keywords:["face","grimace","teeth"],char:'\ud83d\ude2c',fitzpatrick_scale:!1,category:"people"},grin:{keywords:["face","happy","smile","joy","kawaii"],char:'\ud83d\ude01',fitzpatrick_scale:!1,category:"people"},joy:{keywords:["face","cry","tears","weep","happy","happytears","haha"],char:'\ud83d\ude02',fitzpatrick_scale:!1,category:"people"},rofl:{keywords:["face","rolling","floor","laughing","lol","haha"],char:'\ud83e\udd23',fitzpatrick_scale:!1,category:"people"},partying:{keywords:["face","celebration","woohoo"],char:'\ud83e\udd73',fitzpatrick_scale:!1,category:"people"},smiley:{keywords:["face","happy","joy","haha",":D",":)","smile","funny"],char:'\ud83d\ude03',fitzpatrick_scale:!1,category:"people"},smile:{keywords:["face","happy","joy","funny","haha","laugh","like",":D",":)"],char:'\ud83d\ude04',fitzpatrick_scale:!1,category:"people"},sweat_smile:{keywords:["face","hot","happy","laugh","sweat","smile","relief"],char:'\ud83d\ude05',fitzpatrick_scale:!1,category:"people"},laughing:{keywords:["happy","joy","lol","satisfied","haha","face","glad","XD","laugh"],char:'\ud83d\ude06',fitzpatrick_scale:!1,category:"people"},innocent:{keywords:["face","angel","heaven","halo"],char:'\ud83d\ude07',fitzpatrick_scale:!1,category:"people"},wink:{keywords:["face","happy","mischievous","secret",";)","smile","eye"],char:'\ud83d\ude09',fitzpatrick_scale:!1,category:"people"},blush:{keywords:["face","smile","happy","flushed","crush","embarrassed","shy","joy"],char:'\ud83d\ude0a',fitzpatrick_scale:!1,category:"people"},slightly_smiling_face:{keywords:["face","smile"],char:'\ud83d\ude42',fitzpatrick_scale:!1,category:"people"},upside_down_face:{keywords:["face","flipped","silly","smile"],char:'\ud83d\ude43',fitzpatrick_scale:!1,category:"people"},relaxed:{keywords:["face","blush","massage","happiness"],char:'\u263a\ufe0f',fitzpatrick_scale:!1,category:"people"},yum:{keywords:["happy","joy","tongue","smile","face","silly","yummy","nom","delicious","savouring"],char:'\ud83d\ude0b',fitzpatrick_scale:!1,category:"people"},relieved:{keywords:["face","relaxed","phew","massage","happiness"],char:'\ud83d\ude0c',fitzpatrick_scale:!1,category:"people"},heart_eyes:{keywords:["face","love","like","affection","valentines","infatuation","crush","heart"],char:'\ud83d\ude0d',fitzpatrick_scale:!1,category:"people"},smiling_face_with_three_hearts:{keywords:["face","love","like","affection","valentines","infatuation","crush","hearts","adore"],char:'\ud83e\udd70',fitzpatrick_scale:!1,category:"people"},kissing_heart:{keywords:["face","love","like","affection","valentines","infatuation","kiss"],char:'\ud83d\ude18',fitzpatrick_scale:!1,category:"people"},kissing:{keywords:["love","like","face","3","valentines","infatuation","kiss"],char:'\ud83d\ude17',fitzpatrick_scale:!1,category:"people"},kissing_smiling_eyes:{keywords:["face","affection","valentines","infatuation","kiss"],char:'\ud83d\ude19',fitzpatrick_scale:!1,category:"people"},kissing_closed_eyes:{keywords:["face","love","like","affection","valentines","infatuation","kiss"],char:'\ud83d\ude1a',fitzpatrick_scale:!1,category:"people"},stuck_out_tongue_winking_eye:{keywords:["face","prank","childish","playful","mischievous","smile","wink","tongue"],char:'\ud83d\ude1c',fitzpatrick_scale:!1,category:"people"},zany:{keywords:["face","goofy","crazy"],char:'\ud83e\udd2a',fitzpatrick_scale:!1,category:"people"},raised_eyebrow:{keywords:["face","distrust","scepticism","disapproval","disbelief","surprise"],char:'\ud83e\udd28',fitzpatrick_scale:!1,category:"people"},monocle:{keywords:["face","stuffy","wealthy"],char:'\ud83e\uddd0',fitzpatrick_scale:!1,category:"people"},stuck_out_tongue_closed_eyes:{keywords:["face","prank","playful","mischievous","smile","tongue"],char:'\ud83d\ude1d',fitzpatrick_scale:!1,category:"people"},stuck_out_tongue:{keywords:["face","prank","childish","playful","mischievous","smile","tongue"],char:'\ud83d\ude1b',fitzpatrick_scale:!1,category:"people"},money_mouth_face:{keywords:["face","rich","dollar","money"],char:'\ud83e\udd11',fitzpatrick_scale:!1,category:"people"},nerd_face:{keywords:["face","nerdy","geek","dork"],char:'\ud83e\udd13',fitzpatrick_scale:!1,category:"people"},sunglasses:{keywords:["face","cool","smile","summer","beach","sunglass"],char:'\ud83d\ude0e',fitzpatrick_scale:!1,category:"people"},star_struck:{keywords:["face","smile","starry","eyes","grinning"],char:'\ud83e\udd29',fitzpatrick_scale:!1,category:"people"},clown_face:{keywords:["face"],char:'\ud83e\udd21',fitzpatrick_scale:!1,category:"people"},cowboy_hat_face:{keywords:["face","cowgirl","hat"],char:'\ud83e\udd20',fitzpatrick_scale:!1,category:"people"},hugs:{keywords:["face","smile","hug"],char:'\ud83e\udd17',fitzpatrick_scale:!1,category:"people"},smirk:{keywords:["face","smile","mean","prank","smug","sarcasm"],char:'\ud83d\ude0f',fitzpatrick_scale:!1,category:"people"},no_mouth:{keywords:["face","hellokitty"],char:'\ud83d\ude36',fitzpatrick_scale:!1,category:"people"},neutral_face:{keywords:["indifference","meh",":|","neutral"],char:'\ud83d\ude10',fitzpatrick_scale:!1,category:"people"},expressionless:{keywords:["face","indifferent","-_-","meh","deadpan"],char:'\ud83d\ude11',fitzpatrick_scale:!1,category:"people"},unamused:{keywords:["indifference","bored","straight face","serious","sarcasm","unimpressed","skeptical","dubious","side_eye"],char:'\ud83d\ude12',fitzpatrick_scale:!1,category:"people"},roll_eyes:{keywords:["face","eyeroll","frustrated"],char:'\ud83d\ude44',fitzpatrick_scale:!1,category:"people"},thinking:{keywords:["face","hmmm","think","consider"],char:'\ud83e\udd14',fitzpatrick_scale:!1,category:"people"},lying_face:{keywords:["face","lie","pinocchio"],char:'\ud83e\udd25',fitzpatrick_scale:!1,category:"people"},hand_over_mouth:{keywords:["face","whoops","shock","surprise"],char:'\ud83e\udd2d',fitzpatrick_scale:!1,category:"people"},shushing:{keywords:["face","quiet","shhh"],char:'\ud83e\udd2b',fitzpatrick_scale:!1,category:"people"},symbols_over_mouth:{keywords:["face","swearing","cursing","cussing","profanity","expletive"],char:'\ud83e\udd2c',fitzpatrick_scale:!1,category:"people"},exploding_head:{keywords:["face","shocked","mind","blown"],char:'\ud83e\udd2f',fitzpatrick_scale:!1,category:"people"},flushed:{keywords:["face","blush","shy","flattered"],char:'\ud83d\ude33',fitzpatrick_scale:!1,category:"people"},disappointed:{keywords:["face","sad","upset","depressed",":("],char:'\ud83d\ude1e',fitzpatrick_scale:!1,category:"people"},worried:{keywords:["face","concern","nervous",":("],char:'\ud83d\ude1f',fitzpatrick_scale:!1,category:"people"},angry:{keywords:["mad","face","annoyed","frustrated"],char:'\ud83d\ude20',fitzpatrick_scale:!1,category:"people"},rage:{keywords:["angry","mad","hate","despise"],char:'\ud83d\ude21',fitzpatrick_scale:!1,category:"people"},pensive:{keywords:["face","sad","depressed","upset"],char:'\ud83d\ude14',fitzpatrick_scale:!1,category:"people"},confused:{keywords:["face","indifference","huh","weird","hmmm",":/"],char:'\ud83d\ude15',fitzpatrick_scale:!1,category:"people"},slightly_frowning_face:{keywords:["face","frowning","disappointed","sad","upset"],char:'\ud83d\ude41',fitzpatrick_scale:!1,category:"people"},frowning_face:{keywords:["face","sad","upset","frown"],char:'\u2639',fitzpatrick_scale:!1,category:"people"},persevere:{keywords:["face","sick","no","upset","oops"],char:'\ud83d\ude23',fitzpatrick_scale:!1,category:"people"},confounded:{keywords:["face","confused","sick","unwell","oops",":S"],char:'\ud83d\ude16',fitzpatrick_scale:!1,category:"people"},tired_face:{keywords:["sick","whine","upset","frustrated"],char:'\ud83d\ude2b',fitzpatrick_scale:!1,category:"people"},weary:{keywords:["face","tired","sleepy","sad","frustrated","upset"],char:'\ud83d\ude29',fitzpatrick_scale:!1,category:"people"},pleading:{keywords:["face","begging","mercy"],char:'\ud83e\udd7a',fitzpatrick_scale:!1,category:"people"},triumph:{keywords:["face","gas","phew","proud","pride"],char:'\ud83d\ude24',fitzpatrick_scale:!1,category:"people"},open_mouth:{keywords:["face","surprise","impressed","wow","whoa",":O"],char:'\ud83d\ude2e',fitzpatrick_scale:!1,category:"people"},scream:{keywords:["face","munch","scared","omg"],char:'\ud83d\ude31',fitzpatrick_scale:!1,category:"people"},fearful:{keywords:["face","scared","terrified","nervous","oops","huh"],char:'\ud83d\ude28',fitzpatrick_scale:!1,category:"people"},cold_sweat:{keywords:["face","nervous","sweat"],char:'\ud83d\ude30',fitzpatrick_scale:!1,category:"people"},hushed:{keywords:["face","woo","shh"],char:'\ud83d\ude2f',fitzpatrick_scale:!1,category:"people"},frowning:{keywords:["face","aw","what"],char:'\ud83d\ude26',fitzpatrick_scale:!1,category:"people"},anguished:{keywords:["face","stunned","nervous"],char:'\ud83d\ude27',fitzpatrick_scale:!1,category:"people"},cry:{keywords:["face","tears","sad","depressed","upset",":'("],char:'\ud83d\ude22',fitzpatrick_scale:!1,category:"people"},disappointed_relieved:{keywords:["face","phew","sweat","nervous"],char:'\ud83d\ude25',fitzpatrick_scale:!1,category:"people"},drooling_face:{keywords:["face"],char:'\ud83e\udd24',fitzpatrick_scale:!1,category:"people"},sleepy:{keywords:["face","tired","rest","nap"],char:'\ud83d\ude2a',fitzpatrick_scale:!1,category:"people"},sweat:{keywords:["face","hot","sad","tired","exercise"],char:'\ud83d\ude13',fitzpatrick_scale:!1,category:"people"},hot:{keywords:["face","feverish","heat","red","sweating"],char:'\ud83e\udd75',fitzpatrick_scale:!1,category:"people"},cold:{keywords:["face","blue","freezing","frozen","frostbite","icicles"],char:'\ud83e\udd76',fitzpatrick_scale:!1,category:"people"},sob:{keywords:["face","cry","tears","sad","upset","depressed"],char:'\ud83d\ude2d',fitzpatrick_scale:!1,category:"people"},dizzy_face:{keywords:["spent","unconscious","xox","dizzy"],char:'\ud83d\ude35',fitzpatrick_scale:!1,category:"people"},astonished:{keywords:["face","xox","surprised","poisoned"],char:'\ud83d\ude32',fitzpatrick_scale:!1,category:"people"},zipper_mouth_face:{keywords:["face","sealed","zipper","secret"],char:'\ud83e\udd10',fitzpatrick_scale:!1,category:"people"},nauseated_face:{keywords:["face","vomit","gross","green","sick","throw up","ill"],char:'\ud83e\udd22',fitzpatrick_scale:!1,category:"people"},sneezing_face:{keywords:["face","gesundheit","sneeze","sick","allergy"],char:'\ud83e\udd27',fitzpatrick_scale:!1,category:"people"},vomiting:{keywords:["face","sick"],char:'\ud83e\udd2e',fitzpatrick_scale:!1,category:"people"},mask:{keywords:["face","sick","ill","disease"],char:'\ud83d\ude37',fitzpatrick_scale:!1,category:"people"},face_with_thermometer:{keywords:["sick","temperature","thermometer","cold","fever"],char:'\ud83e\udd12',fitzpatrick_scale:!1,category:"people"},face_with_head_bandage:{keywords:["injured","clumsy","bandage","hurt"],char:'\ud83e\udd15',fitzpatrick_scale:!1,category:"people"},woozy:{keywords:["face","dizzy","intoxicated","tipsy","wavy"],char:'\ud83e\udd74',fitzpatrick_scale:!1,category:"people"},sleeping:{keywords:["face","tired","sleepy","night","zzz"],char:'\ud83d\ude34',fitzpatrick_scale:!1,category:"people"},zzz:{keywords:["sleepy","tired","dream"],char:'\ud83d\udca4',fitzpatrick_scale:!1,category:"people"},poop:{keywords:["hankey","shitface","fail","turd","shit"],char:'\ud83d\udca9',fitzpatrick_scale:!1,category:"people"},smiling_imp:{keywords:["devil","horns"],char:'\ud83d\ude08',fitzpatrick_scale:!1,category:"people"},imp:{keywords:["devil","angry","horns"],char:'\ud83d\udc7f',fitzpatrick_scale:!1,category:"people"},japanese_ogre:{keywords:["monster","red","mask","halloween","scary","creepy","devil","demon","japanese","ogre"],char:'\ud83d\udc79',fitzpatrick_scale:!1,category:"people"},japanese_goblin:{keywords:["red","evil","mask","monster","scary","creepy","japanese","goblin"],char:'\ud83d\udc7a',fitzpatrick_scale:!1,category:"people"},skull:{keywords:["dead","skeleton","creepy","death"],char:'\ud83d\udc80',fitzpatrick_scale:!1,category:"people"},ghost:{keywords:["halloween","spooky","scary"],char:'\ud83d\udc7b',fitzpatrick_scale:!1,category:"people"},alien:{keywords:["UFO","paul","weird","outer_space"],char:'\ud83d\udc7d',fitzpatrick_scale:!1,category:"people"},robot:{keywords:["computer","machine","bot"],char:'\ud83e\udd16',fitzpatrick_scale:!1,category:"people"},smiley_cat:{keywords:["animal","cats","happy","smile"],char:'\ud83d\ude3a',fitzpatrick_scale:!1,category:"people"},smile_cat:{keywords:["animal","cats","smile"],char:'\ud83d\ude38',fitzpatrick_scale:!1,category:"people"},joy_cat:{keywords:["animal","cats","haha","happy","tears"],char:'\ud83d\ude39',fitzpatrick_scale:!1,category:"people"},heart_eyes_cat:{keywords:["animal","love","like","affection","cats","valentines","heart"],char:'\ud83d\ude3b',fitzpatrick_scale:!1,category:"people"},smirk_cat:{keywords:["animal","cats","smirk"],char:'\ud83d\ude3c',fitzpatrick_scale:!1,category:"people"},kissing_cat:{keywords:["animal","cats","kiss"],char:'\ud83d\ude3d',fitzpatrick_scale:!1,category:"people"},scream_cat:{keywords:["animal","cats","munch","scared","scream"],char:'\ud83d\ude40',fitzpatrick_scale:!1,category:"people"},crying_cat_face:{keywords:["animal","tears","weep","sad","cats","upset","cry"],char:'\ud83d\ude3f',fitzpatrick_scale:!1,category:"people"},pouting_cat:{keywords:["animal","cats"],char:'\ud83d\ude3e',fitzpatrick_scale:!1,category:"people"},palms_up:{keywords:["hands","gesture","cupped","prayer"],char:'\ud83e\udd32',fitzpatrick_scale:!0,category:"people"},raised_hands:{keywords:["gesture","hooray","yea","celebration","hands"],char:'\ud83d\ude4c',fitzpatrick_scale:!0,category:"people"},clap:{keywords:["hands","praise","applause","congrats","yay"],char:'\ud83d\udc4f',fitzpatrick_scale:!0,category:"people"},wave:{keywords:["hands","gesture","goodbye","solong","farewell","hello","hi","palm"],char:'\ud83d\udc4b',fitzpatrick_scale:!0,category:"people"},call_me_hand:{keywords:["hands","gesture"],char:'\ud83e\udd19',fitzpatrick_scale:!0,category:"people"},"+1":{keywords:["thumbsup","yes","awesome","good","agree","accept","cool","hand","like"],char:'\ud83d\udc4d',fitzpatrick_scale:!0,category:"people"},"-1":{keywords:["thumbsdown","no","dislike","hand"],char:'\ud83d\udc4e',fitzpatrick_scale:!0,category:"people"},facepunch:{keywords:["angry","violence","fist","hit","attack","hand"],char:'\ud83d\udc4a',fitzpatrick_scale:!0,category:"people"},fist:{keywords:["fingers","hand","grasp"],char:'\u270a',fitzpatrick_scale:!0,category:"people"},fist_left:{keywords:["hand","fistbump"],char:'\ud83e\udd1b',fitzpatrick_scale:!0,category:"people"},fist_right:{keywords:["hand","fistbump"],char:'\ud83e\udd1c',fitzpatrick_scale:!0,category:"people"},v:{keywords:["fingers","ohyeah","hand","peace","victory","two"],char:'\u270c',fitzpatrick_scale:!0,category:"people"},ok_hand:{keywords:["fingers","limbs","perfect","ok","okay"],char:'\ud83d\udc4c',fitzpatrick_scale:!0,category:"people"},raised_hand:{keywords:["fingers","stop","highfive","palm","ban"],char:'\u270b',fitzpatrick_scale:!0,category:"people"},raised_back_of_hand:{keywords:["fingers","raised","backhand"],char:'\ud83e\udd1a',fitzpatrick_scale:!0,category:"people"},open_hands:{keywords:["fingers","butterfly","hands","open"],char:'\ud83d\udc50',fitzpatrick_scale:!0,category:"people"},muscle:{keywords:["arm","flex","hand","summer","strong","biceps"],char:'\ud83d\udcaa',fitzpatrick_scale:!0,category:"people"},pray:{keywords:["please","hope","wish","namaste","highfive"],char:'\ud83d\ude4f',fitzpatrick_scale:!0,category:"people"},foot:{keywords:["kick","stomp"],char:'\ud83e\uddb6',fitzpatrick_scale:!0,category:"people"},leg:{keywords:["kick","limb"],char:'\ud83e\uddb5',fitzpatrick_scale:!0,category:"people"},handshake:{keywords:["agreement","shake"],char:'\ud83e\udd1d',fitzpatrick_scale:!1,category:"people"},point_up:{keywords:["hand","fingers","direction","up"],char:'\u261d',fitzpatrick_scale:!0,category:"people"},point_up_2:{keywords:["fingers","hand","direction","up"],char:'\ud83d\udc46',fitzpatrick_scale:!0,category:"people"},point_down:{keywords:["fingers","hand","direction","down"],char:'\ud83d\udc47',fitzpatrick_scale:!0,category:"people"},point_left:{keywords:["direction","fingers","hand","left"],char:'\ud83d\udc48',fitzpatrick_scale:!0,category:"people"},point_right:{keywords:["fingers","hand","direction","right"],char:'\ud83d\udc49',fitzpatrick_scale:!0,category:"people"},fu:{keywords:["hand","fingers","rude","middle","flipping"],char:'\ud83d\udd95',fitzpatrick_scale:!0,category:"people"},raised_hand_with_fingers_splayed:{keywords:["hand","fingers","palm"],char:'\ud83d\udd90',fitzpatrick_scale:!0,category:"people"},love_you:{keywords:["hand","fingers","gesture"],char:'\ud83e\udd1f',fitzpatrick_scale:!0,category:"people"},metal:{keywords:["hand","fingers","evil_eye","sign_of_horns","rock_on"],char:'\ud83e\udd18',fitzpatrick_scale:!0,category:"people"},crossed_fingers:{keywords:["good","lucky"],char:'\ud83e\udd1e',fitzpatrick_scale:!0,category:"people"},vulcan_salute:{keywords:["hand","fingers","spock","star trek"],char:'\ud83d\udd96',fitzpatrick_scale:!0,category:"people"},writing_hand:{keywords:["lower_left_ballpoint_pen","stationery","write","compose"],char:'\u270d',fitzpatrick_scale:!0,category:"people"},selfie:{keywords:["camera","phone"],char:'\ud83e\udd33',fitzpatrick_scale:!0,category:"people"},nail_care:{keywords:["beauty","manicure","finger","fashion","nail"],char:'\ud83d\udc85',fitzpatrick_scale:!0,category:"people"},lips:{keywords:["mouth","kiss"],char:'\ud83d\udc44',fitzpatrick_scale:!1,category:"people"},tooth:{keywords:["teeth","dentist"],char:'\ud83e\uddb7',fitzpatrick_scale:!1,category:"people"},tongue:{keywords:["mouth","playful"],char:'\ud83d\udc45',fitzpatrick_scale:!1,category:"people"},ear:{keywords:["face","hear","sound","listen"],char:'\ud83d\udc42',fitzpatrick_scale:!0,category:"people"},nose:{keywords:["smell","sniff"],char:'\ud83d\udc43',fitzpatrick_scale:!0,category:"people"},eye:{keywords:["face","look","see","watch","stare"],char:'\ud83d\udc41',fitzpatrick_scale:!1,category:"people"},eyes:{keywords:["look","watch","stalk","peek","see"],char:'\ud83d\udc40',fitzpatrick_scale:!1,category:"people"},brain:{keywords:["smart","intelligent"],char:'\ud83e\udde0',fitzpatrick_scale:!1,category:"people"},bust_in_silhouette:{keywords:["user","person","human"],char:'\ud83d\udc64',fitzpatrick_scale:!1,category:"people"},busts_in_silhouette:{keywords:["user","person","human","group","team"],char:'\ud83d\udc65',fitzpatrick_scale:!1,category:"people"},speaking_head:{keywords:["user","person","human","sing","say","talk"],char:'\ud83d\udde3',fitzpatrick_scale:!1,category:"people"},baby:{keywords:["child","boy","girl","toddler"],char:'\ud83d\udc76',fitzpatrick_scale:!0,category:"people"},child:{keywords:["gender-neutral","young"],char:'\ud83e\uddd2',fitzpatrick_scale:!0,category:"people"},boy:{keywords:["man","male","guy","teenager"],char:'\ud83d\udc66',fitzpatrick_scale:!0,category:"people"},girl:{keywords:["female","woman","teenager"],char:'\ud83d\udc67',fitzpatrick_scale:!0,category:"people"},adult:{keywords:["gender-neutral","person"],char:'\ud83e\uddd1',fitzpatrick_scale:!0,category:"people"},man:{keywords:["mustache","father","dad","guy","classy","sir","moustache"],char:'\ud83d\udc68',fitzpatrick_scale:!0,category:"people"},woman:{keywords:["female","girls","lady"],char:'\ud83d\udc69',fitzpatrick_scale:!0,category:"people"},blonde_woman:{keywords:["woman","female","girl","blonde","person"],char:'\ud83d\udc71\u200d\u2640\ufe0f',fitzpatrick_scale:!0,category:"people"},blonde_man:{keywords:["man","male","boy","blonde","guy","person"],char:'\ud83d\udc71',fitzpatrick_scale:!0,category:"people"},bearded_person:{keywords:["person","bewhiskered"],char:'\ud83e\uddd4',fitzpatrick_scale:!0,category:"people"},older_adult:{keywords:["human","elder","senior","gender-neutral"],char:'\ud83e\uddd3',fitzpatrick_scale:!0,category:"people"},older_man:{keywords:["human","male","men","old","elder","senior"],char:'\ud83d\udc74',fitzpatrick_scale:!0,category:"people"},older_woman:{keywords:["human","female","women","lady","old","elder","senior"],char:'\ud83d\udc75',fitzpatrick_scale:!0,category:"people"},man_with_gua_pi_mao:{keywords:["male","boy","chinese"],char:'\ud83d\udc72',fitzpatrick_scale:!0,category:"people"},woman_with_headscarf:{keywords:["female","hijab","mantilla","tichel"],char:'\ud83e\uddd5',fitzpatrick_scale:!0,category:"people"},woman_with_turban:{keywords:["female","indian","hinduism","arabs","woman"],char:'\ud83d\udc73\u200d\u2640\ufe0f',fitzpatrick_scale:!0,category:"people"},man_with_turban:{keywords:["male","indian","hinduism","arabs"],char:'\ud83d\udc73',fitzpatrick_scale:!0,category:"people"},policewoman:{keywords:["woman","police","law","legal","enforcement","arrest","911","female"],char:'\ud83d\udc6e\u200d\u2640\ufe0f',fitzpatrick_scale:!0,category:"people"},policeman:{keywords:["man","police","law","legal","enforcement","arrest","911"],char:'\ud83d\udc6e',fitzpatrick_scale:!0,category:"people"},construction_worker_woman:{keywords:["female","human","wip","build","construction","worker","labor","woman"],char:'\ud83d\udc77\u200d\u2640\ufe0f',fitzpatrick_scale:!0,category:"people"},construction_worker_man:{keywords:["male","human","wip","guy","build","construction","worker","labor"],char:'\ud83d\udc77',fitzpatrick_scale:!0,category:"people"},guardswoman:{keywords:["uk","gb","british","female","royal","woman"],char:'\ud83d\udc82\u200d\u2640\ufe0f',fitzpatrick_scale:!0,category:"people"},guardsman:{keywords:["uk","gb","british","male","guy","royal"],char:'\ud83d\udc82',fitzpatrick_scale:!0,category:"people"},female_detective:{keywords:["human","spy","detective","female","woman"],char:'\ud83d\udd75\ufe0f\u200d\u2640\ufe0f',fitzpatrick_scale:!0,category:"people"},male_detective:{keywords:["human","spy","detective"],char:'\ud83d\udd75',fitzpatrick_scale:!0,category:"people"},woman_health_worker:{keywords:["doctor","nurse","therapist","healthcare","woman","human"],char:'\ud83d\udc69\u200d\u2695\ufe0f',fitzpatrick_scale:!0,category:"people"},man_health_worker:{keywords:["doctor","nurse","therapist","healthcare","man","human"],char:'\ud83d\udc68\u200d\u2695\ufe0f',fitzpatrick_scale:!0,category:"people"},woman_farmer:{keywords:["rancher","gardener","woman","human"],char:'\ud83d\udc69\u200d\ud83c\udf3e',fitzpatrick_scale:!0,category:"people"},man_farmer:{keywords:["rancher","gardener","man","human"],char:'\ud83d\udc68\u200d\ud83c\udf3e',fitzpatrick_scale:!0,category:"people"},woman_cook:{keywords:["chef","woman","human"],char:'\ud83d\udc69\u200d\ud83c\udf73',fitzpatrick_scale:!0,category:"people"},man_cook:{keywords:["chef","man","human"],char:'\ud83d\udc68\u200d\ud83c\udf73',fitzpatrick_scale:!0,category:"people"},woman_student:{keywords:["graduate","woman","human"],char:'\ud83d\udc69\u200d\ud83c\udf93',fitzpatrick_scale:!0,category:"people"},man_student:{keywords:["graduate","man","human"],char:'\ud83d\udc68\u200d\ud83c\udf93',fitzpatrick_scale:!0,category:"people"},woman_singer:{keywords:["rockstar","entertainer","woman","human"],char:'\ud83d\udc69\u200d\ud83c\udfa4',fitzpatrick_scale:!0,category:"people"},man_singer:{keywords:["rockstar","entertainer","man","human"],char:'\ud83d\udc68\u200d\ud83c\udfa4',fitzpatrick_scale:!0,category:"people"},woman_teacher:{keywords:["instructor","professor","woman","human"],char:'\ud83d\udc69\u200d\ud83c\udfeb',fitzpatrick_scale:!0,category:"people"},man_teacher:{keywords:["instructor","professor","man","human"],char:'\ud83d\udc68\u200d\ud83c\udfeb',fitzpatrick_scale:!0,category:"people"},woman_factory_worker:{keywords:["assembly","industrial","woman","human"],char:'\ud83d\udc69\u200d\ud83c\udfed',fitzpatrick_scale:!0,category:"people"},man_factory_worker:{keywords:["assembly","industrial","man","human"],char:'\ud83d\udc68\u200d\ud83c\udfed',fitzpatrick_scale:!0,category:"people"},woman_technologist:{keywords:["coder","developer","engineer","programmer","software","woman","human","laptop","computer"],char:'\ud83d\udc69\u200d\ud83d\udcbb',fitzpatrick_scale:!0,category:"people"},man_technologist:{keywords:["coder","developer","engineer","programmer","software","man","human","laptop","computer"],char:'\ud83d\udc68\u200d\ud83d\udcbb',fitzpatrick_scale:!0,category:"people"},woman_office_worker:{keywords:["business","manager","woman","human"],char:'\ud83d\udc69\u200d\ud83d\udcbc',fitzpatrick_scale:!0,category:"people"},man_office_worker:{keywords:["business","manager","man","human"],char:'\ud83d\udc68\u200d\ud83d\udcbc',fitzpatrick_scale:!0,category:"people"},woman_mechanic:{keywords:["plumber","woman","human","wrench"],char:'\ud83d\udc69\u200d\ud83d\udd27',fitzpatrick_scale:!0,category:"people"},man_mechanic:{keywords:["plumber","man","human","wrench"],char:'\ud83d\udc68\u200d\ud83d\udd27',fitzpatrick_scale:!0,category:"people"},woman_scientist:{keywords:["biologist","chemist","engineer","physicist","woman","human"],char:'\ud83d\udc69\u200d\ud83d\udd2c',fitzpatrick_scale:!0,category:"people"},man_scientist:{keywords:["biologist","chemist","engineer","physicist","man","human"],char:'\ud83d\udc68\u200d\ud83d\udd2c',fitzpatrick_scale:!0,category:"people"},woman_artist:{keywords:["painter","woman","human"],char:'\ud83d\udc69\u200d\ud83c\udfa8',fitzpatrick_scale:!0,category:"people"},man_artist:{keywords:["painter","man","human"],char:'\ud83d\udc68\u200d\ud83c\udfa8',fitzpatrick_scale:!0,category:"people"},woman_firefighter:{keywords:["fireman","woman","human"],char:'\ud83d\udc69\u200d\ud83d\ude92',fitzpatrick_scale:!0,category:"people"},man_firefighter:{keywords:["fireman","man","human"],char:'\ud83d\udc68\u200d\ud83d\ude92',fitzpatrick_scale:!0,category:"people"},woman_pilot:{keywords:["aviator","plane","woman","human"],char:'\ud83d\udc69\u200d\u2708\ufe0f',fitzpatrick_scale:!0,category:"people"},man_pilot:{keywords:["aviator","plane","man","human"],char:'\ud83d\udc68\u200d\u2708\ufe0f',fitzpatrick_scale:!0,category:"people"},woman_astronaut:{keywords:["space","rocket","woman","human"],char:'\ud83d\udc69\u200d\ud83d\ude80',fitzpatrick_scale:!0,category:"people"},man_astronaut:{keywords:["space","rocket","man","human"],char:'\ud83d\udc68\u200d\ud83d\ude80',fitzpatrick_scale:!0,category:"people"},woman_judge:{keywords:["justice","court","woman","human"],char:'\ud83d\udc69\u200d\u2696\ufe0f',fitzpatrick_scale:!0,category:"people"},man_judge:{keywords:["justice","court","man","human"],char:'\ud83d\udc68\u200d\u2696\ufe0f',fitzpatrick_scale:!0,category:"people"},woman_superhero:{keywords:["woman","female","good","heroine","superpowers"],char:'\ud83e\uddb8\u200d\u2640\ufe0f',fitzpatrick_scale:!0,category:"people"},man_superhero:{keywords:["man","male","good","hero","superpowers"],char:'\ud83e\uddb8\u200d\u2642\ufe0f',fitzpatrick_scale:!0,category:"people"},woman_supervillain:{keywords:["woman","female","evil","bad","criminal","heroine","superpowers"],char:'\ud83e\uddb9\u200d\u2640\ufe0f',fitzpatrick_scale:!0,category:"people"},man_supervillain:{keywords:["man","male","evil","bad","criminal","hero","superpowers"],char:'\ud83e\uddb9\u200d\u2642\ufe0f',fitzpatrick_scale:!0,category:"people"},mrs_claus:{keywords:["woman","female","xmas","mother christmas"],char:'\ud83e\udd36',fitzpatrick_scale:!0,category:"people"},santa:{keywords:["festival","man","male","xmas","father christmas"],char:'\ud83c\udf85',fitzpatrick_scale:!0,category:"people"},sorceress:{keywords:["woman","female","mage","witch"],char:'\ud83e\uddd9\u200d\u2640\ufe0f',fitzpatrick_scale:!0,category:"people"},wizard:{keywords:["man","male","mage","sorcerer"],char:'\ud83e\uddd9\u200d\u2642\ufe0f',fitzpatrick_scale:!0,category:"people"},woman_elf:{keywords:["woman","female"],char:'\ud83e\udddd\u200d\u2640\ufe0f',fitzpatrick_scale:!0,category:"people"},man_elf:{keywords:["man","male"],char:'\ud83e\udddd\u200d\u2642\ufe0f',fitzpatrick_scale:!0,category:"people"},woman_vampire:{keywords:["woman","female"],char:'\ud83e\udddb\u200d\u2640\ufe0f',fitzpatrick_scale:!0,category:"people"},man_vampire:{keywords:["man","male","dracula"],char:'\ud83e\udddb\u200d\u2642\ufe0f',fitzpatrick_scale:!0,category:"people"},woman_zombie:{keywords:["woman","female","undead","walking dead"],char:'\ud83e\udddf\u200d\u2640\ufe0f',fitzpatrick_scale:!1,category:"people"},man_zombie:{keywords:["man","male","dracula","undead","walking dead"],char:'\ud83e\udddf\u200d\u2642\ufe0f',fitzpatrick_scale:!1,category:"people"},woman_genie:{keywords:["woman","female"],char:'\ud83e\uddde\u200d\u2640\ufe0f',fitzpatrick_scale:!1,category:"people"},man_genie:{keywords:["man","male"],char:'\ud83e\uddde\u200d\u2642\ufe0f',fitzpatrick_scale:!1,category:"people"},mermaid:{keywords:["woman","female","merwoman","ariel"],char:'\ud83e\udddc\u200d\u2640\ufe0f',fitzpatrick_scale:!0,category:"people"},merman:{keywords:["man","male","triton"],char:'\ud83e\udddc\u200d\u2642\ufe0f',fitzpatrick_scale:!0,category:"people"},woman_fairy:{keywords:["woman","female"],char:'\ud83e\uddda\u200d\u2640\ufe0f',fitzpatrick_scale:!0,category:"people"},man_fairy:{keywords:["man","male"],char:'\ud83e\uddda\u200d\u2642\ufe0f',fitzpatrick_scale:!0,category:"people"},angel:{keywords:["heaven","wings","halo"],char:'\ud83d\udc7c',fitzpatrick_scale:!0,category:"people"},pregnant_woman:{keywords:["baby"],char:'\ud83e\udd30',fitzpatrick_scale:!0,category:"people"},breastfeeding:{keywords:["nursing","baby"],char:'\ud83e\udd31',fitzpatrick_scale:!0,category:"people"},princess:{keywords:["girl","woman","female","blond","crown","royal","queen"],char:'\ud83d\udc78',fitzpatrick_scale:!0,category:"people"},prince:{keywords:["boy","man","male","crown","royal","king"],char:'\ud83e\udd34',fitzpatrick_scale:!0,category:"people"},bride_with_veil:{keywords:["couple","marriage","wedding","woman","bride"],char:'\ud83d\udc70',fitzpatrick_scale:!0,category:"people"},man_in_tuxedo:{keywords:["couple","marriage","wedding","groom"],char:'\ud83e\udd35',fitzpatrick_scale:!0,category:"people"},running_woman:{keywords:["woman","walking","exercise","race","running","female"],char:'\ud83c\udfc3\u200d\u2640\ufe0f',fitzpatrick_scale:!0,category:"people"},running_man:{keywords:["man","walking","exercise","race","running"],char:'\ud83c\udfc3',fitzpatrick_scale:!0,category:"people"},walking_woman:{keywords:["human","feet","steps","woman","female"],char:'\ud83d\udeb6\u200d\u2640\ufe0f',fitzpatrick_scale:!0,category:"people"},walking_man:{keywords:["human","feet","steps"],char:'\ud83d\udeb6',fitzpatrick_scale:!0,category:"people"},dancer:{keywords:["female","girl","woman","fun"],char:'\ud83d\udc83',fitzpatrick_scale:!0,category:"people"},man_dancing:{keywords:["male","boy","fun","dancer"],char:'\ud83d\udd7a',fitzpatrick_scale:!0,category:"people"},dancing_women:{keywords:["female","bunny","women","girls"],char:'\ud83d\udc6f',fitzpatrick_scale:!1,category:"people"},dancing_men:{keywords:["male","bunny","men","boys"],char:'\ud83d\udc6f\u200d\u2642\ufe0f',fitzpatrick_scale:!1,category:"people"},couple:{keywords:["pair","people","human","love","date","dating","like","affection","valentines","marriage"],char:'\ud83d\udc6b',fitzpatrick_scale:!1,category:"people"},two_men_holding_hands:{keywords:["pair","couple","love","like","bromance","friendship","people","human"],char:'\ud83d\udc6c',fitzpatrick_scale:!1,category:"people"},two_women_holding_hands:{keywords:["pair","friendship","couple","love","like","female","people","human"],char:'\ud83d\udc6d',fitzpatrick_scale:!1,category:"people"},bowing_woman:{keywords:["woman","female","girl"],char:'\ud83d\ude47\u200d\u2640\ufe0f',fitzpatrick_scale:!0,category:"people"},bowing_man:{keywords:["man","male","boy"],char:'\ud83d\ude47',fitzpatrick_scale:!0,category:"people"},man_facepalming:{keywords:["man","male","boy","disbelief"],char:'\ud83e\udd26\u200d\u2642\ufe0f',fitzpatrick_scale:!0,category:"people"},woman_facepalming:{keywords:["woman","female","girl","disbelief"],char:'\ud83e\udd26\u200d\u2640\ufe0f',fitzpatrick_scale:!0,category:"people"},woman_shrugging:{keywords:["woman","female","girl","confused","indifferent","doubt"],char:'\ud83e\udd37',fitzpatrick_scale:!0,category:"people"},man_shrugging:{keywords:["man","male","boy","confused","indifferent","doubt"],char:'\ud83e\udd37\u200d\u2642\ufe0f',fitzpatrick_scale:!0,category:"people"},tipping_hand_woman:{keywords:["female","girl","woman","human","information"],char:'\ud83d\udc81',fitzpatrick_scale:!0,category:"people"},tipping_hand_man:{keywords:["male","boy","man","human","information"],char:'\ud83d\udc81\u200d\u2642\ufe0f',fitzpatrick_scale:!0,category:"people"},no_good_woman:{keywords:["female","girl","woman","nope"],char:'\ud83d\ude45',fitzpatrick_scale:!0,category:"people"},no_good_man:{keywords:["male","boy","man","nope"],char:'\ud83d\ude45\u200d\u2642\ufe0f',fitzpatrick_scale:!0,category:"people"},ok_woman:{keywords:["women","girl","female","pink","human","woman"],char:'\ud83d\ude46',fitzpatrick_scale:!0,category:"people"},ok_man:{keywords:["men","boy","male","blue","human","man"],char:'\ud83d\ude46\u200d\u2642\ufe0f',fitzpatrick_scale:!0,category:"people"},raising_hand_woman:{keywords:["female","girl","woman"],char:'\ud83d\ude4b',fitzpatrick_scale:!0,category:"people"},raising_hand_man:{keywords:["male","boy","man"],char:'\ud83d\ude4b\u200d\u2642\ufe0f',fitzpatrick_scale:!0,category:"people"},pouting_woman:{keywords:["female","girl","woman"],char:'\ud83d\ude4e',fitzpatrick_scale:!0,category:"people"},pouting_man:{keywords:["male","boy","man"],char:'\ud83d\ude4e\u200d\u2642\ufe0f',fitzpatrick_scale:!0,category:"people"},frowning_woman:{keywords:["female","girl","woman","sad","depressed","discouraged","unhappy"],char:'\ud83d\ude4d',fitzpatrick_scale:!0,category:"people"},frowning_man:{keywords:["male","boy","man","sad","depressed","discouraged","unhappy"],char:'\ud83d\ude4d\u200d\u2642\ufe0f',fitzpatrick_scale:!0,category:"people"},haircut_woman:{keywords:["female","girl","woman"],char:'\ud83d\udc87',fitzpatrick_scale:!0,category:"people"},haircut_man:{keywords:["male","boy","man"],char:'\ud83d\udc87\u200d\u2642\ufe0f',fitzpatrick_scale:!0,category:"people"},massage_woman:{keywords:["female","girl","woman","head"],char:'\ud83d\udc86',fitzpatrick_scale:!0,category:"people"},massage_man:{keywords:["male","boy","man","head"],char:'\ud83d\udc86\u200d\u2642\ufe0f',fitzpatrick_scale:!0,category:"people"},woman_in_steamy_room:{keywords:["female","woman","spa","steamroom","sauna"],char:'\ud83e\uddd6\u200d\u2640\ufe0f',fitzpatrick_scale:!0,category:"people"},man_in_steamy_room:{keywords:["male","man","spa","steamroom","sauna"],char:'\ud83e\uddd6\u200d\u2642\ufe0f',fitzpatrick_scale:!0,category:"people"},couple_with_heart_woman_man:{keywords:["pair","love","like","affection","human","dating","valentines","marriage"],char:'\ud83d\udc91',fitzpatrick_scale:!1,category:"people"},couple_with_heart_woman_woman:{keywords:["pair","love","like","affection","human","dating","valentines","marriage"],char:'\ud83d\udc69\u200d\u2764\ufe0f\u200d\ud83d\udc69',fitzpatrick_scale:!1,category:"people"},couple_with_heart_man_man:{keywords:["pair","love","like","affection","human","dating","valentines","marriage"],char:'\ud83d\udc68\u200d\u2764\ufe0f\u200d\ud83d\udc68',fitzpatrick_scale:!1,category:"people"},couplekiss_man_woman:{keywords:["pair","valentines","love","like","dating","marriage"],char:'\ud83d\udc8f',fitzpatrick_scale:!1,category:"people"},couplekiss_woman_woman:{keywords:["pair","valentines","love","like","dating","marriage"],char:'\ud83d\udc69\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc69',fitzpatrick_scale:!1,category:"people"},couplekiss_man_man:{keywords:["pair","valentines","love","like","dating","marriage"],char:'\ud83d\udc68\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68',fitzpatrick_scale:!1,category:"people"},family_man_woman_boy:{keywords:["home","parents","child","mom","dad","father","mother","people","human"],char:'\ud83d\udc6a',fitzpatrick_scale:!1,category:"people"},family_man_woman_girl:{keywords:["home","parents","people","human","child"],char:'\ud83d\udc68\u200d\ud83d\udc69\u200d\ud83d\udc67',fitzpatrick_scale:!1,category:"people"},family_man_woman_girl_boy:{keywords:["home","parents","people","human","children"],char:'\ud83d\udc68\u200d\ud83d\udc69\u200d\ud83d\udc67\u200d\ud83d\udc66',fitzpatrick_scale:!1,category:"people"},family_man_woman_boy_boy:{keywords:["home","parents","people","human","children"],char:'\ud83d\udc68\u200d\ud83d\udc69\u200d\ud83d\udc66\u200d\ud83d\udc66',fitzpatrick_scale:!1,category:"people"},family_man_woman_girl_girl:{keywords:["home","parents","people","human","children"],char:'\ud83d\udc68\u200d\ud83d\udc69\u200d\ud83d\udc67\u200d\ud83d\udc67',fitzpatrick_scale:!1,category:"people"},family_woman_woman_boy:{keywords:["home","parents","people","human","children"],char:'\ud83d\udc69\u200d\ud83d\udc69\u200d\ud83d\udc66',fitzpatrick_scale:!1,category:"people"},family_woman_woman_girl:{keywords:["home","parents","people","human","children"],char:'\ud83d\udc69\u200d\ud83d\udc69\u200d\ud83d\udc67',fitzpatrick_scale:!1,category:"people"},family_woman_woman_girl_boy:{keywords:["home","parents","people","human","children"],char:'\ud83d\udc69\u200d\ud83d\udc69\u200d\ud83d\udc67\u200d\ud83d\udc66',fitzpatrick_scale:!1,category:"people"},family_woman_woman_boy_boy:{keywords:["home","parents","people","human","children"],char:'\ud83d\udc69\u200d\ud83d\udc69\u200d\ud83d\udc66\u200d\ud83d\udc66',fitzpatrick_scale:!1,category:"people"},family_woman_woman_girl_girl:{keywords:["home","parents","people","human","children"],char:'\ud83d\udc69\u200d\ud83d\udc69\u200d\ud83d\udc67\u200d\ud83d\udc67',fitzpatrick_scale:!1,category:"people"},family_man_man_boy:{keywords:["home","parents","people","human","children"],char:'\ud83d\udc68\u200d\ud83d\udc68\u200d\ud83d\udc66',fitzpatrick_scale:!1,category:"people"},family_man_man_girl:{keywords:["home","parents","people","human","children"],char:'\ud83d\udc68\u200d\ud83d\udc68\u200d\ud83d\udc67',fitzpatrick_scale:!1,category:"people"},family_man_man_girl_boy:{keywords:["home","parents","people","human","children"],char:'\ud83d\udc68\u200d\ud83d\udc68\u200d\ud83d\udc67\u200d\ud83d\udc66',fitzpatrick_scale:!1,category:"people"},family_man_man_boy_boy:{keywords:["home","parents","people","human","children"],char:'\ud83d\udc68\u200d\ud83d\udc68\u200d\ud83d\udc66\u200d\ud83d\udc66',fitzpatrick_scale:!1,category:"people"},family_man_man_girl_girl:{keywords:["home","parents","people","human","children"],char:'\ud83d\udc68\u200d\ud83d\udc68\u200d\ud83d\udc67\u200d\ud83d\udc67',fitzpatrick_scale:!1,category:"people"},family_woman_boy:{keywords:["home","parent","people","human","child"],char:'\ud83d\udc69\u200d\ud83d\udc66',fitzpatrick_scale:!1,category:"people"},family_woman_girl:{keywords:["home","parent","people","human","child"],char:'\ud83d\udc69\u200d\ud83d\udc67',fitzpatrick_scale:!1,category:"people"},family_woman_girl_boy:{keywords:["home","parent","people","human","children"],char:'\ud83d\udc69\u200d\ud83d\udc67\u200d\ud83d\udc66',fitzpatrick_scale:!1,category:"people"},family_woman_boy_boy:{keywords:["home","parent","people","human","children"],char:'\ud83d\udc69\u200d\ud83d\udc66\u200d\ud83d\udc66',fitzpatrick_scale:!1,category:"people"},family_woman_girl_girl:{keywords:["home","parent","people","human","children"],char:'\ud83d\udc69\u200d\ud83d\udc67\u200d\ud83d\udc67',fitzpatrick_scale:!1,category:"people"},family_man_boy:{keywords:["home","parent","people","human","child"],char:'\ud83d\udc68\u200d\ud83d\udc66',fitzpatrick_scale:!1,category:"people"},family_man_girl:{keywords:["home","parent","people","human","child"],char:'\ud83d\udc68\u200d\ud83d\udc67',fitzpatrick_scale:!1,category:"people"},family_man_girl_boy:{keywords:["home","parent","people","human","children"],char:'\ud83d\udc68\u200d\ud83d\udc67\u200d\ud83d\udc66',fitzpatrick_scale:!1,category:"people"},family_man_boy_boy:{keywords:["home","parent","people","human","children"],char:'\ud83d\udc68\u200d\ud83d\udc66\u200d\ud83d\udc66',fitzpatrick_scale:!1,category:"people"},family_man_girl_girl:{keywords:["home","parent","people","human","children"],char:'\ud83d\udc68\u200d\ud83d\udc67\u200d\ud83d\udc67',fitzpatrick_scale:!1,category:"people"},yarn:{keywords:["ball","crochet","knit"],char:'\ud83e\uddf6',fitzpatrick_scale:!1,category:"people"},thread:{keywords:["needle","sewing","spool","string"],char:'\ud83e\uddf5',fitzpatrick_scale:!1,category:"people"},coat:{keywords:["jacket"],char:'\ud83e\udde5',fitzpatrick_scale:!1,category:"people"},labcoat:{keywords:["doctor","experiment","scientist","chemist"],char:'\ud83e\udd7c',fitzpatrick_scale:!1,category:"people"},womans_clothes:{keywords:["fashion","shopping_bags","female"],char:'\ud83d\udc5a',fitzpatrick_scale:!1,category:"people"},tshirt:{keywords:["fashion","cloth","casual","shirt","tee"],char:'\ud83d\udc55',fitzpatrick_scale:!1,category:"people"},jeans:{keywords:["fashion","shopping"],char:'\ud83d\udc56',fitzpatrick_scale:!1,category:"people"},necktie:{keywords:["shirt","suitup","formal","fashion","cloth","business"],char:'\ud83d\udc54',fitzpatrick_scale:!1,category:"people"},dress:{keywords:["clothes","fashion","shopping"],char:'\ud83d\udc57',fitzpatrick_scale:!1,category:"people"},bikini:{keywords:["swimming","female","woman","girl","fashion","beach","summer"],char:'\ud83d\udc59',fitzpatrick_scale:!1,category:"people"},kimono:{keywords:["dress","fashion","women","female","japanese"],char:'\ud83d\udc58',fitzpatrick_scale:!1,category:"people"},lipstick:{keywords:["female","girl","fashion","woman"],char:'\ud83d\udc84',fitzpatrick_scale:!1,category:"people"},kiss:{keywords:["face","lips","love","like","affection","valentines"],char:'\ud83d\udc8b',fitzpatrick_scale:!1,category:"people"},footprints:{keywords:["feet","tracking","walking","beach"],char:'\ud83d\udc63',fitzpatrick_scale:!1,category:"people"},flat_shoe:{keywords:["ballet","slip-on","slipper"],char:'\ud83e\udd7f',fitzpatrick_scale:!1,category:"people"},high_heel:{keywords:["fashion","shoes","female","pumps","stiletto"],char:'\ud83d\udc60',fitzpatrick_scale:!1,category:"people"},sandal:{keywords:["shoes","fashion","flip flops"],char:'\ud83d\udc61',fitzpatrick_scale:!1,category:"people"},boot:{keywords:["shoes","fashion"],char:'\ud83d\udc62',fitzpatrick_scale:!1,category:"people"},mans_shoe:{keywords:["fashion","male"],char:'\ud83d\udc5e',fitzpatrick_scale:!1,category:"people"},athletic_shoe:{keywords:["shoes","sports","sneakers"],char:'\ud83d\udc5f',fitzpatrick_scale:!1,category:"people"},hiking_boot:{keywords:["backpacking","camping","hiking"],char:'\ud83e\udd7e',fitzpatrick_scale:!1,category:"people"},socks:{keywords:["stockings","clothes"],char:'\ud83e\udde6',fitzpatrick_scale:!1,category:"people"},gloves:{keywords:["hands","winter","clothes"],char:'\ud83e\udde4',fitzpatrick_scale:!1,category:"people"},scarf:{keywords:["neck","winter","clothes"],char:'\ud83e\udde3',fitzpatrick_scale:!1,category:"people"},womans_hat:{keywords:["fashion","accessories","female","lady","spring"],char:'\ud83d\udc52',fitzpatrick_scale:!1,category:"people"},tophat:{keywords:["magic","gentleman","classy","circus"],char:'\ud83c\udfa9',fitzpatrick_scale:!1,category:"people"},billed_hat:{keywords:["cap","baseball"],char:'\ud83e\udde2',fitzpatrick_scale:!1,category:"people"},rescue_worker_helmet:{keywords:["construction","build"],char:'\u26d1',fitzpatrick_scale:!1,category:"people"},mortar_board:{keywords:["school","college","degree","university","graduation","cap","hat","legal","learn","education"],char:'\ud83c\udf93',fitzpatrick_scale:!1,category:"people"},crown:{keywords:["king","kod","leader","royalty","lord"],char:'\ud83d\udc51',fitzpatrick_scale:!1,category:"people"},school_satchel:{keywords:["student","education","bag","backpack"],char:'\ud83c\udf92',fitzpatrick_scale:!1,category:"people"},luggage:{keywords:["packing","travel"],char:'\ud83e\uddf3',fitzpatrick_scale:!1,category:"people"},pouch:{keywords:["bag","accessories","shopping"],char:'\ud83d\udc5d',fitzpatrick_scale:!1,category:"people"},purse:{keywords:["fashion","accessories","money","sales","shopping"],char:'\ud83d\udc5b',fitzpatrick_scale:!1,category:"people"},handbag:{keywords:["fashion","accessory","accessories","shopping"],char:'\ud83d\udc5c',fitzpatrick_scale:!1,category:"people"},briefcase:{keywords:["business","documents","work","law","legal","job","career"],char:'\ud83d\udcbc',fitzpatrick_scale:!1,category:"people"},eyeglasses:{keywords:["fashion","accessories","eyesight","nerdy","dork","geek"],char:'\ud83d\udc53',fitzpatrick_scale:!1,category:"people"},dark_sunglasses:{keywords:["face","cool","accessories"],char:'\ud83d\udd76',fitzpatrick_scale:!1,category:"people"},goggles:{keywords:["eyes","protection","safety"],char:'\ud83e\udd7d',fitzpatrick_scale:!1,category:"people"},ring:{keywords:["wedding","propose","marriage","valentines","diamond","fashion","jewelry","gem","engagement"],char:'\ud83d\udc8d',fitzpatrick_scale:!1,category:"people"},closed_umbrella:{keywords:["weather","rain","drizzle"],char:'\ud83c\udf02',fitzpatrick_scale:!1,category:"people"},dog:{keywords:["animal","friend","nature","woof","puppy","pet","faithful"],char:'\ud83d\udc36',fitzpatrick_scale:!1,category:"animals_and_nature"},cat:{keywords:["animal","meow","nature","pet","kitten"],char:'\ud83d\udc31',fitzpatrick_scale:!1,category:"animals_and_nature"},mouse:{keywords:["animal","nature","cheese_wedge","rodent"],char:'\ud83d\udc2d',fitzpatrick_scale:!1,category:"animals_and_nature"},hamster:{keywords:["animal","nature"],char:'\ud83d\udc39',fitzpatrick_scale:!1,category:"animals_and_nature"},rabbit:{keywords:["animal","nature","pet","spring","magic","bunny"],char:'\ud83d\udc30',fitzpatrick_scale:!1,category:"animals_and_nature"},fox_face:{keywords:["animal","nature","face"],char:'\ud83e\udd8a',fitzpatrick_scale:!1,category:"animals_and_nature"},bear:{keywords:["animal","nature","wild"],char:'\ud83d\udc3b',fitzpatrick_scale:!1,category:"animals_and_nature"},panda_face:{keywords:["animal","nature","panda"],char:'\ud83d\udc3c',fitzpatrick_scale:!1,category:"animals_and_nature"},koala:{keywords:["animal","nature"],char:'\ud83d\udc28',fitzpatrick_scale:!1,category:"animals_and_nature"},tiger:{keywords:["animal","cat","danger","wild","nature","roar"],char:'\ud83d\udc2f',fitzpatrick_scale:!1,category:"animals_and_nature"},lion:{keywords:["animal","nature"],char:'\ud83e\udd81',fitzpatrick_scale:!1,category:"animals_and_nature"},cow:{keywords:["beef","ox","animal","nature","moo","milk"],char:'\ud83d\udc2e',fitzpatrick_scale:!1,category:"animals_and_nature"},pig:{keywords:["animal","oink","nature"],char:'\ud83d\udc37',fitzpatrick_scale:!1,category:"animals_and_nature"},pig_nose:{keywords:["animal","oink"],char:'\ud83d\udc3d',fitzpatrick_scale:!1,category:"animals_and_nature"},frog:{keywords:["animal","nature","croak","toad"],char:'\ud83d\udc38',fitzpatrick_scale:!1,category:"animals_and_nature"},squid:{keywords:["animal","nature","ocean","sea"],char:'\ud83e\udd91',fitzpatrick_scale:!1,category:"animals_and_nature"},octopus:{keywords:["animal","creature","ocean","sea","nature","beach"],char:'\ud83d\udc19',fitzpatrick_scale:!1,category:"animals_and_nature"},shrimp:{keywords:["animal","ocean","nature","seafood"],char:'\ud83e\udd90',fitzpatrick_scale:!1,category:"animals_and_nature"},monkey_face:{keywords:["animal","nature","circus"],char:'\ud83d\udc35',fitzpatrick_scale:!1,category:"animals_and_nature"},gorilla:{keywords:["animal","nature","circus"],char:'\ud83e\udd8d',fitzpatrick_scale:!1,category:"animals_and_nature"},see_no_evil:{keywords:["monkey","animal","nature","haha"],char:'\ud83d\ude48',fitzpatrick_scale:!1,category:"animals_and_nature"},hear_no_evil:{keywords:["animal","monkey","nature"],char:'\ud83d\ude49',fitzpatrick_scale:!1,category:"animals_and_nature"},speak_no_evil:{keywords:["monkey","animal","nature","omg"],char:'\ud83d\ude4a',fitzpatrick_scale:!1,category:"animals_and_nature"},monkey:{keywords:["animal","nature","banana","circus"],char:'\ud83d\udc12',fitzpatrick_scale:!1,category:"animals_and_nature"},chicken:{keywords:["animal","cluck","nature","bird"],char:'\ud83d\udc14',fitzpatrick_scale:!1,category:"animals_and_nature"},penguin:{keywords:["animal","nature"],char:'\ud83d\udc27',fitzpatrick_scale:!1,category:"animals_and_nature"},bird:{keywords:["animal","nature","fly","tweet","spring"],char:'\ud83d\udc26',fitzpatrick_scale:!1,category:"animals_and_nature"},baby_chick:{keywords:["animal","chicken","bird"],char:'\ud83d\udc24',fitzpatrick_scale:!1,category:"animals_and_nature"},hatching_chick:{keywords:["animal","chicken","egg","born","baby","bird"],char:'\ud83d\udc23',fitzpatrick_scale:!1,category:"animals_and_nature"},hatched_chick:{keywords:["animal","chicken","baby","bird"],char:'\ud83d\udc25',fitzpatrick_scale:!1,category:"animals_and_nature"},duck:{keywords:["animal","nature","bird","mallard"],char:'\ud83e\udd86',fitzpatrick_scale:!1,category:"animals_and_nature"},eagle:{keywords:["animal","nature","bird"],char:'\ud83e\udd85',fitzpatrick_scale:!1,category:"animals_and_nature"},owl:{keywords:["animal","nature","bird","hoot"],char:'\ud83e\udd89',fitzpatrick_scale:!1,category:"animals_and_nature"},bat:{keywords:["animal","nature","blind","vampire"],char:'\ud83e\udd87',fitzpatrick_scale:!1,category:"animals_and_nature"},wolf:{keywords:["animal","nature","wild"],char:'\ud83d\udc3a',fitzpatrick_scale:!1,category:"animals_and_nature"},boar:{keywords:["animal","nature"],char:'\ud83d\udc17',fitzpatrick_scale:!1,category:"animals_and_nature"},horse:{keywords:["animal","brown","nature"],char:'\ud83d\udc34',fitzpatrick_scale:!1,category:"animals_and_nature"},unicorn:{keywords:["animal","nature","mystical"],char:'\ud83e\udd84',fitzpatrick_scale:!1,category:"animals_and_nature"},honeybee:{keywords:["animal","insect","nature","bug","spring","honey"],char:'\ud83d\udc1d',fitzpatrick_scale:!1,category:"animals_and_nature"},bug:{keywords:["animal","insect","nature","worm"],char:'\ud83d\udc1b',fitzpatrick_scale:!1,category:"animals_and_nature"},butterfly:{keywords:["animal","insect","nature","caterpillar"],char:'\ud83e\udd8b',fitzpatrick_scale:!1,category:"animals_and_nature"},snail:{keywords:["slow","animal","shell"],char:'\ud83d\udc0c',fitzpatrick_scale:!1,category:"animals_and_nature"},beetle:{keywords:["animal","insect","nature","ladybug"],char:'\ud83d\udc1e',fitzpatrick_scale:!1,category:"animals_and_nature"},ant:{keywords:["animal","insect","nature","bug"],char:'\ud83d\udc1c',fitzpatrick_scale:!1,category:"animals_and_nature"},grasshopper:{keywords:["animal","cricket","chirp"],char:'\ud83e\udd97',fitzpatrick_scale:!1,category:"animals_and_nature"},spider:{keywords:["animal","arachnid"],char:'\ud83d\udd77',fitzpatrick_scale:!1,category:"animals_and_nature"},scorpion:{keywords:["animal","arachnid"],char:'\ud83e\udd82',fitzpatrick_scale:!1,category:"animals_and_nature"},crab:{keywords:["animal","crustacean"],char:'\ud83e\udd80',fitzpatrick_scale:!1,category:"animals_and_nature"},snake:{keywords:["animal","evil","nature","hiss","python"],char:'\ud83d\udc0d',fitzpatrick_scale:!1,category:"animals_and_nature"},lizard:{keywords:["animal","nature","reptile"],char:'\ud83e\udd8e',fitzpatrick_scale:!1,category:"animals_and_nature"},"t-rex":{keywords:["animal","nature","dinosaur","tyrannosaurus","extinct"],char:'\ud83e\udd96',fitzpatrick_scale:!1,category:"animals_and_nature"},sauropod:{keywords:["animal","nature","dinosaur","brachiosaurus","brontosaurus","diplodocus","extinct"],char:'\ud83e\udd95',fitzpatrick_scale:!1,category:"animals_and_nature"},turtle:{keywords:["animal","slow","nature","tortoise"],char:'\ud83d\udc22',fitzpatrick_scale:!1,category:"animals_and_nature"},tropical_fish:{keywords:["animal","swim","ocean","beach","nemo"],char:'\ud83d\udc20',fitzpatrick_scale:!1,category:"animals_and_nature"},fish:{keywords:["animal","food","nature"],char:'\ud83d\udc1f',fitzpatrick_scale:!1,category:"animals_and_nature"},blowfish:{keywords:["animal","nature","food","sea","ocean"],char:'\ud83d\udc21',fitzpatrick_scale:!1,category:"animals_and_nature"},dolphin:{keywords:["animal","nature","fish","sea","ocean","flipper","fins","beach"],char:'\ud83d\udc2c',fitzpatrick_scale:!1,category:"animals_and_nature"},shark:{keywords:["animal","nature","fish","sea","ocean","jaws","fins","beach"],char:'\ud83e\udd88',fitzpatrick_scale:!1,category:"animals_and_nature"},whale:{keywords:["animal","nature","sea","ocean"],char:'\ud83d\udc33',fitzpatrick_scale:!1,category:"animals_and_nature"},whale2:{keywords:["animal","nature","sea","ocean"],char:'\ud83d\udc0b',fitzpatrick_scale:!1,category:"animals_and_nature"},crocodile:{keywords:["animal","nature","reptile","lizard","alligator"],char:'\ud83d\udc0a',fitzpatrick_scale:!1,category:"animals_and_nature"},leopard:{keywords:["animal","nature"],char:'\ud83d\udc06',fitzpatrick_scale:!1,category:"animals_and_nature"},zebra:{keywords:["animal","nature","stripes","safari"],char:'\ud83e\udd93',fitzpatrick_scale:!1,category:"animals_and_nature"},tiger2:{keywords:["animal","nature","roar"],char:'\ud83d\udc05',fitzpatrick_scale:!1,category:"animals_and_nature"},water_buffalo:{keywords:["animal","nature","ox","cow"],char:'\ud83d\udc03',fitzpatrick_scale:!1,category:"animals_and_nature"},ox:{keywords:["animal","cow","beef"],char:'\ud83d\udc02',fitzpatrick_scale:!1,category:"animals_and_nature"},cow2:{keywords:["beef","ox","animal","nature","moo","milk"],char:'\ud83d\udc04',fitzpatrick_scale:!1,category:"animals_and_nature"},deer:{keywords:["animal","nature","horns","venison"],char:'\ud83e\udd8c',fitzpatrick_scale:!1,category:"animals_and_nature"},dromedary_camel:{keywords:["animal","hot","desert","hump"],char:'\ud83d\udc2a',fitzpatrick_scale:!1,category:"animals_and_nature"},camel:{keywords:["animal","nature","hot","desert","hump"],char:'\ud83d\udc2b',fitzpatrick_scale:!1,category:"animals_and_nature"},giraffe:{keywords:["animal","nature","spots","safari"],char:'\ud83e\udd92',fitzpatrick_scale:!1,category:"animals_and_nature"},elephant:{keywords:["animal","nature","nose","th","circus"],char:'\ud83d\udc18',fitzpatrick_scale:!1,category:"animals_and_nature"},rhinoceros:{keywords:["animal","nature","horn"],char:'\ud83e\udd8f',fitzpatrick_scale:!1,category:"animals_and_nature"},goat:{keywords:["animal","nature"],char:'\ud83d\udc10',fitzpatrick_scale:!1,category:"animals_and_nature"},ram:{keywords:["animal","sheep","nature"],char:'\ud83d\udc0f',fitzpatrick_scale:!1,category:"animals_and_nature"},sheep:{keywords:["animal","nature","wool","shipit"],char:'\ud83d\udc11',fitzpatrick_scale:!1,category:"animals_and_nature"},racehorse:{keywords:["animal","gamble","luck"],char:'\ud83d\udc0e',fitzpatrick_scale:!1,category:"animals_and_nature"},pig2:{keywords:["animal","nature"],char:'\ud83d\udc16',fitzpatrick_scale:!1,category:"animals_and_nature"},rat:{keywords:["animal","mouse","rodent"],char:'\ud83d\udc00',fitzpatrick_scale:!1,category:"animals_and_nature"},mouse2:{keywords:["animal","nature","rodent"],char:'\ud83d\udc01',fitzpatrick_scale:!1,category:"animals_and_nature"},rooster:{keywords:["animal","nature","chicken"],char:'\ud83d\udc13',fitzpatrick_scale:!1,category:"animals_and_nature"},turkey:{keywords:["animal","bird"],char:'\ud83e\udd83',fitzpatrick_scale:!1,category:"animals_and_nature"},dove:{keywords:["animal","bird"],char:'\ud83d\udd4a',fitzpatrick_scale:!1,category:"animals_and_nature"},dog2:{keywords:["animal","nature","friend","doge","pet","faithful"],char:'\ud83d\udc15',fitzpatrick_scale:!1,category:"animals_and_nature"},poodle:{keywords:["dog","animal","101","nature","pet"],char:'\ud83d\udc29',fitzpatrick_scale:!1,category:"animals_and_nature"},cat2:{keywords:["animal","meow","pet","cats"],char:'\ud83d\udc08',fitzpatrick_scale:!1,category:"animals_and_nature"},rabbit2:{keywords:["animal","nature","pet","magic","spring"],char:'\ud83d\udc07',fitzpatrick_scale:!1,category:"animals_and_nature"},chipmunk:{keywords:["animal","nature","rodent","squirrel"],char:'\ud83d\udc3f',fitzpatrick_scale:!1,category:"animals_and_nature"},hedgehog:{keywords:["animal","nature","spiny"],char:'\ud83e\udd94',fitzpatrick_scale:!1,category:"animals_and_nature"},raccoon:{keywords:["animal","nature"],char:'\ud83e\udd9d',fitzpatrick_scale:!1,category:"animals_and_nature"},llama:{keywords:["animal","nature","alpaca"],char:'\ud83e\udd99',fitzpatrick_scale:!1,category:"animals_and_nature"},hippopotamus:{keywords:["animal","nature"],char:'\ud83e\udd9b',fitzpatrick_scale:!1,category:"animals_and_nature"},kangaroo:{keywords:["animal","nature","australia","joey","hop","marsupial"],char:'\ud83e\udd98',fitzpatrick_scale:!1,category:"animals_and_nature"},badger:{keywords:["animal","nature","honey"],char:'\ud83e\udda1',fitzpatrick_scale:!1,category:"animals_and_nature"},swan:{keywords:["animal","nature","bird"],char:'\ud83e\udda2',fitzpatrick_scale:!1,category:"animals_and_nature"},peacock:{keywords:["animal","nature","peahen","bird"],char:'\ud83e\udd9a',fitzpatrick_scale:!1,category:"animals_and_nature"},parrot:{keywords:["animal","nature","bird","pirate","talk"],char:'\ud83e\udd9c',fitzpatrick_scale:!1,category:"animals_and_nature"},lobster:{keywords:["animal","nature","bisque","claws","seafood"],char:'\ud83e\udd9e',fitzpatrick_scale:!1,category:"animals_and_nature"},mosquito:{keywords:["animal","nature","insect","malaria"],char:'\ud83e\udd9f',fitzpatrick_scale:!1,category:"animals_and_nature"},paw_prints:{keywords:["animal","tracking","footprints","dog","cat","pet","feet"],char:'\ud83d\udc3e',fitzpatrick_scale:!1,category:"animals_and_nature"},dragon:{keywords:["animal","myth","nature","chinese","green"],char:'\ud83d\udc09',fitzpatrick_scale:!1,category:"animals_and_nature"},dragon_face:{keywords:["animal","myth","nature","chinese","green"],char:'\ud83d\udc32',fitzpatrick_scale:!1,category:"animals_and_nature"},cactus:{keywords:["vegetable","plant","nature"],char:'\ud83c\udf35',fitzpatrick_scale:!1,category:"animals_and_nature"},christmas_tree:{keywords:["festival","vacation","december","xmas","celebration"],char:'\ud83c\udf84',fitzpatrick_scale:!1,category:"animals_and_nature"},evergreen_tree:{keywords:["plant","nature"],char:'\ud83c\udf32',fitzpatrick_scale:!1,category:"animals_and_nature"},deciduous_tree:{keywords:["plant","nature"],char:'\ud83c\udf33',fitzpatrick_scale:!1,category:"animals_and_nature"},palm_tree:{keywords:["plant","vegetable","nature","summer","beach","mojito","tropical"],char:'\ud83c\udf34',fitzpatrick_scale:!1,category:"animals_and_nature"},seedling:{keywords:["plant","nature","grass","lawn","spring"],char:'\ud83c\udf31',fitzpatrick_scale:!1,category:"animals_and_nature"},herb:{keywords:["vegetable","plant","medicine","weed","grass","lawn"],char:'\ud83c\udf3f',fitzpatrick_scale:!1,category:"animals_and_nature"},shamrock:{keywords:["vegetable","plant","nature","irish","clover"],char:'\u2618',fitzpatrick_scale:!1,category:"animals_and_nature"},four_leaf_clover:{keywords:["vegetable","plant","nature","lucky","irish"],char:'\ud83c\udf40',fitzpatrick_scale:!1,category:"animals_and_nature"},bamboo:{keywords:["plant","nature","vegetable","panda","pine_decoration"],char:'\ud83c\udf8d',fitzpatrick_scale:!1,category:"animals_and_nature"},tanabata_tree:{keywords:["plant","nature","branch","summer"],char:'\ud83c\udf8b',fitzpatrick_scale:!1,category:"animals_and_nature"},leaves:{keywords:["nature","plant","tree","vegetable","grass","lawn","spring"],char:'\ud83c\udf43',fitzpatrick_scale:!1,category:"animals_and_nature"},fallen_leaf:{keywords:["nature","plant","vegetable","leaves"],char:'\ud83c\udf42',fitzpatrick_scale:!1,category:"animals_and_nature"},maple_leaf:{keywords:["nature","plant","vegetable","ca","fall"],char:'\ud83c\udf41',fitzpatrick_scale:!1,category:"animals_and_nature"},ear_of_rice:{keywords:["nature","plant"],char:'\ud83c\udf3e',fitzpatrick_scale:!1,category:"animals_and_nature"},hibiscus:{keywords:["plant","vegetable","flowers","beach"],char:'\ud83c\udf3a',fitzpatrick_scale:!1,category:"animals_and_nature"},sunflower:{keywords:["nature","plant","fall"],char:'\ud83c\udf3b',fitzpatrick_scale:!1,category:"animals_and_nature"},rose:{keywords:["flowers","valentines","love","spring"],char:'\ud83c\udf39',fitzpatrick_scale:!1,category:"animals_and_nature"},wilted_flower:{keywords:["plant","nature","flower"],char:'\ud83e\udd40',fitzpatrick_scale:!1,category:"animals_and_nature"},tulip:{keywords:["flowers","plant","nature","summer","spring"],char:'\ud83c\udf37',fitzpatrick_scale:!1,category:"animals_and_nature"},blossom:{keywords:["nature","flowers","yellow"],char:'\ud83c\udf3c',fitzpatrick_scale:!1,category:"animals_and_nature"},cherry_blossom:{keywords:["nature","plant","spring","flower"],char:'\ud83c\udf38',fitzpatrick_scale:!1,category:"animals_and_nature"},bouquet:{keywords:["flowers","nature","spring"],char:'\ud83d\udc90',fitzpatrick_scale:!1,category:"animals_and_nature"},mushroom:{keywords:["plant","vegetable"],char:'\ud83c\udf44',fitzpatrick_scale:!1,category:"animals_and_nature"},chestnut:{keywords:["food","squirrel"],char:'\ud83c\udf30',fitzpatrick_scale:!1,category:"animals_and_nature"},jack_o_lantern:{keywords:["halloween","light","pumpkin","creepy","fall"],char:'\ud83c\udf83',fitzpatrick_scale:!1,category:"animals_and_nature"},shell:{keywords:["nature","sea","beach"],char:'\ud83d\udc1a',fitzpatrick_scale:!1,category:"animals_and_nature"},spider_web:{keywords:["animal","insect","arachnid","silk"],char:'\ud83d\udd78',fitzpatrick_scale:!1,category:"animals_and_nature"},earth_americas:{keywords:["globe","world","USA","international"],char:'\ud83c\udf0e',fitzpatrick_scale:!1,category:"animals_and_nature"},earth_africa:{keywords:["globe","world","international"],char:'\ud83c\udf0d',fitzpatrick_scale:!1,category:"animals_and_nature"},earth_asia:{keywords:["globe","world","east","international"],char:'\ud83c\udf0f',fitzpatrick_scale:!1,category:"animals_and_nature"},full_moon:{keywords:["nature","yellow","twilight","planet","space","night","evening","sleep"],char:'\ud83c\udf15',fitzpatrick_scale:!1,category:"animals_and_nature"},waning_gibbous_moon:{keywords:["nature","twilight","planet","space","night","evening","sleep","waxing_gibbous_moon"],char:'\ud83c\udf16',fitzpatrick_scale:!1,category:"animals_and_nature"},last_quarter_moon:{keywords:["nature","twilight","planet","space","night","evening","sleep"],char:'\ud83c\udf17',fitzpatrick_scale:!1,category:"animals_and_nature"},waning_crescent_moon:{keywords:["nature","twilight","planet","space","night","evening","sleep"],char:'\ud83c\udf18',fitzpatrick_scale:!1,category:"animals_and_nature"},new_moon:{keywords:["nature","twilight","planet","space","night","evening","sleep"],char:'\ud83c\udf11',fitzpatrick_scale:!1,category:"animals_and_nature"},waxing_crescent_moon:{keywords:["nature","twilight","planet","space","night","evening","sleep"],char:'\ud83c\udf12',fitzpatrick_scale:!1,category:"animals_and_nature"},first_quarter_moon:{keywords:["nature","twilight","planet","space","night","evening","sleep"],char:'\ud83c\udf13',fitzpatrick_scale:!1,category:"animals_and_nature"},waxing_gibbous_moon:{keywords:["nature","night","sky","gray","twilight","planet","space","evening","sleep"],char:'\ud83c\udf14',fitzpatrick_scale:!1,category:"animals_and_nature"},new_moon_with_face:{keywords:["nature","twilight","planet","space","night","evening","sleep"],char:'\ud83c\udf1a',fitzpatrick_scale:!1,category:"animals_and_nature"},full_moon_with_face:{keywords:["nature","twilight","planet","space","night","evening","sleep"],char:'\ud83c\udf1d',fitzpatrick_scale:!1,category:"animals_and_nature"},first_quarter_moon_with_face:{keywords:["nature","twilight","planet","space","night","evening","sleep"],char:'\ud83c\udf1b',fitzpatrick_scale:!1,category:"animals_and_nature"},last_quarter_moon_with_face:{keywords:["nature","twilight","planet","space","night","evening","sleep"],char:'\ud83c\udf1c',fitzpatrick_scale:!1,category:"animals_and_nature"},sun_with_face:{keywords:["nature","morning","sky"],char:'\ud83c\udf1e',fitzpatrick_scale:!1,category:"animals_and_nature"},crescent_moon:{keywords:["night","sleep","sky","evening","magic"],char:'\ud83c\udf19',fitzpatrick_scale:!1,category:"animals_and_nature"},star:{keywords:["night","yellow"],char:'\u2b50',fitzpatrick_scale:!1,category:"animals_and_nature"},star2:{keywords:["night","sparkle","awesome","good","magic"],char:'\ud83c\udf1f',fitzpatrick_scale:!1,category:"animals_and_nature"},dizzy:{keywords:["star","sparkle","shoot","magic"],char:'\ud83d\udcab',fitzpatrick_scale:!1,category:"animals_and_nature"},sparkles:{keywords:["stars","shine","shiny","cool","awesome","good","magic"],char:'\u2728',fitzpatrick_scale:!1,category:"animals_and_nature"},comet:{keywords:["space"],char:'\u2604',fitzpatrick_scale:!1,category:"animals_and_nature"},sunny:{keywords:["weather","nature","brightness","summer","beach","spring"],char:'\u2600\ufe0f',fitzpatrick_scale:!1,category:"animals_and_nature"},sun_behind_small_cloud:{keywords:["weather"],char:'\ud83c\udf24',fitzpatrick_scale:!1,category:"animals_and_nature"},partly_sunny:{keywords:["weather","nature","cloudy","morning","fall","spring"],char:'\u26c5',fitzpatrick_scale:!1,category:"animals_and_nature"},sun_behind_large_cloud:{keywords:["weather"],char:'\ud83c\udf25',fitzpatrick_scale:!1,category:"animals_and_nature"},sun_behind_rain_cloud:{keywords:["weather"],char:'\ud83c\udf26',fitzpatrick_scale:!1,category:"animals_and_nature"},cloud:{keywords:["weather","sky"],char:'\u2601\ufe0f',fitzpatrick_scale:!1,category:"animals_and_nature"},cloud_with_rain:{keywords:["weather"],char:'\ud83c\udf27',fitzpatrick_scale:!1,category:"animals_and_nature"},cloud_with_lightning_and_rain:{keywords:["weather","lightning"],char:'\u26c8',fitzpatrick_scale:!1,category:"animals_and_nature"},cloud_with_lightning:{keywords:["weather","thunder"],char:'\ud83c\udf29',fitzpatrick_scale:!1,category:"animals_and_nature"},zap:{keywords:["thunder","weather","lightning bolt","fast"],char:'\u26a1',fitzpatrick_scale:!1,category:"animals_and_nature"},fire:{keywords:["hot","cook","flame"],char:'\ud83d\udd25',fitzpatrick_scale:!1,category:"animals_and_nature"},boom:{keywords:["bomb","explode","explosion","collision","blown"],char:'\ud83d\udca5',fitzpatrick_scale:!1,category:"animals_and_nature"},snowflake:{keywords:["winter","season","cold","weather","christmas","xmas"],char:'\u2744\ufe0f',fitzpatrick_scale:!1,category:"animals_and_nature"},cloud_with_snow:{keywords:["weather"],char:'\ud83c\udf28',fitzpatrick_scale:!1,category:"animals_and_nature"},snowman:{keywords:["winter","season","cold","weather","christmas","xmas","frozen","without_snow"],char:'\u26c4',fitzpatrick_scale:!1,category:"animals_and_nature"},snowman_with_snow:{keywords:["winter","season","cold","weather","christmas","xmas","frozen"],char:'\u2603',fitzpatrick_scale:!1,category:"animals_and_nature"},wind_face:{keywords:["gust","air"],char:'\ud83c\udf2c',fitzpatrick_scale:!1,category:"animals_and_nature"},dash:{keywords:["wind","air","fast","shoo","fart","smoke","puff"],char:'\ud83d\udca8',fitzpatrick_scale:!1,category:"animals_and_nature"},tornado:{keywords:["weather","cyclone","twister"],char:'\ud83c\udf2a',fitzpatrick_scale:!1,category:"animals_and_nature"},fog:{keywords:["weather"],char:'\ud83c\udf2b',fitzpatrick_scale:!1,category:"animals_and_nature"},open_umbrella:{keywords:["weather","spring"],char:'\u2602',fitzpatrick_scale:!1,category:"animals_and_nature"},umbrella:{keywords:["rainy","weather","spring"],char:'\u2614',fitzpatrick_scale:!1,category:"animals_and_nature"},droplet:{keywords:["water","drip","faucet","spring"],char:'\ud83d\udca7',fitzpatrick_scale:!1,category:"animals_and_nature"},sweat_drops:{keywords:["water","drip","oops"],char:'\ud83d\udca6',fitzpatrick_scale:!1,category:"animals_and_nature"},ocean:{keywords:["sea","water","wave","nature","tsunami","disaster"],char:'\ud83c\udf0a',fitzpatrick_scale:!1,category:"animals_and_nature"},green_apple:{keywords:["fruit","nature"],char:'\ud83c\udf4f',fitzpatrick_scale:!1,category:"food_and_drink"},apple:{keywords:["fruit","mac","school"],char:'\ud83c\udf4e',fitzpatrick_scale:!1,category:"food_and_drink"},pear:{keywords:["fruit","nature","food"],char:'\ud83c\udf50',fitzpatrick_scale:!1,category:"food_and_drink"},tangerine:{keywords:["food","fruit","nature","orange"],char:'\ud83c\udf4a',fitzpatrick_scale:!1,category:"food_and_drink"},lemon:{keywords:["fruit","nature"],char:'\ud83c\udf4b',fitzpatrick_scale:!1,category:"food_and_drink"},banana:{keywords:["fruit","food","monkey"],char:'\ud83c\udf4c',fitzpatrick_scale:!1,category:"food_and_drink"},watermelon:{keywords:["fruit","food","picnic","summer"],char:'\ud83c\udf49',fitzpatrick_scale:!1,category:"food_and_drink"},grapes:{keywords:["fruit","food","wine"],char:'\ud83c\udf47',fitzpatrick_scale:!1,category:"food_and_drink"},strawberry:{keywords:["fruit","food","nature"],char:'\ud83c\udf53',fitzpatrick_scale:!1,category:"food_and_drink"},melon:{keywords:["fruit","nature","food"],char:'\ud83c\udf48',fitzpatrick_scale:!1,category:"food_and_drink"},cherries:{keywords:["food","fruit"],char:'\ud83c\udf52',fitzpatrick_scale:!1,category:"food_and_drink"},peach:{keywords:["fruit","nature","food"],char:'\ud83c\udf51',fitzpatrick_scale:!1,category:"food_and_drink"},pineapple:{keywords:["fruit","nature","food"],char:'\ud83c\udf4d',fitzpatrick_scale:!1,category:"food_and_drink"},coconut:{keywords:["fruit","nature","food","palm"],char:'\ud83e\udd65',fitzpatrick_scale:!1,category:"food_and_drink"},kiwi_fruit:{keywords:["fruit","food"],char:'\ud83e\udd5d',fitzpatrick_scale:!1,category:"food_and_drink"},mango:{keywords:["fruit","food","tropical"],char:'\ud83e\udd6d',fitzpatrick_scale:!1,category:"food_and_drink"},avocado:{keywords:["fruit","food"],char:'\ud83e\udd51',fitzpatrick_scale:!1,category:"food_and_drink"},broccoli:{keywords:["fruit","food","vegetable"],char:'\ud83e\udd66',fitzpatrick_scale:!1,category:"food_and_drink"},tomato:{keywords:["fruit","vegetable","nature","food"],char:'\ud83c\udf45',fitzpatrick_scale:!1,category:"food_and_drink"},eggplant:{keywords:["vegetable","nature","food","aubergine"],char:'\ud83c\udf46',fitzpatrick_scale:!1,category:"food_and_drink"},cucumber:{keywords:["fruit","food","pickle"],char:'\ud83e\udd52',fitzpatrick_scale:!1,category:"food_and_drink"},carrot:{keywords:["vegetable","food","orange"],char:'\ud83e\udd55',fitzpatrick_scale:!1,category:"food_and_drink"},hot_pepper:{keywords:["food","spicy","chilli","chili"],char:'\ud83c\udf36',fitzpatrick_scale:!1,category:"food_and_drink"},potato:{keywords:["food","tuber","vegatable","starch"],char:'\ud83e\udd54',fitzpatrick_scale:!1,category:"food_and_drink"},corn:{keywords:["food","vegetable","plant"],char:'\ud83c\udf3d',fitzpatrick_scale:!1,category:"food_and_drink"},leafy_greens:{keywords:["food","vegetable","plant","bok choy","cabbage","kale","lettuce"],char:'\ud83e\udd6c',fitzpatrick_scale:!1,category:"food_and_drink"},sweet_potato:{keywords:["food","nature"],char:'\ud83c\udf60',fitzpatrick_scale:!1,category:"food_and_drink"},peanuts:{keywords:["food","nut"],char:'\ud83e\udd5c',fitzpatrick_scale:!1,category:"food_and_drink"},honey_pot:{keywords:["bees","sweet","kitchen"],char:'\ud83c\udf6f',fitzpatrick_scale:!1,category:"food_and_drink"},croissant:{keywords:["food","bread","french"],char:'\ud83e\udd50',fitzpatrick_scale:!1,category:"food_and_drink"},bread:{keywords:["food","wheat","breakfast","toast"],char:'\ud83c\udf5e',fitzpatrick_scale:!1,category:"food_and_drink"},baguette_bread:{keywords:["food","bread","french"],char:'\ud83e\udd56',fitzpatrick_scale:!1,category:"food_and_drink"},bagel:{keywords:["food","bread","bakery","schmear"],char:'\ud83e\udd6f',fitzpatrick_scale:!1,category:"food_and_drink"},pretzel:{keywords:["food","bread","twisted"],char:'\ud83e\udd68',fitzpatrick_scale:!1,category:"food_and_drink"},cheese:{keywords:["food","chadder"],char:'\ud83e\uddc0',fitzpatrick_scale:!1,category:"food_and_drink"},egg:{keywords:["food","chicken","breakfast"],char:'\ud83e\udd5a',fitzpatrick_scale:!1,category:"food_and_drink"},bacon:{keywords:["food","breakfast","pork","pig","meat"],char:'\ud83e\udd53',fitzpatrick_scale:!1,category:"food_and_drink"},steak:{keywords:["food","cow","meat","cut","chop","lambchop","porkchop"],char:'\ud83e\udd69',fitzpatrick_scale:!1,category:"food_and_drink"},pancakes:{keywords:["food","breakfast","flapjacks","hotcakes"],char:'\ud83e\udd5e',fitzpatrick_scale:!1,category:"food_and_drink"},poultry_leg:{keywords:["food","meat","drumstick","bird","chicken","turkey"],char:'\ud83c\udf57',fitzpatrick_scale:!1,category:"food_and_drink"},meat_on_bone:{keywords:["good","food","drumstick"],char:'\ud83c\udf56',fitzpatrick_scale:!1,category:"food_and_drink"},bone:{keywords:["skeleton"],char:'\ud83e\uddb4',fitzpatrick_scale:!1,category:"food_and_drink"},fried_shrimp:{keywords:["food","animal","appetizer","summer"],char:'\ud83c\udf64',fitzpatrick_scale:!1,category:"food_and_drink"},fried_egg:{keywords:["food","breakfast","kitchen","egg"],char:'\ud83c\udf73',fitzpatrick_scale:!1,category:"food_and_drink"},hamburger:{keywords:["meat","fast food","beef","cheeseburger","mcdonalds","burger king"],char:'\ud83c\udf54',fitzpatrick_scale:!1,category:"food_and_drink"},fries:{keywords:["chips","snack","fast food"],char:'\ud83c\udf5f',fitzpatrick_scale:!1,category:"food_and_drink"},stuffed_flatbread:{keywords:["food","flatbread","stuffed","gyro"],char:'\ud83e\udd59',fitzpatrick_scale:!1,category:"food_and_drink"},hotdog:{keywords:["food","frankfurter"],char:'\ud83c\udf2d',fitzpatrick_scale:!1,category:"food_and_drink"},pizza:{keywords:["food","party"],char:'\ud83c\udf55',fitzpatrick_scale:!1,category:"food_and_drink"},sandwich:{keywords:["food","lunch","bread"],char:'\ud83e\udd6a',fitzpatrick_scale:!1,category:"food_and_drink"},canned_food:{keywords:["food","soup"],char:'\ud83e\udd6b',fitzpatrick_scale:!1,category:"food_and_drink"},spaghetti:{keywords:["food","italian","noodle"],char:'\ud83c\udf5d',fitzpatrick_scale:!1,category:"food_and_drink"},taco:{keywords:["food","mexican"],char:'\ud83c\udf2e',fitzpatrick_scale:!1,category:"food_and_drink"},burrito:{keywords:["food","mexican"],char:'\ud83c\udf2f',fitzpatrick_scale:!1,category:"food_and_drink"},green_salad:{keywords:["food","healthy","lettuce"],char:'\ud83e\udd57',fitzpatrick_scale:!1,category:"food_and_drink"},shallow_pan_of_food:{keywords:["food","cooking","casserole","paella"],char:'\ud83e\udd58',fitzpatrick_scale:!1,category:"food_and_drink"},ramen:{keywords:["food","japanese","noodle","chopsticks"],char:'\ud83c\udf5c',fitzpatrick_scale:!1,category:"food_and_drink"},stew:{keywords:["food","meat","soup"],char:'\ud83c\udf72',fitzpatrick_scale:!1,category:"food_and_drink"},fish_cake:{keywords:["food","japan","sea","beach","narutomaki","pink","swirl","kamaboko","surimi","ramen"],char:'\ud83c\udf65',fitzpatrick_scale:!1,category:"food_and_drink"},fortune_cookie:{keywords:["food","prophecy"],char:'\ud83e\udd60',fitzpatrick_scale:!1,category:"food_and_drink"},sushi:{keywords:["food","fish","japanese","rice"],char:'\ud83c\udf63',fitzpatrick_scale:!1,category:"food_and_drink"},bento:{keywords:["food","japanese","box"],char:'\ud83c\udf71',fitzpatrick_scale:!1,category:"food_and_drink"},curry:{keywords:["food","spicy","hot","indian"],char:'\ud83c\udf5b',fitzpatrick_scale:!1,category:"food_and_drink"},rice_ball:{keywords:["food","japanese"],char:'\ud83c\udf59',fitzpatrick_scale:!1,category:"food_and_drink"},rice:{keywords:["food","china","asian"],char:'\ud83c\udf5a',fitzpatrick_scale:!1,category:"food_and_drink"},rice_cracker:{keywords:["food","japanese"],char:'\ud83c\udf58',fitzpatrick_scale:!1,category:"food_and_drink"},oden:{keywords:["food","japanese"],char:'\ud83c\udf62',fitzpatrick_scale:!1,category:"food_and_drink"},dango:{keywords:["food","dessert","sweet","japanese","barbecue","meat"],char:'\ud83c\udf61',fitzpatrick_scale:!1,category:"food_and_drink"},shaved_ice:{keywords:["hot","dessert","summer"],char:'\ud83c\udf67',fitzpatrick_scale:!1,category:"food_and_drink"},ice_cream:{keywords:["food","hot","dessert"],char:'\ud83c\udf68',fitzpatrick_scale:!1,category:"food_and_drink"},icecream:{keywords:["food","hot","dessert","summer"],char:'\ud83c\udf66',fitzpatrick_scale:!1,category:"food_and_drink"},pie:{keywords:["food","dessert","pastry"],char:'\ud83e\udd67',fitzpatrick_scale:!1,category:"food_and_drink"},cake:{keywords:["food","dessert"],char:'\ud83c\udf70',fitzpatrick_scale:!1,category:"food_and_drink"},cupcake:{keywords:["food","dessert","bakery","sweet"],char:'\ud83e\uddc1',fitzpatrick_scale:!1,category:"food_and_drink"},moon_cake:{keywords:["food","autumn"],char:'\ud83e\udd6e',fitzpatrick_scale:!1,category:"food_and_drink"},birthday:{keywords:["food","dessert","cake"],char:'\ud83c\udf82',fitzpatrick_scale:!1,category:"food_and_drink"},custard:{keywords:["dessert","food"],char:'\ud83c\udf6e',fitzpatrick_scale:!1,category:"food_and_drink"},candy:{keywords:["snack","dessert","sweet","lolly"],char:'\ud83c\udf6c',fitzpatrick_scale:!1,category:"food_and_drink"},lollipop:{keywords:["food","snack","candy","sweet"],char:'\ud83c\udf6d',fitzpatrick_scale:!1,category:"food_and_drink"},chocolate_bar:{keywords:["food","snack","dessert","sweet"],char:'\ud83c\udf6b',fitzpatrick_scale:!1,category:"food_and_drink"},popcorn:{keywords:["food","movie theater","films","snack"],char:'\ud83c\udf7f',fitzpatrick_scale:!1,category:"food_and_drink"},dumpling:{keywords:["food","empanada","pierogi","potsticker"],char:'\ud83e\udd5f',fitzpatrick_scale:!1,category:"food_and_drink"},doughnut:{keywords:["food","dessert","snack","sweet","donut"],char:'\ud83c\udf69',fitzpatrick_scale:!1,category:"food_and_drink"},cookie:{keywords:["food","snack","oreo","chocolate","sweet","dessert"],char:'\ud83c\udf6a',fitzpatrick_scale:!1,category:"food_and_drink"},milk_glass:{keywords:["beverage","drink","cow"],char:'\ud83e\udd5b',fitzpatrick_scale:!1,category:"food_and_drink"},beer:{keywords:["relax","beverage","drink","drunk","party","pub","summer","alcohol","booze"],char:'\ud83c\udf7a',fitzpatrick_scale:!1,category:"food_and_drink"},beers:{keywords:["relax","beverage","drink","drunk","party","pub","summer","alcohol","booze"],char:'\ud83c\udf7b',fitzpatrick_scale:!1,category:"food_and_drink"},clinking_glasses:{keywords:["beverage","drink","party","alcohol","celebrate","cheers","wine","champagne","toast"],char:'\ud83e\udd42',fitzpatrick_scale:!1,category:"food_and_drink"},wine_glass:{keywords:["drink","beverage","drunk","alcohol","booze"],char:'\ud83c\udf77',fitzpatrick_scale:!1,category:"food_and_drink"},tumbler_glass:{keywords:["drink","beverage","drunk","alcohol","liquor","booze","bourbon","scotch","whisky","glass","shot"],char:'\ud83e\udd43',fitzpatrick_scale:!1,category:"food_and_drink"},cocktail:{keywords:["drink","drunk","alcohol","beverage","booze","mojito"],char:'\ud83c\udf78',fitzpatrick_scale:!1,category:"food_and_drink"},tropical_drink:{keywords:["beverage","cocktail","summer","beach","alcohol","booze","mojito"],char:'\ud83c\udf79',fitzpatrick_scale:!1,category:"food_and_drink"},champagne:{keywords:["drink","wine","bottle","celebration"],char:'\ud83c\udf7e',fitzpatrick_scale:!1,category:"food_and_drink"},sake:{keywords:["wine","drink","drunk","beverage","japanese","alcohol","booze"],char:'\ud83c\udf76',fitzpatrick_scale:!1,category:"food_and_drink"},tea:{keywords:["drink","bowl","breakfast","green","british"],char:'\ud83c\udf75',fitzpatrick_scale:!1,category:"food_and_drink"},cup_with_straw:{keywords:["drink","soda"],char:'\ud83e\udd64',fitzpatrick_scale:!1,category:"food_and_drink"},coffee:{keywords:["beverage","caffeine","latte","espresso"],char:'\u2615',fitzpatrick_scale:!1,category:"food_and_drink"},baby_bottle:{keywords:["food","container","milk"],char:'\ud83c\udf7c',fitzpatrick_scale:!1,category:"food_and_drink"},salt:{keywords:["condiment","shaker"],char:'\ud83e\uddc2',fitzpatrick_scale:!1,category:"food_and_drink"},spoon:{keywords:["cutlery","kitchen","tableware"],char:'\ud83e\udd44',fitzpatrick_scale:!1,category:"food_and_drink"},fork_and_knife:{keywords:["cutlery","kitchen"],char:'\ud83c\udf74',fitzpatrick_scale:!1,category:"food_and_drink"},plate_with_cutlery:{keywords:["food","eat","meal","lunch","dinner","restaurant"],char:'\ud83c\udf7d',fitzpatrick_scale:!1,category:"food_and_drink"},bowl_with_spoon:{keywords:["food","breakfast","cereal","oatmeal","porridge"],char:'\ud83e\udd63',fitzpatrick_scale:!1,category:"food_and_drink"},takeout_box:{keywords:["food","leftovers"],char:'\ud83e\udd61',fitzpatrick_scale:!1,category:"food_and_drink"},chopsticks:{keywords:["food"],char:'\ud83e\udd62',fitzpatrick_scale:!1,category:"food_and_drink"},soccer:{keywords:["sports","football"],char:'\u26bd',fitzpatrick_scale:!1,category:"activity"},basketball:{keywords:["sports","balls","NBA"],char:'\ud83c\udfc0',fitzpatrick_scale:!1,category:"activity"},football:{keywords:["sports","balls","NFL"],char:'\ud83c\udfc8',fitzpatrick_scale:!1,category:"activity"},baseball:{keywords:["sports","balls"],char:'\u26be',fitzpatrick_scale:!1,category:"activity"},softball:{keywords:["sports","balls"],char:'\ud83e\udd4e',fitzpatrick_scale:!1,category:"activity"},tennis:{keywords:["sports","balls","green"],char:'\ud83c\udfbe',fitzpatrick_scale:!1,category:"activity"},volleyball:{keywords:["sports","balls"],char:'\ud83c\udfd0',fitzpatrick_scale:!1,category:"activity"},rugby_football:{keywords:["sports","team"],char:'\ud83c\udfc9',fitzpatrick_scale:!1,category:"activity"},flying_disc:{keywords:["sports","frisbee","ultimate"],char:'\ud83e\udd4f',fitzpatrick_scale:!1,category:"activity"},"8ball":{keywords:["pool","hobby","game","luck","magic"],char:'\ud83c\udfb1',fitzpatrick_scale:!1,category:"activity"},golf:{keywords:["sports","business","flag","hole","summer"],char:'\u26f3',fitzpatrick_scale:!1,category:"activity"},golfing_woman:{keywords:["sports","business","woman","female"],char:'\ud83c\udfcc\ufe0f\u200d\u2640\ufe0f',fitzpatrick_scale:!1,category:"activity"},golfing_man:{keywords:["sports","business"],char:'\ud83c\udfcc',fitzpatrick_scale:!0,category:"activity"},ping_pong:{keywords:["sports","pingpong"],char:'\ud83c\udfd3',fitzpatrick_scale:!1,category:"activity"},badminton:{keywords:["sports"],char:'\ud83c\udff8',fitzpatrick_scale:!1,category:"activity"},goal_net:{keywords:["sports"],char:'\ud83e\udd45',fitzpatrick_scale:!1,category:"activity"},ice_hockey:{keywords:["sports"],char:'\ud83c\udfd2',fitzpatrick_scale:!1,category:"activity"},field_hockey:{keywords:["sports"],char:'\ud83c\udfd1',fitzpatrick_scale:!1,category:"activity"},lacrosse:{keywords:["sports","ball","stick"],char:'\ud83e\udd4d',fitzpatrick_scale:!1,category:"activity"},cricket:{keywords:["sports"],char:'\ud83c\udfcf',fitzpatrick_scale:!1,category:"activity"},ski:{keywords:["sports","winter","cold","snow"],char:'\ud83c\udfbf',fitzpatrick_scale:!1,category:"activity"},skier:{keywords:["sports","winter","snow"],char:'\u26f7',fitzpatrick_scale:!1,category:"activity"},snowboarder:{keywords:["sports","winter"],char:'\ud83c\udfc2',fitzpatrick_scale:!0,category:"activity"},person_fencing:{keywords:["sports","fencing","sword"],char:'\ud83e\udd3a',fitzpatrick_scale:!1,category:"activity"},women_wrestling:{keywords:["sports","wrestlers"],char:'\ud83e\udd3c\u200d\u2640\ufe0f',fitzpatrick_scale:!1,category:"activity"},men_wrestling:{keywords:["sports","wrestlers"],char:'\ud83e\udd3c\u200d\u2642\ufe0f',fitzpatrick_scale:!1,category:"activity"},woman_cartwheeling:{keywords:["gymnastics"],char:'\ud83e\udd38\u200d\u2640\ufe0f',fitzpatrick_scale:!0,category:"activity"},man_cartwheeling:{keywords:["gymnastics"],char:'\ud83e\udd38\u200d\u2642\ufe0f',fitzpatrick_scale:!0,category:"activity"},woman_playing_handball:{keywords:["sports"],char:'\ud83e\udd3e\u200d\u2640\ufe0f',fitzpatrick_scale:!0,category:"activity"},man_playing_handball:{keywords:["sports"],char:'\ud83e\udd3e\u200d\u2642\ufe0f',fitzpatrick_scale:!0,category:"activity"},ice_skate:{keywords:["sports"],char:'\u26f8',fitzpatrick_scale:!1,category:"activity"},curling_stone:{keywords:["sports"],char:'\ud83e\udd4c',fitzpatrick_scale:!1,category:"activity"},skateboard:{keywords:["board"],char:'\ud83d\udef9',fitzpatrick_scale:!1,category:"activity"},sled:{keywords:["sleigh","luge","toboggan"],char:'\ud83d\udef7',fitzpatrick_scale:!1,category:"activity"},bow_and_arrow:{keywords:["sports"],char:'\ud83c\udff9',fitzpatrick_scale:!1,category:"activity"},fishing_pole_and_fish:{keywords:["food","hobby","summer"],char:'\ud83c\udfa3',fitzpatrick_scale:!1,category:"activity"},boxing_glove:{keywords:["sports","fighting"],char:'\ud83e\udd4a',fitzpatrick_scale:!1,category:"activity"},martial_arts_uniform:{keywords:["judo","karate","taekwondo"],char:'\ud83e\udd4b',fitzpatrick_scale:!1,category:"activity"},rowing_woman:{keywords:["sports","hobby","water","ship","woman","female"],char:'\ud83d\udea3\u200d\u2640\ufe0f',fitzpatrick_scale:!0,category:"activity"},rowing_man:{keywords:["sports","hobby","water","ship"],char:'\ud83d\udea3',fitzpatrick_scale:!0,category:"activity"},climbing_woman:{keywords:["sports","hobby","woman","female","rock"],char:'\ud83e\uddd7\u200d\u2640\ufe0f',fitzpatrick_scale:!0,category:"activity"},climbing_man:{keywords:["sports","hobby","man","male","rock"],char:'\ud83e\uddd7\u200d\u2642\ufe0f',fitzpatrick_scale:!0,category:"activity"},swimming_woman:{keywords:["sports","exercise","human","athlete","water","summer","woman","female"],char:'\ud83c\udfca\u200d\u2640\ufe0f',fitzpatrick_scale:!0,category:"activity"},swimming_man:{keywords:["sports","exercise","human","athlete","water","summer"],char:'\ud83c\udfca',fitzpatrick_scale:!0,category:"activity"},woman_playing_water_polo:{keywords:["sports","pool"],char:'\ud83e\udd3d\u200d\u2640\ufe0f',fitzpatrick_scale:!0,category:"activity"},man_playing_water_polo:{keywords:["sports","pool"],char:'\ud83e\udd3d\u200d\u2642\ufe0f',fitzpatrick_scale:!0,category:"activity"},woman_in_lotus_position:{keywords:["woman","female","meditation","yoga","serenity","zen","mindfulness"],char:'\ud83e\uddd8\u200d\u2640\ufe0f',fitzpatrick_scale:!0,category:"activity"},man_in_lotus_position:{keywords:["man","male","meditation","yoga","serenity","zen","mindfulness"],char:'\ud83e\uddd8\u200d\u2642\ufe0f',fitzpatrick_scale:!0,category:"activity"},surfing_woman:{keywords:["sports","ocean","sea","summer","beach","woman","female"],char:'\ud83c\udfc4\u200d\u2640\ufe0f',fitzpatrick_scale:!0,category:"activity"},surfing_man:{keywords:["sports","ocean","sea","summer","beach"],char:'\ud83c\udfc4',fitzpatrick_scale:!0,category:"activity"},bath:{keywords:["clean","shower","bathroom"],char:'\ud83d\udec0',fitzpatrick_scale:!0,category:"activity"},basketball_woman:{keywords:["sports","human","woman","female"],char:'\u26f9\ufe0f\u200d\u2640\ufe0f',fitzpatrick_scale:!0,category:"activity"},basketball_man:{keywords:["sports","human"],char:'\u26f9',fitzpatrick_scale:!0,category:"activity"},weight_lifting_woman:{keywords:["sports","training","exercise","woman","female"],char:'\ud83c\udfcb\ufe0f\u200d\u2640\ufe0f',fitzpatrick_scale:!0,category:"activity"},weight_lifting_man:{keywords:["sports","training","exercise"],char:'\ud83c\udfcb',fitzpatrick_scale:!0,category:"activity"},biking_woman:{keywords:["sports","bike","exercise","hipster","woman","female"],char:'\ud83d\udeb4\u200d\u2640\ufe0f',fitzpatrick_scale:!0,category:"activity"},biking_man:{keywords:["sports","bike","exercise","hipster"],char:'\ud83d\udeb4',fitzpatrick_scale:!0,category:"activity"},mountain_biking_woman:{keywords:["transportation","sports","human","race","bike","woman","female"],char:'\ud83d\udeb5\u200d\u2640\ufe0f',fitzpatrick_scale:!0,category:"activity"},mountain_biking_man:{keywords:["transportation","sports","human","race","bike"],char:'\ud83d\udeb5',fitzpatrick_scale:!0,category:"activity"},horse_racing:{keywords:["animal","betting","competition","gambling","luck"],char:'\ud83c\udfc7',fitzpatrick_scale:!0,category:"activity"},business_suit_levitating:{keywords:["suit","business","levitate","hover","jump"],char:'\ud83d\udd74',fitzpatrick_scale:!0,category:"activity"},trophy:{keywords:["win","award","contest","place","ftw","ceremony"],char:'\ud83c\udfc6',fitzpatrick_scale:!1,category:"activity"},running_shirt_with_sash:{keywords:["play","pageant"],char:'\ud83c\udfbd',fitzpatrick_scale:!1,category:"activity"},medal_sports:{keywords:["award","winning"],char:'\ud83c\udfc5',fitzpatrick_scale:!1,category:"activity"},medal_military:{keywords:["award","winning","army"],char:'\ud83c\udf96',fitzpatrick_scale:!1,category:"activity"},"1st_place_medal":{keywords:["award","winning","first"],char:'\ud83e\udd47',fitzpatrick_scale:!1,category:"activity"},"2nd_place_medal":{keywords:["award","second"],char:'\ud83e\udd48',fitzpatrick_scale:!1,category:"activity"},"3rd_place_medal":{keywords:["award","third"],char:'\ud83e\udd49',fitzpatrick_scale:!1,category:"activity"},reminder_ribbon:{keywords:["sports","cause","support","awareness"],char:'\ud83c\udf97',fitzpatrick_scale:!1,category:"activity"},rosette:{keywords:["flower","decoration","military"],char:'\ud83c\udff5',fitzpatrick_scale:!1,category:"activity"},ticket:{keywords:["event","concert","pass"],char:'\ud83c\udfab',fitzpatrick_scale:!1,category:"activity"},tickets:{keywords:["sports","concert","entrance"],char:'\ud83c\udf9f',fitzpatrick_scale:!1,category:"activity"},performing_arts:{keywords:["acting","theater","drama"],char:'\ud83c\udfad',fitzpatrick_scale:!1,category:"activity"},art:{keywords:["design","paint","draw","colors"],char:'\ud83c\udfa8',fitzpatrick_scale:!1,category:"activity"},circus_tent:{keywords:["festival","carnival","party"],char:'\ud83c\udfaa',fitzpatrick_scale:!1,category:"activity"},woman_juggling:{keywords:["juggle","balance","skill","multitask"],char:'\ud83e\udd39\u200d\u2640\ufe0f',fitzpatrick_scale:!0,category:"activity"},man_juggling:{keywords:["juggle","balance","skill","multitask"],char:'\ud83e\udd39\u200d\u2642\ufe0f',fitzpatrick_scale:!0,category:"activity"},microphone:{keywords:["sound","music","PA","sing","talkshow"],char:'\ud83c\udfa4',fitzpatrick_scale:!1,category:"activity"},headphones:{keywords:["music","score","gadgets"],char:'\ud83c\udfa7',fitzpatrick_scale:!1,category:"activity"},musical_score:{keywords:["treble","clef","compose"],char:'\ud83c\udfbc',fitzpatrick_scale:!1,category:"activity"},musical_keyboard:{keywords:["piano","instrument","compose"],char:'\ud83c\udfb9',fitzpatrick_scale:!1,category:"activity"},drum:{keywords:["music","instrument","drumsticks","snare"],char:'\ud83e\udd41',fitzpatrick_scale:!1,category:"activity"},saxophone:{keywords:["music","instrument","jazz","blues"],char:'\ud83c\udfb7',fitzpatrick_scale:!1,category:"activity"},trumpet:{keywords:["music","brass"],char:'\ud83c\udfba',fitzpatrick_scale:!1,category:"activity"},guitar:{keywords:["music","instrument"],char:'\ud83c\udfb8',fitzpatrick_scale:!1,category:"activity"},violin:{keywords:["music","instrument","orchestra","symphony"],char:'\ud83c\udfbb',fitzpatrick_scale:!1,category:"activity"},clapper:{keywords:["movie","film","record"],char:'\ud83c\udfac',fitzpatrick_scale:!1,category:"activity"},video_game:{keywords:["play","console","PS4","controller"],char:'\ud83c\udfae',fitzpatrick_scale:!1,category:"activity"},space_invader:{keywords:["game","arcade","play"],char:'\ud83d\udc7e',fitzpatrick_scale:!1,category:"activity"},dart:{keywords:["game","play","bar","target","bullseye"],char:'\ud83c\udfaf',fitzpatrick_scale:!1,category:"activity"},game_die:{keywords:["dice","random","tabletop","play","luck"],char:'\ud83c\udfb2',fitzpatrick_scale:!1,category:"activity"},chess_pawn:{keywords:["expendable"],char:"\u265f",fitzpatrick_scale:!1,category:"activity"},slot_machine:{keywords:["bet","gamble","vegas","fruit machine","luck","casino"],char:'\ud83c\udfb0',fitzpatrick_scale:!1,category:"activity"},jigsaw:{keywords:["interlocking","puzzle","piece"],char:'\ud83e\udde9',fitzpatrick_scale:!1,category:"activity"},bowling:{keywords:["sports","fun","play"],char:'\ud83c\udfb3',fitzpatrick_scale:!1,category:"activity"},red_car:{keywords:["red","transportation","vehicle"],char:'\ud83d\ude97',fitzpatrick_scale:!1,category:"travel_and_places"},taxi:{keywords:["uber","vehicle","cars","transportation"],char:'\ud83d\ude95',fitzpatrick_scale:!1,category:"travel_and_places"},blue_car:{keywords:["transportation","vehicle"],char:'\ud83d\ude99',fitzpatrick_scale:!1,category:"travel_and_places"},bus:{keywords:["car","vehicle","transportation"],char:'\ud83d\ude8c',fitzpatrick_scale:!1,category:"travel_and_places"},trolleybus:{keywords:["bart","transportation","vehicle"],char:'\ud83d\ude8e',fitzpatrick_scale:!1,category:"travel_and_places"},racing_car:{keywords:["sports","race","fast","formula","f1"],char:'\ud83c\udfce',fitzpatrick_scale:!1,category:"travel_and_places"},police_car:{keywords:["vehicle","cars","transportation","law","legal","enforcement"],char:'\ud83d\ude93',fitzpatrick_scale:!1,category:"travel_and_places"},ambulance:{keywords:["health","911","hospital"],char:'\ud83d\ude91',fitzpatrick_scale:!1,category:"travel_and_places"},fire_engine:{keywords:["transportation","cars","vehicle"],char:'\ud83d\ude92',fitzpatrick_scale:!1,category:"travel_and_places"},minibus:{keywords:["vehicle","car","transportation"],char:'\ud83d\ude90',fitzpatrick_scale:!1,category:"travel_and_places"},truck:{keywords:["cars","transportation"],char:'\ud83d\ude9a',fitzpatrick_scale:!1,category:"travel_and_places"},articulated_lorry:{keywords:["vehicle","cars","transportation","express"],char:'\ud83d\ude9b',fitzpatrick_scale:!1,category:"travel_and_places"},tractor:{keywords:["vehicle","car","farming","agriculture"],char:'\ud83d\ude9c',fitzpatrick_scale:!1,category:"travel_and_places"},kick_scooter:{keywords:["vehicle","kick","razor"],char:'\ud83d\udef4',fitzpatrick_scale:!1,category:"travel_and_places"},motorcycle:{keywords:["race","sports","fast"],char:'\ud83c\udfcd',fitzpatrick_scale:!1,category:"travel_and_places"},bike:{keywords:["sports","bicycle","exercise","hipster"],char:'\ud83d\udeb2',fitzpatrick_scale:!1,category:"travel_and_places"},motor_scooter:{keywords:["vehicle","vespa","sasha"],char:'\ud83d\udef5',fitzpatrick_scale:!1,category:"travel_and_places"},rotating_light:{keywords:["police","ambulance","911","emergency","alert","error","pinged","law","legal"],char:'\ud83d\udea8',fitzpatrick_scale:!1,category:"travel_and_places"},oncoming_police_car:{keywords:["vehicle","law","legal","enforcement","911"],char:'\ud83d\ude94',fitzpatrick_scale:!1,category:"travel_and_places"},oncoming_bus:{keywords:["vehicle","transportation"],char:'\ud83d\ude8d',fitzpatrick_scale:!1,category:"travel_and_places"},oncoming_automobile:{keywords:["car","vehicle","transportation"],char:'\ud83d\ude98',fitzpatrick_scale:!1,category:"travel_and_places"},oncoming_taxi:{keywords:["vehicle","cars","uber"],char:'\ud83d\ude96',fitzpatrick_scale:!1,category:"travel_and_places"},aerial_tramway:{keywords:["transportation","vehicle","ski"],char:'\ud83d\udea1',fitzpatrick_scale:!1,category:"travel_and_places"},mountain_cableway:{keywords:["transportation","vehicle","ski"],char:'\ud83d\udea0',fitzpatrick_scale:!1,category:"travel_and_places"},suspension_railway:{keywords:["vehicle","transportation"],char:'\ud83d\ude9f',fitzpatrick_scale:!1,category:"travel_and_places"},railway_car:{keywords:["transportation","vehicle"],char:'\ud83d\ude83',fitzpatrick_scale:!1,category:"travel_and_places"},train:{keywords:["transportation","vehicle","carriage","public","travel"],char:'\ud83d\ude8b',fitzpatrick_scale:!1,category:"travel_and_places"},monorail:{keywords:["transportation","vehicle"],char:'\ud83d\ude9d',fitzpatrick_scale:!1,category:"travel_and_places"},bullettrain_side:{keywords:["transportation","vehicle"],char:'\ud83d\ude84',fitzpatrick_scale:!1,category:"travel_and_places"},bullettrain_front:{keywords:["transportation","vehicle","speed","fast","public","travel"],char:'\ud83d\ude85',fitzpatrick_scale:!1,category:"travel_and_places"},light_rail:{keywords:["transportation","vehicle"],char:'\ud83d\ude88',fitzpatrick_scale:!1,category:"travel_and_places"},mountain_railway:{keywords:["transportation","vehicle"],char:'\ud83d\ude9e',fitzpatrick_scale:!1,category:"travel_and_places"},steam_locomotive:{keywords:["transportation","vehicle","train"],char:'\ud83d\ude82',fitzpatrick_scale:!1,category:"travel_and_places"},train2:{keywords:["transportation","vehicle"],char:'\ud83d\ude86',fitzpatrick_scale:!1,category:"travel_and_places"},metro:{keywords:["transportation","blue-square","mrt","underground","tube"],char:'\ud83d\ude87',fitzpatrick_scale:!1,category:"travel_and_places"},tram:{keywords:["transportation","vehicle"],char:'\ud83d\ude8a',fitzpatrick_scale:!1,category:"travel_and_places"},station:{keywords:["transportation","vehicle","public"],char:'\ud83d\ude89',fitzpatrick_scale:!1,category:"travel_and_places"},flying_saucer:{keywords:["transportation","vehicle","ufo"],char:'\ud83d\udef8',fitzpatrick_scale:!1,category:"travel_and_places"},helicopter:{keywords:["transportation","vehicle","fly"],char:'\ud83d\ude81',fitzpatrick_scale:!1,category:"travel_and_places"},small_airplane:{keywords:["flight","transportation","fly","vehicle"],char:'\ud83d\udee9',fitzpatrick_scale:!1,category:"travel_and_places"},airplane:{keywords:["vehicle","transportation","flight","fly"],char:'\u2708\ufe0f',fitzpatrick_scale:!1,category:"travel_and_places"},flight_departure:{keywords:["airport","flight","landing"],char:'\ud83d\udeeb',fitzpatrick_scale:!1,category:"travel_and_places"},flight_arrival:{keywords:["airport","flight","boarding"],char:'\ud83d\udeec',fitzpatrick_scale:!1,category:"travel_and_places"},sailboat:{keywords:["ship","summer","transportation","water","sailing"],char:'\u26f5',fitzpatrick_scale:!1,category:"travel_and_places"},motor_boat:{keywords:["ship"],char:'\ud83d\udee5',fitzpatrick_scale:!1,category:"travel_and_places"},speedboat:{keywords:["ship","transportation","vehicle","summer"],char:'\ud83d\udea4',fitzpatrick_scale:!1,category:"travel_and_places"},ferry:{keywords:["boat","ship","yacht"],char:'\u26f4',fitzpatrick_scale:!1,category:"travel_and_places"},passenger_ship:{keywords:["yacht","cruise","ferry"],char:'\ud83d\udef3',fitzpatrick_scale:!1,category:"travel_and_places"},rocket:{keywords:["launch","ship","staffmode","NASA","outer space","outer_space","fly"],char:'\ud83d\ude80',fitzpatrick_scale:!1,category:"travel_and_places"},artificial_satellite:{keywords:["communication","gps","orbit","spaceflight","NASA","ISS"],char:'\ud83d\udef0',fitzpatrick_scale:!1,category:"travel_and_places"},seat:{keywords:["sit","airplane","transport","bus","flight","fly"],char:'\ud83d\udcba',fitzpatrick_scale:!1,category:"travel_and_places"},canoe:{keywords:["boat","paddle","water","ship"],char:'\ud83d\udef6',fitzpatrick_scale:!1,category:"travel_and_places"},anchor:{keywords:["ship","ferry","sea","boat"],char:'\u2693',fitzpatrick_scale:!1,category:"travel_and_places"},construction:{keywords:["wip","progress","caution","warning"],char:'\ud83d\udea7',fitzpatrick_scale:!1,category:"travel_and_places"},fuelpump:{keywords:["gas station","petroleum"],char:'\u26fd',fitzpatrick_scale:!1,category:"travel_and_places"},busstop:{keywords:["transportation","wait"],char:'\ud83d\ude8f',fitzpatrick_scale:!1,category:"travel_and_places"},vertical_traffic_light:{keywords:["transportation","driving"],char:'\ud83d\udea6',fitzpatrick_scale:!1,category:"travel_and_places"},traffic_light:{keywords:["transportation","signal"],char:'\ud83d\udea5',fitzpatrick_scale:!1,category:"travel_and_places"},checkered_flag:{keywords:["contest","finishline","race","gokart"],char:'\ud83c\udfc1',fitzpatrick_scale:!1,category:"travel_and_places"},ship:{keywords:["transportation","titanic","deploy"],char:'\ud83d\udea2',fitzpatrick_scale:!1,category:"travel_and_places"},ferris_wheel:{keywords:["photo","carnival","londoneye"],char:'\ud83c\udfa1',fitzpatrick_scale:!1,category:"travel_and_places"},roller_coaster:{keywords:["carnival","playground","photo","fun"],char:'\ud83c\udfa2',fitzpatrick_scale:!1,category:"travel_and_places"},carousel_horse:{keywords:["photo","carnival"],char:'\ud83c\udfa0',fitzpatrick_scale:!1,category:"travel_and_places"},building_construction:{keywords:["wip","working","progress"],char:'\ud83c\udfd7',fitzpatrick_scale:!1,category:"travel_and_places"},foggy:{keywords:["photo","mountain"],char:'\ud83c\udf01',fitzpatrick_scale:!1,category:"travel_and_places"},tokyo_tower:{keywords:["photo","japanese"],char:'\ud83d\uddfc',fitzpatrick_scale:!1,category:"travel_and_places"},factory:{keywords:["building","industry","pollution","smoke"],char:'\ud83c\udfed',fitzpatrick_scale:!1,category:"travel_and_places"},fountain:{keywords:["photo","summer","water","fresh"],char:'\u26f2',fitzpatrick_scale:!1,category:"travel_and_places"},rice_scene:{keywords:["photo","japan","asia","tsukimi"],char:'\ud83c\udf91',fitzpatrick_scale:!1,category:"travel_and_places"},mountain:{keywords:["photo","nature","environment"],char:'\u26f0',fitzpatrick_scale:!1,category:"travel_and_places"},mountain_snow:{keywords:["photo","nature","environment","winter","cold"],char:'\ud83c\udfd4',fitzpatrick_scale:!1,category:"travel_and_places"},mount_fuji:{keywords:["photo","mountain","nature","japanese"],char:'\ud83d\uddfb',fitzpatrick_scale:!1,category:"travel_and_places"},volcano:{keywords:["photo","nature","disaster"],char:'\ud83c\udf0b',fitzpatrick_scale:!1,category:"travel_and_places"},japan:{keywords:["nation","country","japanese","asia"],char:'\ud83d\uddfe',fitzpatrick_scale:!1,category:"travel_and_places"},camping:{keywords:["photo","outdoors","tent"],char:'\ud83c\udfd5',fitzpatrick_scale:!1,category:"travel_and_places"},tent:{keywords:["photo","camping","outdoors"],char:'\u26fa',fitzpatrick_scale:!1,category:"travel_and_places"},national_park:{keywords:["photo","environment","nature"],char:'\ud83c\udfde',fitzpatrick_scale:!1,category:"travel_and_places"},motorway:{keywords:["road","cupertino","interstate","highway"],char:'\ud83d\udee3',fitzpatrick_scale:!1,category:"travel_and_places"},railway_track:{keywords:["train","transportation"],char:'\ud83d\udee4',fitzpatrick_scale:!1,category:"travel_and_places"},sunrise:{keywords:["morning","view","vacation","photo"],char:'\ud83c\udf05',fitzpatrick_scale:!1,category:"travel_and_places"},sunrise_over_mountains:{keywords:["view","vacation","photo"],char:'\ud83c\udf04',fitzpatrick_scale:!1,category:"travel_and_places"},desert:{keywords:["photo","warm","saharah"],char:'\ud83c\udfdc',fitzpatrick_scale:!1,category:"travel_and_places"},beach_umbrella:{keywords:["weather","summer","sunny","sand","mojito"],char:'\ud83c\udfd6',fitzpatrick_scale:!1,category:"travel_and_places"},desert_island:{keywords:["photo","tropical","mojito"],char:'\ud83c\udfdd',fitzpatrick_scale:!1,category:"travel_and_places"},city_sunrise:{keywords:["photo","good morning","dawn"],char:'\ud83c\udf07',fitzpatrick_scale:!1,category:"travel_and_places"},city_sunset:{keywords:["photo","evening","sky","buildings"],char:'\ud83c\udf06',fitzpatrick_scale:!1,category:"travel_and_places"},cityscape:{keywords:["photo","night life","urban"],char:'\ud83c\udfd9',fitzpatrick_scale:!1,category:"travel_and_places"},night_with_stars:{keywords:["evening","city","downtown"],char:'\ud83c\udf03',fitzpatrick_scale:!1,category:"travel_and_places"},bridge_at_night:{keywords:["photo","sanfrancisco"],char:'\ud83c\udf09',fitzpatrick_scale:!1,category:"travel_and_places"},milky_way:{keywords:["photo","space","stars"],char:'\ud83c\udf0c',fitzpatrick_scale:!1,category:"travel_and_places"},stars:{keywords:["night","photo"],char:'\ud83c\udf20',fitzpatrick_scale:!1,category:"travel_and_places"},sparkler:{keywords:["stars","night","shine"],char:'\ud83c\udf87',fitzpatrick_scale:!1,category:"travel_and_places"},fireworks:{keywords:["photo","festival","carnival","congratulations"],char:'\ud83c\udf86',fitzpatrick_scale:!1,category:"travel_and_places"},rainbow:{keywords:["nature","happy","unicorn_face","photo","sky","spring"],char:'\ud83c\udf08',fitzpatrick_scale:!1,category:"travel_and_places"},houses:{keywords:["buildings","photo"],char:'\ud83c\udfd8',fitzpatrick_scale:!1,category:"travel_and_places"},european_castle:{keywords:["building","royalty","history"],char:'\ud83c\udff0',fitzpatrick_scale:!1,category:"travel_and_places"},japanese_castle:{keywords:["photo","building"],char:'\ud83c\udfef',fitzpatrick_scale:!1,category:"travel_and_places"},stadium:{keywords:["photo","place","sports","concert","venue"],char:'\ud83c\udfdf',fitzpatrick_scale:!1,category:"travel_and_places"},statue_of_liberty:{keywords:["american","newyork"],char:'\ud83d\uddfd',fitzpatrick_scale:!1,category:"travel_and_places"},house:{keywords:["building","home"],char:'\ud83c\udfe0',fitzpatrick_scale:!1,category:"travel_and_places"},house_with_garden:{keywords:["home","plant","nature"],char:'\ud83c\udfe1',fitzpatrick_scale:!1,category:"travel_and_places"},derelict_house:{keywords:["abandon","evict","broken","building"],char:'\ud83c\udfda',fitzpatrick_scale:!1,category:"travel_and_places"},office:{keywords:["building","bureau","work"],char:'\ud83c\udfe2',fitzpatrick_scale:!1,category:"travel_and_places"},department_store:{keywords:["building","shopping","mall"],char:'\ud83c\udfec',fitzpatrick_scale:!1,category:"travel_and_places"},post_office:{keywords:["building","envelope","communication"],char:'\ud83c\udfe3',fitzpatrick_scale:!1,category:"travel_and_places"},european_post_office:{keywords:["building","email"],char:'\ud83c\udfe4',fitzpatrick_scale:!1,category:"travel_and_places"},hospital:{keywords:["building","health","surgery","doctor"],char:'\ud83c\udfe5',fitzpatrick_scale:!1,category:"travel_and_places"},bank:{keywords:["building","money","sales","cash","business","enterprise"],char:'\ud83c\udfe6',fitzpatrick_scale:!1,category:"travel_and_places"},hotel:{keywords:["building","accomodation","checkin"],char:'\ud83c\udfe8',fitzpatrick_scale:!1,category:"travel_and_places"},convenience_store:{keywords:["building","shopping","groceries"],char:'\ud83c\udfea',fitzpatrick_scale:!1,category:"travel_and_places"},school:{keywords:["building","student","education","learn","teach"],char:'\ud83c\udfeb',fitzpatrick_scale:!1,category:"travel_and_places"},love_hotel:{keywords:["like","affection","dating"],char:'\ud83c\udfe9',fitzpatrick_scale:!1,category:"travel_and_places"},wedding:{keywords:["love","like","affection","couple","marriage","bride","groom"],char:'\ud83d\udc92',fitzpatrick_scale:!1,category:"travel_and_places"},classical_building:{keywords:["art","culture","history"],char:'\ud83c\udfdb',fitzpatrick_scale:!1,category:"travel_and_places"},church:{keywords:["building","religion","christ"],char:'\u26ea',fitzpatrick_scale:!1,category:"travel_and_places"},mosque:{keywords:["islam","worship","minaret"],char:'\ud83d\udd4c',fitzpatrick_scale:!1,category:"travel_and_places"},synagogue:{keywords:["judaism","worship","temple","jewish"],char:'\ud83d\udd4d',fitzpatrick_scale:!1,category:"travel_and_places"},kaaba:{keywords:["mecca","mosque","islam"],char:'\ud83d\udd4b',fitzpatrick_scale:!1,category:"travel_and_places"},shinto_shrine:{keywords:["temple","japan","kyoto"],char:'\u26e9',fitzpatrick_scale:!1,category:"travel_and_places"},watch:{keywords:["time","accessories"],char:'\u231a',fitzpatrick_scale:!1,category:"objects"},iphone:{keywords:["technology","apple","gadgets","dial"],char:'\ud83d\udcf1',fitzpatrick_scale:!1,category:"objects"},calling:{keywords:["iphone","incoming"],char:'\ud83d\udcf2',fitzpatrick_scale:!1,category:"objects"},computer:{keywords:["technology","laptop","screen","display","monitor"],char:'\ud83d\udcbb',fitzpatrick_scale:!1,category:"objects"},keyboard:{keywords:["technology","computer","type","input","text"],char:'\u2328',fitzpatrick_scale:!1,category:"objects"},desktop_computer:{keywords:["technology","computing","screen"],char:'\ud83d\udda5',fitzpatrick_scale:!1,category:"objects"},printer:{keywords:["paper","ink"],char:'\ud83d\udda8',fitzpatrick_scale:!1,category:"objects"},computer_mouse:{keywords:["click"],char:'\ud83d\uddb1',fitzpatrick_scale:!1,category:"objects"},trackball:{keywords:["technology","trackpad"],char:'\ud83d\uddb2',fitzpatrick_scale:!1,category:"objects"},joystick:{keywords:["game","play"],char:'\ud83d\udd79',fitzpatrick_scale:!1,category:"objects"},clamp:{keywords:["tool"],char:'\ud83d\udddc',fitzpatrick_scale:!1,category:"objects"},minidisc:{keywords:["technology","record","data","disk","90s"],char:'\ud83d\udcbd',fitzpatrick_scale:!1,category:"objects"},floppy_disk:{keywords:["oldschool","technology","save","90s","80s"],char:'\ud83d\udcbe',fitzpatrick_scale:!1,category:"objects"},cd:{keywords:["technology","dvd","disk","disc","90s"],char:'\ud83d\udcbf',fitzpatrick_scale:!1,category:"objects"},dvd:{keywords:["cd","disk","disc"],char:'\ud83d\udcc0',fitzpatrick_scale:!1,category:"objects"},vhs:{keywords:["record","video","oldschool","90s","80s"],char:'\ud83d\udcfc',fitzpatrick_scale:!1,category:"objects"},camera:{keywords:["gadgets","photography"],char:'\ud83d\udcf7',fitzpatrick_scale:!1,category:"objects"},camera_flash:{keywords:["photography","gadgets"],char:'\ud83d\udcf8',fitzpatrick_scale:!1,category:"objects"},video_camera:{keywords:["film","record"],char:'\ud83d\udcf9',fitzpatrick_scale:!1,category:"objects"},movie_camera:{keywords:["film","record"],char:'\ud83c\udfa5',fitzpatrick_scale:!1,category:"objects"},film_projector:{keywords:["video","tape","record","movie"],char:'\ud83d\udcfd',fitzpatrick_scale:!1,category:"objects"},film_strip:{keywords:["movie"],char:'\ud83c\udf9e',fitzpatrick_scale:!1,category:"objects"},telephone_receiver:{keywords:["technology","communication","dial"],char:'\ud83d\udcde',fitzpatrick_scale:!1,category:"objects"},phone:{keywords:["technology","communication","dial","telephone"],char:'\u260e\ufe0f',fitzpatrick_scale:!1,category:"objects"},pager:{keywords:["bbcall","oldschool","90s"],char:'\ud83d\udcdf',fitzpatrick_scale:!1,category:"objects"},fax:{keywords:["communication","technology"],char:'\ud83d\udce0',fitzpatrick_scale:!1,category:"objects"},tv:{keywords:["technology","program","oldschool","show","television"],char:'\ud83d\udcfa',fitzpatrick_scale:!1,category:"objects"},radio:{keywords:["communication","music","podcast","program"],char:'\ud83d\udcfb',fitzpatrick_scale:!1,category:"objects"},studio_microphone:{keywords:["sing","recording","artist","talkshow"],char:'\ud83c\udf99',fitzpatrick_scale:!1,category:"objects"},level_slider:{keywords:["scale"],char:'\ud83c\udf9a',fitzpatrick_scale:!1,category:"objects"},control_knobs:{keywords:["dial"],char:'\ud83c\udf9b',fitzpatrick_scale:!1,category:"objects"},compass:{keywords:["magnetic","navigation","orienteering"],char:'\ud83e\udded',fitzpatrick_scale:!1,category:"objects"},stopwatch:{keywords:["time","deadline"],char:'\u23f1',fitzpatrick_scale:!1,category:"objects"},timer_clock:{keywords:["alarm"],char:'\u23f2',fitzpatrick_scale:!1,category:"objects"},alarm_clock:{keywords:["time","wake"],char:'\u23f0',fitzpatrick_scale:!1,category:"objects"},mantelpiece_clock:{keywords:["time"],char:'\ud83d\udd70',fitzpatrick_scale:!1,category:"objects"},hourglass_flowing_sand:{keywords:["oldschool","time","countdown"],char:'\u23f3',fitzpatrick_scale:!1,category:"objects"},hourglass:{keywords:["time","clock","oldschool","limit","exam","quiz","test"],char:'\u231b',fitzpatrick_scale:!1,category:"objects"},satellite:{keywords:["communication","future","radio","space"],char:'\ud83d\udce1',fitzpatrick_scale:!1,category:"objects"},battery:{keywords:["power","energy","sustain"],char:'\ud83d\udd0b',fitzpatrick_scale:!1,category:"objects"},electric_plug:{keywords:["charger","power"],char:'\ud83d\udd0c',fitzpatrick_scale:!1,category:"objects"},bulb:{keywords:["light","electricity","idea"],char:'\ud83d\udca1',fitzpatrick_scale:!1,category:"objects"},flashlight:{keywords:["dark","camping","sight","night"],char:'\ud83d\udd26',fitzpatrick_scale:!1,category:"objects"},candle:{keywords:["fire","wax"],char:'\ud83d\udd6f',fitzpatrick_scale:!1,category:"objects"},fire_extinguisher:{keywords:["quench"],char:'\ud83e\uddef',fitzpatrick_scale:!1,category:"objects"},wastebasket:{keywords:["bin","trash","rubbish","garbage","toss"],char:'\ud83d\uddd1',fitzpatrick_scale:!1,category:"objects"},oil_drum:{keywords:["barrell"],char:'\ud83d\udee2',fitzpatrick_scale:!1,category:"objects"},money_with_wings:{keywords:["dollar","bills","payment","sale"],char:'\ud83d\udcb8',fitzpatrick_scale:!1,category:"objects"},dollar:{keywords:["money","sales","bill","currency"],char:'\ud83d\udcb5',fitzpatrick_scale:!1,category:"objects"},yen:{keywords:["money","sales","japanese","dollar","currency"],char:'\ud83d\udcb4',fitzpatrick_scale:!1,category:"objects"},euro:{keywords:["money","sales","dollar","currency"],char:'\ud83d\udcb6',fitzpatrick_scale:!1,category:"objects"},pound:{keywords:["british","sterling","money","sales","bills","uk","england","currency"],char:'\ud83d\udcb7',fitzpatrick_scale:!1,category:"objects"},moneybag:{keywords:["dollar","payment","coins","sale"],char:'\ud83d\udcb0',fitzpatrick_scale:!1,category:"objects"},credit_card:{keywords:["money","sales","dollar","bill","payment","shopping"],char:'\ud83d\udcb3',fitzpatrick_scale:!1,category:"objects"},gem:{keywords:["blue","ruby","diamond","jewelry"],char:'\ud83d\udc8e',fitzpatrick_scale:!1,category:"objects"},balance_scale:{keywords:["law","fairness","weight"],char:'\u2696',fitzpatrick_scale:!1,category:"objects"},toolbox:{keywords:["tools","diy","fix","maintainer","mechanic"],char:'\ud83e\uddf0',fitzpatrick_scale:!1,category:"objects"},wrench:{keywords:["tools","diy","ikea","fix","maintainer"],char:'\ud83d\udd27',fitzpatrick_scale:!1,category:"objects"},hammer:{keywords:["tools","build","create"],char:'\ud83d\udd28',fitzpatrick_scale:!1,category:"objects"},hammer_and_pick:{keywords:["tools","build","create"],char:'\u2692',fitzpatrick_scale:!1,category:"objects"},hammer_and_wrench:{keywords:["tools","build","create"],char:'\ud83d\udee0',fitzpatrick_scale:!1,category:"objects"},pick:{keywords:["tools","dig"],char:'\u26cf',fitzpatrick_scale:!1,category:"objects"},nut_and_bolt:{keywords:["handy","tools","fix"],char:'\ud83d\udd29',fitzpatrick_scale:!1,category:"objects"},gear:{keywords:["cog"],char:'\u2699',fitzpatrick_scale:!1,category:"objects"},brick:{keywords:["bricks"],char:'\ud83e\uddf1',fitzpatrick_scale:!1,category:"objects"},chains:{keywords:["lock","arrest"],char:'\u26d3',fitzpatrick_scale:!1,category:"objects"},magnet:{keywords:["attraction","magnetic"],char:'\ud83e\uddf2',fitzpatrick_scale:!1,category:"objects"},gun:{keywords:["violence","weapon","pistol","revolver"],char:'\ud83d\udd2b',fitzpatrick_scale:!1,category:"objects"},bomb:{keywords:["boom","explode","explosion","terrorism"],char:'\ud83d\udca3',fitzpatrick_scale:!1,category:"objects"},firecracker:{keywords:["dynamite","boom","explode","explosion","explosive"],char:'\ud83e\udde8',fitzpatrick_scale:!1,category:"objects"},hocho:{keywords:["knife","blade","cutlery","kitchen","weapon"],char:'\ud83d\udd2a',fitzpatrick_scale:!1,category:"objects"},dagger:{keywords:["weapon"],char:'\ud83d\udde1',fitzpatrick_scale:!1,category:"objects"},crossed_swords:{keywords:["weapon"],char:'\u2694',fitzpatrick_scale:!1,category:"objects"},shield:{keywords:["protection","security"],char:'\ud83d\udee1',fitzpatrick_scale:!1,category:"objects"},smoking:{keywords:["kills","tobacco","cigarette","joint","smoke"],char:'\ud83d\udeac',fitzpatrick_scale:!1,category:"objects"},skull_and_crossbones:{keywords:["poison","danger","deadly","scary","death","pirate","evil"],char:'\u2620',fitzpatrick_scale:!1,category:"objects"},coffin:{keywords:["vampire","dead","die","death","rip","graveyard","cemetery","casket","funeral","box"],char:'\u26b0',fitzpatrick_scale:!1,category:"objects"},funeral_urn:{keywords:["dead","die","death","rip","ashes"],char:'\u26b1',fitzpatrick_scale:!1,category:"objects"},amphora:{keywords:["vase","jar"],char:'\ud83c\udffa',fitzpatrick_scale:!1,category:"objects"},crystal_ball:{keywords:["disco","party","magic","circus","fortune_teller"],char:'\ud83d\udd2e',fitzpatrick_scale:!1,category:"objects"},prayer_beads:{keywords:["dhikr","religious"],char:'\ud83d\udcff',fitzpatrick_scale:!1,category:"objects"},nazar_amulet:{keywords:["bead","charm"],char:'\ud83e\uddff',fitzpatrick_scale:!1,category:"objects"},barber:{keywords:["hair","salon","style"],char:'\ud83d\udc88',fitzpatrick_scale:!1,category:"objects"},alembic:{keywords:["distilling","science","experiment","chemistry"],char:'\u2697',fitzpatrick_scale:!1,category:"objects"},telescope:{keywords:["stars","space","zoom","science","astronomy"],char:'\ud83d\udd2d',fitzpatrick_scale:!1,category:"objects"},microscope:{keywords:["laboratory","experiment","zoomin","science","study"],char:'\ud83d\udd2c',fitzpatrick_scale:!1,category:"objects"},hole:{keywords:["embarrassing"],char:'\ud83d\udd73',fitzpatrick_scale:!1,category:"objects"},pill:{keywords:["health","medicine","doctor","pharmacy","drug"],char:'\ud83d\udc8a',fitzpatrick_scale:!1,category:"objects"},syringe:{keywords:["health","hospital","drugs","blood","medicine","needle","doctor","nurse"],char:'\ud83d\udc89',fitzpatrick_scale:!1,category:"objects"},dna:{keywords:["biologist","genetics","life"],char:'\ud83e\uddec',fitzpatrick_scale:!1,category:"objects"},microbe:{keywords:["amoeba","bacteria","germs"],char:'\ud83e\udda0',fitzpatrick_scale:!1,category:"objects"},petri_dish:{keywords:["bacteria","biology","culture","lab"],char:'\ud83e\uddeb',fitzpatrick_scale:!1,category:"objects"},test_tube:{keywords:["chemistry","experiment","lab","science"],char:'\ud83e\uddea',fitzpatrick_scale:!1,category:"objects"},thermometer:{keywords:["weather","temperature","hot","cold"],char:'\ud83c\udf21',fitzpatrick_scale:!1,category:"objects"},broom:{keywords:["cleaning","sweeping","witch"],char:'\ud83e\uddf9',fitzpatrick_scale:!1,category:"objects"},basket:{keywords:["laundry"],char:'\ud83e\uddfa',fitzpatrick_scale:!1,category:"objects"},toilet_paper:{keywords:["roll"],char:'\ud83e\uddfb',fitzpatrick_scale:!1,category:"objects"},label:{keywords:["sale","tag"],char:'\ud83c\udff7',fitzpatrick_scale:!1,category:"objects"},bookmark:{keywords:["favorite","label","save"],char:'\ud83d\udd16',fitzpatrick_scale:!1,category:"objects"},toilet:{keywords:["restroom","wc","washroom","bathroom","potty"],char:'\ud83d\udebd',fitzpatrick_scale:!1,category:"objects"},shower:{keywords:["clean","water","bathroom"],char:'\ud83d\udebf',fitzpatrick_scale:!1,category:"objects"},bathtub:{keywords:["clean","shower","bathroom"],char:'\ud83d\udec1',fitzpatrick_scale:!1,category:"objects"},soap:{keywords:["bar","bathing","cleaning","lather"],char:'\ud83e\uddfc',fitzpatrick_scale:!1,category:"objects"},sponge:{keywords:["absorbing","cleaning","porous"],char:'\ud83e\uddfd',fitzpatrick_scale:!1,category:"objects"},lotion_bottle:{keywords:["moisturizer","sunscreen"],char:'\ud83e\uddf4',fitzpatrick_scale:!1,category:"objects"},key:{keywords:["lock","door","password"],char:'\ud83d\udd11',fitzpatrick_scale:!1,category:"objects"},old_key:{keywords:["lock","door","password"],char:'\ud83d\udddd',fitzpatrick_scale:!1,category:"objects"},couch_and_lamp:{keywords:["read","chill"],char:'\ud83d\udecb',fitzpatrick_scale:!1,category:"objects"},sleeping_bed:{keywords:["bed","rest"],char:'\ud83d\udecc',fitzpatrick_scale:!0,category:"objects"},bed:{keywords:["sleep","rest"],char:'\ud83d\udecf',fitzpatrick_scale:!1,category:"objects"},door:{keywords:["house","entry","exit"],char:'\ud83d\udeaa',fitzpatrick_scale:!1,category:"objects"},bellhop_bell:{keywords:["service"],char:'\ud83d\udece',fitzpatrick_scale:!1,category:"objects"},teddy_bear:{keywords:["plush","stuffed"],char:'\ud83e\uddf8',fitzpatrick_scale:!1,category:"objects"},framed_picture:{keywords:["photography"],char:'\ud83d\uddbc',fitzpatrick_scale:!1,category:"objects"},world_map:{keywords:["location","direction"],char:'\ud83d\uddfa',fitzpatrick_scale:!1,category:"objects"},parasol_on_ground:{keywords:["weather","summer"],char:'\u26f1',fitzpatrick_scale:!1,category:"objects"},moyai:{keywords:["rock","easter island","moai"],char:'\ud83d\uddff',fitzpatrick_scale:!1,category:"objects"},shopping:{keywords:["mall","buy","purchase"],char:'\ud83d\udecd',fitzpatrick_scale:!1,category:"objects"},shopping_cart:{keywords:["trolley"],char:'\ud83d\uded2',fitzpatrick_scale:!1,category:"objects"},balloon:{keywords:["party","celebration","birthday","circus"],char:'\ud83c\udf88',fitzpatrick_scale:!1,category:"objects"},flags:{keywords:["fish","japanese","koinobori","carp","banner"],char:'\ud83c\udf8f',fitzpatrick_scale:!1,category:"objects"},ribbon:{keywords:["decoration","pink","girl","bowtie"],char:'\ud83c\udf80',fitzpatrick_scale:!1,category:"objects"},gift:{keywords:["present","birthday","christmas","xmas"],char:'\ud83c\udf81',fitzpatrick_scale:!1,category:"objects"},confetti_ball:{keywords:["festival","party","birthday","circus"],char:'\ud83c\udf8a',fitzpatrick_scale:!1,category:"objects"},tada:{keywords:["party","congratulations","birthday","magic","circus","celebration"],char:'\ud83c\udf89',fitzpatrick_scale:!1,category:"objects"},dolls:{keywords:["japanese","toy","kimono"],char:'\ud83c\udf8e',fitzpatrick_scale:!1,category:"objects"},wind_chime:{keywords:["nature","ding","spring","bell"],char:'\ud83c\udf90',fitzpatrick_scale:!1,category:"objects"},crossed_flags:{keywords:["japanese","nation","country","border"],char:'\ud83c\udf8c',fitzpatrick_scale:!1,category:"objects"},izakaya_lantern:{keywords:["light","paper","halloween","spooky"],char:'\ud83c\udfee',fitzpatrick_scale:!1,category:"objects"},red_envelope:{keywords:["gift"],char:'\ud83e\udde7',fitzpatrick_scale:!1,category:"objects"},email:{keywords:["letter","postal","inbox","communication"],char:'\u2709\ufe0f',fitzpatrick_scale:!1,category:"objects"},envelope_with_arrow:{keywords:["email","communication"],char:'\ud83d\udce9',fitzpatrick_scale:!1,category:"objects"},incoming_envelope:{keywords:["email","inbox"],char:'\ud83d\udce8',fitzpatrick_scale:!1,category:"objects"},"e-mail":{keywords:["communication","inbox"],char:'\ud83d\udce7',fitzpatrick_scale:!1,category:"objects"},love_letter:{keywords:["email","like","affection","envelope","valentines"],char:'\ud83d\udc8c',fitzpatrick_scale:!1,category:"objects"},postbox:{keywords:["email","letter","envelope"],char:'\ud83d\udcee',fitzpatrick_scale:!1,category:"objects"},mailbox_closed:{keywords:["email","communication","inbox"],char:'\ud83d\udcea',fitzpatrick_scale:!1,category:"objects"},mailbox:{keywords:["email","inbox","communication"],char:'\ud83d\udceb',fitzpatrick_scale:!1,category:"objects"},mailbox_with_mail:{keywords:["email","inbox","communication"],char:'\ud83d\udcec',fitzpatrick_scale:!1,category:"objects"},mailbox_with_no_mail:{keywords:["email","inbox"],char:'\ud83d\udced',fitzpatrick_scale:!1,category:"objects"},package:{keywords:["mail","gift","cardboard","box","moving"],char:'\ud83d\udce6',fitzpatrick_scale:!1,category:"objects"},postal_horn:{keywords:["instrument","music"],char:'\ud83d\udcef',fitzpatrick_scale:!1,category:"objects"},inbox_tray:{keywords:["email","documents"],char:'\ud83d\udce5',fitzpatrick_scale:!1,category:"objects"},outbox_tray:{keywords:["inbox","email"],char:'\ud83d\udce4',fitzpatrick_scale:!1,category:"objects"},scroll:{keywords:["documents","ancient","history","paper"],char:'\ud83d\udcdc',fitzpatrick_scale:!1,category:"objects"},page_with_curl:{keywords:["documents","office","paper"],char:'\ud83d\udcc3',fitzpatrick_scale:!1,category:"objects"},bookmark_tabs:{keywords:["favorite","save","order","tidy"],char:'\ud83d\udcd1',fitzpatrick_scale:!1,category:"objects"},receipt:{keywords:["accounting","expenses"],char:'\ud83e\uddfe',fitzpatrick_scale:!1,category:"objects"},bar_chart:{keywords:["graph","presentation","stats"],char:'\ud83d\udcca',fitzpatrick_scale:!1,category:"objects"},chart_with_upwards_trend:{keywords:["graph","presentation","stats","recovery","business","economics","money","sales","good","success"],char:'\ud83d\udcc8',fitzpatrick_scale:!1,category:"objects"},chart_with_downwards_trend:{keywords:["graph","presentation","stats","recession","business","economics","money","sales","bad","failure"],char:'\ud83d\udcc9',fitzpatrick_scale:!1,category:"objects"},page_facing_up:{keywords:["documents","office","paper","information"],char:'\ud83d\udcc4',fitzpatrick_scale:!1,category:"objects"},date:{keywords:["calendar","schedule"],char:'\ud83d\udcc5',fitzpatrick_scale:!1,category:"objects"},calendar:{keywords:["schedule","date","planning"],char:'\ud83d\udcc6',fitzpatrick_scale:!1,category:"objects"},spiral_calendar:{keywords:["date","schedule","planning"],char:'\ud83d\uddd3',fitzpatrick_scale:!1,category:"objects"},card_index:{keywords:["business","stationery"],char:'\ud83d\udcc7',fitzpatrick_scale:!1,category:"objects"},card_file_box:{keywords:["business","stationery"],char:'\ud83d\uddc3',fitzpatrick_scale:!1,category:"objects"},ballot_box:{keywords:["election","vote"],char:'\ud83d\uddf3',fitzpatrick_scale:!1,category:"objects"},file_cabinet:{keywords:["filing","organizing"],char:'\ud83d\uddc4',fitzpatrick_scale:!1,category:"objects"},clipboard:{keywords:["stationery","documents"],char:'\ud83d\udccb',fitzpatrick_scale:!1,category:"objects"},spiral_notepad:{keywords:["memo","stationery"],char:'\ud83d\uddd2',fitzpatrick_scale:!1,category:"objects"},file_folder:{keywords:["documents","business","office"],char:'\ud83d\udcc1',fitzpatrick_scale:!1,category:"objects"},open_file_folder:{keywords:["documents","load"],char:'\ud83d\udcc2',fitzpatrick_scale:!1,category:"objects"},card_index_dividers:{keywords:["organizing","business","stationery"],char:'\ud83d\uddc2',fitzpatrick_scale:!1,category:"objects"},newspaper_roll:{keywords:["press","headline"],char:'\ud83d\uddde',fitzpatrick_scale:!1,category:"objects"},newspaper:{keywords:["press","headline"],char:'\ud83d\udcf0',fitzpatrick_scale:!1,category:"objects"},notebook:{keywords:["stationery","record","notes","paper","study"],char:'\ud83d\udcd3',fitzpatrick_scale:!1,category:"objects"},closed_book:{keywords:["read","library","knowledge","textbook","learn"],char:'\ud83d\udcd5',fitzpatrick_scale:!1,category:"objects"},green_book:{keywords:["read","library","knowledge","study"],char:'\ud83d\udcd7',fitzpatrick_scale:!1,category:"objects"},blue_book:{keywords:["read","library","knowledge","learn","study"],char:'\ud83d\udcd8',fitzpatrick_scale:!1,category:"objects"},orange_book:{keywords:["read","library","knowledge","textbook","study"],char:'\ud83d\udcd9',fitzpatrick_scale:!1,category:"objects"},notebook_with_decorative_cover:{keywords:["classroom","notes","record","paper","study"],char:'\ud83d\udcd4',fitzpatrick_scale:!1,category:"objects"},ledger:{keywords:["notes","paper"],char:'\ud83d\udcd2',fitzpatrick_scale:!1,category:"objects"},books:{keywords:["literature","library","study"],char:'\ud83d\udcda',fitzpatrick_scale:!1,category:"objects"},open_book:{keywords:["book","read","library","knowledge","literature","learn","study"],char:'\ud83d\udcd6',fitzpatrick_scale:!1,category:"objects"},safety_pin:{keywords:["diaper"],char:'\ud83e\uddf7',fitzpatrick_scale:!1,category:"objects"},link:{keywords:["rings","url"],char:'\ud83d\udd17',fitzpatrick_scale:!1,category:"objects"},paperclip:{keywords:["documents","stationery"],char:'\ud83d\udcce',fitzpatrick_scale:!1,category:"objects"},paperclips:{keywords:["documents","stationery"],char:'\ud83d\udd87',fitzpatrick_scale:!1,category:"objects"},scissors:{keywords:["stationery","cut"],char:'\u2702\ufe0f',fitzpatrick_scale:!1,category:"objects"},triangular_ruler:{keywords:["stationery","math","architect","sketch"],char:'\ud83d\udcd0',fitzpatrick_scale:!1,category:"objects"},straight_ruler:{keywords:["stationery","calculate","length","math","school","drawing","architect","sketch"],char:'\ud83d\udccf',fitzpatrick_scale:!1,category:"objects"},abacus:{keywords:["calculation"],char:'\ud83e\uddee',fitzpatrick_scale:!1,category:"objects"},pushpin:{keywords:["stationery","mark","here"],char:'\ud83d\udccc',fitzpatrick_scale:!1,category:"objects"},round_pushpin:{keywords:["stationery","location","map","here"],char:'\ud83d\udccd',fitzpatrick_scale:!1,category:"objects"},triangular_flag_on_post:{keywords:["mark","milestone","place"],char:'\ud83d\udea9',fitzpatrick_scale:!1,category:"objects"},white_flag:{keywords:["losing","loser","lost","surrender","give up","fail"],char:'\ud83c\udff3',fitzpatrick_scale:!1,category:"objects"},black_flag:{keywords:["pirate"],char:'\ud83c\udff4',fitzpatrick_scale:!1,category:"objects"},rainbow_flag:{keywords:["flag","rainbow","pride","gay","lgbt","glbt","queer","homosexual","lesbian","bisexual","transgender"],char:'\ud83c\udff3\ufe0f\u200d\ud83c\udf08',fitzpatrick_scale:!1,category:"objects"},closed_lock_with_key:{keywords:["security","privacy"],char:'\ud83d\udd10',fitzpatrick_scale:!1,category:"objects"},lock:{keywords:["security","password","padlock"],char:'\ud83d\udd12',fitzpatrick_scale:!1,category:"objects"},unlock:{keywords:["privacy","security"],char:'\ud83d\udd13',fitzpatrick_scale:!1,category:"objects"},lock_with_ink_pen:{keywords:["security","secret"],char:'\ud83d\udd0f',fitzpatrick_scale:!1,category:"objects"},pen:{keywords:["stationery","writing","write"],char:'\ud83d\udd8a',fitzpatrick_scale:!1,category:"objects"},fountain_pen:{keywords:["stationery","writing","write"],char:'\ud83d\udd8b',fitzpatrick_scale:!1,category:"objects"},black_nib:{keywords:["pen","stationery","writing","write"],char:'\u2712\ufe0f',fitzpatrick_scale:!1,category:"objects"},memo:{keywords:["write","documents","stationery","pencil","paper","writing","legal","exam","quiz","test","study","compose"],char:'\ud83d\udcdd',fitzpatrick_scale:!1,category:"objects"},pencil2:{keywords:["stationery","write","paper","writing","school","study"],char:'\u270f\ufe0f',fitzpatrick_scale:!1,category:"objects"},crayon:{keywords:["drawing","creativity"],char:'\ud83d\udd8d',fitzpatrick_scale:!1,category:"objects"},paintbrush:{keywords:["drawing","creativity","art"],char:'\ud83d\udd8c',fitzpatrick_scale:!1,category:"objects"},mag:{keywords:["search","zoom","find","detective"],char:'\ud83d\udd0d',fitzpatrick_scale:!1,category:"objects"},mag_right:{keywords:["search","zoom","find","detective"],char:'\ud83d\udd0e',fitzpatrick_scale:!1,category:"objects"},heart:{keywords:["love","like","valentines"],char:'\u2764\ufe0f',fitzpatrick_scale:!1,category:"symbols"},orange_heart:{keywords:["love","like","affection","valentines"],char:'\ud83e\udde1',fitzpatrick_scale:!1,category:"symbols"},yellow_heart:{keywords:["love","like","affection","valentines"],char:'\ud83d\udc9b',fitzpatrick_scale:!1,category:"symbols"},green_heart:{keywords:["love","like","affection","valentines"],char:'\ud83d\udc9a',fitzpatrick_scale:!1,category:"symbols"},blue_heart:{keywords:["love","like","affection","valentines"],char:'\ud83d\udc99',fitzpatrick_scale:!1,category:"symbols"},purple_heart:{keywords:["love","like","affection","valentines"],char:'\ud83d\udc9c',fitzpatrick_scale:!1,category:"symbols"},black_heart:{keywords:["evil"],char:'\ud83d\udda4',fitzpatrick_scale:!1,category:"symbols"},broken_heart:{keywords:["sad","sorry","break","heart","heartbreak"],char:'\ud83d\udc94',fitzpatrick_scale:!1,category:"symbols"},heavy_heart_exclamation:{keywords:["decoration","love"],char:'\u2763',fitzpatrick_scale:!1,category:"symbols"},two_hearts:{keywords:["love","like","affection","valentines","heart"],char:'\ud83d\udc95',fitzpatrick_scale:!1,category:"symbols"},revolving_hearts:{keywords:["love","like","affection","valentines"],char:'\ud83d\udc9e',fitzpatrick_scale:!1,category:"symbols"},heartbeat:{keywords:["love","like","affection","valentines","pink","heart"],char:'\ud83d\udc93',fitzpatrick_scale:!1,category:"symbols"},heartpulse:{keywords:["like","love","affection","valentines","pink"],char:'\ud83d\udc97',fitzpatrick_scale:!1,category:"symbols"},sparkling_heart:{keywords:["love","like","affection","valentines"],char:'\ud83d\udc96',fitzpatrick_scale:!1,category:"symbols"},cupid:{keywords:["love","like","heart","affection","valentines"],char:'\ud83d\udc98',fitzpatrick_scale:!1,category:"symbols"},gift_heart:{keywords:["love","valentines"],char:'\ud83d\udc9d',fitzpatrick_scale:!1,category:"symbols"},heart_decoration:{keywords:["purple-square","love","like"],char:'\ud83d\udc9f',fitzpatrick_scale:!1,category:"symbols"},peace_symbol:{keywords:["hippie"],char:'\u262e',fitzpatrick_scale:!1,category:"symbols"},latin_cross:{keywords:["christianity"],char:'\u271d',fitzpatrick_scale:!1,category:"symbols"},star_and_crescent:{keywords:["islam"],char:'\u262a',fitzpatrick_scale:!1,category:"symbols"},om:{keywords:["hinduism","buddhism","sikhism","jainism"],char:'\ud83d\udd49',fitzpatrick_scale:!1,category:"symbols"},wheel_of_dharma:{keywords:["hinduism","buddhism","sikhism","jainism"],char:'\u2638',fitzpatrick_scale:!1,category:"symbols"},star_of_david:{keywords:["judaism"],char:'\u2721',fitzpatrick_scale:!1,category:"symbols"},six_pointed_star:{keywords:["purple-square","religion","jewish","hexagram"],char:'\ud83d\udd2f',fitzpatrick_scale:!1,category:"symbols"},menorah:{keywords:["hanukkah","candles","jewish"],char:'\ud83d\udd4e',fitzpatrick_scale:!1,category:"symbols"},yin_yang:{keywords:["balance"],char:'\u262f',fitzpatrick_scale:!1,category:"symbols"},orthodox_cross:{keywords:["suppedaneum","religion"],char:'\u2626',fitzpatrick_scale:!1,category:"symbols"},place_of_worship:{keywords:["religion","church","temple","prayer"],char:'\ud83d\uded0',fitzpatrick_scale:!1,category:"symbols"},ophiuchus:{keywords:["sign","purple-square","constellation","astrology"],char:'\u26ce',fitzpatrick_scale:!1,category:"symbols"},aries:{keywords:["sign","purple-square","zodiac","astrology"],char:'\u2648',fitzpatrick_scale:!1,category:"symbols"},taurus:{keywords:["purple-square","sign","zodiac","astrology"],char:'\u2649',fitzpatrick_scale:!1,category:"symbols"},gemini:{keywords:["sign","zodiac","purple-square","astrology"],char:'\u264a',fitzpatrick_scale:!1,category:"symbols"},cancer:{keywords:["sign","zodiac","purple-square","astrology"],char:'\u264b',fitzpatrick_scale:!1,category:"symbols"},leo:{keywords:["sign","purple-square","zodiac","astrology"],char:'\u264c',fitzpatrick_scale:!1,category:"symbols"},virgo:{keywords:["sign","zodiac","purple-square","astrology"],char:'\u264d',fitzpatrick_scale:!1,category:"symbols"},libra:{keywords:["sign","purple-square","zodiac","astrology"],char:'\u264e',fitzpatrick_scale:!1,category:"symbols"},scorpius:{keywords:["sign","zodiac","purple-square","astrology","scorpio"],char:'\u264f',fitzpatrick_scale:!1,category:"symbols"},sagittarius:{keywords:["sign","zodiac","purple-square","astrology"],char:'\u2650',fitzpatrick_scale:!1,category:"symbols"},capricorn:{keywords:["sign","zodiac","purple-square","astrology"],char:'\u2651',fitzpatrick_scale:!1,category:"symbols"},aquarius:{keywords:["sign","purple-square","zodiac","astrology"],char:'\u2652',fitzpatrick_scale:!1,category:"symbols"},pisces:{keywords:["purple-square","sign","zodiac","astrology"],char:'\u2653',fitzpatrick_scale:!1,category:"symbols"},id:{keywords:["purple-square","words"],char:'\ud83c\udd94',fitzpatrick_scale:!1,category:"symbols"},atom_symbol:{keywords:["science","physics","chemistry"],char:'\u269b',fitzpatrick_scale:!1,category:"symbols"},u7a7a:{keywords:["kanji","japanese","chinese","empty","sky","blue-square"],char:'\ud83c\ude33',fitzpatrick_scale:!1,category:"symbols"},u5272:{keywords:["cut","divide","chinese","kanji","pink-square"],char:'\ud83c\ude39',fitzpatrick_scale:!1,category:"symbols"},radioactive:{keywords:["nuclear","danger"],char:'\u2622',fitzpatrick_scale:!1,category:"symbols"},biohazard:{keywords:["danger"],char:'\u2623',fitzpatrick_scale:!1,category:"symbols"},mobile_phone_off:{keywords:["mute","orange-square","silence","quiet"],char:'\ud83d\udcf4',fitzpatrick_scale:!1,category:"symbols"},vibration_mode:{keywords:["orange-square","phone"],char:'\ud83d\udcf3',fitzpatrick_scale:!1,category:"symbols"},u6709:{keywords:["orange-square","chinese","have","kanji"],char:'\ud83c\ude36',fitzpatrick_scale:!1,category:"symbols"},u7121:{keywords:["nothing","chinese","kanji","japanese","orange-square"],char:'\ud83c\ude1a',fitzpatrick_scale:!1,category:"symbols"},u7533:{keywords:["chinese","japanese","kanji","orange-square"],char:'\ud83c\ude38',fitzpatrick_scale:!1,category:"symbols"},u55b6:{keywords:["japanese","opening hours","orange-square"],char:'\ud83c\ude3a',fitzpatrick_scale:!1,category:"symbols"},u6708:{keywords:["chinese","month","moon","japanese","orange-square","kanji"],char:'\ud83c\ude37\ufe0f',fitzpatrick_scale:!1,category:"symbols"},eight_pointed_black_star:{keywords:["orange-square","shape","polygon"],char:'\u2734\ufe0f',fitzpatrick_scale:!1,category:"symbols"},vs:{keywords:["words","orange-square"],char:'\ud83c\udd9a',fitzpatrick_scale:!1,category:"symbols"},accept:{keywords:["ok","good","chinese","kanji","agree","yes","orange-circle"],char:'\ud83c\ude51',fitzpatrick_scale:!1,category:"symbols"},white_flower:{keywords:["japanese","spring"],char:'\ud83d\udcae',fitzpatrick_scale:!1,category:"symbols"},ideograph_advantage:{keywords:["chinese","kanji","obtain","get","circle"],char:'\ud83c\ude50',fitzpatrick_scale:!1,category:"symbols"},secret:{keywords:["privacy","chinese","sshh","kanji","red-circle"],char:'\u3299\ufe0f',fitzpatrick_scale:!1,category:"symbols"},congratulations:{keywords:["chinese","kanji","japanese","red-circle"],char:'\u3297\ufe0f',fitzpatrick_scale:!1,category:"symbols"},u5408:{keywords:["japanese","chinese","join","kanji","red-square"],char:'\ud83c\ude34',fitzpatrick_scale:!1,category:"symbols"},u6e80:{keywords:["full","chinese","japanese","red-square","kanji"],char:'\ud83c\ude35',fitzpatrick_scale:!1,category:"symbols"},u7981:{keywords:["kanji","japanese","chinese","forbidden","limit","restricted","red-square"],char:'\ud83c\ude32',fitzpatrick_scale:!1,category:"symbols"},a:{keywords:["red-square","alphabet","letter"],char:'\ud83c\udd70\ufe0f',fitzpatrick_scale:!1,category:"symbols"},b:{keywords:["red-square","alphabet","letter"],char:'\ud83c\udd71\ufe0f',fitzpatrick_scale:!1,category:"symbols"},ab:{keywords:["red-square","alphabet"],char:'\ud83c\udd8e',fitzpatrick_scale:!1,category:"symbols"},cl:{keywords:["alphabet","words","red-square"],char:'\ud83c\udd91',fitzpatrick_scale:!1,category:"symbols"},o2:{keywords:["alphabet","red-square","letter"],char:'\ud83c\udd7e\ufe0f',fitzpatrick_scale:!1,category:"symbols"},sos:{keywords:["help","red-square","words","emergency","911"],char:'\ud83c\udd98',fitzpatrick_scale:!1,category:"symbols"},no_entry:{keywords:["limit","security","privacy","bad","denied","stop","circle"],char:'\u26d4',fitzpatrick_scale:!1,category:"symbols"},name_badge:{keywords:["fire","forbid"],char:'\ud83d\udcdb',fitzpatrick_scale:!1,category:"symbols"},no_entry_sign:{keywords:["forbid","stop","limit","denied","disallow","circle"],char:'\ud83d\udeab',fitzpatrick_scale:!1,category:"symbols"},x:{keywords:["no","delete","remove","cancel","red"],char:'\u274c',fitzpatrick_scale:!1,category:"symbols"},o:{keywords:["circle","round"],char:'\u2b55',fitzpatrick_scale:!1,category:"symbols"},stop_sign:{keywords:["stop"],char:'\ud83d\uded1',fitzpatrick_scale:!1,category:"symbols"},anger:{keywords:["angry","mad"],char:'\ud83d\udca2',fitzpatrick_scale:!1,category:"symbols"},hotsprings:{keywords:["bath","warm","relax"],char:'\u2668\ufe0f',fitzpatrick_scale:!1,category:"symbols"},no_pedestrians:{keywords:["rules","crossing","walking","circle"],char:'\ud83d\udeb7',fitzpatrick_scale:!1,category:"symbols"},do_not_litter:{keywords:["trash","bin","garbage","circle"],char:'\ud83d\udeaf',fitzpatrick_scale:!1,category:"symbols"},no_bicycles:{keywords:["cyclist","prohibited","circle"],char:'\ud83d\udeb3',fitzpatrick_scale:!1,category:"symbols"},"non-potable_water":{keywords:["drink","faucet","tap","circle"],char:'\ud83d\udeb1',fitzpatrick_scale:!1,category:"symbols"},underage:{keywords:["18","drink","pub","night","minor","circle"],char:'\ud83d\udd1e',fitzpatrick_scale:!1,category:"symbols"},no_mobile_phones:{keywords:["iphone","mute","circle"],char:'\ud83d\udcf5',fitzpatrick_scale:!1,category:"symbols"},exclamation:{keywords:["heavy_exclamation_mark","danger","surprise","punctuation","wow","warning"],char:'\u2757',fitzpatrick_scale:!1,category:"symbols"},grey_exclamation:{keywords:["surprise","punctuation","gray","wow","warning"],char:'\u2755',fitzpatrick_scale:!1,category:"symbols"},question:{keywords:["doubt","confused"],char:'\u2753',fitzpatrick_scale:!1,category:"symbols"},grey_question:{keywords:["doubts","gray","huh","confused"],char:'\u2754',fitzpatrick_scale:!1,category:"symbols"},bangbang:{keywords:["exclamation","surprise"],char:'\u203c\ufe0f',fitzpatrick_scale:!1,category:"symbols"},interrobang:{keywords:["wat","punctuation","surprise"],char:'\u2049\ufe0f',fitzpatrick_scale:!1,category:"symbols"},low_brightness:{keywords:["sun","afternoon","warm","summer"],char:'\ud83d\udd05',fitzpatrick_scale:!1,category:"symbols"},high_brightness:{keywords:["sun","light"],char:'\ud83d\udd06',fitzpatrick_scale:!1,category:"symbols"},trident:{keywords:["weapon","spear"],char:'\ud83d\udd31',fitzpatrick_scale:!1,category:"symbols"},fleur_de_lis:{keywords:["decorative","scout"],char:'\u269c',fitzpatrick_scale:!1,category:"symbols"},part_alternation_mark:{keywords:["graph","presentation","stats","business","economics","bad"],char:'\u303d\ufe0f',fitzpatrick_scale:!1,category:"symbols"},warning:{keywords:["exclamation","wip","alert","error","problem","issue"],char:'\u26a0\ufe0f',fitzpatrick_scale:!1,category:"symbols"},children_crossing:{keywords:["school","warning","danger","sign","driving","yellow-diamond"],char:'\ud83d\udeb8',fitzpatrick_scale:!1,category:"symbols"},beginner:{keywords:["badge","shield"],char:'\ud83d\udd30',fitzpatrick_scale:!1,category:"symbols"},recycle:{keywords:["arrow","environment","garbage","trash"],char:'\u267b\ufe0f',fitzpatrick_scale:!1,category:"symbols"},u6307:{keywords:["chinese","point","green-square","kanji"],char:'\ud83c\ude2f',fitzpatrick_scale:!1,category:"symbols"},chart:{keywords:["green-square","graph","presentation","stats"],char:'\ud83d\udcb9',fitzpatrick_scale:!1,category:"symbols"},sparkle:{keywords:["stars","green-square","awesome","good","fireworks"],char:'\u2747\ufe0f',fitzpatrick_scale:!1,category:"symbols"},eight_spoked_asterisk:{keywords:["star","sparkle","green-square"],char:'\u2733\ufe0f',fitzpatrick_scale:!1,category:"symbols"},negative_squared_cross_mark:{keywords:["x","green-square","no","deny"],char:'\u274e',fitzpatrick_scale:!1,category:"symbols"},white_check_mark:{keywords:["green-square","ok","agree","vote","election","answer","tick"],char:'\u2705',fitzpatrick_scale:!1,category:"symbols"},diamond_shape_with_a_dot_inside:{keywords:["jewel","blue","gem","crystal","fancy"],char:'\ud83d\udca0',fitzpatrick_scale:!1,category:"symbols"},cyclone:{keywords:["weather","swirl","blue","cloud","vortex","spiral","whirlpool","spin","tornado","hurricane","typhoon"],char:'\ud83c\udf00',fitzpatrick_scale:!1,category:"symbols"},loop:{keywords:["tape","cassette"],char:'\u27bf',fitzpatrick_scale:!1,category:"symbols"},globe_with_meridians:{keywords:["earth","international","world","internet","interweb","i18n"],char:'\ud83c\udf10',fitzpatrick_scale:!1,category:"symbols"},m:{keywords:["alphabet","blue-circle","letter"],char:'\u24c2\ufe0f',fitzpatrick_scale:!1,category:"symbols"},atm:{keywords:["money","sales","cash","blue-square","payment","bank"],char:'\ud83c\udfe7',fitzpatrick_scale:!1,category:"symbols"},sa:{keywords:["japanese","blue-square","katakana"],char:'\ud83c\ude02\ufe0f',fitzpatrick_scale:!1,category:"symbols"},passport_control:{keywords:["custom","blue-square"],char:'\ud83d\udec2',fitzpatrick_scale:!1,category:"symbols"},customs:{keywords:["passport","border","blue-square"],char:'\ud83d\udec3',fitzpatrick_scale:!1,category:"symbols"},baggage_claim:{keywords:["blue-square","airport","transport"],char:'\ud83d\udec4',fitzpatrick_scale:!1,category:"symbols"},left_luggage:{keywords:["blue-square","travel"],char:'\ud83d\udec5',fitzpatrick_scale:!1,category:"symbols"},wheelchair:{keywords:["blue-square","disabled","a11y","accessibility"],char:'\u267f',fitzpatrick_scale:!1,category:"symbols"},no_smoking:{keywords:["cigarette","blue-square","smell","smoke"],char:'\ud83d\udead',fitzpatrick_scale:!1,category:"symbols"},wc:{keywords:["toilet","restroom","blue-square"],char:'\ud83d\udebe',fitzpatrick_scale:!1,category:"symbols"},parking:{keywords:["cars","blue-square","alphabet","letter"],char:'\ud83c\udd7f\ufe0f',fitzpatrick_scale:!1,category:"symbols"},potable_water:{keywords:["blue-square","liquid","restroom","cleaning","faucet"],char:'\ud83d\udeb0',fitzpatrick_scale:!1,category:"symbols"},mens:{keywords:["toilet","restroom","wc","blue-square","gender","male"],char:'\ud83d\udeb9',fitzpatrick_scale:!1,category:"symbols"},womens:{keywords:["purple-square","woman","female","toilet","loo","restroom","gender"],char:'\ud83d\udeba',fitzpatrick_scale:!1,category:"symbols"},baby_symbol:{keywords:["orange-square","child"],char:'\ud83d\udebc',fitzpatrick_scale:!1,category:"symbols"},restroom:{keywords:["blue-square","toilet","refresh","wc","gender"],char:'\ud83d\udebb',fitzpatrick_scale:!1,category:"symbols"},put_litter_in_its_place:{keywords:["blue-square","sign","human","info"],char:'\ud83d\udeae',fitzpatrick_scale:!1,category:"symbols"},cinema:{keywords:["blue-square","record","film","movie","curtain","stage","theater"],char:'\ud83c\udfa6',fitzpatrick_scale:!1,category:"symbols"},signal_strength:{keywords:["blue-square","reception","phone","internet","connection","wifi","bluetooth","bars"],char:'\ud83d\udcf6',fitzpatrick_scale:!1,category:"symbols"},koko:{keywords:["blue-square","here","katakana","japanese","destination"],char:'\ud83c\ude01',fitzpatrick_scale:!1,category:"symbols"},ng:{keywords:["blue-square","words","shape","icon"],char:'\ud83c\udd96',fitzpatrick_scale:!1,category:"symbols"},ok:{keywords:["good","agree","yes","blue-square"],char:'\ud83c\udd97',fitzpatrick_scale:!1,category:"symbols"},up:{keywords:["blue-square","above","high"],char:'\ud83c\udd99',fitzpatrick_scale:!1,category:"symbols"},cool:{keywords:["words","blue-square"],char:'\ud83c\udd92',fitzpatrick_scale:!1,category:"symbols"},new:{keywords:["blue-square","words","start"],char:'\ud83c\udd95',fitzpatrick_scale:!1,category:"symbols"},free:{keywords:["blue-square","words"],char:'\ud83c\udd93',fitzpatrick_scale:!1,category:"symbols"},zero:{keywords:["0","numbers","blue-square","null"],char:'0\ufe0f\u20e3',fitzpatrick_scale:!1,category:"symbols"},one:{keywords:["blue-square","numbers","1"],char:'1\ufe0f\u20e3',fitzpatrick_scale:!1,category:"symbols"},two:{keywords:["numbers","2","prime","blue-square"],char:'2\ufe0f\u20e3',fitzpatrick_scale:!1,category:"symbols"},three:{keywords:["3","numbers","prime","blue-square"],char:'3\ufe0f\u20e3',fitzpatrick_scale:!1,category:"symbols"},four:{keywords:["4","numbers","blue-square"],char:'4\ufe0f\u20e3',fitzpatrick_scale:!1,category:"symbols"},five:{keywords:["5","numbers","blue-square","prime"],char:'5\ufe0f\u20e3',fitzpatrick_scale:!1,category:"symbols"},six:{keywords:["6","numbers","blue-square"],char:'6\ufe0f\u20e3',fitzpatrick_scale:!1,category:"symbols"},seven:{keywords:["7","numbers","blue-square","prime"],char:'7\ufe0f\u20e3',fitzpatrick_scale:!1,category:"symbols"},eight:{keywords:["8","blue-square","numbers"],char:'8\ufe0f\u20e3',fitzpatrick_scale:!1,category:"symbols"},nine:{keywords:["blue-square","numbers","9"],char:'9\ufe0f\u20e3',fitzpatrick_scale:!1,category:"symbols"},keycap_ten:{keywords:["numbers","10","blue-square"],char:'\ud83d\udd1f',fitzpatrick_scale:!1,category:"symbols"},asterisk:{keywords:["star","keycap"],char:'*\u20e3',fitzpatrick_scale:!1,category:"symbols"},eject_button:{keywords:["blue-square"],char:'\u23cf\ufe0f',fitzpatrick_scale:!1,category:"symbols"},arrow_forward:{keywords:["blue-square","right","direction","play"],char:'\u25b6\ufe0f',fitzpatrick_scale:!1,category:"symbols"},pause_button:{keywords:["pause","blue-square"],char:'\u23f8',fitzpatrick_scale:!1,category:"symbols"},next_track_button:{keywords:["forward","next","blue-square"],char:'\u23ed',fitzpatrick_scale:!1,category:"symbols"},stop_button:{keywords:["blue-square"],char:'\u23f9',fitzpatrick_scale:!1,category:"symbols"},record_button:{keywords:["blue-square"],char:'\u23fa',fitzpatrick_scale:!1,category:"symbols"},play_or_pause_button:{keywords:["blue-square","play","pause"],char:'\u23ef',fitzpatrick_scale:!1,category:"symbols"},previous_track_button:{keywords:["backward"],char:'\u23ee',fitzpatrick_scale:!1,category:"symbols"},fast_forward:{keywords:["blue-square","play","speed","continue"],char:'\u23e9',fitzpatrick_scale:!1,category:"symbols"},rewind:{keywords:["play","blue-square"],char:'\u23ea',fitzpatrick_scale:!1,category:"symbols"},twisted_rightwards_arrows:{keywords:["blue-square","shuffle","music","random"],char:'\ud83d\udd00',fitzpatrick_scale:!1,category:"symbols"},repeat:{keywords:["loop","record"],char:'\ud83d\udd01',fitzpatrick_scale:!1,category:"symbols"},repeat_one:{keywords:["blue-square","loop"],char:'\ud83d\udd02',fitzpatrick_scale:!1,category:"symbols"},arrow_backward:{keywords:["blue-square","left","direction"],char:'\u25c0\ufe0f',fitzpatrick_scale:!1,category:"symbols"},arrow_up_small:{keywords:["blue-square","triangle","direction","point","forward","top"],char:'\ud83d\udd3c',fitzpatrick_scale:!1,category:"symbols"},arrow_down_small:{keywords:["blue-square","direction","bottom"],char:'\ud83d\udd3d',fitzpatrick_scale:!1,category:"symbols"},arrow_double_up:{keywords:["blue-square","direction","top"],char:'\u23eb',fitzpatrick_scale:!1,category:"symbols"},arrow_double_down:{keywords:["blue-square","direction","bottom"],char:'\u23ec',fitzpatrick_scale:!1,category:"symbols"},arrow_right:{keywords:["blue-square","next"],char:'\u27a1\ufe0f',fitzpatrick_scale:!1,category:"symbols"},arrow_left:{keywords:["blue-square","previous","back"],char:'\u2b05\ufe0f',fitzpatrick_scale:!1,category:"symbols"},arrow_up:{keywords:["blue-square","continue","top","direction"],char:'\u2b06\ufe0f',fitzpatrick_scale:!1,category:"symbols"},arrow_down:{keywords:["blue-square","direction","bottom"],char:'\u2b07\ufe0f',fitzpatrick_scale:!1,category:"symbols"},arrow_upper_right:{keywords:["blue-square","point","direction","diagonal","northeast"],char:'\u2197\ufe0f',fitzpatrick_scale:!1,category:"symbols"},arrow_lower_right:{keywords:["blue-square","direction","diagonal","southeast"],char:'\u2198\ufe0f',fitzpatrick_scale:!1,category:"symbols"},arrow_lower_left:{keywords:["blue-square","direction","diagonal","southwest"],char:'\u2199\ufe0f',fitzpatrick_scale:!1,category:"symbols"},arrow_upper_left:{keywords:["blue-square","point","direction","diagonal","northwest"],char:'\u2196\ufe0f',fitzpatrick_scale:!1,category:"symbols"},arrow_up_down:{keywords:["blue-square","direction","way","vertical"],char:'\u2195\ufe0f',fitzpatrick_scale:!1,category:"symbols"},left_right_arrow:{keywords:["shape","direction","horizontal","sideways"],char:'\u2194\ufe0f',fitzpatrick_scale:!1,category:"symbols"},arrows_counterclockwise:{keywords:["blue-square","sync","cycle"],char:'\ud83d\udd04',fitzpatrick_scale:!1,category:"symbols"},arrow_right_hook:{keywords:["blue-square","return","rotate","direction"],char:'\u21aa\ufe0f',fitzpatrick_scale:!1,category:"symbols"},leftwards_arrow_with_hook:{keywords:["back","return","blue-square","undo","enter"],char:'\u21a9\ufe0f',fitzpatrick_scale:!1,category:"symbols"},arrow_heading_up:{keywords:["blue-square","direction","top"],char:'\u2934\ufe0f',fitzpatrick_scale:!1,category:"symbols"},arrow_heading_down:{keywords:["blue-square","direction","bottom"],char:'\u2935\ufe0f',fitzpatrick_scale:!1,category:"symbols"},hash:{keywords:["symbol","blue-square","twitter"],char:'#\ufe0f\u20e3',fitzpatrick_scale:!1,category:"symbols"},information_source:{keywords:["blue-square","alphabet","letter"],char:'\u2139\ufe0f',fitzpatrick_scale:!1,category:"symbols"},abc:{keywords:["blue-square","alphabet"],char:'\ud83d\udd24',fitzpatrick_scale:!1,category:"symbols"},abcd:{keywords:["blue-square","alphabet"],char:'\ud83d\udd21',fitzpatrick_scale:!1,category:"symbols"},capital_abcd:{keywords:["alphabet","words","blue-square"],char:'\ud83d\udd20',fitzpatrick_scale:!1,category:"symbols"},symbols:{keywords:["blue-square","music","note","ampersand","percent","glyphs","characters"],char:'\ud83d\udd23',fitzpatrick_scale:!1,category:"symbols"},musical_note:{keywords:["score","tone","sound"],char:'\ud83c\udfb5',fitzpatrick_scale:!1,category:"symbols"},notes:{keywords:["music","score"],char:'\ud83c\udfb6',fitzpatrick_scale:!1,category:"symbols"},wavy_dash:{keywords:["draw","line","moustache","mustache","squiggle","scribble"],char:'\u3030\ufe0f',fitzpatrick_scale:!1,category:"symbols"},curly_loop:{keywords:["scribble","draw","shape","squiggle"],char:'\u27b0',fitzpatrick_scale:!1,category:"symbols"},heavy_check_mark:{keywords:["ok","nike","answer","yes","tick"],char:'\u2714\ufe0f',fitzpatrick_scale:!1,category:"symbols"},arrows_clockwise:{keywords:["sync","cycle","round","repeat"],char:'\ud83d\udd03',fitzpatrick_scale:!1,category:"symbols"},heavy_plus_sign:{keywords:["math","calculation","addition","more","increase"],char:'\u2795',fitzpatrick_scale:!1,category:"symbols"},heavy_minus_sign:{keywords:["math","calculation","subtract","less"],char:'\u2796',fitzpatrick_scale:!1,category:"symbols"},heavy_division_sign:{keywords:["divide","math","calculation"],char:'\u2797',fitzpatrick_scale:!1,category:"symbols"},heavy_multiplication_x:{keywords:["math","calculation"],char:'\u2716\ufe0f',fitzpatrick_scale:!1,category:"symbols"},infinity:{keywords:["forever"],char:'\u267e',fitzpatrick_scale:!1,category:"symbols"},heavy_dollar_sign:{keywords:["money","sales","payment","currency","buck"],char:'\ud83d\udcb2',fitzpatrick_scale:!1,category:"symbols"},currency_exchange:{keywords:["money","sales","dollar","travel"],char:'\ud83d\udcb1',fitzpatrick_scale:!1,category:"symbols"},copyright:{keywords:["ip","license","circle","law","legal"],char:'\xa9\ufe0f',fitzpatrick_scale:!1,category:"symbols"},registered:{keywords:["alphabet","circle"],char:'\xae\ufe0f',fitzpatrick_scale:!1,category:"symbols"},tm:{keywords:["trademark","brand","law","legal"],char:'\u2122\ufe0f',fitzpatrick_scale:!1,category:"symbols"},end:{keywords:["words","arrow"],char:'\ud83d\udd1a',fitzpatrick_scale:!1,category:"symbols"},back:{keywords:["arrow","words","return"],char:'\ud83d\udd19',fitzpatrick_scale:!1,category:"symbols"},on:{keywords:["arrow","words"],char:'\ud83d\udd1b',fitzpatrick_scale:!1,category:"symbols"},top:{keywords:["words","blue-square"],char:'\ud83d\udd1d',fitzpatrick_scale:!1,category:"symbols"},soon:{keywords:["arrow","words"],char:'\ud83d\udd1c',fitzpatrick_scale:!1,category:"symbols"},ballot_box_with_check:{keywords:["ok","agree","confirm","black-square","vote","election","yes","tick"],char:'\u2611\ufe0f',fitzpatrick_scale:!1,category:"symbols"},radio_button:{keywords:["input","old","music","circle"],char:'\ud83d\udd18',fitzpatrick_scale:!1,category:"symbols"},white_circle:{keywords:["shape","round"],char:'\u26aa',fitzpatrick_scale:!1,category:"symbols"},black_circle:{keywords:["shape","button","round"],char:'\u26ab',fitzpatrick_scale:!1,category:"symbols"},red_circle:{keywords:["shape","error","danger"],char:'\ud83d\udd34',fitzpatrick_scale:!1,category:"symbols"},large_blue_circle:{keywords:["shape","icon","button"],char:'\ud83d\udd35',fitzpatrick_scale:!1,category:"symbols"},small_orange_diamond:{keywords:["shape","jewel","gem"],char:'\ud83d\udd38',fitzpatrick_scale:!1,category:"symbols"},small_blue_diamond:{keywords:["shape","jewel","gem"],char:'\ud83d\udd39',fitzpatrick_scale:!1,category:"symbols"},large_orange_diamond:{keywords:["shape","jewel","gem"],char:'\ud83d\udd36',fitzpatrick_scale:!1,category:"symbols"},large_blue_diamond:{keywords:["shape","jewel","gem"],char:'\ud83d\udd37',fitzpatrick_scale:!1,category:"symbols"},small_red_triangle:{keywords:["shape","direction","up","top"],char:'\ud83d\udd3a',fitzpatrick_scale:!1,category:"symbols"},black_small_square:{keywords:["shape","icon"],char:'\u25aa\ufe0f',fitzpatrick_scale:!1,category:"symbols"},white_small_square:{keywords:["shape","icon"],char:'\u25ab\ufe0f',fitzpatrick_scale:!1,category:"symbols"},black_large_square:{keywords:["shape","icon","button"],char:'\u2b1b',fitzpatrick_scale:!1,category:"symbols"},white_large_square:{keywords:["shape","icon","stone","button"],char:'\u2b1c',fitzpatrick_scale:!1,category:"symbols"},small_red_triangle_down:{keywords:["shape","direction","bottom"],char:'\ud83d\udd3b',fitzpatrick_scale:!1,category:"symbols"},black_medium_square:{keywords:["shape","button","icon"],char:'\u25fc\ufe0f',fitzpatrick_scale:!1,category:"symbols"},white_medium_square:{keywords:["shape","stone","icon"],char:'\u25fb\ufe0f',fitzpatrick_scale:!1,category:"symbols"},black_medium_small_square:{keywords:["icon","shape","button"],char:'\u25fe',fitzpatrick_scale:!1,category:"symbols"},white_medium_small_square:{keywords:["shape","stone","icon","button"],char:'\u25fd',fitzpatrick_scale:!1,category:"symbols"},black_square_button:{keywords:["shape","input","frame"],char:'\ud83d\udd32',fitzpatrick_scale:!1,category:"symbols"},white_square_button:{keywords:["shape","input"],char:'\ud83d\udd33',fitzpatrick_scale:!1,category:"symbols"},speaker:{keywords:["sound","volume","silence","broadcast"],char:'\ud83d\udd08',fitzpatrick_scale:!1,category:"symbols"},sound:{keywords:["volume","speaker","broadcast"],char:'\ud83d\udd09',fitzpatrick_scale:!1,category:"symbols"},loud_sound:{keywords:["volume","noise","noisy","speaker","broadcast"],char:'\ud83d\udd0a',fitzpatrick_scale:!1,category:"symbols"},mute:{keywords:["sound","volume","silence","quiet"],char:'\ud83d\udd07',fitzpatrick_scale:!1,category:"symbols"},mega:{keywords:["sound","speaker","volume"],char:'\ud83d\udce3',fitzpatrick_scale:!1,category:"symbols"},loudspeaker:{keywords:["volume","sound"],char:'\ud83d\udce2',fitzpatrick_scale:!1,category:"symbols"},bell:{keywords:["sound","notification","christmas","xmas","chime"],char:'\ud83d\udd14',fitzpatrick_scale:!1,category:"symbols"},no_bell:{keywords:["sound","volume","mute","quiet","silent"],char:'\ud83d\udd15',fitzpatrick_scale:!1,category:"symbols"},black_joker:{keywords:["poker","cards","game","play","magic"],char:'\ud83c\udccf',fitzpatrick_scale:!1,category:"symbols"},mahjong:{keywords:["game","play","chinese","kanji"],char:'\ud83c\udc04',fitzpatrick_scale:!1,category:"symbols"},spades:{keywords:["poker","cards","suits","magic"],char:'\u2660\ufe0f',fitzpatrick_scale:!1,category:"symbols"},clubs:{keywords:["poker","cards","magic","suits"],char:'\u2663\ufe0f',fitzpatrick_scale:!1,category:"symbols"},hearts:{keywords:["poker","cards","magic","suits"],char:'\u2665\ufe0f',fitzpatrick_scale:!1,category:"symbols"},diamonds:{keywords:["poker","cards","magic","suits"],char:'\u2666\ufe0f',fitzpatrick_scale:!1,category:"symbols"},flower_playing_cards:{keywords:["game","sunset","red"],char:'\ud83c\udfb4',fitzpatrick_scale:!1,category:"symbols"},thought_balloon:{keywords:["bubble","cloud","speech","thinking","dream"],char:'\ud83d\udcad',fitzpatrick_scale:!1,category:"symbols"},right_anger_bubble:{keywords:["caption","speech","thinking","mad"],char:'\ud83d\uddef',fitzpatrick_scale:!1,category:"symbols"},speech_balloon:{keywords:["bubble","words","message","talk","chatting"],char:'\ud83d\udcac',fitzpatrick_scale:!1,category:"symbols"},left_speech_bubble:{keywords:["words","message","talk","chatting"],char:'\ud83d\udde8',fitzpatrick_scale:!1,category:"symbols"},clock1:{keywords:["time","late","early","schedule"],char:'\ud83d\udd50',fitzpatrick_scale:!1,category:"symbols"},clock2:{keywords:["time","late","early","schedule"],char:'\ud83d\udd51',fitzpatrick_scale:!1,category:"symbols"},clock3:{keywords:["time","late","early","schedule"],char:'\ud83d\udd52',fitzpatrick_scale:!1,category:"symbols"},clock4:{keywords:["time","late","early","schedule"],char:'\ud83d\udd53',fitzpatrick_scale:!1,category:"symbols"},clock5:{keywords:["time","late","early","schedule"],char:'\ud83d\udd54',fitzpatrick_scale:!1,category:"symbols"},clock6:{keywords:["time","late","early","schedule","dawn","dusk"],char:'\ud83d\udd55',fitzpatrick_scale:!1,category:"symbols"},clock7:{keywords:["time","late","early","schedule"],char:'\ud83d\udd56',fitzpatrick_scale:!1,category:"symbols"},clock8:{keywords:["time","late","early","schedule"],char:'\ud83d\udd57',fitzpatrick_scale:!1,category:"symbols"},clock9:{keywords:["time","late","early","schedule"],char:'\ud83d\udd58',fitzpatrick_scale:!1,category:"symbols"},clock10:{keywords:["time","late","early","schedule"],char:'\ud83d\udd59',fitzpatrick_scale:!1,category:"symbols"},clock11:{keywords:["time","late","early","schedule"],char:'\ud83d\udd5a',fitzpatrick_scale:!1,category:"symbols"},clock12:{keywords:["time","noon","midnight","midday","late","early","schedule"],char:'\ud83d\udd5b',fitzpatrick_scale:!1,category:"symbols"},clock130:{keywords:["time","late","early","schedule"],char:'\ud83d\udd5c',fitzpatrick_scale:!1,category:"symbols"},clock230:{keywords:["time","late","early","schedule"],char:'\ud83d\udd5d',fitzpatrick_scale:!1,category:"symbols"},clock330:{keywords:["time","late","early","schedule"],char:'\ud83d\udd5e',fitzpatrick_scale:!1,category:"symbols"},clock430:{keywords:["time","late","early","schedule"],char:'\ud83d\udd5f',fitzpatrick_scale:!1,category:"symbols"},clock530:{keywords:["time","late","early","schedule"],char:'\ud83d\udd60',fitzpatrick_scale:!1,category:"symbols"},clock630:{keywords:["time","late","early","schedule"],char:'\ud83d\udd61',fitzpatrick_scale:!1,category:"symbols"},clock730:{keywords:["time","late","early","schedule"],char:'\ud83d\udd62',fitzpatrick_scale:!1,category:"symbols"},clock830:{keywords:["time","late","early","schedule"],char:'\ud83d\udd63',fitzpatrick_scale:!1,category:"symbols"},clock930:{keywords:["time","late","early","schedule"],char:'\ud83d\udd64',fitzpatrick_scale:!1,category:"symbols"},clock1030:{keywords:["time","late","early","schedule"],char:'\ud83d\udd65',fitzpatrick_scale:!1,category:"symbols"},clock1130:{keywords:["time","late","early","schedule"],char:'\ud83d\udd66',fitzpatrick_scale:!1,category:"symbols"},clock1230:{keywords:["time","late","early","schedule"],char:'\ud83d\udd67',fitzpatrick_scale:!1,category:"symbols"},afghanistan:{keywords:["af","flag","nation","country","banner"],char:'\ud83c\udde6\ud83c\uddeb',fitzpatrick_scale:!1,category:"flags"},aland_islands:{keywords:["\xc5land","islands","flag","nation","country","banner"],char:'\ud83c\udde6\ud83c\uddfd',fitzpatrick_scale:!1,category:"flags"},albania:{keywords:["al","flag","nation","country","banner"],char:'\ud83c\udde6\ud83c\uddf1',fitzpatrick_scale:!1,category:"flags"},algeria:{keywords:["dz","flag","nation","country","banner"],char:'\ud83c\udde9\ud83c\uddff',fitzpatrick_scale:!1,category:"flags"},american_samoa:{keywords:["american","ws","flag","nation","country","banner"],char:'\ud83c\udde6\ud83c\uddf8',fitzpatrick_scale:!1,category:"flags"},andorra:{keywords:["ad","flag","nation","country","banner"],char:'\ud83c\udde6\ud83c\udde9',fitzpatrick_scale:!1,category:"flags"},angola:{keywords:["ao","flag","nation","country","banner"],char:'\ud83c\udde6\ud83c\uddf4',fitzpatrick_scale:!1,category:"flags"},anguilla:{keywords:["ai","flag","nation","country","banner"],char:'\ud83c\udde6\ud83c\uddee',fitzpatrick_scale:!1,category:"flags"},antarctica:{keywords:["aq","flag","nation","country","banner"],char:'\ud83c\udde6\ud83c\uddf6',fitzpatrick_scale:!1,category:"flags"},antigua_barbuda:{keywords:["antigua","barbuda","flag","nation","country","banner"],char:'\ud83c\udde6\ud83c\uddec',fitzpatrick_scale:!1,category:"flags"},argentina:{keywords:["ar","flag","nation","country","banner"],char:'\ud83c\udde6\ud83c\uddf7',fitzpatrick_scale:!1,category:"flags"},armenia:{keywords:["am","flag","nation","country","banner"],char:'\ud83c\udde6\ud83c\uddf2',fitzpatrick_scale:!1,category:"flags"},aruba:{keywords:["aw","flag","nation","country","banner"],char:'\ud83c\udde6\ud83c\uddfc',fitzpatrick_scale:!1,category:"flags"},australia:{keywords:["au","flag","nation","country","banner"],char:'\ud83c\udde6\ud83c\uddfa',fitzpatrick_scale:!1,category:"flags"},austria:{keywords:["at","flag","nation","country","banner"],char:'\ud83c\udde6\ud83c\uddf9',fitzpatrick_scale:!1,category:"flags"},azerbaijan:{keywords:["az","flag","nation","country","banner"],char:'\ud83c\udde6\ud83c\uddff',fitzpatrick_scale:!1,category:"flags"},bahamas:{keywords:["bs","flag","nation","country","banner"],char:'\ud83c\udde7\ud83c\uddf8',fitzpatrick_scale:!1,category:"flags"},bahrain:{keywords:["bh","flag","nation","country","banner"],char:'\ud83c\udde7\ud83c\udded',fitzpatrick_scale:!1,category:"flags"},bangladesh:{keywords:["bd","flag","nation","country","banner"],char:'\ud83c\udde7\ud83c\udde9',fitzpatrick_scale:!1,category:"flags"},barbados:{keywords:["bb","flag","nation","country","banner"],char:'\ud83c\udde7\ud83c\udde7',fitzpatrick_scale:!1,category:"flags"},belarus:{keywords:["by","flag","nation","country","banner"],char:'\ud83c\udde7\ud83c\uddfe',fitzpatrick_scale:!1,category:"flags"},belgium:{keywords:["be","flag","nation","country","banner"],char:'\ud83c\udde7\ud83c\uddea',fitzpatrick_scale:!1,category:"flags"},belize:{keywords:["bz","flag","nation","country","banner"],char:'\ud83c\udde7\ud83c\uddff',fitzpatrick_scale:!1,category:"flags"},benin:{keywords:["bj","flag","nation","country","banner"],char:'\ud83c\udde7\ud83c\uddef',fitzpatrick_scale:!1,category:"flags"},bermuda:{keywords:["bm","flag","nation","country","banner"],char:'\ud83c\udde7\ud83c\uddf2',fitzpatrick_scale:!1,category:"flags"},bhutan:{keywords:["bt","flag","nation","country","banner"],char:'\ud83c\udde7\ud83c\uddf9',fitzpatrick_scale:!1,category:"flags"},bolivia:{keywords:["bo","flag","nation","country","banner"],char:'\ud83c\udde7\ud83c\uddf4',fitzpatrick_scale:!1,category:"flags"},caribbean_netherlands:{keywords:["bonaire","flag","nation","country","banner"],char:'\ud83c\udde7\ud83c\uddf6',fitzpatrick_scale:!1,category:"flags"},bosnia_herzegovina:{keywords:["bosnia","herzegovina","flag","nation","country","banner"],char:'\ud83c\udde7\ud83c\udde6',fitzpatrick_scale:!1,category:"flags"},botswana:{keywords:["bw","flag","nation","country","banner"],char:'\ud83c\udde7\ud83c\uddfc',fitzpatrick_scale:!1,category:"flags"},brazil:{keywords:["br","flag","nation","country","banner"],char:'\ud83c\udde7\ud83c\uddf7',fitzpatrick_scale:!1,category:"flags"},british_indian_ocean_territory:{keywords:["british","indian","ocean","territory","flag","nation","country","banner"],char:'\ud83c\uddee\ud83c\uddf4',fitzpatrick_scale:!1,category:"flags"},british_virgin_islands:{keywords:["british","virgin","islands","bvi","flag","nation","country","banner"],char:'\ud83c\uddfb\ud83c\uddec',fitzpatrick_scale:!1,category:"flags"},brunei:{keywords:["bn","darussalam","flag","nation","country","banner"],char:'\ud83c\udde7\ud83c\uddf3',fitzpatrick_scale:!1,category:"flags"},bulgaria:{keywords:["bg","flag","nation","country","banner"],char:'\ud83c\udde7\ud83c\uddec',fitzpatrick_scale:!1,category:"flags"},burkina_faso:{keywords:["burkina","faso","flag","nation","country","banner"],char:'\ud83c\udde7\ud83c\uddeb',fitzpatrick_scale:!1,category:"flags"},burundi:{keywords:["bi","flag","nation","country","banner"],char:'\ud83c\udde7\ud83c\uddee',fitzpatrick_scale:!1,category:"flags"},cape_verde:{keywords:["cabo","verde","flag","nation","country","banner"],char:'\ud83c\udde8\ud83c\uddfb',fitzpatrick_scale:!1,category:"flags"},cambodia:{keywords:["kh","flag","nation","country","banner"],char:'\ud83c\uddf0\ud83c\udded',fitzpatrick_scale:!1,category:"flags"},cameroon:{keywords:["cm","flag","nation","country","banner"],char:'\ud83c\udde8\ud83c\uddf2',fitzpatrick_scale:!1,category:"flags"},canada:{keywords:["ca","flag","nation","country","banner"],char:'\ud83c\udde8\ud83c\udde6',fitzpatrick_scale:!1,category:"flags"},canary_islands:{keywords:["canary","islands","flag","nation","country","banner"],char:'\ud83c\uddee\ud83c\udde8',fitzpatrick_scale:!1,category:"flags"},cayman_islands:{keywords:["cayman","islands","flag","nation","country","banner"],char:'\ud83c\uddf0\ud83c\uddfe',fitzpatrick_scale:!1,category:"flags"},central_african_republic:{keywords:["central","african","republic","flag","nation","country","banner"],char:'\ud83c\udde8\ud83c\uddeb',fitzpatrick_scale:!1,category:"flags"},chad:{keywords:["td","flag","nation","country","banner"],char:'\ud83c\uddf9\ud83c\udde9',fitzpatrick_scale:!1,category:"flags"},chile:{keywords:["flag","nation","country","banner"],char:'\ud83c\udde8\ud83c\uddf1',fitzpatrick_scale:!1,category:"flags"},cn:{keywords:["china","chinese","prc","flag","country","nation","banner"],char:'\ud83c\udde8\ud83c\uddf3',fitzpatrick_scale:!1,category:"flags"},christmas_island:{keywords:["christmas","island","flag","nation","country","banner"],char:'\ud83c\udde8\ud83c\uddfd',fitzpatrick_scale:!1,category:"flags"},cocos_islands:{keywords:["cocos","keeling","islands","flag","nation","country","banner"],char:'\ud83c\udde8\ud83c\udde8',fitzpatrick_scale:!1,category:"flags"},colombia:{keywords:["co","flag","nation","country","banner"],char:'\ud83c\udde8\ud83c\uddf4',fitzpatrick_scale:!1,category:"flags"},comoros:{keywords:["km","flag","nation","country","banner"],char:'\ud83c\uddf0\ud83c\uddf2',fitzpatrick_scale:!1,category:"flags"},congo_brazzaville:{keywords:["congo","flag","nation","country","banner"],char:'\ud83c\udde8\ud83c\uddec',fitzpatrick_scale:!1,category:"flags"},congo_kinshasa:{keywords:["congo","democratic","republic","flag","nation","country","banner"],char:'\ud83c\udde8\ud83c\udde9',fitzpatrick_scale:!1,category:"flags"},cook_islands:{keywords:["cook","islands","flag","nation","country","banner"],char:'\ud83c\udde8\ud83c\uddf0',fitzpatrick_scale:!1,category:"flags"},costa_rica:{keywords:["costa","rica","flag","nation","country","banner"],char:'\ud83c\udde8\ud83c\uddf7',fitzpatrick_scale:!1,category:"flags"},croatia:{keywords:["hr","flag","nation","country","banner"],char:'\ud83c\udded\ud83c\uddf7',fitzpatrick_scale:!1,category:"flags"},cuba:{keywords:["cu","flag","nation","country","banner"],char:'\ud83c\udde8\ud83c\uddfa',fitzpatrick_scale:!1,category:"flags"},curacao:{keywords:["cura\xe7ao","flag","nation","country","banner"],char:'\ud83c\udde8\ud83c\uddfc',fitzpatrick_scale:!1,category:"flags"},cyprus:{keywords:["cy","flag","nation","country","banner"],char:'\ud83c\udde8\ud83c\uddfe',fitzpatrick_scale:!1,category:"flags"},czech_republic:{keywords:["cz","flag","nation","country","banner"],char:'\ud83c\udde8\ud83c\uddff',fitzpatrick_scale:!1,category:"flags"},denmark:{keywords:["dk","flag","nation","country","banner"],char:'\ud83c\udde9\ud83c\uddf0',fitzpatrick_scale:!1,category:"flags"},djibouti:{keywords:["dj","flag","nation","country","banner"],char:'\ud83c\udde9\ud83c\uddef',fitzpatrick_scale:!1,category:"flags"},dominica:{keywords:["dm","flag","nation","country","banner"],char:'\ud83c\udde9\ud83c\uddf2',fitzpatrick_scale:!1,category:"flags"},dominican_republic:{keywords:["dominican","republic","flag","nation","country","banner"],char:'\ud83c\udde9\ud83c\uddf4',fitzpatrick_scale:!1,category:"flags"},ecuador:{keywords:["ec","flag","nation","country","banner"],char:'\ud83c\uddea\ud83c\udde8',fitzpatrick_scale:!1,category:"flags"},egypt:{keywords:["eg","flag","nation","country","banner"],char:'\ud83c\uddea\ud83c\uddec',fitzpatrick_scale:!1,category:"flags"},el_salvador:{keywords:["el","salvador","flag","nation","country","banner"],char:'\ud83c\uddf8\ud83c\uddfb',fitzpatrick_scale:!1,category:"flags"},equatorial_guinea:{keywords:["equatorial","gn","flag","nation","country","banner"],char:'\ud83c\uddec\ud83c\uddf6',fitzpatrick_scale:!1,category:"flags"},eritrea:{keywords:["er","flag","nation","country","banner"],char:'\ud83c\uddea\ud83c\uddf7',fitzpatrick_scale:!1,category:"flags"},estonia:{keywords:["ee","flag","nation","country","banner"],char:'\ud83c\uddea\ud83c\uddea',fitzpatrick_scale:!1,category:"flags"},ethiopia:{keywords:["et","flag","nation","country","banner"],char:'\ud83c\uddea\ud83c\uddf9',fitzpatrick_scale:!1,category:"flags"},eu:{keywords:["european","union","flag","banner"],char:'\ud83c\uddea\ud83c\uddfa',fitzpatrick_scale:!1,category:"flags"},falkland_islands:{keywords:["falkland","islands","malvinas","flag","nation","country","banner"],char:'\ud83c\uddeb\ud83c\uddf0',fitzpatrick_scale:!1,category:"flags"},faroe_islands:{keywords:["faroe","islands","flag","nation","country","banner"],char:'\ud83c\uddeb\ud83c\uddf4',fitzpatrick_scale:!1,category:"flags"},fiji:{keywords:["fj","flag","nation","country","banner"],char:'\ud83c\uddeb\ud83c\uddef',fitzpatrick_scale:!1,category:"flags"},finland:{keywords:["fi","flag","nation","country","banner"],char:'\ud83c\uddeb\ud83c\uddee',fitzpatrick_scale:!1,category:"flags"},fr:{keywords:["banner","flag","nation","france","french","country"],char:'\ud83c\uddeb\ud83c\uddf7',fitzpatrick_scale:!1,category:"flags"},french_guiana:{keywords:["french","guiana","flag","nation","country","banner"],char:'\ud83c\uddec\ud83c\uddeb',fitzpatrick_scale:!1,category:"flags"},french_polynesia:{keywords:["french","polynesia","flag","nation","country","banner"],char:'\ud83c\uddf5\ud83c\uddeb',fitzpatrick_scale:!1,category:"flags"},french_southern_territories:{keywords:["french","southern","territories","flag","nation","country","banner"],char:'\ud83c\uddf9\ud83c\uddeb',fitzpatrick_scale:!1,category:"flags"},gabon:{keywords:["ga","flag","nation","country","banner"],char:'\ud83c\uddec\ud83c\udde6',fitzpatrick_scale:!1,category:"flags"},gambia:{keywords:["gm","flag","nation","country","banner"],char:'\ud83c\uddec\ud83c\uddf2',fitzpatrick_scale:!1,category:"flags"},georgia:{keywords:["ge","flag","nation","country","banner"],char:'\ud83c\uddec\ud83c\uddea',fitzpatrick_scale:!1,category:"flags"},de:{keywords:["german","nation","flag","country","banner"],char:'\ud83c\udde9\ud83c\uddea',fitzpatrick_scale:!1,category:"flags"},ghana:{keywords:["gh","flag","nation","country","banner"],char:'\ud83c\uddec\ud83c\udded',fitzpatrick_scale:!1,category:"flags"},gibraltar:{keywords:["gi","flag","nation","country","banner"],char:'\ud83c\uddec\ud83c\uddee',fitzpatrick_scale:!1,category:"flags"},greece:{keywords:["gr","flag","nation","country","banner"],char:'\ud83c\uddec\ud83c\uddf7',fitzpatrick_scale:!1,category:"flags"},greenland:{keywords:["gl","flag","nation","country","banner"],char:'\ud83c\uddec\ud83c\uddf1',fitzpatrick_scale:!1,category:"flags"},grenada:{keywords:["gd","flag","nation","country","banner"],char:'\ud83c\uddec\ud83c\udde9',fitzpatrick_scale:!1,category:"flags"},guadeloupe:{keywords:["gp","flag","nation","country","banner"],char:'\ud83c\uddec\ud83c\uddf5',fitzpatrick_scale:!1,category:"flags"},guam:{keywords:["gu","flag","nation","country","banner"],char:'\ud83c\uddec\ud83c\uddfa',fitzpatrick_scale:!1,category:"flags"},guatemala:{keywords:["gt","flag","nation","country","banner"],char:'\ud83c\uddec\ud83c\uddf9',fitzpatrick_scale:!1,category:"flags"},guernsey:{keywords:["gg","flag","nation","country","banner"],char:'\ud83c\uddec\ud83c\uddec',fitzpatrick_scale:!1,category:"flags"},guinea:{keywords:["gn","flag","nation","country","banner"],char:'\ud83c\uddec\ud83c\uddf3',fitzpatrick_scale:!1,category:"flags"},guinea_bissau:{keywords:["gw","bissau","flag","nation","country","banner"],char:'\ud83c\uddec\ud83c\uddfc',fitzpatrick_scale:!1,category:"flags"},guyana:{keywords:["gy","flag","nation","country","banner"],char:'\ud83c\uddec\ud83c\uddfe',fitzpatrick_scale:!1,category:"flags"},haiti:{keywords:["ht","flag","nation","country","banner"],char:'\ud83c\udded\ud83c\uddf9',fitzpatrick_scale:!1,category:"flags"},honduras:{keywords:["hn","flag","nation","country","banner"],char:'\ud83c\udded\ud83c\uddf3',fitzpatrick_scale:!1,category:"flags"},hong_kong:{keywords:["hong","kong","flag","nation","country","banner"],char:'\ud83c\udded\ud83c\uddf0',fitzpatrick_scale:!1,category:"flags"},hungary:{keywords:["hu","flag","nation","country","banner"],char:'\ud83c\udded\ud83c\uddfa',fitzpatrick_scale:!1,category:"flags"},iceland:{keywords:["is","flag","nation","country","banner"],char:'\ud83c\uddee\ud83c\uddf8',fitzpatrick_scale:!1,category:"flags"},india:{keywords:["in","flag","nation","country","banner"],char:'\ud83c\uddee\ud83c\uddf3',fitzpatrick_scale:!1,category:"flags"},indonesia:{keywords:["flag","nation","country","banner"],char:'\ud83c\uddee\ud83c\udde9',fitzpatrick_scale:!1,category:"flags"},iran:{keywords:["iran,","islamic","republic","flag","nation","country","banner"],char:'\ud83c\uddee\ud83c\uddf7',fitzpatrick_scale:!1,category:"flags"},iraq:{keywords:["iq","flag","nation","country","banner"],char:'\ud83c\uddee\ud83c\uddf6',fitzpatrick_scale:!1,category:"flags"},ireland:{keywords:["ie","flag","nation","country","banner"],char:'\ud83c\uddee\ud83c\uddea',fitzpatrick_scale:!1,category:"flags"},isle_of_man:{keywords:["isle","man","flag","nation","country","banner"],char:'\ud83c\uddee\ud83c\uddf2',fitzpatrick_scale:!1,category:"flags"},israel:{keywords:["il","flag","nation","country","banner"],char:'\ud83c\uddee\ud83c\uddf1',fitzpatrick_scale:!1,category:"flags"},it:{keywords:["italy","flag","nation","country","banner"],char:'\ud83c\uddee\ud83c\uddf9',fitzpatrick_scale:!1,category:"flags"},cote_divoire:{keywords:["ivory","coast","flag","nation","country","banner"],char:'\ud83c\udde8\ud83c\uddee',fitzpatrick_scale:!1,category:"flags"},jamaica:{keywords:["jm","flag","nation","country","banner"],char:'\ud83c\uddef\ud83c\uddf2',fitzpatrick_scale:!1,category:"flags"},jp:{keywords:["japanese","nation","flag","country","banner"],char:'\ud83c\uddef\ud83c\uddf5',fitzpatrick_scale:!1,category:"flags"},jersey:{keywords:["je","flag","nation","country","banner"],char:'\ud83c\uddef\ud83c\uddea',fitzpatrick_scale:!1,category:"flags"},jordan:{keywords:["jo","flag","nation","country","banner"],char:'\ud83c\uddef\ud83c\uddf4',fitzpatrick_scale:!1,category:"flags"},kazakhstan:{keywords:["kz","flag","nation","country","banner"],char:'\ud83c\uddf0\ud83c\uddff',fitzpatrick_scale:!1,category:"flags"},kenya:{keywords:["ke","flag","nation","country","banner"],char:'\ud83c\uddf0\ud83c\uddea',fitzpatrick_scale:!1,category:"flags"},kiribati:{keywords:["ki","flag","nation","country","banner"],char:'\ud83c\uddf0\ud83c\uddee',fitzpatrick_scale:!1,category:"flags"},kosovo:{keywords:["xk","flag","nation","country","banner"],char:'\ud83c\uddfd\ud83c\uddf0',fitzpatrick_scale:!1,category:"flags"},kuwait:{keywords:["kw","flag","nation","country","banner"],char:'\ud83c\uddf0\ud83c\uddfc',fitzpatrick_scale:!1,category:"flags"},kyrgyzstan:{keywords:["kg","flag","nation","country","banner"],char:'\ud83c\uddf0\ud83c\uddec',fitzpatrick_scale:!1,category:"flags"},laos:{keywords:["lao","democratic","republic","flag","nation","country","banner"],char:'\ud83c\uddf1\ud83c\udde6',fitzpatrick_scale:!1,category:"flags"},latvia:{keywords:["lv","flag","nation","country","banner"],char:'\ud83c\uddf1\ud83c\uddfb',fitzpatrick_scale:!1,category:"flags"},lebanon:{keywords:["lb","flag","nation","country","banner"],char:'\ud83c\uddf1\ud83c\udde7',fitzpatrick_scale:!1,category:"flags"},lesotho:{keywords:["ls","flag","nation","country","banner"],char:'\ud83c\uddf1\ud83c\uddf8',fitzpatrick_scale:!1,category:"flags"},liberia:{keywords:["lr","flag","nation","country","banner"],char:'\ud83c\uddf1\ud83c\uddf7',fitzpatrick_scale:!1,category:"flags"},libya:{keywords:["ly","flag","nation","country","banner"],char:'\ud83c\uddf1\ud83c\uddfe',fitzpatrick_scale:!1,category:"flags"},liechtenstein:{keywords:["li","flag","nation","country","banner"],char:'\ud83c\uddf1\ud83c\uddee',fitzpatrick_scale:!1,category:"flags"},lithuania:{keywords:["lt","flag","nation","country","banner"],char:'\ud83c\uddf1\ud83c\uddf9',fitzpatrick_scale:!1,category:"flags"},luxembourg:{keywords:["lu","flag","nation","country","banner"],char:'\ud83c\uddf1\ud83c\uddfa',fitzpatrick_scale:!1,category:"flags"},macau:{keywords:["macao","flag","nation","country","banner"],char:'\ud83c\uddf2\ud83c\uddf4',fitzpatrick_scale:!1,category:"flags"},macedonia:{keywords:["macedonia,","flag","nation","country","banner"],char:'\ud83c\uddf2\ud83c\uddf0',fitzpatrick_scale:!1,category:"flags"},madagascar:{keywords:["mg","flag","nation","country","banner"],char:'\ud83c\uddf2\ud83c\uddec',fitzpatrick_scale:!1,category:"flags"},malawi:{keywords:["mw","flag","nation","country","banner"],char:'\ud83c\uddf2\ud83c\uddfc',fitzpatrick_scale:!1,category:"flags"},malaysia:{keywords:["my","flag","nation","country","banner"],char:'\ud83c\uddf2\ud83c\uddfe',fitzpatrick_scale:!1,category:"flags"},maldives:{keywords:["mv","flag","nation","country","banner"],char:'\ud83c\uddf2\ud83c\uddfb',fitzpatrick_scale:!1,category:"flags"},mali:{keywords:["ml","flag","nation","country","banner"],char:'\ud83c\uddf2\ud83c\uddf1',fitzpatrick_scale:!1,category:"flags"},malta:{keywords:["mt","flag","nation","country","banner"],char:'\ud83c\uddf2\ud83c\uddf9',fitzpatrick_scale:!1,category:"flags"},marshall_islands:{keywords:["marshall","islands","flag","nation","country","banner"],char:'\ud83c\uddf2\ud83c\udded',fitzpatrick_scale:!1,category:"flags"},martinique:{keywords:["mq","flag","nation","country","banner"],char:'\ud83c\uddf2\ud83c\uddf6',fitzpatrick_scale:!1,category:"flags"},mauritania:{keywords:["mr","flag","nation","country","banner"],char:'\ud83c\uddf2\ud83c\uddf7',fitzpatrick_scale:!1,category:"flags"},mauritius:{keywords:["mu","flag","nation","country","banner"],char:'\ud83c\uddf2\ud83c\uddfa',fitzpatrick_scale:!1,category:"flags"},mayotte:{keywords:["yt","flag","nation","country","banner"],char:'\ud83c\uddfe\ud83c\uddf9',fitzpatrick_scale:!1,category:"flags"},mexico:{keywords:["mx","flag","nation","country","banner"],char:'\ud83c\uddf2\ud83c\uddfd',fitzpatrick_scale:!1,category:"flags"},micronesia:{keywords:["micronesia,","federated","states","flag","nation","country","banner"],char:'\ud83c\uddeb\ud83c\uddf2',fitzpatrick_scale:!1,category:"flags"},moldova:{keywords:["moldova,","republic","flag","nation","country","banner"],char:'\ud83c\uddf2\ud83c\udde9',fitzpatrick_scale:!1,category:"flags"},monaco:{keywords:["mc","flag","nation","country","banner"],char:'\ud83c\uddf2\ud83c\udde8',fitzpatrick_scale:!1,category:"flags"},mongolia:{keywords:["mn","flag","nation","country","banner"],char:'\ud83c\uddf2\ud83c\uddf3',fitzpatrick_scale:!1,category:"flags"},montenegro:{keywords:["me","flag","nation","country","banner"],char:'\ud83c\uddf2\ud83c\uddea',fitzpatrick_scale:!1,category:"flags"},montserrat:{keywords:["ms","flag","nation","country","banner"],char:'\ud83c\uddf2\ud83c\uddf8',fitzpatrick_scale:!1,category:"flags"},morocco:{keywords:["ma","flag","nation","country","banner"],char:'\ud83c\uddf2\ud83c\udde6',fitzpatrick_scale:!1,category:"flags"},mozambique:{keywords:["mz","flag","nation","country","banner"],char:'\ud83c\uddf2\ud83c\uddff',fitzpatrick_scale:!1,category:"flags"},myanmar:{keywords:["mm","flag","nation","country","banner"],char:'\ud83c\uddf2\ud83c\uddf2',fitzpatrick_scale:!1,category:"flags"},namibia:{keywords:["na","flag","nation","country","banner"],char:'\ud83c\uddf3\ud83c\udde6',fitzpatrick_scale:!1,category:"flags"},nauru:{keywords:["nr","flag","nation","country","banner"],char:'\ud83c\uddf3\ud83c\uddf7',fitzpatrick_scale:!1,category:"flags"},nepal:{keywords:["np","flag","nation","country","banner"],char:'\ud83c\uddf3\ud83c\uddf5',fitzpatrick_scale:!1,category:"flags"},netherlands:{keywords:["nl","flag","nation","country","banner"],char:'\ud83c\uddf3\ud83c\uddf1',fitzpatrick_scale:!1,category:"flags"},new_caledonia:{keywords:["new","caledonia","flag","nation","country","banner"],char:'\ud83c\uddf3\ud83c\udde8',fitzpatrick_scale:!1,category:"flags"},new_zealand:{keywords:["new","zealand","flag","nation","country","banner"],char:'\ud83c\uddf3\ud83c\uddff',fitzpatrick_scale:!1,category:"flags"},nicaragua:{keywords:["ni","flag","nation","country","banner"],char:'\ud83c\uddf3\ud83c\uddee',fitzpatrick_scale:!1,category:"flags"},niger:{keywords:["ne","flag","nation","country","banner"],char:'\ud83c\uddf3\ud83c\uddea',fitzpatrick_scale:!1,category:"flags"},nigeria:{keywords:["flag","nation","country","banner"],char:'\ud83c\uddf3\ud83c\uddec',fitzpatrick_scale:!1,category:"flags"},niue:{keywords:["nu","flag","nation","country","banner"],char:'\ud83c\uddf3\ud83c\uddfa',fitzpatrick_scale:!1,category:"flags"},norfolk_island:{keywords:["norfolk","island","flag","nation","country","banner"],char:'\ud83c\uddf3\ud83c\uddeb',fitzpatrick_scale:!1,category:"flags"},northern_mariana_islands:{keywords:["northern","mariana","islands","flag","nation","country","banner"],char:'\ud83c\uddf2\ud83c\uddf5',fitzpatrick_scale:!1,category:"flags"},north_korea:{keywords:["north","korea","nation","flag","country","banner"],char:'\ud83c\uddf0\ud83c\uddf5',fitzpatrick_scale:!1,category:"flags"},norway:{keywords:["no","flag","nation","country","banner"],char:'\ud83c\uddf3\ud83c\uddf4',fitzpatrick_scale:!1,category:"flags"},oman:{keywords:["om_symbol","flag","nation","country","banner"],char:'\ud83c\uddf4\ud83c\uddf2',fitzpatrick_scale:!1,category:"flags"},pakistan:{keywords:["pk","flag","nation","country","banner"],char:'\ud83c\uddf5\ud83c\uddf0',fitzpatrick_scale:!1,category:"flags"},palau:{keywords:["pw","flag","nation","country","banner"],char:'\ud83c\uddf5\ud83c\uddfc',fitzpatrick_scale:!1,category:"flags"},palestinian_territories:{keywords:["palestine","palestinian","territories","flag","nation","country","banner"],char:'\ud83c\uddf5\ud83c\uddf8',fitzpatrick_scale:!1,category:"flags"},panama:{keywords:["pa","flag","nation","country","banner"],char:'\ud83c\uddf5\ud83c\udde6',fitzpatrick_scale:!1,category:"flags"},papua_new_guinea:{keywords:["papua","new","guinea","flag","nation","country","banner"],char:'\ud83c\uddf5\ud83c\uddec',fitzpatrick_scale:!1,category:"flags"},paraguay:{keywords:["py","flag","nation","country","banner"],char:'\ud83c\uddf5\ud83c\uddfe',fitzpatrick_scale:!1,category:"flags"},peru:{keywords:["pe","flag","nation","country","banner"],char:'\ud83c\uddf5\ud83c\uddea',fitzpatrick_scale:!1,category:"flags"},philippines:{keywords:["ph","flag","nation","country","banner"],char:'\ud83c\uddf5\ud83c\udded',fitzpatrick_scale:!1,category:"flags"},pitcairn_islands:{keywords:["pitcairn","flag","nation","country","banner"],char:'\ud83c\uddf5\ud83c\uddf3',fitzpatrick_scale:!1,category:"flags"},poland:{keywords:["pl","flag","nation","country","banner"],char:'\ud83c\uddf5\ud83c\uddf1',fitzpatrick_scale:!1,category:"flags"},portugal:{keywords:["pt","flag","nation","country","banner"],char:'\ud83c\uddf5\ud83c\uddf9',fitzpatrick_scale:!1,category:"flags"},puerto_rico:{keywords:["puerto","rico","flag","nation","country","banner"],char:'\ud83c\uddf5\ud83c\uddf7',fitzpatrick_scale:!1,category:"flags"},qatar:{keywords:["qa","flag","nation","country","banner"],char:'\ud83c\uddf6\ud83c\udde6',fitzpatrick_scale:!1,category:"flags"},reunion:{keywords:["r\xe9union","flag","nation","country","banner"],char:'\ud83c\uddf7\ud83c\uddea',fitzpatrick_scale:!1,category:"flags"},romania:{keywords:["ro","flag","nation","country","banner"],char:'\ud83c\uddf7\ud83c\uddf4',fitzpatrick_scale:!1,category:"flags"},ru:{keywords:["russian","federation","flag","nation","country","banner"],char:'\ud83c\uddf7\ud83c\uddfa',fitzpatrick_scale:!1,category:"flags"},rwanda:{keywords:["rw","flag","nation","country","banner"],char:'\ud83c\uddf7\ud83c\uddfc',fitzpatrick_scale:!1,category:"flags"},st_barthelemy:{keywords:["saint","barth\xe9lemy","flag","nation","country","banner"],char:'\ud83c\udde7\ud83c\uddf1',fitzpatrick_scale:!1,category:"flags"},st_helena:{keywords:["saint","helena","ascension","tristan","cunha","flag","nation","country","banner"],char:'\ud83c\uddf8\ud83c\udded',fitzpatrick_scale:!1,category:"flags"},st_kitts_nevis:{keywords:["saint","kitts","nevis","flag","nation","country","banner"],char:'\ud83c\uddf0\ud83c\uddf3',fitzpatrick_scale:!1,category:"flags"},st_lucia:{keywords:["saint","lucia","flag","nation","country","banner"],char:'\ud83c\uddf1\ud83c\udde8',fitzpatrick_scale:!1,category:"flags"},st_pierre_miquelon:{keywords:["saint","pierre","miquelon","flag","nation","country","banner"],char:'\ud83c\uddf5\ud83c\uddf2',fitzpatrick_scale:!1,category:"flags"},st_vincent_grenadines:{keywords:["saint","vincent","grenadines","flag","nation","country","banner"],char:'\ud83c\uddfb\ud83c\udde8',fitzpatrick_scale:!1,category:"flags"},samoa:{keywords:["ws","flag","nation","country","banner"],char:'\ud83c\uddfc\ud83c\uddf8',fitzpatrick_scale:!1,category:"flags"},san_marino:{keywords:["san","marino","flag","nation","country","banner"],char:'\ud83c\uddf8\ud83c\uddf2',fitzpatrick_scale:!1,category:"flags"},sao_tome_principe:{keywords:["sao","tome","principe","flag","nation","country","banner"],char:'\ud83c\uddf8\ud83c\uddf9',fitzpatrick_scale:!1,category:"flags"},saudi_arabia:{keywords:["flag","nation","country","banner"],char:'\ud83c\uddf8\ud83c\udde6',fitzpatrick_scale:!1,category:"flags"},senegal:{keywords:["sn","flag","nation","country","banner"],char:'\ud83c\uddf8\ud83c\uddf3',fitzpatrick_scale:!1,category:"flags"},serbia:{keywords:["rs","flag","nation","country","banner"],char:'\ud83c\uddf7\ud83c\uddf8',fitzpatrick_scale:!1,category:"flags"},seychelles:{keywords:["sc","flag","nation","country","banner"],char:'\ud83c\uddf8\ud83c\udde8',fitzpatrick_scale:!1,category:"flags"},sierra_leone:{keywords:["sierra","leone","flag","nation","country","banner"],char:'\ud83c\uddf8\ud83c\uddf1',fitzpatrick_scale:!1,category:"flags"},singapore:{keywords:["sg","flag","nation","country","banner"],char:'\ud83c\uddf8\ud83c\uddec',fitzpatrick_scale:!1,category:"flags"},sint_maarten:{keywords:["sint","maarten","dutch","flag","nation","country","banner"],char:'\ud83c\uddf8\ud83c\uddfd',fitzpatrick_scale:!1,category:"flags"},slovakia:{keywords:["sk","flag","nation","country","banner"],char:'\ud83c\uddf8\ud83c\uddf0',fitzpatrick_scale:!1,category:"flags"},slovenia:{keywords:["si","flag","nation","country","banner"],char:'\ud83c\uddf8\ud83c\uddee',fitzpatrick_scale:!1,category:"flags"},solomon_islands:{keywords:["solomon","islands","flag","nation","country","banner"],char:'\ud83c\uddf8\ud83c\udde7',fitzpatrick_scale:!1,category:"flags"},somalia:{keywords:["so","flag","nation","country","banner"],char:'\ud83c\uddf8\ud83c\uddf4',fitzpatrick_scale:!1,category:"flags"},south_africa:{keywords:["south","africa","flag","nation","country","banner"],char:'\ud83c\uddff\ud83c\udde6',fitzpatrick_scale:!1,category:"flags"},south_georgia_south_sandwich_islands:{keywords:["south","georgia","sandwich","islands","flag","nation","country","banner"],char:'\ud83c\uddec\ud83c\uddf8',fitzpatrick_scale:!1,category:"flags"},kr:{keywords:["south","korea","nation","flag","country","banner"],char:'\ud83c\uddf0\ud83c\uddf7',fitzpatrick_scale:!1,category:"flags"},south_sudan:{keywords:["south","sd","flag","nation","country","banner"],char:'\ud83c\uddf8\ud83c\uddf8',fitzpatrick_scale:!1,category:"flags"},es:{keywords:["spain","flag","nation","country","banner"],char:'\ud83c\uddea\ud83c\uddf8',fitzpatrick_scale:!1,category:"flags"},sri_lanka:{keywords:["sri","lanka","flag","nation","country","banner"],char:'\ud83c\uddf1\ud83c\uddf0',fitzpatrick_scale:!1,category:"flags"},sudan:{keywords:["sd","flag","nation","country","banner"],char:'\ud83c\uddf8\ud83c\udde9',fitzpatrick_scale:!1,category:"flags"},suriname:{keywords:["sr","flag","nation","country","banner"],char:'\ud83c\uddf8\ud83c\uddf7',fitzpatrick_scale:!1,category:"flags"},swaziland:{keywords:["sz","flag","nation","country","banner"],char:'\ud83c\uddf8\ud83c\uddff',fitzpatrick_scale:!1,category:"flags"},sweden:{keywords:["se","flag","nation","country","banner"],char:'\ud83c\uddf8\ud83c\uddea',fitzpatrick_scale:!1,category:"flags"},switzerland:{keywords:["ch","flag","nation","country","banner"],char:'\ud83c\udde8\ud83c\udded',fitzpatrick_scale:!1,category:"flags"},syria:{keywords:["syrian","arab","republic","flag","nation","country","banner"],char:'\ud83c\uddf8\ud83c\uddfe',fitzpatrick_scale:!1,category:"flags"},taiwan:{keywords:["tw","flag","nation","country","banner"],char:'\ud83c\uddf9\ud83c\uddfc',fitzpatrick_scale:!1,category:"flags"},tajikistan:{keywords:["tj","flag","nation","country","banner"],char:'\ud83c\uddf9\ud83c\uddef',fitzpatrick_scale:!1,category:"flags"},tanzania:{keywords:["tanzania,","united","republic","flag","nation","country","banner"],char:'\ud83c\uddf9\ud83c\uddff',fitzpatrick_scale:!1,category:"flags"},thailand:{keywords:["th","flag","nation","country","banner"],char:'\ud83c\uddf9\ud83c\udded',fitzpatrick_scale:!1,category:"flags"},timor_leste:{keywords:["timor","leste","flag","nation","country","banner"],char:'\ud83c\uddf9\ud83c\uddf1',fitzpatrick_scale:!1,category:"flags"},togo:{keywords:["tg","flag","nation","country","banner"],char:'\ud83c\uddf9\ud83c\uddec',fitzpatrick_scale:!1,category:"flags"},tokelau:{keywords:["tk","flag","nation","country","banner"],char:'\ud83c\uddf9\ud83c\uddf0',fitzpatrick_scale:!1,category:"flags"},tonga:{keywords:["to","flag","nation","country","banner"],char:'\ud83c\uddf9\ud83c\uddf4',fitzpatrick_scale:!1,category:"flags"},trinidad_tobago:{keywords:["trinidad","tobago","flag","nation","country","banner"],char:'\ud83c\uddf9\ud83c\uddf9',fitzpatrick_scale:!1,category:"flags"},tunisia:{keywords:["tn","flag","nation","country","banner"],char:'\ud83c\uddf9\ud83c\uddf3',fitzpatrick_scale:!1,category:"flags"},tr:{keywords:["turkey","flag","nation","country","banner"],char:'\ud83c\uddf9\ud83c\uddf7',fitzpatrick_scale:!1,category:"flags"},turkmenistan:{keywords:["flag","nation","country","banner"],char:'\ud83c\uddf9\ud83c\uddf2',fitzpatrick_scale:!1,category:"flags"},turks_caicos_islands:{keywords:["turks","caicos","islands","flag","nation","country","banner"],char:'\ud83c\uddf9\ud83c\udde8',fitzpatrick_scale:!1,category:"flags"},tuvalu:{keywords:["flag","nation","country","banner"],char:'\ud83c\uddf9\ud83c\uddfb',fitzpatrick_scale:!1,category:"flags"},uganda:{keywords:["ug","flag","nation","country","banner"],char:'\ud83c\uddfa\ud83c\uddec',fitzpatrick_scale:!1,category:"flags"},ukraine:{keywords:["ua","flag","nation","country","banner"],char:'\ud83c\uddfa\ud83c\udde6',fitzpatrick_scale:!1,category:"flags"},united_arab_emirates:{keywords:["united","arab","emirates","flag","nation","country","banner"],char:'\ud83c\udde6\ud83c\uddea',fitzpatrick_scale:!1,category:"flags"},uk:{keywords:["united","kingdom","great","britain","northern","ireland","flag","nation","country","banner","british","UK","english","england","union jack"],char:'\ud83c\uddec\ud83c\udde7',fitzpatrick_scale:!1,category:"flags"},england:{keywords:["flag","english"],char:'\ud83c\udff4\udb40\udc67\udb40\udc62\udb40\udc65\udb40\udc6e\udb40\udc67\udb40\udc7f',fitzpatrick_scale:!1,category:"flags"},scotland:{keywords:["flag","scottish"],char:'\ud83c\udff4\udb40\udc67\udb40\udc62\udb40\udc73\udb40\udc63\udb40\udc74\udb40\udc7f',fitzpatrick_scale:!1,category:"flags"},wales:{keywords:["flag","welsh"],char:'\ud83c\udff4\udb40\udc67\udb40\udc62\udb40\udc77\udb40\udc6c\udb40\udc73\udb40\udc7f',fitzpatrick_scale:!1,category:"flags"},us:{keywords:["united","states","america","flag","nation","country","banner"],char:'\ud83c\uddfa\ud83c\uddf8',fitzpatrick_scale:!1,category:"flags"},us_virgin_islands:{keywords:["virgin","islands","us","flag","nation","country","banner"],char:'\ud83c\uddfb\ud83c\uddee',fitzpatrick_scale:!1,category:"flags"},uruguay:{keywords:["uy","flag","nation","country","banner"],char:'\ud83c\uddfa\ud83c\uddfe',fitzpatrick_scale:!1,category:"flags"},uzbekistan:{keywords:["uz","flag","nation","country","banner"],char:'\ud83c\uddfa\ud83c\uddff',fitzpatrick_scale:!1,category:"flags"},vanuatu:{keywords:["vu","flag","nation","country","banner"],char:'\ud83c\uddfb\ud83c\uddfa',fitzpatrick_scale:!1,category:"flags"},vatican_city:{keywords:["vatican","city","flag","nation","country","banner"],char:'\ud83c\uddfb\ud83c\udde6',fitzpatrick_scale:!1,category:"flags"},venezuela:{keywords:["ve","bolivarian","republic","flag","nation","country","banner"],char:'\ud83c\uddfb\ud83c\uddea',fitzpatrick_scale:!1,category:"flags"},vietnam:{keywords:["viet","nam","flag","nation","country","banner"],char:'\ud83c\uddfb\ud83c\uddf3',fitzpatrick_scale:!1,category:"flags"},wallis_futuna:{keywords:["wallis","futuna","flag","nation","country","banner"],char:'\ud83c\uddfc\ud83c\uddeb',fitzpatrick_scale:!1,category:"flags"},western_sahara:{keywords:["western","sahara","flag","nation","country","banner"],char:'\ud83c\uddea\ud83c\udded',fitzpatrick_scale:!1,category:"flags"},yemen:{keywords:["ye","flag","nation","country","banner"],char:'\ud83c\uddfe\ud83c\uddea',fitzpatrick_scale:!1,category:"flags"},zambia:{keywords:["zm","flag","nation","country","banner"],char:'\ud83c\uddff\ud83c\uddf2',fitzpatrick_scale:!1,category:"flags"},zimbabwe:{keywords:["zw","flag","nation","country","banner"],char:'\ud83c\uddff\ud83c\uddfc',fitzpatrick_scale:!1,category:"flags"},united_nations:{keywords:["un","flag","banner"],char:'\ud83c\uddfa\ud83c\uddf3',fitzpatrick_scale:!1,category:"flags"},pirate_flag:{keywords:["skull","crossbones","flag","banner"],char:'\ud83c\udff4\u200d\u2620\ufe0f',fitzpatrick_scale:!1,category:"flags"}}); \ No newline at end of file diff --git a/website/admin/tinymce/plugins/emoticons/js/emojis.js b/website/admin/tinymce/plugins/emoticons/js/emojis.js new file mode 100644 index 0000000..fd14058 --- /dev/null +++ b/website/admin/tinymce/plugins/emoticons/js/emojis.js @@ -0,0 +1 @@ +window.tinymce.Resource.add("tinymce.plugins.emoticons",{grinning:{keywords:["face","smile","happy","joy",":D","grin"],char:"\ud83d\ude00",fitzpatrick_scale:!1,category:"people"},grimacing:{keywords:["face","grimace","teeth"],char:"\ud83d\ude2c",fitzpatrick_scale:!1,category:"people"},grin:{keywords:["face","happy","smile","joy","kawaii"],char:"\ud83d\ude01",fitzpatrick_scale:!1,category:"people"},joy:{keywords:["face","cry","tears","weep","happy","happytears","haha"],char:"\ud83d\ude02",fitzpatrick_scale:!1,category:"people"},rofl:{keywords:["face","rolling","floor","laughing","lol","haha"],char:"\ud83e\udd23",fitzpatrick_scale:!1,category:"people"},partying:{keywords:["face","celebration","woohoo"],char:"\ud83e\udd73",fitzpatrick_scale:!1,category:"people"},smiley:{keywords:["face","happy","joy","haha",":D",":)","smile","funny"],char:"\ud83d\ude03",fitzpatrick_scale:!1,category:"people"},smile:{keywords:["face","happy","joy","funny","haha","laugh","like",":D",":)"],char:"\ud83d\ude04",fitzpatrick_scale:!1,category:"people"},sweat_smile:{keywords:["face","hot","happy","laugh","sweat","smile","relief"],char:"\ud83d\ude05",fitzpatrick_scale:!1,category:"people"},laughing:{keywords:["happy","joy","lol","satisfied","haha","face","glad","XD","laugh"],char:"\ud83d\ude06",fitzpatrick_scale:!1,category:"people"},innocent:{keywords:["face","angel","heaven","halo"],char:"\ud83d\ude07",fitzpatrick_scale:!1,category:"people"},wink:{keywords:["face","happy","mischievous","secret",";)","smile","eye"],char:"\ud83d\ude09",fitzpatrick_scale:!1,category:"people"},blush:{keywords:["face","smile","happy","flushed","crush","embarrassed","shy","joy"],char:"\ud83d\ude0a",fitzpatrick_scale:!1,category:"people"},slightly_smiling_face:{keywords:["face","smile"],char:"\ud83d\ude42",fitzpatrick_scale:!1,category:"people"},upside_down_face:{keywords:["face","flipped","silly","smile"],char:"\ud83d\ude43",fitzpatrick_scale:!1,category:"people"},relaxed:{keywords:["face","blush","massage","happiness"],char:"\u263a\ufe0f",fitzpatrick_scale:!1,category:"people"},yum:{keywords:["happy","joy","tongue","smile","face","silly","yummy","nom","delicious","savouring"],char:"\ud83d\ude0b",fitzpatrick_scale:!1,category:"people"},relieved:{keywords:["face","relaxed","phew","massage","happiness"],char:"\ud83d\ude0c",fitzpatrick_scale:!1,category:"people"},heart_eyes:{keywords:["face","love","like","affection","valentines","infatuation","crush","heart"],char:"\ud83d\ude0d",fitzpatrick_scale:!1,category:"people"},smiling_face_with_three_hearts:{keywords:["face","love","like","affection","valentines","infatuation","crush","hearts","adore"],char:"\ud83e\udd70",fitzpatrick_scale:!1,category:"people"},kissing_heart:{keywords:["face","love","like","affection","valentines","infatuation","kiss"],char:"\ud83d\ude18",fitzpatrick_scale:!1,category:"people"},kissing:{keywords:["love","like","face","3","valentines","infatuation","kiss"],char:"\ud83d\ude17",fitzpatrick_scale:!1,category:"people"},kissing_smiling_eyes:{keywords:["face","affection","valentines","infatuation","kiss"],char:"\ud83d\ude19",fitzpatrick_scale:!1,category:"people"},kissing_closed_eyes:{keywords:["face","love","like","affection","valentines","infatuation","kiss"],char:"\ud83d\ude1a",fitzpatrick_scale:!1,category:"people"},stuck_out_tongue_winking_eye:{keywords:["face","prank","childish","playful","mischievous","smile","wink","tongue"],char:"\ud83d\ude1c",fitzpatrick_scale:!1,category:"people"},zany:{keywords:["face","goofy","crazy"],char:"\ud83e\udd2a",fitzpatrick_scale:!1,category:"people"},raised_eyebrow:{keywords:["face","distrust","scepticism","disapproval","disbelief","surprise"],char:"\ud83e\udd28",fitzpatrick_scale:!1,category:"people"},monocle:{keywords:["face","stuffy","wealthy"],char:"\ud83e\uddd0",fitzpatrick_scale:!1,category:"people"},stuck_out_tongue_closed_eyes:{keywords:["face","prank","playful","mischievous","smile","tongue"],char:"\ud83d\ude1d",fitzpatrick_scale:!1,category:"people"},stuck_out_tongue:{keywords:["face","prank","childish","playful","mischievous","smile","tongue"],char:"\ud83d\ude1b",fitzpatrick_scale:!1,category:"people"},money_mouth_face:{keywords:["face","rich","dollar","money"],char:"\ud83e\udd11",fitzpatrick_scale:!1,category:"people"},nerd_face:{keywords:["face","nerdy","geek","dork"],char:"\ud83e\udd13",fitzpatrick_scale:!1,category:"people"},sunglasses:{keywords:["face","cool","smile","summer","beach","sunglass"],char:"\ud83d\ude0e",fitzpatrick_scale:!1,category:"people"},star_struck:{keywords:["face","smile","starry","eyes","grinning"],char:"\ud83e\udd29",fitzpatrick_scale:!1,category:"people"},clown_face:{keywords:["face"],char:"\ud83e\udd21",fitzpatrick_scale:!1,category:"people"},cowboy_hat_face:{keywords:["face","cowgirl","hat"],char:"\ud83e\udd20",fitzpatrick_scale:!1,category:"people"},hugs:{keywords:["face","smile","hug"],char:"\ud83e\udd17",fitzpatrick_scale:!1,category:"people"},smirk:{keywords:["face","smile","mean","prank","smug","sarcasm"],char:"\ud83d\ude0f",fitzpatrick_scale:!1,category:"people"},no_mouth:{keywords:["face","hellokitty"],char:"\ud83d\ude36",fitzpatrick_scale:!1,category:"people"},neutral_face:{keywords:["indifference","meh",":|","neutral"],char:"\ud83d\ude10",fitzpatrick_scale:!1,category:"people"},expressionless:{keywords:["face","indifferent","-_-","meh","deadpan"],char:"\ud83d\ude11",fitzpatrick_scale:!1,category:"people"},unamused:{keywords:["indifference","bored","straight face","serious","sarcasm","unimpressed","skeptical","dubious","side_eye"],char:"\ud83d\ude12",fitzpatrick_scale:!1,category:"people"},roll_eyes:{keywords:["face","eyeroll","frustrated"],char:"\ud83d\ude44",fitzpatrick_scale:!1,category:"people"},thinking:{keywords:["face","hmmm","think","consider"],char:"\ud83e\udd14",fitzpatrick_scale:!1,category:"people"},lying_face:{keywords:["face","lie","pinocchio"],char:"\ud83e\udd25",fitzpatrick_scale:!1,category:"people"},hand_over_mouth:{keywords:["face","whoops","shock","surprise"],char:"\ud83e\udd2d",fitzpatrick_scale:!1,category:"people"},shushing:{keywords:["face","quiet","shhh"],char:"\ud83e\udd2b",fitzpatrick_scale:!1,category:"people"},symbols_over_mouth:{keywords:["face","swearing","cursing","cussing","profanity","expletive"],char:"\ud83e\udd2c",fitzpatrick_scale:!1,category:"people"},exploding_head:{keywords:["face","shocked","mind","blown"],char:"\ud83e\udd2f",fitzpatrick_scale:!1,category:"people"},flushed:{keywords:["face","blush","shy","flattered"],char:"\ud83d\ude33",fitzpatrick_scale:!1,category:"people"},disappointed:{keywords:["face","sad","upset","depressed",":("],char:"\ud83d\ude1e",fitzpatrick_scale:!1,category:"people"},worried:{keywords:["face","concern","nervous",":("],char:"\ud83d\ude1f",fitzpatrick_scale:!1,category:"people"},angry:{keywords:["mad","face","annoyed","frustrated"],char:"\ud83d\ude20",fitzpatrick_scale:!1,category:"people"},rage:{keywords:["angry","mad","hate","despise"],char:"\ud83d\ude21",fitzpatrick_scale:!1,category:"people"},pensive:{keywords:["face","sad","depressed","upset"],char:"\ud83d\ude14",fitzpatrick_scale:!1,category:"people"},confused:{keywords:["face","indifference","huh","weird","hmmm",":/"],char:"\ud83d\ude15",fitzpatrick_scale:!1,category:"people"},slightly_frowning_face:{keywords:["face","frowning","disappointed","sad","upset"],char:"\ud83d\ude41",fitzpatrick_scale:!1,category:"people"},frowning_face:{keywords:["face","sad","upset","frown"],char:"\u2639",fitzpatrick_scale:!1,category:"people"},persevere:{keywords:["face","sick","no","upset","oops"],char:"\ud83d\ude23",fitzpatrick_scale:!1,category:"people"},confounded:{keywords:["face","confused","sick","unwell","oops",":S"],char:"\ud83d\ude16",fitzpatrick_scale:!1,category:"people"},tired_face:{keywords:["sick","whine","upset","frustrated"],char:"\ud83d\ude2b",fitzpatrick_scale:!1,category:"people"},weary:{keywords:["face","tired","sleepy","sad","frustrated","upset"],char:"\ud83d\ude29",fitzpatrick_scale:!1,category:"people"},pleading:{keywords:["face","begging","mercy"],char:"\ud83e\udd7a",fitzpatrick_scale:!1,category:"people"},triumph:{keywords:["face","gas","phew","proud","pride"],char:"\ud83d\ude24",fitzpatrick_scale:!1,category:"people"},open_mouth:{keywords:["face","surprise","impressed","wow","whoa",":O"],char:"\ud83d\ude2e",fitzpatrick_scale:!1,category:"people"},scream:{keywords:["face","munch","scared","omg"],char:"\ud83d\ude31",fitzpatrick_scale:!1,category:"people"},fearful:{keywords:["face","scared","terrified","nervous","oops","huh"],char:"\ud83d\ude28",fitzpatrick_scale:!1,category:"people"},cold_sweat:{keywords:["face","nervous","sweat"],char:"\ud83d\ude30",fitzpatrick_scale:!1,category:"people"},hushed:{keywords:["face","woo","shh"],char:"\ud83d\ude2f",fitzpatrick_scale:!1,category:"people"},frowning:{keywords:["face","aw","what"],char:"\ud83d\ude26",fitzpatrick_scale:!1,category:"people"},anguished:{keywords:["face","stunned","nervous"],char:"\ud83d\ude27",fitzpatrick_scale:!1,category:"people"},cry:{keywords:["face","tears","sad","depressed","upset",":'("],char:"\ud83d\ude22",fitzpatrick_scale:!1,category:"people"},disappointed_relieved:{keywords:["face","phew","sweat","nervous"],char:"\ud83d\ude25",fitzpatrick_scale:!1,category:"people"},drooling_face:{keywords:["face"],char:"\ud83e\udd24",fitzpatrick_scale:!1,category:"people"},sleepy:{keywords:["face","tired","rest","nap"],char:"\ud83d\ude2a",fitzpatrick_scale:!1,category:"people"},sweat:{keywords:["face","hot","sad","tired","exercise"],char:"\ud83d\ude13",fitzpatrick_scale:!1,category:"people"},hot:{keywords:["face","feverish","heat","red","sweating"],char:"\ud83e\udd75",fitzpatrick_scale:!1,category:"people"},cold:{keywords:["face","blue","freezing","frozen","frostbite","icicles"],char:"\ud83e\udd76",fitzpatrick_scale:!1,category:"people"},sob:{keywords:["face","cry","tears","sad","upset","depressed"],char:"\ud83d\ude2d",fitzpatrick_scale:!1,category:"people"},dizzy_face:{keywords:["spent","unconscious","xox","dizzy"],char:"\ud83d\ude35",fitzpatrick_scale:!1,category:"people"},astonished:{keywords:["face","xox","surprised","poisoned"],char:"\ud83d\ude32",fitzpatrick_scale:!1,category:"people"},zipper_mouth_face:{keywords:["face","sealed","zipper","secret"],char:"\ud83e\udd10",fitzpatrick_scale:!1,category:"people"},nauseated_face:{keywords:["face","vomit","gross","green","sick","throw up","ill"],char:"\ud83e\udd22",fitzpatrick_scale:!1,category:"people"},sneezing_face:{keywords:["face","gesundheit","sneeze","sick","allergy"],char:"\ud83e\udd27",fitzpatrick_scale:!1,category:"people"},vomiting:{keywords:["face","sick"],char:"\ud83e\udd2e",fitzpatrick_scale:!1,category:"people"},mask:{keywords:["face","sick","ill","disease"],char:"\ud83d\ude37",fitzpatrick_scale:!1,category:"people"},face_with_thermometer:{keywords:["sick","temperature","thermometer","cold","fever"],char:"\ud83e\udd12",fitzpatrick_scale:!1,category:"people"},face_with_head_bandage:{keywords:["injured","clumsy","bandage","hurt"],char:"\ud83e\udd15",fitzpatrick_scale:!1,category:"people"},woozy:{keywords:["face","dizzy","intoxicated","tipsy","wavy"],char:"\ud83e\udd74",fitzpatrick_scale:!1,category:"people"},sleeping:{keywords:["face","tired","sleepy","night","zzz"],char:"\ud83d\ude34",fitzpatrick_scale:!1,category:"people"},zzz:{keywords:["sleepy","tired","dream"],char:"\ud83d\udca4",fitzpatrick_scale:!1,category:"people"},poop:{keywords:["hankey","shitface","fail","turd","shit"],char:"\ud83d\udca9",fitzpatrick_scale:!1,category:"people"},smiling_imp:{keywords:["devil","horns"],char:"\ud83d\ude08",fitzpatrick_scale:!1,category:"people"},imp:{keywords:["devil","angry","horns"],char:"\ud83d\udc7f",fitzpatrick_scale:!1,category:"people"},japanese_ogre:{keywords:["monster","red","mask","halloween","scary","creepy","devil","demon","japanese","ogre"],char:"\ud83d\udc79",fitzpatrick_scale:!1,category:"people"},japanese_goblin:{keywords:["red","evil","mask","monster","scary","creepy","japanese","goblin"],char:"\ud83d\udc7a",fitzpatrick_scale:!1,category:"people"},skull:{keywords:["dead","skeleton","creepy","death"],char:"\ud83d\udc80",fitzpatrick_scale:!1,category:"people"},ghost:{keywords:["halloween","spooky","scary"],char:"\ud83d\udc7b",fitzpatrick_scale:!1,category:"people"},alien:{keywords:["UFO","paul","weird","outer_space"],char:"\ud83d\udc7d",fitzpatrick_scale:!1,category:"people"},robot:{keywords:["computer","machine","bot"],char:"\ud83e\udd16",fitzpatrick_scale:!1,category:"people"},smiley_cat:{keywords:["animal","cats","happy","smile"],char:"\ud83d\ude3a",fitzpatrick_scale:!1,category:"people"},smile_cat:{keywords:["animal","cats","smile"],char:"\ud83d\ude38",fitzpatrick_scale:!1,category:"people"},joy_cat:{keywords:["animal","cats","haha","happy","tears"],char:"\ud83d\ude39",fitzpatrick_scale:!1,category:"people"},heart_eyes_cat:{keywords:["animal","love","like","affection","cats","valentines","heart"],char:"\ud83d\ude3b",fitzpatrick_scale:!1,category:"people"},smirk_cat:{keywords:["animal","cats","smirk"],char:"\ud83d\ude3c",fitzpatrick_scale:!1,category:"people"},kissing_cat:{keywords:["animal","cats","kiss"],char:"\ud83d\ude3d",fitzpatrick_scale:!1,category:"people"},scream_cat:{keywords:["animal","cats","munch","scared","scream"],char:"\ud83d\ude40",fitzpatrick_scale:!1,category:"people"},crying_cat_face:{keywords:["animal","tears","weep","sad","cats","upset","cry"],char:"\ud83d\ude3f",fitzpatrick_scale:!1,category:"people"},pouting_cat:{keywords:["animal","cats"],char:"\ud83d\ude3e",fitzpatrick_scale:!1,category:"people"},palms_up:{keywords:["hands","gesture","cupped","prayer"],char:"\ud83e\udd32",fitzpatrick_scale:!0,category:"people"},raised_hands:{keywords:["gesture","hooray","yea","celebration","hands"],char:"\ud83d\ude4c",fitzpatrick_scale:!0,category:"people"},clap:{keywords:["hands","praise","applause","congrats","yay"],char:"\ud83d\udc4f",fitzpatrick_scale:!0,category:"people"},wave:{keywords:["hands","gesture","goodbye","solong","farewell","hello","hi","palm"],char:"\ud83d\udc4b",fitzpatrick_scale:!0,category:"people"},call_me_hand:{keywords:["hands","gesture"],char:"\ud83e\udd19",fitzpatrick_scale:!0,category:"people"},"+1":{keywords:["thumbsup","yes","awesome","good","agree","accept","cool","hand","like"],char:"\ud83d\udc4d",fitzpatrick_scale:!0,category:"people"},"-1":{keywords:["thumbsdown","no","dislike","hand"],char:"\ud83d\udc4e",fitzpatrick_scale:!0,category:"people"},facepunch:{keywords:["angry","violence","fist","hit","attack","hand"],char:"\ud83d\udc4a",fitzpatrick_scale:!0,category:"people"},fist:{keywords:["fingers","hand","grasp"],char:"\u270a",fitzpatrick_scale:!0,category:"people"},fist_left:{keywords:["hand","fistbump"],char:"\ud83e\udd1b",fitzpatrick_scale:!0,category:"people"},fist_right:{keywords:["hand","fistbump"],char:"\ud83e\udd1c",fitzpatrick_scale:!0,category:"people"},v:{keywords:["fingers","ohyeah","hand","peace","victory","two"],char:"\u270c",fitzpatrick_scale:!0,category:"people"},ok_hand:{keywords:["fingers","limbs","perfect","ok","okay"],char:"\ud83d\udc4c",fitzpatrick_scale:!0,category:"people"},raised_hand:{keywords:["fingers","stop","highfive","palm","ban"],char:"\u270b",fitzpatrick_scale:!0,category:"people"},raised_back_of_hand:{keywords:["fingers","raised","backhand"],char:"\ud83e\udd1a",fitzpatrick_scale:!0,category:"people"},open_hands:{keywords:["fingers","butterfly","hands","open"],char:"\ud83d\udc50",fitzpatrick_scale:!0,category:"people"},muscle:{keywords:["arm","flex","hand","summer","strong","biceps"],char:"\ud83d\udcaa",fitzpatrick_scale:!0,category:"people"},pray:{keywords:["please","hope","wish","namaste","highfive"],char:"\ud83d\ude4f",fitzpatrick_scale:!0,category:"people"},foot:{keywords:["kick","stomp"],char:"\ud83e\uddb6",fitzpatrick_scale:!0,category:"people"},leg:{keywords:["kick","limb"],char:"\ud83e\uddb5",fitzpatrick_scale:!0,category:"people"},handshake:{keywords:["agreement","shake"],char:"\ud83e\udd1d",fitzpatrick_scale:!1,category:"people"},point_up:{keywords:["hand","fingers","direction","up"],char:"\u261d",fitzpatrick_scale:!0,category:"people"},point_up_2:{keywords:["fingers","hand","direction","up"],char:"\ud83d\udc46",fitzpatrick_scale:!0,category:"people"},point_down:{keywords:["fingers","hand","direction","down"],char:"\ud83d\udc47",fitzpatrick_scale:!0,category:"people"},point_left:{keywords:["direction","fingers","hand","left"],char:"\ud83d\udc48",fitzpatrick_scale:!0,category:"people"},point_right:{keywords:["fingers","hand","direction","right"],char:"\ud83d\udc49",fitzpatrick_scale:!0,category:"people"},fu:{keywords:["hand","fingers","rude","middle","flipping"],char:"\ud83d\udd95",fitzpatrick_scale:!0,category:"people"},raised_hand_with_fingers_splayed:{keywords:["hand","fingers","palm"],char:"\ud83d\udd90",fitzpatrick_scale:!0,category:"people"},love_you:{keywords:["hand","fingers","gesture"],char:"\ud83e\udd1f",fitzpatrick_scale:!0,category:"people"},metal:{keywords:["hand","fingers","evil_eye","sign_of_horns","rock_on"],char:"\ud83e\udd18",fitzpatrick_scale:!0,category:"people"},crossed_fingers:{keywords:["good","lucky"],char:"\ud83e\udd1e",fitzpatrick_scale:!0,category:"people"},vulcan_salute:{keywords:["hand","fingers","spock","star trek"],char:"\ud83d\udd96",fitzpatrick_scale:!0,category:"people"},writing_hand:{keywords:["lower_left_ballpoint_pen","stationery","write","compose"],char:"\u270d",fitzpatrick_scale:!0,category:"people"},selfie:{keywords:["camera","phone"],char:"\ud83e\udd33",fitzpatrick_scale:!0,category:"people"},nail_care:{keywords:["beauty","manicure","finger","fashion","nail"],char:"\ud83d\udc85",fitzpatrick_scale:!0,category:"people"},lips:{keywords:["mouth","kiss"],char:"\ud83d\udc44",fitzpatrick_scale:!1,category:"people"},tooth:{keywords:["teeth","dentist"],char:"\ud83e\uddb7",fitzpatrick_scale:!1,category:"people"},tongue:{keywords:["mouth","playful"],char:"\ud83d\udc45",fitzpatrick_scale:!1,category:"people"},ear:{keywords:["face","hear","sound","listen"],char:"\ud83d\udc42",fitzpatrick_scale:!0,category:"people"},nose:{keywords:["smell","sniff"],char:"\ud83d\udc43",fitzpatrick_scale:!0,category:"people"},eye:{keywords:["face","look","see","watch","stare"],char:"\ud83d\udc41",fitzpatrick_scale:!1,category:"people"},eyes:{keywords:["look","watch","stalk","peek","see"],char:"\ud83d\udc40",fitzpatrick_scale:!1,category:"people"},brain:{keywords:["smart","intelligent"],char:"\ud83e\udde0",fitzpatrick_scale:!1,category:"people"},bust_in_silhouette:{keywords:["user","person","human"],char:"\ud83d\udc64",fitzpatrick_scale:!1,category:"people"},busts_in_silhouette:{keywords:["user","person","human","group","team"],char:"\ud83d\udc65",fitzpatrick_scale:!1,category:"people"},speaking_head:{keywords:["user","person","human","sing","say","talk"],char:"\ud83d\udde3",fitzpatrick_scale:!1,category:"people"},baby:{keywords:["child","boy","girl","toddler"],char:"\ud83d\udc76",fitzpatrick_scale:!0,category:"people"},child:{keywords:["gender-neutral","young"],char:"\ud83e\uddd2",fitzpatrick_scale:!0,category:"people"},boy:{keywords:["man","male","guy","teenager"],char:"\ud83d\udc66",fitzpatrick_scale:!0,category:"people"},girl:{keywords:["female","woman","teenager"],char:"\ud83d\udc67",fitzpatrick_scale:!0,category:"people"},adult:{keywords:["gender-neutral","person"],char:"\ud83e\uddd1",fitzpatrick_scale:!0,category:"people"},man:{keywords:["mustache","father","dad","guy","classy","sir","moustache"],char:"\ud83d\udc68",fitzpatrick_scale:!0,category:"people"},woman:{keywords:["female","girls","lady"],char:"\ud83d\udc69",fitzpatrick_scale:!0,category:"people"},blonde_woman:{keywords:["woman","female","girl","blonde","person"],char:"\ud83d\udc71\u200d\u2640\ufe0f",fitzpatrick_scale:!0,category:"people"},blonde_man:{keywords:["man","male","boy","blonde","guy","person"],char:"\ud83d\udc71",fitzpatrick_scale:!0,category:"people"},bearded_person:{keywords:["person","bewhiskered"],char:"\ud83e\uddd4",fitzpatrick_scale:!0,category:"people"},older_adult:{keywords:["human","elder","senior","gender-neutral"],char:"\ud83e\uddd3",fitzpatrick_scale:!0,category:"people"},older_man:{keywords:["human","male","men","old","elder","senior"],char:"\ud83d\udc74",fitzpatrick_scale:!0,category:"people"},older_woman:{keywords:["human","female","women","lady","old","elder","senior"],char:"\ud83d\udc75",fitzpatrick_scale:!0,category:"people"},man_with_gua_pi_mao:{keywords:["male","boy","chinese"],char:"\ud83d\udc72",fitzpatrick_scale:!0,category:"people"},woman_with_headscarf:{keywords:["female","hijab","mantilla","tichel"],char:"\ud83e\uddd5",fitzpatrick_scale:!0,category:"people"},woman_with_turban:{keywords:["female","indian","hinduism","arabs","woman"],char:"\ud83d\udc73\u200d\u2640\ufe0f",fitzpatrick_scale:!0,category:"people"},man_with_turban:{keywords:["male","indian","hinduism","arabs"],char:"\ud83d\udc73",fitzpatrick_scale:!0,category:"people"},policewoman:{keywords:["woman","police","law","legal","enforcement","arrest","911","female"],char:"\ud83d\udc6e\u200d\u2640\ufe0f",fitzpatrick_scale:!0,category:"people"},policeman:{keywords:["man","police","law","legal","enforcement","arrest","911"],char:"\ud83d\udc6e",fitzpatrick_scale:!0,category:"people"},construction_worker_woman:{keywords:["female","human","wip","build","construction","worker","labor","woman"],char:"\ud83d\udc77\u200d\u2640\ufe0f",fitzpatrick_scale:!0,category:"people"},construction_worker_man:{keywords:["male","human","wip","guy","build","construction","worker","labor"],char:"\ud83d\udc77",fitzpatrick_scale:!0,category:"people"},guardswoman:{keywords:["uk","gb","british","female","royal","woman"],char:"\ud83d\udc82\u200d\u2640\ufe0f",fitzpatrick_scale:!0,category:"people"},guardsman:{keywords:["uk","gb","british","male","guy","royal"],char:"\ud83d\udc82",fitzpatrick_scale:!0,category:"people"},female_detective:{keywords:["human","spy","detective","female","woman"],char:"\ud83d\udd75\ufe0f\u200d\u2640\ufe0f",fitzpatrick_scale:!0,category:"people"},male_detective:{keywords:["human","spy","detective"],char:"\ud83d\udd75",fitzpatrick_scale:!0,category:"people"},woman_health_worker:{keywords:["doctor","nurse","therapist","healthcare","woman","human"],char:"\ud83d\udc69\u200d\u2695\ufe0f",fitzpatrick_scale:!0,category:"people"},man_health_worker:{keywords:["doctor","nurse","therapist","healthcare","man","human"],char:"\ud83d\udc68\u200d\u2695\ufe0f",fitzpatrick_scale:!0,category:"people"},woman_farmer:{keywords:["rancher","gardener","woman","human"],char:"\ud83d\udc69\u200d\ud83c\udf3e",fitzpatrick_scale:!0,category:"people"},man_farmer:{keywords:["rancher","gardener","man","human"],char:"\ud83d\udc68\u200d\ud83c\udf3e",fitzpatrick_scale:!0,category:"people"},woman_cook:{keywords:["chef","woman","human"],char:"\ud83d\udc69\u200d\ud83c\udf73",fitzpatrick_scale:!0,category:"people"},man_cook:{keywords:["chef","man","human"],char:"\ud83d\udc68\u200d\ud83c\udf73",fitzpatrick_scale:!0,category:"people"},woman_student:{keywords:["graduate","woman","human"],char:"\ud83d\udc69\u200d\ud83c\udf93",fitzpatrick_scale:!0,category:"people"},man_student:{keywords:["graduate","man","human"],char:"\ud83d\udc68\u200d\ud83c\udf93",fitzpatrick_scale:!0,category:"people"},woman_singer:{keywords:["rockstar","entertainer","woman","human"],char:"\ud83d\udc69\u200d\ud83c\udfa4",fitzpatrick_scale:!0,category:"people"},man_singer:{keywords:["rockstar","entertainer","man","human"],char:"\ud83d\udc68\u200d\ud83c\udfa4",fitzpatrick_scale:!0,category:"people"},woman_teacher:{keywords:["instructor","professor","woman","human"],char:"\ud83d\udc69\u200d\ud83c\udfeb",fitzpatrick_scale:!0,category:"people"},man_teacher:{keywords:["instructor","professor","man","human"],char:"\ud83d\udc68\u200d\ud83c\udfeb",fitzpatrick_scale:!0,category:"people"},woman_factory_worker:{keywords:["assembly","industrial","woman","human"],char:"\ud83d\udc69\u200d\ud83c\udfed",fitzpatrick_scale:!0,category:"people"},man_factory_worker:{keywords:["assembly","industrial","man","human"],char:"\ud83d\udc68\u200d\ud83c\udfed",fitzpatrick_scale:!0,category:"people"},woman_technologist:{keywords:["coder","developer","engineer","programmer","software","woman","human","laptop","computer"],char:"\ud83d\udc69\u200d\ud83d\udcbb",fitzpatrick_scale:!0,category:"people"},man_technologist:{keywords:["coder","developer","engineer","programmer","software","man","human","laptop","computer"],char:"\ud83d\udc68\u200d\ud83d\udcbb",fitzpatrick_scale:!0,category:"people"},woman_office_worker:{keywords:["business","manager","woman","human"],char:"\ud83d\udc69\u200d\ud83d\udcbc",fitzpatrick_scale:!0,category:"people"},man_office_worker:{keywords:["business","manager","man","human"],char:"\ud83d\udc68\u200d\ud83d\udcbc",fitzpatrick_scale:!0,category:"people"},woman_mechanic:{keywords:["plumber","woman","human","wrench"],char:"\ud83d\udc69\u200d\ud83d\udd27",fitzpatrick_scale:!0,category:"people"},man_mechanic:{keywords:["plumber","man","human","wrench"],char:"\ud83d\udc68\u200d\ud83d\udd27",fitzpatrick_scale:!0,category:"people"},woman_scientist:{keywords:["biologist","chemist","engineer","physicist","woman","human"],char:"\ud83d\udc69\u200d\ud83d\udd2c",fitzpatrick_scale:!0,category:"people"},man_scientist:{keywords:["biologist","chemist","engineer","physicist","man","human"],char:"\ud83d\udc68\u200d\ud83d\udd2c",fitzpatrick_scale:!0,category:"people"},woman_artist:{keywords:["painter","woman","human"],char:"\ud83d\udc69\u200d\ud83c\udfa8",fitzpatrick_scale:!0,category:"people"},man_artist:{keywords:["painter","man","human"],char:"\ud83d\udc68\u200d\ud83c\udfa8",fitzpatrick_scale:!0,category:"people"},woman_firefighter:{keywords:["fireman","woman","human"],char:"\ud83d\udc69\u200d\ud83d\ude92",fitzpatrick_scale:!0,category:"people"},man_firefighter:{keywords:["fireman","man","human"],char:"\ud83d\udc68\u200d\ud83d\ude92",fitzpatrick_scale:!0,category:"people"},woman_pilot:{keywords:["aviator","plane","woman","human"],char:"\ud83d\udc69\u200d\u2708\ufe0f",fitzpatrick_scale:!0,category:"people"},man_pilot:{keywords:["aviator","plane","man","human"],char:"\ud83d\udc68\u200d\u2708\ufe0f",fitzpatrick_scale:!0,category:"people"},woman_astronaut:{keywords:["space","rocket","woman","human"],char:"\ud83d\udc69\u200d\ud83d\ude80",fitzpatrick_scale:!0,category:"people"},man_astronaut:{keywords:["space","rocket","man","human"],char:"\ud83d\udc68\u200d\ud83d\ude80",fitzpatrick_scale:!0,category:"people"},woman_judge:{keywords:["justice","court","woman","human"],char:"\ud83d\udc69\u200d\u2696\ufe0f",fitzpatrick_scale:!0,category:"people"},man_judge:{keywords:["justice","court","man","human"],char:"\ud83d\udc68\u200d\u2696\ufe0f",fitzpatrick_scale:!0,category:"people"},woman_superhero:{keywords:["woman","female","good","heroine","superpowers"],char:"\ud83e\uddb8\u200d\u2640\ufe0f",fitzpatrick_scale:!0,category:"people"},man_superhero:{keywords:["man","male","good","hero","superpowers"],char:"\ud83e\uddb8\u200d\u2642\ufe0f",fitzpatrick_scale:!0,category:"people"},woman_supervillain:{keywords:["woman","female","evil","bad","criminal","heroine","superpowers"],char:"\ud83e\uddb9\u200d\u2640\ufe0f",fitzpatrick_scale:!0,category:"people"},man_supervillain:{keywords:["man","male","evil","bad","criminal","hero","superpowers"],char:"\ud83e\uddb9\u200d\u2642\ufe0f",fitzpatrick_scale:!0,category:"people"},mrs_claus:{keywords:["woman","female","xmas","mother christmas"],char:"\ud83e\udd36",fitzpatrick_scale:!0,category:"people"},santa:{keywords:["festival","man","male","xmas","father christmas"],char:"\ud83c\udf85",fitzpatrick_scale:!0,category:"people"},sorceress:{keywords:["woman","female","mage","witch"],char:"\ud83e\uddd9\u200d\u2640\ufe0f",fitzpatrick_scale:!0,category:"people"},wizard:{keywords:["man","male","mage","sorcerer"],char:"\ud83e\uddd9\u200d\u2642\ufe0f",fitzpatrick_scale:!0,category:"people"},woman_elf:{keywords:["woman","female"],char:"\ud83e\udddd\u200d\u2640\ufe0f",fitzpatrick_scale:!0,category:"people"},man_elf:{keywords:["man","male"],char:"\ud83e\udddd\u200d\u2642\ufe0f",fitzpatrick_scale:!0,category:"people"},woman_vampire:{keywords:["woman","female"],char:"\ud83e\udddb\u200d\u2640\ufe0f",fitzpatrick_scale:!0,category:"people"},man_vampire:{keywords:["man","male","dracula"],char:"\ud83e\udddb\u200d\u2642\ufe0f",fitzpatrick_scale:!0,category:"people"},woman_zombie:{keywords:["woman","female","undead","walking dead"],char:"\ud83e\udddf\u200d\u2640\ufe0f",fitzpatrick_scale:!1,category:"people"},man_zombie:{keywords:["man","male","dracula","undead","walking dead"],char:"\ud83e\udddf\u200d\u2642\ufe0f",fitzpatrick_scale:!1,category:"people"},woman_genie:{keywords:["woman","female"],char:"\ud83e\uddde\u200d\u2640\ufe0f",fitzpatrick_scale:!1,category:"people"},man_genie:{keywords:["man","male"],char:"\ud83e\uddde\u200d\u2642\ufe0f",fitzpatrick_scale:!1,category:"people"},mermaid:{keywords:["woman","female","merwoman","ariel"],char:"\ud83e\udddc\u200d\u2640\ufe0f",fitzpatrick_scale:!0,category:"people"},merman:{keywords:["man","male","triton"],char:"\ud83e\udddc\u200d\u2642\ufe0f",fitzpatrick_scale:!0,category:"people"},woman_fairy:{keywords:["woman","female"],char:"\ud83e\uddda\u200d\u2640\ufe0f",fitzpatrick_scale:!0,category:"people"},man_fairy:{keywords:["man","male"],char:"\ud83e\uddda\u200d\u2642\ufe0f",fitzpatrick_scale:!0,category:"people"},angel:{keywords:["heaven","wings","halo"],char:"\ud83d\udc7c",fitzpatrick_scale:!0,category:"people"},pregnant_woman:{keywords:["baby"],char:"\ud83e\udd30",fitzpatrick_scale:!0,category:"people"},breastfeeding:{keywords:["nursing","baby"],char:"\ud83e\udd31",fitzpatrick_scale:!0,category:"people"},princess:{keywords:["girl","woman","female","blond","crown","royal","queen"],char:"\ud83d\udc78",fitzpatrick_scale:!0,category:"people"},prince:{keywords:["boy","man","male","crown","royal","king"],char:"\ud83e\udd34",fitzpatrick_scale:!0,category:"people"},bride_with_veil:{keywords:["couple","marriage","wedding","woman","bride"],char:"\ud83d\udc70",fitzpatrick_scale:!0,category:"people"},man_in_tuxedo:{keywords:["couple","marriage","wedding","groom"],char:"\ud83e\udd35",fitzpatrick_scale:!0,category:"people"},running_woman:{keywords:["woman","walking","exercise","race","running","female"],char:"\ud83c\udfc3\u200d\u2640\ufe0f",fitzpatrick_scale:!0,category:"people"},running_man:{keywords:["man","walking","exercise","race","running"],char:"\ud83c\udfc3",fitzpatrick_scale:!0,category:"people"},walking_woman:{keywords:["human","feet","steps","woman","female"],char:"\ud83d\udeb6\u200d\u2640\ufe0f",fitzpatrick_scale:!0,category:"people"},walking_man:{keywords:["human","feet","steps"],char:"\ud83d\udeb6",fitzpatrick_scale:!0,category:"people"},dancer:{keywords:["female","girl","woman","fun"],char:"\ud83d\udc83",fitzpatrick_scale:!0,category:"people"},man_dancing:{keywords:["male","boy","fun","dancer"],char:"\ud83d\udd7a",fitzpatrick_scale:!0,category:"people"},dancing_women:{keywords:["female","bunny","women","girls"],char:"\ud83d\udc6f",fitzpatrick_scale:!1,category:"people"},dancing_men:{keywords:["male","bunny","men","boys"],char:"\ud83d\udc6f\u200d\u2642\ufe0f",fitzpatrick_scale:!1,category:"people"},couple:{keywords:["pair","people","human","love","date","dating","like","affection","valentines","marriage"],char:"\ud83d\udc6b",fitzpatrick_scale:!1,category:"people"},two_men_holding_hands:{keywords:["pair","couple","love","like","bromance","friendship","people","human"],char:"\ud83d\udc6c",fitzpatrick_scale:!1,category:"people"},two_women_holding_hands:{keywords:["pair","friendship","couple","love","like","female","people","human"],char:"\ud83d\udc6d",fitzpatrick_scale:!1,category:"people"},bowing_woman:{keywords:["woman","female","girl"],char:"\ud83d\ude47\u200d\u2640\ufe0f",fitzpatrick_scale:!0,category:"people"},bowing_man:{keywords:["man","male","boy"],char:"\ud83d\ude47",fitzpatrick_scale:!0,category:"people"},man_facepalming:{keywords:["man","male","boy","disbelief"],char:"\ud83e\udd26\u200d\u2642\ufe0f",fitzpatrick_scale:!0,category:"people"},woman_facepalming:{keywords:["woman","female","girl","disbelief"],char:"\ud83e\udd26\u200d\u2640\ufe0f",fitzpatrick_scale:!0,category:"people"},woman_shrugging:{keywords:["woman","female","girl","confused","indifferent","doubt"],char:"\ud83e\udd37",fitzpatrick_scale:!0,category:"people"},man_shrugging:{keywords:["man","male","boy","confused","indifferent","doubt"],char:"\ud83e\udd37\u200d\u2642\ufe0f",fitzpatrick_scale:!0,category:"people"},tipping_hand_woman:{keywords:["female","girl","woman","human","information"],char:"\ud83d\udc81",fitzpatrick_scale:!0,category:"people"},tipping_hand_man:{keywords:["male","boy","man","human","information"],char:"\ud83d\udc81\u200d\u2642\ufe0f",fitzpatrick_scale:!0,category:"people"},no_good_woman:{keywords:["female","girl","woman","nope"],char:"\ud83d\ude45",fitzpatrick_scale:!0,category:"people"},no_good_man:{keywords:["male","boy","man","nope"],char:"\ud83d\ude45\u200d\u2642\ufe0f",fitzpatrick_scale:!0,category:"people"},ok_woman:{keywords:["women","girl","female","pink","human","woman"],char:"\ud83d\ude46",fitzpatrick_scale:!0,category:"people"},ok_man:{keywords:["men","boy","male","blue","human","man"],char:"\ud83d\ude46\u200d\u2642\ufe0f",fitzpatrick_scale:!0,category:"people"},raising_hand_woman:{keywords:["female","girl","woman"],char:"\ud83d\ude4b",fitzpatrick_scale:!0,category:"people"},raising_hand_man:{keywords:["male","boy","man"],char:"\ud83d\ude4b\u200d\u2642\ufe0f",fitzpatrick_scale:!0,category:"people"},pouting_woman:{keywords:["female","girl","woman"],char:"\ud83d\ude4e",fitzpatrick_scale:!0,category:"people"},pouting_man:{keywords:["male","boy","man"],char:"\ud83d\ude4e\u200d\u2642\ufe0f",fitzpatrick_scale:!0,category:"people"},frowning_woman:{keywords:["female","girl","woman","sad","depressed","discouraged","unhappy"],char:"\ud83d\ude4d",fitzpatrick_scale:!0,category:"people"},frowning_man:{keywords:["male","boy","man","sad","depressed","discouraged","unhappy"],char:"\ud83d\ude4d\u200d\u2642\ufe0f",fitzpatrick_scale:!0,category:"people"},haircut_woman:{keywords:["female","girl","woman"],char:"\ud83d\udc87",fitzpatrick_scale:!0,category:"people"},haircut_man:{keywords:["male","boy","man"],char:"\ud83d\udc87\u200d\u2642\ufe0f",fitzpatrick_scale:!0,category:"people"},massage_woman:{keywords:["female","girl","woman","head"],char:"\ud83d\udc86",fitzpatrick_scale:!0,category:"people"},massage_man:{keywords:["male","boy","man","head"],char:"\ud83d\udc86\u200d\u2642\ufe0f",fitzpatrick_scale:!0,category:"people"},woman_in_steamy_room:{keywords:["female","woman","spa","steamroom","sauna"],char:"\ud83e\uddd6\u200d\u2640\ufe0f",fitzpatrick_scale:!0,category:"people"},man_in_steamy_room:{keywords:["male","man","spa","steamroom","sauna"],char:"\ud83e\uddd6\u200d\u2642\ufe0f",fitzpatrick_scale:!0,category:"people"},couple_with_heart_woman_man:{keywords:["pair","love","like","affection","human","dating","valentines","marriage"],char:"\ud83d\udc91",fitzpatrick_scale:!1,category:"people"},couple_with_heart_woman_woman:{keywords:["pair","love","like","affection","human","dating","valentines","marriage"],char:"\ud83d\udc69\u200d\u2764\ufe0f\u200d\ud83d\udc69",fitzpatrick_scale:!1,category:"people"},couple_with_heart_man_man:{keywords:["pair","love","like","affection","human","dating","valentines","marriage"],char:"\ud83d\udc68\u200d\u2764\ufe0f\u200d\ud83d\udc68",fitzpatrick_scale:!1,category:"people"},couplekiss_man_woman:{keywords:["pair","valentines","love","like","dating","marriage"],char:"\ud83d\udc8f",fitzpatrick_scale:!1,category:"people"},couplekiss_woman_woman:{keywords:["pair","valentines","love","like","dating","marriage"],char:"\ud83d\udc69\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc69",fitzpatrick_scale:!1,category:"people"},couplekiss_man_man:{keywords:["pair","valentines","love","like","dating","marriage"],char:"\ud83d\udc68\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68",fitzpatrick_scale:!1,category:"people"},family_man_woman_boy:{keywords:["home","parents","child","mom","dad","father","mother","people","human"],char:"\ud83d\udc6a",fitzpatrick_scale:!1,category:"people"},family_man_woman_girl:{keywords:["home","parents","people","human","child"],char:"\ud83d\udc68\u200d\ud83d\udc69\u200d\ud83d\udc67",fitzpatrick_scale:!1,category:"people"},family_man_woman_girl_boy:{keywords:["home","parents","people","human","children"],char:"\ud83d\udc68\u200d\ud83d\udc69\u200d\ud83d\udc67\u200d\ud83d\udc66",fitzpatrick_scale:!1,category:"people"},family_man_woman_boy_boy:{keywords:["home","parents","people","human","children"],char:"\ud83d\udc68\u200d\ud83d\udc69\u200d\ud83d\udc66\u200d\ud83d\udc66",fitzpatrick_scale:!1,category:"people"},family_man_woman_girl_girl:{keywords:["home","parents","people","human","children"],char:"\ud83d\udc68\u200d\ud83d\udc69\u200d\ud83d\udc67\u200d\ud83d\udc67",fitzpatrick_scale:!1,category:"people"},family_woman_woman_boy:{keywords:["home","parents","people","human","children"],char:"\ud83d\udc69\u200d\ud83d\udc69\u200d\ud83d\udc66",fitzpatrick_scale:!1,category:"people"},family_woman_woman_girl:{keywords:["home","parents","people","human","children"],char:"\ud83d\udc69\u200d\ud83d\udc69\u200d\ud83d\udc67",fitzpatrick_scale:!1,category:"people"},family_woman_woman_girl_boy:{keywords:["home","parents","people","human","children"],char:"\ud83d\udc69\u200d\ud83d\udc69\u200d\ud83d\udc67\u200d\ud83d\udc66",fitzpatrick_scale:!1,category:"people"},family_woman_woman_boy_boy:{keywords:["home","parents","people","human","children"],char:"\ud83d\udc69\u200d\ud83d\udc69\u200d\ud83d\udc66\u200d\ud83d\udc66",fitzpatrick_scale:!1,category:"people"},family_woman_woman_girl_girl:{keywords:["home","parents","people","human","children"],char:"\ud83d\udc69\u200d\ud83d\udc69\u200d\ud83d\udc67\u200d\ud83d\udc67",fitzpatrick_scale:!1,category:"people"},family_man_man_boy:{keywords:["home","parents","people","human","children"],char:"\ud83d\udc68\u200d\ud83d\udc68\u200d\ud83d\udc66",fitzpatrick_scale:!1,category:"people"},family_man_man_girl:{keywords:["home","parents","people","human","children"],char:"\ud83d\udc68\u200d\ud83d\udc68\u200d\ud83d\udc67",fitzpatrick_scale:!1,category:"people"},family_man_man_girl_boy:{keywords:["home","parents","people","human","children"],char:"\ud83d\udc68\u200d\ud83d\udc68\u200d\ud83d\udc67\u200d\ud83d\udc66",fitzpatrick_scale:!1,category:"people"},family_man_man_boy_boy:{keywords:["home","parents","people","human","children"],char:"\ud83d\udc68\u200d\ud83d\udc68\u200d\ud83d\udc66\u200d\ud83d\udc66",fitzpatrick_scale:!1,category:"people"},family_man_man_girl_girl:{keywords:["home","parents","people","human","children"],char:"\ud83d\udc68\u200d\ud83d\udc68\u200d\ud83d\udc67\u200d\ud83d\udc67",fitzpatrick_scale:!1,category:"people"},family_woman_boy:{keywords:["home","parent","people","human","child"],char:"\ud83d\udc69\u200d\ud83d\udc66",fitzpatrick_scale:!1,category:"people"},family_woman_girl:{keywords:["home","parent","people","human","child"],char:"\ud83d\udc69\u200d\ud83d\udc67",fitzpatrick_scale:!1,category:"people"},family_woman_girl_boy:{keywords:["home","parent","people","human","children"],char:"\ud83d\udc69\u200d\ud83d\udc67\u200d\ud83d\udc66",fitzpatrick_scale:!1,category:"people"},family_woman_boy_boy:{keywords:["home","parent","people","human","children"],char:"\ud83d\udc69\u200d\ud83d\udc66\u200d\ud83d\udc66",fitzpatrick_scale:!1,category:"people"},family_woman_girl_girl:{keywords:["home","parent","people","human","children"],char:"\ud83d\udc69\u200d\ud83d\udc67\u200d\ud83d\udc67",fitzpatrick_scale:!1,category:"people"},family_man_boy:{keywords:["home","parent","people","human","child"],char:"\ud83d\udc68\u200d\ud83d\udc66",fitzpatrick_scale:!1,category:"people"},family_man_girl:{keywords:["home","parent","people","human","child"],char:"\ud83d\udc68\u200d\ud83d\udc67",fitzpatrick_scale:!1,category:"people"},family_man_girl_boy:{keywords:["home","parent","people","human","children"],char:"\ud83d\udc68\u200d\ud83d\udc67\u200d\ud83d\udc66",fitzpatrick_scale:!1,category:"people"},family_man_boy_boy:{keywords:["home","parent","people","human","children"],char:"\ud83d\udc68\u200d\ud83d\udc66\u200d\ud83d\udc66",fitzpatrick_scale:!1,category:"people"},family_man_girl_girl:{keywords:["home","parent","people","human","children"],char:"\ud83d\udc68\u200d\ud83d\udc67\u200d\ud83d\udc67",fitzpatrick_scale:!1,category:"people"},yarn:{keywords:["ball","crochet","knit"],char:"\ud83e\uddf6",fitzpatrick_scale:!1,category:"people"},thread:{keywords:["needle","sewing","spool","string"],char:"\ud83e\uddf5",fitzpatrick_scale:!1,category:"people"},coat:{keywords:["jacket"],char:"\ud83e\udde5",fitzpatrick_scale:!1,category:"people"},labcoat:{keywords:["doctor","experiment","scientist","chemist"],char:"\ud83e\udd7c",fitzpatrick_scale:!1,category:"people"},womans_clothes:{keywords:["fashion","shopping_bags","female"],char:"\ud83d\udc5a",fitzpatrick_scale:!1,category:"people"},tshirt:{keywords:["fashion","cloth","casual","shirt","tee"],char:"\ud83d\udc55",fitzpatrick_scale:!1,category:"people"},jeans:{keywords:["fashion","shopping"],char:"\ud83d\udc56",fitzpatrick_scale:!1,category:"people"},necktie:{keywords:["shirt","suitup","formal","fashion","cloth","business"],char:"\ud83d\udc54",fitzpatrick_scale:!1,category:"people"},dress:{keywords:["clothes","fashion","shopping"],char:"\ud83d\udc57",fitzpatrick_scale:!1,category:"people"},bikini:{keywords:["swimming","female","woman","girl","fashion","beach","summer"],char:"\ud83d\udc59",fitzpatrick_scale:!1,category:"people"},kimono:{keywords:["dress","fashion","women","female","japanese"],char:"\ud83d\udc58",fitzpatrick_scale:!1,category:"people"},lipstick:{keywords:["female","girl","fashion","woman"],char:"\ud83d\udc84",fitzpatrick_scale:!1,category:"people"},kiss:{keywords:["face","lips","love","like","affection","valentines"],char:"\ud83d\udc8b",fitzpatrick_scale:!1,category:"people"},footprints:{keywords:["feet","tracking","walking","beach"],char:"\ud83d\udc63",fitzpatrick_scale:!1,category:"people"},flat_shoe:{keywords:["ballet","slip-on","slipper"],char:"\ud83e\udd7f",fitzpatrick_scale:!1,category:"people"},high_heel:{keywords:["fashion","shoes","female","pumps","stiletto"],char:"\ud83d\udc60",fitzpatrick_scale:!1,category:"people"},sandal:{keywords:["shoes","fashion","flip flops"],char:"\ud83d\udc61",fitzpatrick_scale:!1,category:"people"},boot:{keywords:["shoes","fashion"],char:"\ud83d\udc62",fitzpatrick_scale:!1,category:"people"},mans_shoe:{keywords:["fashion","male"],char:"\ud83d\udc5e",fitzpatrick_scale:!1,category:"people"},athletic_shoe:{keywords:["shoes","sports","sneakers"],char:"\ud83d\udc5f",fitzpatrick_scale:!1,category:"people"},hiking_boot:{keywords:["backpacking","camping","hiking"],char:"\ud83e\udd7e",fitzpatrick_scale:!1,category:"people"},socks:{keywords:["stockings","clothes"],char:"\ud83e\udde6",fitzpatrick_scale:!1,category:"people"},gloves:{keywords:["hands","winter","clothes"],char:"\ud83e\udde4",fitzpatrick_scale:!1,category:"people"},scarf:{keywords:["neck","winter","clothes"],char:"\ud83e\udde3",fitzpatrick_scale:!1,category:"people"},womans_hat:{keywords:["fashion","accessories","female","lady","spring"],char:"\ud83d\udc52",fitzpatrick_scale:!1,category:"people"},tophat:{keywords:["magic","gentleman","classy","circus"],char:"\ud83c\udfa9",fitzpatrick_scale:!1,category:"people"},billed_hat:{keywords:["cap","baseball"],char:"\ud83e\udde2",fitzpatrick_scale:!1,category:"people"},rescue_worker_helmet:{keywords:["construction","build"],char:"\u26d1",fitzpatrick_scale:!1,category:"people"},mortar_board:{keywords:["school","college","degree","university","graduation","cap","hat","legal","learn","education"],char:"\ud83c\udf93",fitzpatrick_scale:!1,category:"people"},crown:{keywords:["king","kod","leader","royalty","lord"],char:"\ud83d\udc51",fitzpatrick_scale:!1,category:"people"},school_satchel:{keywords:["student","education","bag","backpack"],char:"\ud83c\udf92",fitzpatrick_scale:!1,category:"people"},luggage:{keywords:["packing","travel"],char:"\ud83e\uddf3",fitzpatrick_scale:!1,category:"people"},pouch:{keywords:["bag","accessories","shopping"],char:"\ud83d\udc5d",fitzpatrick_scale:!1,category:"people"},purse:{keywords:["fashion","accessories","money","sales","shopping"],char:"\ud83d\udc5b",fitzpatrick_scale:!1,category:"people"},handbag:{keywords:["fashion","accessory","accessories","shopping"],char:"\ud83d\udc5c",fitzpatrick_scale:!1,category:"people"},briefcase:{keywords:["business","documents","work","law","legal","job","career"],char:"\ud83d\udcbc",fitzpatrick_scale:!1,category:"people"},eyeglasses:{keywords:["fashion","accessories","eyesight","nerdy","dork","geek"],char:"\ud83d\udc53",fitzpatrick_scale:!1,category:"people"},dark_sunglasses:{keywords:["face","cool","accessories"],char:"\ud83d\udd76",fitzpatrick_scale:!1,category:"people"},goggles:{keywords:["eyes","protection","safety"],char:"\ud83e\udd7d",fitzpatrick_scale:!1,category:"people"},ring:{keywords:["wedding","propose","marriage","valentines","diamond","fashion","jewelry","gem","engagement"],char:"\ud83d\udc8d",fitzpatrick_scale:!1,category:"people"},closed_umbrella:{keywords:["weather","rain","drizzle"],char:"\ud83c\udf02",fitzpatrick_scale:!1,category:"people"},dog:{keywords:["animal","friend","nature","woof","puppy","pet","faithful"],char:"\ud83d\udc36",fitzpatrick_scale:!1,category:"animals_and_nature"},cat:{keywords:["animal","meow","nature","pet","kitten"],char:"\ud83d\udc31",fitzpatrick_scale:!1,category:"animals_and_nature"},mouse:{keywords:["animal","nature","cheese_wedge","rodent"],char:"\ud83d\udc2d",fitzpatrick_scale:!1,category:"animals_and_nature"},hamster:{keywords:["animal","nature"],char:"\ud83d\udc39",fitzpatrick_scale:!1,category:"animals_and_nature"},rabbit:{keywords:["animal","nature","pet","spring","magic","bunny"],char:"\ud83d\udc30",fitzpatrick_scale:!1,category:"animals_and_nature"},fox_face:{keywords:["animal","nature","face"],char:"\ud83e\udd8a",fitzpatrick_scale:!1,category:"animals_and_nature"},bear:{keywords:["animal","nature","wild"],char:"\ud83d\udc3b",fitzpatrick_scale:!1,category:"animals_and_nature"},panda_face:{keywords:["animal","nature","panda"],char:"\ud83d\udc3c",fitzpatrick_scale:!1,category:"animals_and_nature"},koala:{keywords:["animal","nature"],char:"\ud83d\udc28",fitzpatrick_scale:!1,category:"animals_and_nature"},tiger:{keywords:["animal","cat","danger","wild","nature","roar"],char:"\ud83d\udc2f",fitzpatrick_scale:!1,category:"animals_and_nature"},lion:{keywords:["animal","nature"],char:"\ud83e\udd81",fitzpatrick_scale:!1,category:"animals_and_nature"},cow:{keywords:["beef","ox","animal","nature","moo","milk"],char:"\ud83d\udc2e",fitzpatrick_scale:!1,category:"animals_and_nature"},pig:{keywords:["animal","oink","nature"],char:"\ud83d\udc37",fitzpatrick_scale:!1,category:"animals_and_nature"},pig_nose:{keywords:["animal","oink"],char:"\ud83d\udc3d",fitzpatrick_scale:!1,category:"animals_and_nature"},frog:{keywords:["animal","nature","croak","toad"],char:"\ud83d\udc38",fitzpatrick_scale:!1,category:"animals_and_nature"},squid:{keywords:["animal","nature","ocean","sea"],char:"\ud83e\udd91",fitzpatrick_scale:!1,category:"animals_and_nature"},octopus:{keywords:["animal","creature","ocean","sea","nature","beach"],char:"\ud83d\udc19",fitzpatrick_scale:!1,category:"animals_and_nature"},shrimp:{keywords:["animal","ocean","nature","seafood"],char:"\ud83e\udd90",fitzpatrick_scale:!1,category:"animals_and_nature"},monkey_face:{keywords:["animal","nature","circus"],char:"\ud83d\udc35",fitzpatrick_scale:!1,category:"animals_and_nature"},gorilla:{keywords:["animal","nature","circus"],char:"\ud83e\udd8d",fitzpatrick_scale:!1,category:"animals_and_nature"},see_no_evil:{keywords:["monkey","animal","nature","haha"],char:"\ud83d\ude48",fitzpatrick_scale:!1,category:"animals_and_nature"},hear_no_evil:{keywords:["animal","monkey","nature"],char:"\ud83d\ude49",fitzpatrick_scale:!1,category:"animals_and_nature"},speak_no_evil:{keywords:["monkey","animal","nature","omg"],char:"\ud83d\ude4a",fitzpatrick_scale:!1,category:"animals_and_nature"},monkey:{keywords:["animal","nature","banana","circus"],char:"\ud83d\udc12",fitzpatrick_scale:!1,category:"animals_and_nature"},chicken:{keywords:["animal","cluck","nature","bird"],char:"\ud83d\udc14",fitzpatrick_scale:!1,category:"animals_and_nature"},penguin:{keywords:["animal","nature"],char:"\ud83d\udc27",fitzpatrick_scale:!1,category:"animals_and_nature"},bird:{keywords:["animal","nature","fly","tweet","spring"],char:"\ud83d\udc26",fitzpatrick_scale:!1,category:"animals_and_nature"},baby_chick:{keywords:["animal","chicken","bird"],char:"\ud83d\udc24",fitzpatrick_scale:!1,category:"animals_and_nature"},hatching_chick:{keywords:["animal","chicken","egg","born","baby","bird"],char:"\ud83d\udc23",fitzpatrick_scale:!1,category:"animals_and_nature"},hatched_chick:{keywords:["animal","chicken","baby","bird"],char:"\ud83d\udc25",fitzpatrick_scale:!1,category:"animals_and_nature"},duck:{keywords:["animal","nature","bird","mallard"],char:"\ud83e\udd86",fitzpatrick_scale:!1,category:"animals_and_nature"},eagle:{keywords:["animal","nature","bird"],char:"\ud83e\udd85",fitzpatrick_scale:!1,category:"animals_and_nature"},owl:{keywords:["animal","nature","bird","hoot"],char:"\ud83e\udd89",fitzpatrick_scale:!1,category:"animals_and_nature"},bat:{keywords:["animal","nature","blind","vampire"],char:"\ud83e\udd87",fitzpatrick_scale:!1,category:"animals_and_nature"},wolf:{keywords:["animal","nature","wild"],char:"\ud83d\udc3a",fitzpatrick_scale:!1,category:"animals_and_nature"},boar:{keywords:["animal","nature"],char:"\ud83d\udc17",fitzpatrick_scale:!1,category:"animals_and_nature"},horse:{keywords:["animal","brown","nature"],char:"\ud83d\udc34",fitzpatrick_scale:!1,category:"animals_and_nature"},unicorn:{keywords:["animal","nature","mystical"],char:"\ud83e\udd84",fitzpatrick_scale:!1,category:"animals_and_nature"},honeybee:{keywords:["animal","insect","nature","bug","spring","honey"],char:"\ud83d\udc1d",fitzpatrick_scale:!1,category:"animals_and_nature"},bug:{keywords:["animal","insect","nature","worm"],char:"\ud83d\udc1b",fitzpatrick_scale:!1,category:"animals_and_nature"},butterfly:{keywords:["animal","insect","nature","caterpillar"],char:"\ud83e\udd8b",fitzpatrick_scale:!1,category:"animals_and_nature"},snail:{keywords:["slow","animal","shell"],char:"\ud83d\udc0c",fitzpatrick_scale:!1,category:"animals_and_nature"},beetle:{keywords:["animal","insect","nature","ladybug"],char:"\ud83d\udc1e",fitzpatrick_scale:!1,category:"animals_and_nature"},ant:{keywords:["animal","insect","nature","bug"],char:"\ud83d\udc1c",fitzpatrick_scale:!1,category:"animals_and_nature"},grasshopper:{keywords:["animal","cricket","chirp"],char:"\ud83e\udd97",fitzpatrick_scale:!1,category:"animals_and_nature"},spider:{keywords:["animal","arachnid"],char:"\ud83d\udd77",fitzpatrick_scale:!1,category:"animals_and_nature"},scorpion:{keywords:["animal","arachnid"],char:"\ud83e\udd82",fitzpatrick_scale:!1,category:"animals_and_nature"},crab:{keywords:["animal","crustacean"],char:"\ud83e\udd80",fitzpatrick_scale:!1,category:"animals_and_nature"},snake:{keywords:["animal","evil","nature","hiss","python"],char:"\ud83d\udc0d",fitzpatrick_scale:!1,category:"animals_and_nature"},lizard:{keywords:["animal","nature","reptile"],char:"\ud83e\udd8e",fitzpatrick_scale:!1,category:"animals_and_nature"},"t-rex":{keywords:["animal","nature","dinosaur","tyrannosaurus","extinct"],char:"\ud83e\udd96",fitzpatrick_scale:!1,category:"animals_and_nature"},sauropod:{keywords:["animal","nature","dinosaur","brachiosaurus","brontosaurus","diplodocus","extinct"],char:"\ud83e\udd95",fitzpatrick_scale:!1,category:"animals_and_nature"},turtle:{keywords:["animal","slow","nature","tortoise"],char:"\ud83d\udc22",fitzpatrick_scale:!1,category:"animals_and_nature"},tropical_fish:{keywords:["animal","swim","ocean","beach","nemo"],char:"\ud83d\udc20",fitzpatrick_scale:!1,category:"animals_and_nature"},fish:{keywords:["animal","food","nature"],char:"\ud83d\udc1f",fitzpatrick_scale:!1,category:"animals_and_nature"},blowfish:{keywords:["animal","nature","food","sea","ocean"],char:"\ud83d\udc21",fitzpatrick_scale:!1,category:"animals_and_nature"},dolphin:{keywords:["animal","nature","fish","sea","ocean","flipper","fins","beach"],char:"\ud83d\udc2c",fitzpatrick_scale:!1,category:"animals_and_nature"},shark:{keywords:["animal","nature","fish","sea","ocean","jaws","fins","beach"],char:"\ud83e\udd88",fitzpatrick_scale:!1,category:"animals_and_nature"},whale:{keywords:["animal","nature","sea","ocean"],char:"\ud83d\udc33",fitzpatrick_scale:!1,category:"animals_and_nature"},whale2:{keywords:["animal","nature","sea","ocean"],char:"\ud83d\udc0b",fitzpatrick_scale:!1,category:"animals_and_nature"},crocodile:{keywords:["animal","nature","reptile","lizard","alligator"],char:"\ud83d\udc0a",fitzpatrick_scale:!1,category:"animals_and_nature"},leopard:{keywords:["animal","nature"],char:"\ud83d\udc06",fitzpatrick_scale:!1,category:"animals_and_nature"},zebra:{keywords:["animal","nature","stripes","safari"],char:"\ud83e\udd93",fitzpatrick_scale:!1,category:"animals_and_nature"},tiger2:{keywords:["animal","nature","roar"],char:"\ud83d\udc05",fitzpatrick_scale:!1,category:"animals_and_nature"},water_buffalo:{keywords:["animal","nature","ox","cow"],char:"\ud83d\udc03",fitzpatrick_scale:!1,category:"animals_and_nature"},ox:{keywords:["animal","cow","beef"],char:"\ud83d\udc02",fitzpatrick_scale:!1,category:"animals_and_nature"},cow2:{keywords:["beef","ox","animal","nature","moo","milk"],char:"\ud83d\udc04",fitzpatrick_scale:!1,category:"animals_and_nature"},deer:{keywords:["animal","nature","horns","venison"],char:"\ud83e\udd8c",fitzpatrick_scale:!1,category:"animals_and_nature"},dromedary_camel:{keywords:["animal","hot","desert","hump"],char:"\ud83d\udc2a",fitzpatrick_scale:!1,category:"animals_and_nature"},camel:{keywords:["animal","nature","hot","desert","hump"],char:"\ud83d\udc2b",fitzpatrick_scale:!1,category:"animals_and_nature"},giraffe:{keywords:["animal","nature","spots","safari"],char:"\ud83e\udd92",fitzpatrick_scale:!1,category:"animals_and_nature"},elephant:{keywords:["animal","nature","nose","th","circus"],char:"\ud83d\udc18",fitzpatrick_scale:!1,category:"animals_and_nature"},rhinoceros:{keywords:["animal","nature","horn"],char:"\ud83e\udd8f",fitzpatrick_scale:!1,category:"animals_and_nature"},goat:{keywords:["animal","nature"],char:"\ud83d\udc10",fitzpatrick_scale:!1,category:"animals_and_nature"},ram:{keywords:["animal","sheep","nature"],char:"\ud83d\udc0f",fitzpatrick_scale:!1,category:"animals_and_nature"},sheep:{keywords:["animal","nature","wool","shipit"],char:"\ud83d\udc11",fitzpatrick_scale:!1,category:"animals_and_nature"},racehorse:{keywords:["animal","gamble","luck"],char:"\ud83d\udc0e",fitzpatrick_scale:!1,category:"animals_and_nature"},pig2:{keywords:["animal","nature"],char:"\ud83d\udc16",fitzpatrick_scale:!1,category:"animals_and_nature"},rat:{keywords:["animal","mouse","rodent"],char:"\ud83d\udc00",fitzpatrick_scale:!1,category:"animals_and_nature"},mouse2:{keywords:["animal","nature","rodent"],char:"\ud83d\udc01",fitzpatrick_scale:!1,category:"animals_and_nature"},rooster:{keywords:["animal","nature","chicken"],char:"\ud83d\udc13",fitzpatrick_scale:!1,category:"animals_and_nature"},turkey:{keywords:["animal","bird"],char:"\ud83e\udd83",fitzpatrick_scale:!1,category:"animals_and_nature"},dove:{keywords:["animal","bird"],char:"\ud83d\udd4a",fitzpatrick_scale:!1,category:"animals_and_nature"},dog2:{keywords:["animal","nature","friend","doge","pet","faithful"],char:"\ud83d\udc15",fitzpatrick_scale:!1,category:"animals_and_nature"},poodle:{keywords:["dog","animal","101","nature","pet"],char:"\ud83d\udc29",fitzpatrick_scale:!1,category:"animals_and_nature"},cat2:{keywords:["animal","meow","pet","cats"],char:"\ud83d\udc08",fitzpatrick_scale:!1,category:"animals_and_nature"},rabbit2:{keywords:["animal","nature","pet","magic","spring"],char:"\ud83d\udc07",fitzpatrick_scale:!1,category:"animals_and_nature"},chipmunk:{keywords:["animal","nature","rodent","squirrel"],char:"\ud83d\udc3f",fitzpatrick_scale:!1,category:"animals_and_nature"},hedgehog:{keywords:["animal","nature","spiny"],char:"\ud83e\udd94",fitzpatrick_scale:!1,category:"animals_and_nature"},raccoon:{keywords:["animal","nature"],char:"\ud83e\udd9d",fitzpatrick_scale:!1,category:"animals_and_nature"},llama:{keywords:["animal","nature","alpaca"],char:"\ud83e\udd99",fitzpatrick_scale:!1,category:"animals_and_nature"},hippopotamus:{keywords:["animal","nature"],char:"\ud83e\udd9b",fitzpatrick_scale:!1,category:"animals_and_nature"},kangaroo:{keywords:["animal","nature","australia","joey","hop","marsupial"],char:"\ud83e\udd98",fitzpatrick_scale:!1,category:"animals_and_nature"},badger:{keywords:["animal","nature","honey"],char:"\ud83e\udda1",fitzpatrick_scale:!1,category:"animals_and_nature"},swan:{keywords:["animal","nature","bird"],char:"\ud83e\udda2",fitzpatrick_scale:!1,category:"animals_and_nature"},peacock:{keywords:["animal","nature","peahen","bird"],char:"\ud83e\udd9a",fitzpatrick_scale:!1,category:"animals_and_nature"},parrot:{keywords:["animal","nature","bird","pirate","talk"],char:"\ud83e\udd9c",fitzpatrick_scale:!1,category:"animals_and_nature"},lobster:{keywords:["animal","nature","bisque","claws","seafood"],char:"\ud83e\udd9e",fitzpatrick_scale:!1,category:"animals_and_nature"},mosquito:{keywords:["animal","nature","insect","malaria"],char:"\ud83e\udd9f",fitzpatrick_scale:!1,category:"animals_and_nature"},paw_prints:{keywords:["animal","tracking","footprints","dog","cat","pet","feet"],char:"\ud83d\udc3e",fitzpatrick_scale:!1,category:"animals_and_nature"},dragon:{keywords:["animal","myth","nature","chinese","green"],char:"\ud83d\udc09",fitzpatrick_scale:!1,category:"animals_and_nature"},dragon_face:{keywords:["animal","myth","nature","chinese","green"],char:"\ud83d\udc32",fitzpatrick_scale:!1,category:"animals_and_nature"},cactus:{keywords:["vegetable","plant","nature"],char:"\ud83c\udf35",fitzpatrick_scale:!1,category:"animals_and_nature"},christmas_tree:{keywords:["festival","vacation","december","xmas","celebration"],char:"\ud83c\udf84",fitzpatrick_scale:!1,category:"animals_and_nature"},evergreen_tree:{keywords:["plant","nature"],char:"\ud83c\udf32",fitzpatrick_scale:!1,category:"animals_and_nature"},deciduous_tree:{keywords:["plant","nature"],char:"\ud83c\udf33",fitzpatrick_scale:!1,category:"animals_and_nature"},palm_tree:{keywords:["plant","vegetable","nature","summer","beach","mojito","tropical"],char:"\ud83c\udf34",fitzpatrick_scale:!1,category:"animals_and_nature"},seedling:{keywords:["plant","nature","grass","lawn","spring"],char:"\ud83c\udf31",fitzpatrick_scale:!1,category:"animals_and_nature"},herb:{keywords:["vegetable","plant","medicine","weed","grass","lawn"],char:"\ud83c\udf3f",fitzpatrick_scale:!1,category:"animals_and_nature"},shamrock:{keywords:["vegetable","plant","nature","irish","clover"],char:"\u2618",fitzpatrick_scale:!1,category:"animals_and_nature"},four_leaf_clover:{keywords:["vegetable","plant","nature","lucky","irish"],char:"\ud83c\udf40",fitzpatrick_scale:!1,category:"animals_and_nature"},bamboo:{keywords:["plant","nature","vegetable","panda","pine_decoration"],char:"\ud83c\udf8d",fitzpatrick_scale:!1,category:"animals_and_nature"},tanabata_tree:{keywords:["plant","nature","branch","summer"],char:"\ud83c\udf8b",fitzpatrick_scale:!1,category:"animals_and_nature"},leaves:{keywords:["nature","plant","tree","vegetable","grass","lawn","spring"],char:"\ud83c\udf43",fitzpatrick_scale:!1,category:"animals_and_nature"},fallen_leaf:{keywords:["nature","plant","vegetable","leaves"],char:"\ud83c\udf42",fitzpatrick_scale:!1,category:"animals_and_nature"},maple_leaf:{keywords:["nature","plant","vegetable","ca","fall"],char:"\ud83c\udf41",fitzpatrick_scale:!1,category:"animals_and_nature"},ear_of_rice:{keywords:["nature","plant"],char:"\ud83c\udf3e",fitzpatrick_scale:!1,category:"animals_and_nature"},hibiscus:{keywords:["plant","vegetable","flowers","beach"],char:"\ud83c\udf3a",fitzpatrick_scale:!1,category:"animals_and_nature"},sunflower:{keywords:["nature","plant","fall"],char:"\ud83c\udf3b",fitzpatrick_scale:!1,category:"animals_and_nature"},rose:{keywords:["flowers","valentines","love","spring"],char:"\ud83c\udf39",fitzpatrick_scale:!1,category:"animals_and_nature"},wilted_flower:{keywords:["plant","nature","flower"],char:"\ud83e\udd40",fitzpatrick_scale:!1,category:"animals_and_nature"},tulip:{keywords:["flowers","plant","nature","summer","spring"],char:"\ud83c\udf37",fitzpatrick_scale:!1,category:"animals_and_nature"},blossom:{keywords:["nature","flowers","yellow"],char:"\ud83c\udf3c",fitzpatrick_scale:!1,category:"animals_and_nature"},cherry_blossom:{keywords:["nature","plant","spring","flower"],char:"\ud83c\udf38",fitzpatrick_scale:!1,category:"animals_and_nature"},bouquet:{keywords:["flowers","nature","spring"],char:"\ud83d\udc90",fitzpatrick_scale:!1,category:"animals_and_nature"},mushroom:{keywords:["plant","vegetable"],char:"\ud83c\udf44",fitzpatrick_scale:!1,category:"animals_and_nature"},chestnut:{keywords:["food","squirrel"],char:"\ud83c\udf30",fitzpatrick_scale:!1,category:"animals_and_nature"},jack_o_lantern:{keywords:["halloween","light","pumpkin","creepy","fall"],char:"\ud83c\udf83",fitzpatrick_scale:!1,category:"animals_and_nature"},shell:{keywords:["nature","sea","beach"],char:"\ud83d\udc1a",fitzpatrick_scale:!1,category:"animals_and_nature"},spider_web:{keywords:["animal","insect","arachnid","silk"],char:"\ud83d\udd78",fitzpatrick_scale:!1,category:"animals_and_nature"},earth_americas:{keywords:["globe","world","USA","international"],char:"\ud83c\udf0e",fitzpatrick_scale:!1,category:"animals_and_nature"},earth_africa:{keywords:["globe","world","international"],char:"\ud83c\udf0d",fitzpatrick_scale:!1,category:"animals_and_nature"},earth_asia:{keywords:["globe","world","east","international"],char:"\ud83c\udf0f",fitzpatrick_scale:!1,category:"animals_and_nature"},full_moon:{keywords:["nature","yellow","twilight","planet","space","night","evening","sleep"],char:"\ud83c\udf15",fitzpatrick_scale:!1,category:"animals_and_nature"},waning_gibbous_moon:{keywords:["nature","twilight","planet","space","night","evening","sleep","waxing_gibbous_moon"],char:"\ud83c\udf16",fitzpatrick_scale:!1,category:"animals_and_nature"},last_quarter_moon:{keywords:["nature","twilight","planet","space","night","evening","sleep"],char:"\ud83c\udf17",fitzpatrick_scale:!1,category:"animals_and_nature"},waning_crescent_moon:{keywords:["nature","twilight","planet","space","night","evening","sleep"],char:"\ud83c\udf18",fitzpatrick_scale:!1,category:"animals_and_nature"},new_moon:{keywords:["nature","twilight","planet","space","night","evening","sleep"],char:"\ud83c\udf11",fitzpatrick_scale:!1,category:"animals_and_nature"},waxing_crescent_moon:{keywords:["nature","twilight","planet","space","night","evening","sleep"],char:"\ud83c\udf12",fitzpatrick_scale:!1,category:"animals_and_nature"},first_quarter_moon:{keywords:["nature","twilight","planet","space","night","evening","sleep"],char:"\ud83c\udf13",fitzpatrick_scale:!1,category:"animals_and_nature"},waxing_gibbous_moon:{keywords:["nature","night","sky","gray","twilight","planet","space","evening","sleep"],char:"\ud83c\udf14",fitzpatrick_scale:!1,category:"animals_and_nature"},new_moon_with_face:{keywords:["nature","twilight","planet","space","night","evening","sleep"],char:"\ud83c\udf1a",fitzpatrick_scale:!1,category:"animals_and_nature"},full_moon_with_face:{keywords:["nature","twilight","planet","space","night","evening","sleep"],char:"\ud83c\udf1d",fitzpatrick_scale:!1,category:"animals_and_nature"},first_quarter_moon_with_face:{keywords:["nature","twilight","planet","space","night","evening","sleep"],char:"\ud83c\udf1b",fitzpatrick_scale:!1,category:"animals_and_nature"},last_quarter_moon_with_face:{keywords:["nature","twilight","planet","space","night","evening","sleep"],char:"\ud83c\udf1c",fitzpatrick_scale:!1,category:"animals_and_nature"},sun_with_face:{keywords:["nature","morning","sky"],char:"\ud83c\udf1e",fitzpatrick_scale:!1,category:"animals_and_nature"},crescent_moon:{keywords:["night","sleep","sky","evening","magic"],char:"\ud83c\udf19",fitzpatrick_scale:!1,category:"animals_and_nature"},star:{keywords:["night","yellow"],char:"\u2b50",fitzpatrick_scale:!1,category:"animals_and_nature"},star2:{keywords:["night","sparkle","awesome","good","magic"],char:"\ud83c\udf1f",fitzpatrick_scale:!1,category:"animals_and_nature"},dizzy:{keywords:["star","sparkle","shoot","magic"],char:"\ud83d\udcab",fitzpatrick_scale:!1,category:"animals_and_nature"},sparkles:{keywords:["stars","shine","shiny","cool","awesome","good","magic"],char:"\u2728",fitzpatrick_scale:!1,category:"animals_and_nature"},comet:{keywords:["space"],char:"\u2604",fitzpatrick_scale:!1,category:"animals_and_nature"},sunny:{keywords:["weather","nature","brightness","summer","beach","spring"],char:"\u2600\ufe0f",fitzpatrick_scale:!1,category:"animals_and_nature"},sun_behind_small_cloud:{keywords:["weather"],char:"\ud83c\udf24",fitzpatrick_scale:!1,category:"animals_and_nature"},partly_sunny:{keywords:["weather","nature","cloudy","morning","fall","spring"],char:"\u26c5",fitzpatrick_scale:!1,category:"animals_and_nature"},sun_behind_large_cloud:{keywords:["weather"],char:"\ud83c\udf25",fitzpatrick_scale:!1,category:"animals_and_nature"},sun_behind_rain_cloud:{keywords:["weather"],char:"\ud83c\udf26",fitzpatrick_scale:!1,category:"animals_and_nature"},cloud:{keywords:["weather","sky"],char:"\u2601\ufe0f",fitzpatrick_scale:!1,category:"animals_and_nature"},cloud_with_rain:{keywords:["weather"],char:"\ud83c\udf27",fitzpatrick_scale:!1,category:"animals_and_nature"},cloud_with_lightning_and_rain:{keywords:["weather","lightning"],char:"\u26c8",fitzpatrick_scale:!1,category:"animals_and_nature"},cloud_with_lightning:{keywords:["weather","thunder"],char:"\ud83c\udf29",fitzpatrick_scale:!1,category:"animals_and_nature"},zap:{keywords:["thunder","weather","lightning bolt","fast"],char:"\u26a1",fitzpatrick_scale:!1,category:"animals_and_nature"},fire:{keywords:["hot","cook","flame"],char:"\ud83d\udd25",fitzpatrick_scale:!1,category:"animals_and_nature"},boom:{keywords:["bomb","explode","explosion","collision","blown"],char:"\ud83d\udca5",fitzpatrick_scale:!1,category:"animals_and_nature"},snowflake:{keywords:["winter","season","cold","weather","christmas","xmas"],char:"\u2744\ufe0f",fitzpatrick_scale:!1,category:"animals_and_nature"},cloud_with_snow:{keywords:["weather"],char:"\ud83c\udf28",fitzpatrick_scale:!1,category:"animals_and_nature"},snowman:{keywords:["winter","season","cold","weather","christmas","xmas","frozen","without_snow"],char:"\u26c4",fitzpatrick_scale:!1,category:"animals_and_nature"},snowman_with_snow:{keywords:["winter","season","cold","weather","christmas","xmas","frozen"],char:"\u2603",fitzpatrick_scale:!1,category:"animals_and_nature"},wind_face:{keywords:["gust","air"],char:"\ud83c\udf2c",fitzpatrick_scale:!1,category:"animals_and_nature"},dash:{keywords:["wind","air","fast","shoo","fart","smoke","puff"],char:"\ud83d\udca8",fitzpatrick_scale:!1,category:"animals_and_nature"},tornado:{keywords:["weather","cyclone","twister"],char:"\ud83c\udf2a",fitzpatrick_scale:!1,category:"animals_and_nature"},fog:{keywords:["weather"],char:"\ud83c\udf2b",fitzpatrick_scale:!1,category:"animals_and_nature"},open_umbrella:{keywords:["weather","spring"],char:"\u2602",fitzpatrick_scale:!1,category:"animals_and_nature"},umbrella:{keywords:["rainy","weather","spring"],char:"\u2614",fitzpatrick_scale:!1,category:"animals_and_nature"},droplet:{keywords:["water","drip","faucet","spring"],char:"\ud83d\udca7",fitzpatrick_scale:!1,category:"animals_and_nature"},sweat_drops:{keywords:["water","drip","oops"],char:"\ud83d\udca6",fitzpatrick_scale:!1,category:"animals_and_nature"},ocean:{keywords:["sea","water","wave","nature","tsunami","disaster"],char:"\ud83c\udf0a",fitzpatrick_scale:!1,category:"animals_and_nature"},green_apple:{keywords:["fruit","nature"],char:"\ud83c\udf4f",fitzpatrick_scale:!1,category:"food_and_drink"},apple:{keywords:["fruit","mac","school"],char:"\ud83c\udf4e",fitzpatrick_scale:!1,category:"food_and_drink"},pear:{keywords:["fruit","nature","food"],char:"\ud83c\udf50",fitzpatrick_scale:!1,category:"food_and_drink"},tangerine:{keywords:["food","fruit","nature","orange"],char:"\ud83c\udf4a",fitzpatrick_scale:!1,category:"food_and_drink"},lemon:{keywords:["fruit","nature"],char:"\ud83c\udf4b",fitzpatrick_scale:!1,category:"food_and_drink"},banana:{keywords:["fruit","food","monkey"],char:"\ud83c\udf4c",fitzpatrick_scale:!1,category:"food_and_drink"},watermelon:{keywords:["fruit","food","picnic","summer"],char:"\ud83c\udf49",fitzpatrick_scale:!1,category:"food_and_drink"},grapes:{keywords:["fruit","food","wine"],char:"\ud83c\udf47",fitzpatrick_scale:!1,category:"food_and_drink"},strawberry:{keywords:["fruit","food","nature"],char:"\ud83c\udf53",fitzpatrick_scale:!1,category:"food_and_drink"},melon:{keywords:["fruit","nature","food"],char:"\ud83c\udf48",fitzpatrick_scale:!1,category:"food_and_drink"},cherries:{keywords:["food","fruit"],char:"\ud83c\udf52",fitzpatrick_scale:!1,category:"food_and_drink"},peach:{keywords:["fruit","nature","food"],char:"\ud83c\udf51",fitzpatrick_scale:!1,category:"food_and_drink"},pineapple:{keywords:["fruit","nature","food"],char:"\ud83c\udf4d",fitzpatrick_scale:!1,category:"food_and_drink"},coconut:{keywords:["fruit","nature","food","palm"],char:"\ud83e\udd65",fitzpatrick_scale:!1,category:"food_and_drink"},kiwi_fruit:{keywords:["fruit","food"],char:"\ud83e\udd5d",fitzpatrick_scale:!1,category:"food_and_drink"},mango:{keywords:["fruit","food","tropical"],char:"\ud83e\udd6d",fitzpatrick_scale:!1,category:"food_and_drink"},avocado:{keywords:["fruit","food"],char:"\ud83e\udd51",fitzpatrick_scale:!1,category:"food_and_drink"},broccoli:{keywords:["fruit","food","vegetable"],char:"\ud83e\udd66",fitzpatrick_scale:!1,category:"food_and_drink"},tomato:{keywords:["fruit","vegetable","nature","food"],char:"\ud83c\udf45",fitzpatrick_scale:!1,category:"food_and_drink"},eggplant:{keywords:["vegetable","nature","food","aubergine"],char:"\ud83c\udf46",fitzpatrick_scale:!1,category:"food_and_drink"},cucumber:{keywords:["fruit","food","pickle"],char:"\ud83e\udd52",fitzpatrick_scale:!1,category:"food_and_drink"},carrot:{keywords:["vegetable","food","orange"],char:"\ud83e\udd55",fitzpatrick_scale:!1,category:"food_and_drink"},hot_pepper:{keywords:["food","spicy","chilli","chili"],char:"\ud83c\udf36",fitzpatrick_scale:!1,category:"food_and_drink"},potato:{keywords:["food","tuber","vegatable","starch"],char:"\ud83e\udd54",fitzpatrick_scale:!1,category:"food_and_drink"},corn:{keywords:["food","vegetable","plant"],char:"\ud83c\udf3d",fitzpatrick_scale:!1,category:"food_and_drink"},leafy_greens:{keywords:["food","vegetable","plant","bok choy","cabbage","kale","lettuce"],char:"\ud83e\udd6c",fitzpatrick_scale:!1,category:"food_and_drink"},sweet_potato:{keywords:["food","nature"],char:"\ud83c\udf60",fitzpatrick_scale:!1,category:"food_and_drink"},peanuts:{keywords:["food","nut"],char:"\ud83e\udd5c",fitzpatrick_scale:!1,category:"food_and_drink"},honey_pot:{keywords:["bees","sweet","kitchen"],char:"\ud83c\udf6f",fitzpatrick_scale:!1,category:"food_and_drink"},croissant:{keywords:["food","bread","french"],char:"\ud83e\udd50",fitzpatrick_scale:!1,category:"food_and_drink"},bread:{keywords:["food","wheat","breakfast","toast"],char:"\ud83c\udf5e",fitzpatrick_scale:!1,category:"food_and_drink"},baguette_bread:{keywords:["food","bread","french"],char:"\ud83e\udd56",fitzpatrick_scale:!1,category:"food_and_drink"},bagel:{keywords:["food","bread","bakery","schmear"],char:"\ud83e\udd6f",fitzpatrick_scale:!1,category:"food_and_drink"},pretzel:{keywords:["food","bread","twisted"],char:"\ud83e\udd68",fitzpatrick_scale:!1,category:"food_and_drink"},cheese:{keywords:["food","chadder"],char:"\ud83e\uddc0",fitzpatrick_scale:!1,category:"food_and_drink"},egg:{keywords:["food","chicken","breakfast"],char:"\ud83e\udd5a",fitzpatrick_scale:!1,category:"food_and_drink"},bacon:{keywords:["food","breakfast","pork","pig","meat"],char:"\ud83e\udd53",fitzpatrick_scale:!1,category:"food_and_drink"},steak:{keywords:["food","cow","meat","cut","chop","lambchop","porkchop"],char:"\ud83e\udd69",fitzpatrick_scale:!1,category:"food_and_drink"},pancakes:{keywords:["food","breakfast","flapjacks","hotcakes"],char:"\ud83e\udd5e",fitzpatrick_scale:!1,category:"food_and_drink"},poultry_leg:{keywords:["food","meat","drumstick","bird","chicken","turkey"],char:"\ud83c\udf57",fitzpatrick_scale:!1,category:"food_and_drink"},meat_on_bone:{keywords:["good","food","drumstick"],char:"\ud83c\udf56",fitzpatrick_scale:!1,category:"food_and_drink"},bone:{keywords:["skeleton"],char:"\ud83e\uddb4",fitzpatrick_scale:!1,category:"food_and_drink"},fried_shrimp:{keywords:["food","animal","appetizer","summer"],char:"\ud83c\udf64",fitzpatrick_scale:!1,category:"food_and_drink"},fried_egg:{keywords:["food","breakfast","kitchen","egg"],char:"\ud83c\udf73",fitzpatrick_scale:!1,category:"food_and_drink"},hamburger:{keywords:["meat","fast food","beef","cheeseburger","mcdonalds","burger king"],char:"\ud83c\udf54",fitzpatrick_scale:!1,category:"food_and_drink"},fries:{keywords:["chips","snack","fast food"],char:"\ud83c\udf5f",fitzpatrick_scale:!1,category:"food_and_drink"},stuffed_flatbread:{keywords:["food","flatbread","stuffed","gyro"],char:"\ud83e\udd59",fitzpatrick_scale:!1,category:"food_and_drink"},hotdog:{keywords:["food","frankfurter"],char:"\ud83c\udf2d",fitzpatrick_scale:!1,category:"food_and_drink"},pizza:{keywords:["food","party"],char:"\ud83c\udf55",fitzpatrick_scale:!1,category:"food_and_drink"},sandwich:{keywords:["food","lunch","bread"],char:"\ud83e\udd6a",fitzpatrick_scale:!1,category:"food_and_drink"},canned_food:{keywords:["food","soup"],char:"\ud83e\udd6b",fitzpatrick_scale:!1,category:"food_and_drink"},spaghetti:{keywords:["food","italian","noodle"],char:"\ud83c\udf5d",fitzpatrick_scale:!1,category:"food_and_drink"},taco:{keywords:["food","mexican"],char:"\ud83c\udf2e",fitzpatrick_scale:!1,category:"food_and_drink"},burrito:{keywords:["food","mexican"],char:"\ud83c\udf2f",fitzpatrick_scale:!1,category:"food_and_drink"},green_salad:{keywords:["food","healthy","lettuce"],char:"\ud83e\udd57",fitzpatrick_scale:!1,category:"food_and_drink"},shallow_pan_of_food:{keywords:["food","cooking","casserole","paella"],char:"\ud83e\udd58",fitzpatrick_scale:!1,category:"food_and_drink"},ramen:{keywords:["food","japanese","noodle","chopsticks"],char:"\ud83c\udf5c",fitzpatrick_scale:!1,category:"food_and_drink"},stew:{keywords:["food","meat","soup"],char:"\ud83c\udf72",fitzpatrick_scale:!1,category:"food_and_drink"},fish_cake:{keywords:["food","japan","sea","beach","narutomaki","pink","swirl","kamaboko","surimi","ramen"],char:"\ud83c\udf65",fitzpatrick_scale:!1,category:"food_and_drink"},fortune_cookie:{keywords:["food","prophecy"],char:"\ud83e\udd60",fitzpatrick_scale:!1,category:"food_and_drink"},sushi:{keywords:["food","fish","japanese","rice"],char:"\ud83c\udf63",fitzpatrick_scale:!1,category:"food_and_drink"},bento:{keywords:["food","japanese","box"],char:"\ud83c\udf71",fitzpatrick_scale:!1,category:"food_and_drink"},curry:{keywords:["food","spicy","hot","indian"],char:"\ud83c\udf5b",fitzpatrick_scale:!1,category:"food_and_drink"},rice_ball:{keywords:["food","japanese"],char:"\ud83c\udf59",fitzpatrick_scale:!1,category:"food_and_drink"},rice:{keywords:["food","china","asian"],char:"\ud83c\udf5a",fitzpatrick_scale:!1,category:"food_and_drink"},rice_cracker:{keywords:["food","japanese"],char:"\ud83c\udf58",fitzpatrick_scale:!1,category:"food_and_drink"},oden:{keywords:["food","japanese"],char:"\ud83c\udf62",fitzpatrick_scale:!1,category:"food_and_drink"},dango:{keywords:["food","dessert","sweet","japanese","barbecue","meat"],char:"\ud83c\udf61",fitzpatrick_scale:!1,category:"food_and_drink"},shaved_ice:{keywords:["hot","dessert","summer"],char:"\ud83c\udf67",fitzpatrick_scale:!1,category:"food_and_drink"},ice_cream:{keywords:["food","hot","dessert"],char:"\ud83c\udf68",fitzpatrick_scale:!1,category:"food_and_drink"},icecream:{keywords:["food","hot","dessert","summer"],char:"\ud83c\udf66",fitzpatrick_scale:!1,category:"food_and_drink"},pie:{keywords:["food","dessert","pastry"],char:"\ud83e\udd67",fitzpatrick_scale:!1,category:"food_and_drink"},cake:{keywords:["food","dessert"],char:"\ud83c\udf70",fitzpatrick_scale:!1,category:"food_and_drink"},cupcake:{keywords:["food","dessert","bakery","sweet"],char:"\ud83e\uddc1",fitzpatrick_scale:!1,category:"food_and_drink"},moon_cake:{keywords:["food","autumn"],char:"\ud83e\udd6e",fitzpatrick_scale:!1,category:"food_and_drink"},birthday:{keywords:["food","dessert","cake"],char:"\ud83c\udf82",fitzpatrick_scale:!1,category:"food_and_drink"},custard:{keywords:["dessert","food"],char:"\ud83c\udf6e",fitzpatrick_scale:!1,category:"food_and_drink"},candy:{keywords:["snack","dessert","sweet","lolly"],char:"\ud83c\udf6c",fitzpatrick_scale:!1,category:"food_and_drink"},lollipop:{keywords:["food","snack","candy","sweet"],char:"\ud83c\udf6d",fitzpatrick_scale:!1,category:"food_and_drink"},chocolate_bar:{keywords:["food","snack","dessert","sweet"],char:"\ud83c\udf6b",fitzpatrick_scale:!1,category:"food_and_drink"},popcorn:{keywords:["food","movie theater","films","snack"],char:"\ud83c\udf7f",fitzpatrick_scale:!1,category:"food_and_drink"},dumpling:{keywords:["food","empanada","pierogi","potsticker"],char:"\ud83e\udd5f",fitzpatrick_scale:!1,category:"food_and_drink"},doughnut:{keywords:["food","dessert","snack","sweet","donut"],char:"\ud83c\udf69",fitzpatrick_scale:!1,category:"food_and_drink"},cookie:{keywords:["food","snack","oreo","chocolate","sweet","dessert"],char:"\ud83c\udf6a",fitzpatrick_scale:!1,category:"food_and_drink"},milk_glass:{keywords:["beverage","drink","cow"],char:"\ud83e\udd5b",fitzpatrick_scale:!1,category:"food_and_drink"},beer:{keywords:["relax","beverage","drink","drunk","party","pub","summer","alcohol","booze"],char:"\ud83c\udf7a",fitzpatrick_scale:!1,category:"food_and_drink"},beers:{keywords:["relax","beverage","drink","drunk","party","pub","summer","alcohol","booze"],char:"\ud83c\udf7b",fitzpatrick_scale:!1,category:"food_and_drink"},clinking_glasses:{keywords:["beverage","drink","party","alcohol","celebrate","cheers","wine","champagne","toast"],char:"\ud83e\udd42",fitzpatrick_scale:!1,category:"food_and_drink"},wine_glass:{keywords:["drink","beverage","drunk","alcohol","booze"],char:"\ud83c\udf77",fitzpatrick_scale:!1,category:"food_and_drink"},tumbler_glass:{keywords:["drink","beverage","drunk","alcohol","liquor","booze","bourbon","scotch","whisky","glass","shot"],char:"\ud83e\udd43",fitzpatrick_scale:!1,category:"food_and_drink"},cocktail:{keywords:["drink","drunk","alcohol","beverage","booze","mojito"],char:"\ud83c\udf78",fitzpatrick_scale:!1,category:"food_and_drink"},tropical_drink:{keywords:["beverage","cocktail","summer","beach","alcohol","booze","mojito"],char:"\ud83c\udf79",fitzpatrick_scale:!1,category:"food_and_drink"},champagne:{keywords:["drink","wine","bottle","celebration"],char:"\ud83c\udf7e",fitzpatrick_scale:!1,category:"food_and_drink"},sake:{keywords:["wine","drink","drunk","beverage","japanese","alcohol","booze"],char:"\ud83c\udf76",fitzpatrick_scale:!1,category:"food_and_drink"},tea:{keywords:["drink","bowl","breakfast","green","british"],char:"\ud83c\udf75",fitzpatrick_scale:!1,category:"food_and_drink"},cup_with_straw:{keywords:["drink","soda"],char:"\ud83e\udd64",fitzpatrick_scale:!1,category:"food_and_drink"},coffee:{keywords:["beverage","caffeine","latte","espresso"],char:"\u2615",fitzpatrick_scale:!1,category:"food_and_drink"},baby_bottle:{keywords:["food","container","milk"],char:"\ud83c\udf7c",fitzpatrick_scale:!1,category:"food_and_drink"},salt:{keywords:["condiment","shaker"],char:"\ud83e\uddc2",fitzpatrick_scale:!1,category:"food_and_drink"},spoon:{keywords:["cutlery","kitchen","tableware"],char:"\ud83e\udd44",fitzpatrick_scale:!1,category:"food_and_drink"},fork_and_knife:{keywords:["cutlery","kitchen"],char:"\ud83c\udf74",fitzpatrick_scale:!1,category:"food_and_drink"},plate_with_cutlery:{keywords:["food","eat","meal","lunch","dinner","restaurant"],char:"\ud83c\udf7d",fitzpatrick_scale:!1,category:"food_and_drink"},bowl_with_spoon:{keywords:["food","breakfast","cereal","oatmeal","porridge"],char:"\ud83e\udd63",fitzpatrick_scale:!1,category:"food_and_drink"},takeout_box:{keywords:["food","leftovers"],char:"\ud83e\udd61",fitzpatrick_scale:!1,category:"food_and_drink"},chopsticks:{keywords:["food"],char:"\ud83e\udd62",fitzpatrick_scale:!1,category:"food_and_drink"},soccer:{keywords:["sports","football"],char:"\u26bd",fitzpatrick_scale:!1,category:"activity"},basketball:{keywords:["sports","balls","NBA"],char:"\ud83c\udfc0",fitzpatrick_scale:!1,category:"activity"},football:{keywords:["sports","balls","NFL"],char:"\ud83c\udfc8",fitzpatrick_scale:!1,category:"activity"},baseball:{keywords:["sports","balls"],char:"\u26be",fitzpatrick_scale:!1,category:"activity"},softball:{keywords:["sports","balls"],char:"\ud83e\udd4e",fitzpatrick_scale:!1,category:"activity"},tennis:{keywords:["sports","balls","green"],char:"\ud83c\udfbe",fitzpatrick_scale:!1,category:"activity"},volleyball:{keywords:["sports","balls"],char:"\ud83c\udfd0",fitzpatrick_scale:!1,category:"activity"},rugby_football:{keywords:["sports","team"],char:"\ud83c\udfc9",fitzpatrick_scale:!1,category:"activity"},flying_disc:{keywords:["sports","frisbee","ultimate"],char:"\ud83e\udd4f",fitzpatrick_scale:!1,category:"activity"},"8ball":{keywords:["pool","hobby","game","luck","magic"],char:"\ud83c\udfb1",fitzpatrick_scale:!1,category:"activity"},golf:{keywords:["sports","business","flag","hole","summer"],char:"\u26f3",fitzpatrick_scale:!1,category:"activity"},golfing_woman:{keywords:["sports","business","woman","female"],char:"\ud83c\udfcc\ufe0f\u200d\u2640\ufe0f",fitzpatrick_scale:!1,category:"activity"},golfing_man:{keywords:["sports","business"],char:"\ud83c\udfcc",fitzpatrick_scale:!0,category:"activity"},ping_pong:{keywords:["sports","pingpong"],char:"\ud83c\udfd3",fitzpatrick_scale:!1,category:"activity"},badminton:{keywords:["sports"],char:"\ud83c\udff8",fitzpatrick_scale:!1,category:"activity"},goal_net:{keywords:["sports"],char:"\ud83e\udd45",fitzpatrick_scale:!1,category:"activity"},ice_hockey:{keywords:["sports"],char:"\ud83c\udfd2",fitzpatrick_scale:!1,category:"activity"},field_hockey:{keywords:["sports"],char:"\ud83c\udfd1",fitzpatrick_scale:!1,category:"activity"},lacrosse:{keywords:["sports","ball","stick"],char:"\ud83e\udd4d",fitzpatrick_scale:!1,category:"activity"},cricket:{keywords:["sports"],char:"\ud83c\udfcf",fitzpatrick_scale:!1,category:"activity"},ski:{keywords:["sports","winter","cold","snow"],char:"\ud83c\udfbf",fitzpatrick_scale:!1,category:"activity"},skier:{keywords:["sports","winter","snow"],char:"\u26f7",fitzpatrick_scale:!1,category:"activity"},snowboarder:{keywords:["sports","winter"],char:"\ud83c\udfc2",fitzpatrick_scale:!0,category:"activity"},person_fencing:{keywords:["sports","fencing","sword"],char:"\ud83e\udd3a",fitzpatrick_scale:!1,category:"activity"},women_wrestling:{keywords:["sports","wrestlers"],char:"\ud83e\udd3c\u200d\u2640\ufe0f",fitzpatrick_scale:!1,category:"activity"},men_wrestling:{keywords:["sports","wrestlers"],char:"\ud83e\udd3c\u200d\u2642\ufe0f",fitzpatrick_scale:!1,category:"activity"},woman_cartwheeling:{keywords:["gymnastics"],char:"\ud83e\udd38\u200d\u2640\ufe0f",fitzpatrick_scale:!0,category:"activity"},man_cartwheeling:{keywords:["gymnastics"],char:"\ud83e\udd38\u200d\u2642\ufe0f",fitzpatrick_scale:!0,category:"activity"},woman_playing_handball:{keywords:["sports"],char:"\ud83e\udd3e\u200d\u2640\ufe0f",fitzpatrick_scale:!0,category:"activity"},man_playing_handball:{keywords:["sports"],char:"\ud83e\udd3e\u200d\u2642\ufe0f",fitzpatrick_scale:!0,category:"activity"},ice_skate:{keywords:["sports"],char:"\u26f8",fitzpatrick_scale:!1,category:"activity"},curling_stone:{keywords:["sports"],char:"\ud83e\udd4c",fitzpatrick_scale:!1,category:"activity"},skateboard:{keywords:["board"],char:"\ud83d\udef9",fitzpatrick_scale:!1,category:"activity"},sled:{keywords:["sleigh","luge","toboggan"],char:"\ud83d\udef7",fitzpatrick_scale:!1,category:"activity"},bow_and_arrow:{keywords:["sports"],char:"\ud83c\udff9",fitzpatrick_scale:!1,category:"activity"},fishing_pole_and_fish:{keywords:["food","hobby","summer"],char:"\ud83c\udfa3",fitzpatrick_scale:!1,category:"activity"},boxing_glove:{keywords:["sports","fighting"],char:"\ud83e\udd4a",fitzpatrick_scale:!1,category:"activity"},martial_arts_uniform:{keywords:["judo","karate","taekwondo"],char:"\ud83e\udd4b",fitzpatrick_scale:!1,category:"activity"},rowing_woman:{keywords:["sports","hobby","water","ship","woman","female"],char:"\ud83d\udea3\u200d\u2640\ufe0f",fitzpatrick_scale:!0,category:"activity"},rowing_man:{keywords:["sports","hobby","water","ship"],char:"\ud83d\udea3",fitzpatrick_scale:!0,category:"activity"},climbing_woman:{keywords:["sports","hobby","woman","female","rock"],char:"\ud83e\uddd7\u200d\u2640\ufe0f",fitzpatrick_scale:!0,category:"activity"},climbing_man:{keywords:["sports","hobby","man","male","rock"],char:"\ud83e\uddd7\u200d\u2642\ufe0f",fitzpatrick_scale:!0,category:"activity"},swimming_woman:{keywords:["sports","exercise","human","athlete","water","summer","woman","female"],char:"\ud83c\udfca\u200d\u2640\ufe0f",fitzpatrick_scale:!0,category:"activity"},swimming_man:{keywords:["sports","exercise","human","athlete","water","summer"],char:"\ud83c\udfca",fitzpatrick_scale:!0,category:"activity"},woman_playing_water_polo:{keywords:["sports","pool"],char:"\ud83e\udd3d\u200d\u2640\ufe0f",fitzpatrick_scale:!0,category:"activity"},man_playing_water_polo:{keywords:["sports","pool"],char:"\ud83e\udd3d\u200d\u2642\ufe0f",fitzpatrick_scale:!0,category:"activity"},woman_in_lotus_position:{keywords:["woman","female","meditation","yoga","serenity","zen","mindfulness"],char:"\ud83e\uddd8\u200d\u2640\ufe0f",fitzpatrick_scale:!0,category:"activity"},man_in_lotus_position:{keywords:["man","male","meditation","yoga","serenity","zen","mindfulness"],char:"\ud83e\uddd8\u200d\u2642\ufe0f",fitzpatrick_scale:!0,category:"activity"},surfing_woman:{keywords:["sports","ocean","sea","summer","beach","woman","female"],char:"\ud83c\udfc4\u200d\u2640\ufe0f",fitzpatrick_scale:!0,category:"activity"},surfing_man:{keywords:["sports","ocean","sea","summer","beach"],char:"\ud83c\udfc4",fitzpatrick_scale:!0,category:"activity"},bath:{keywords:["clean","shower","bathroom"],char:"\ud83d\udec0",fitzpatrick_scale:!0,category:"activity"},basketball_woman:{keywords:["sports","human","woman","female"],char:"\u26f9\ufe0f\u200d\u2640\ufe0f",fitzpatrick_scale:!0,category:"activity"},basketball_man:{keywords:["sports","human"],char:"\u26f9",fitzpatrick_scale:!0,category:"activity"},weight_lifting_woman:{keywords:["sports","training","exercise","woman","female"],char:"\ud83c\udfcb\ufe0f\u200d\u2640\ufe0f",fitzpatrick_scale:!0,category:"activity"},weight_lifting_man:{keywords:["sports","training","exercise"],char:"\ud83c\udfcb",fitzpatrick_scale:!0,category:"activity"},biking_woman:{keywords:["sports","bike","exercise","hipster","woman","female"],char:"\ud83d\udeb4\u200d\u2640\ufe0f",fitzpatrick_scale:!0,category:"activity"},biking_man:{keywords:["sports","bike","exercise","hipster"],char:"\ud83d\udeb4",fitzpatrick_scale:!0,category:"activity"},mountain_biking_woman:{keywords:["transportation","sports","human","race","bike","woman","female"],char:"\ud83d\udeb5\u200d\u2640\ufe0f",fitzpatrick_scale:!0,category:"activity"},mountain_biking_man:{keywords:["transportation","sports","human","race","bike"],char:"\ud83d\udeb5",fitzpatrick_scale:!0,category:"activity"},horse_racing:{keywords:["animal","betting","competition","gambling","luck"],char:"\ud83c\udfc7",fitzpatrick_scale:!0,category:"activity"},business_suit_levitating:{keywords:["suit","business","levitate","hover","jump"],char:"\ud83d\udd74",fitzpatrick_scale:!0,category:"activity"},trophy:{keywords:["win","award","contest","place","ftw","ceremony"],char:"\ud83c\udfc6",fitzpatrick_scale:!1,category:"activity"},running_shirt_with_sash:{keywords:["play","pageant"],char:"\ud83c\udfbd",fitzpatrick_scale:!1,category:"activity"},medal_sports:{keywords:["award","winning"],char:"\ud83c\udfc5",fitzpatrick_scale:!1,category:"activity"},medal_military:{keywords:["award","winning","army"],char:"\ud83c\udf96",fitzpatrick_scale:!1,category:"activity"},"1st_place_medal":{keywords:["award","winning","first"],char:"\ud83e\udd47",fitzpatrick_scale:!1,category:"activity"},"2nd_place_medal":{keywords:["award","second"],char:"\ud83e\udd48",fitzpatrick_scale:!1,category:"activity"},"3rd_place_medal":{keywords:["award","third"],char:"\ud83e\udd49",fitzpatrick_scale:!1,category:"activity"},reminder_ribbon:{keywords:["sports","cause","support","awareness"],char:"\ud83c\udf97",fitzpatrick_scale:!1,category:"activity"},rosette:{keywords:["flower","decoration","military"],char:"\ud83c\udff5",fitzpatrick_scale:!1,category:"activity"},ticket:{keywords:["event","concert","pass"],char:"\ud83c\udfab",fitzpatrick_scale:!1,category:"activity"},tickets:{keywords:["sports","concert","entrance"],char:"\ud83c\udf9f",fitzpatrick_scale:!1,category:"activity"},performing_arts:{keywords:["acting","theater","drama"],char:"\ud83c\udfad",fitzpatrick_scale:!1,category:"activity"},art:{keywords:["design","paint","draw","colors"],char:"\ud83c\udfa8",fitzpatrick_scale:!1,category:"activity"},circus_tent:{keywords:["festival","carnival","party"],char:"\ud83c\udfaa",fitzpatrick_scale:!1,category:"activity"},woman_juggling:{keywords:["juggle","balance","skill","multitask"],char:"\ud83e\udd39\u200d\u2640\ufe0f",fitzpatrick_scale:!0,category:"activity"},man_juggling:{keywords:["juggle","balance","skill","multitask"],char:"\ud83e\udd39\u200d\u2642\ufe0f",fitzpatrick_scale:!0,category:"activity"},microphone:{keywords:["sound","music","PA","sing","talkshow"],char:"\ud83c\udfa4",fitzpatrick_scale:!1,category:"activity"},headphones:{keywords:["music","score","gadgets"],char:"\ud83c\udfa7",fitzpatrick_scale:!1,category:"activity"},musical_score:{keywords:["treble","clef","compose"],char:"\ud83c\udfbc",fitzpatrick_scale:!1,category:"activity"},musical_keyboard:{keywords:["piano","instrument","compose"],char:"\ud83c\udfb9",fitzpatrick_scale:!1,category:"activity"},drum:{keywords:["music","instrument","drumsticks","snare"],char:"\ud83e\udd41",fitzpatrick_scale:!1,category:"activity"},saxophone:{keywords:["music","instrument","jazz","blues"],char:"\ud83c\udfb7",fitzpatrick_scale:!1,category:"activity"},trumpet:{keywords:["music","brass"],char:"\ud83c\udfba",fitzpatrick_scale:!1,category:"activity"},guitar:{keywords:["music","instrument"],char:"\ud83c\udfb8",fitzpatrick_scale:!1,category:"activity"},violin:{keywords:["music","instrument","orchestra","symphony"],char:"\ud83c\udfbb",fitzpatrick_scale:!1,category:"activity"},clapper:{keywords:["movie","film","record"],char:"\ud83c\udfac",fitzpatrick_scale:!1,category:"activity"},video_game:{keywords:["play","console","PS4","controller"],char:"\ud83c\udfae",fitzpatrick_scale:!1,category:"activity"},space_invader:{keywords:["game","arcade","play"],char:"\ud83d\udc7e",fitzpatrick_scale:!1,category:"activity"},dart:{keywords:["game","play","bar","target","bullseye"],char:"\ud83c\udfaf",fitzpatrick_scale:!1,category:"activity"},game_die:{keywords:["dice","random","tabletop","play","luck"],char:"\ud83c\udfb2",fitzpatrick_scale:!1,category:"activity"},chess_pawn:{keywords:["expendable"],char:"\u265f",fitzpatrick_scale:!1,category:"activity"},slot_machine:{keywords:["bet","gamble","vegas","fruit machine","luck","casino"],char:"\ud83c\udfb0",fitzpatrick_scale:!1,category:"activity"},jigsaw:{keywords:["interlocking","puzzle","piece"],char:"\ud83e\udde9",fitzpatrick_scale:!1,category:"activity"},bowling:{keywords:["sports","fun","play"],char:"\ud83c\udfb3",fitzpatrick_scale:!1,category:"activity"},red_car:{keywords:["red","transportation","vehicle"],char:"\ud83d\ude97",fitzpatrick_scale:!1,category:"travel_and_places"},taxi:{keywords:["uber","vehicle","cars","transportation"],char:"\ud83d\ude95",fitzpatrick_scale:!1,category:"travel_and_places"},blue_car:{keywords:["transportation","vehicle"],char:"\ud83d\ude99",fitzpatrick_scale:!1,category:"travel_and_places"},bus:{keywords:["car","vehicle","transportation"],char:"\ud83d\ude8c",fitzpatrick_scale:!1,category:"travel_and_places"},trolleybus:{keywords:["bart","transportation","vehicle"],char:"\ud83d\ude8e",fitzpatrick_scale:!1,category:"travel_and_places"},racing_car:{keywords:["sports","race","fast","formula","f1"],char:"\ud83c\udfce",fitzpatrick_scale:!1,category:"travel_and_places"},police_car:{keywords:["vehicle","cars","transportation","law","legal","enforcement"],char:"\ud83d\ude93",fitzpatrick_scale:!1,category:"travel_and_places"},ambulance:{keywords:["health","911","hospital"],char:"\ud83d\ude91",fitzpatrick_scale:!1,category:"travel_and_places"},fire_engine:{keywords:["transportation","cars","vehicle"],char:"\ud83d\ude92",fitzpatrick_scale:!1,category:"travel_and_places"},minibus:{keywords:["vehicle","car","transportation"],char:"\ud83d\ude90",fitzpatrick_scale:!1,category:"travel_and_places"},truck:{keywords:["cars","transportation"],char:"\ud83d\ude9a",fitzpatrick_scale:!1,category:"travel_and_places"},articulated_lorry:{keywords:["vehicle","cars","transportation","express"],char:"\ud83d\ude9b",fitzpatrick_scale:!1,category:"travel_and_places"},tractor:{keywords:["vehicle","car","farming","agriculture"],char:"\ud83d\ude9c",fitzpatrick_scale:!1,category:"travel_and_places"},kick_scooter:{keywords:["vehicle","kick","razor"],char:"\ud83d\udef4",fitzpatrick_scale:!1,category:"travel_and_places"},motorcycle:{keywords:["race","sports","fast"],char:"\ud83c\udfcd",fitzpatrick_scale:!1,category:"travel_and_places"},bike:{keywords:["sports","bicycle","exercise","hipster"],char:"\ud83d\udeb2",fitzpatrick_scale:!1,category:"travel_and_places"},motor_scooter:{keywords:["vehicle","vespa","sasha"],char:"\ud83d\udef5",fitzpatrick_scale:!1,category:"travel_and_places"},rotating_light:{keywords:["police","ambulance","911","emergency","alert","error","pinged","law","legal"],char:"\ud83d\udea8",fitzpatrick_scale:!1,category:"travel_and_places"},oncoming_police_car:{keywords:["vehicle","law","legal","enforcement","911"],char:"\ud83d\ude94",fitzpatrick_scale:!1,category:"travel_and_places"},oncoming_bus:{keywords:["vehicle","transportation"],char:"\ud83d\ude8d",fitzpatrick_scale:!1,category:"travel_and_places"},oncoming_automobile:{keywords:["car","vehicle","transportation"],char:"\ud83d\ude98",fitzpatrick_scale:!1,category:"travel_and_places"},oncoming_taxi:{keywords:["vehicle","cars","uber"],char:"\ud83d\ude96",fitzpatrick_scale:!1,category:"travel_and_places"},aerial_tramway:{keywords:["transportation","vehicle","ski"],char:"\ud83d\udea1",fitzpatrick_scale:!1,category:"travel_and_places"},mountain_cableway:{keywords:["transportation","vehicle","ski"],char:"\ud83d\udea0",fitzpatrick_scale:!1,category:"travel_and_places"},suspension_railway:{keywords:["vehicle","transportation"],char:"\ud83d\ude9f",fitzpatrick_scale:!1,category:"travel_and_places"},railway_car:{keywords:["transportation","vehicle"],char:"\ud83d\ude83",fitzpatrick_scale:!1,category:"travel_and_places"},train:{keywords:["transportation","vehicle","carriage","public","travel"],char:"\ud83d\ude8b",fitzpatrick_scale:!1,category:"travel_and_places"},monorail:{keywords:["transportation","vehicle"],char:"\ud83d\ude9d",fitzpatrick_scale:!1,category:"travel_and_places"},bullettrain_side:{keywords:["transportation","vehicle"],char:"\ud83d\ude84",fitzpatrick_scale:!1,category:"travel_and_places"},bullettrain_front:{keywords:["transportation","vehicle","speed","fast","public","travel"],char:"\ud83d\ude85",fitzpatrick_scale:!1,category:"travel_and_places"},light_rail:{keywords:["transportation","vehicle"],char:"\ud83d\ude88",fitzpatrick_scale:!1,category:"travel_and_places"},mountain_railway:{keywords:["transportation","vehicle"],char:"\ud83d\ude9e",fitzpatrick_scale:!1,category:"travel_and_places"},steam_locomotive:{keywords:["transportation","vehicle","train"],char:"\ud83d\ude82",fitzpatrick_scale:!1,category:"travel_and_places"},train2:{keywords:["transportation","vehicle"],char:"\ud83d\ude86",fitzpatrick_scale:!1,category:"travel_and_places"},metro:{keywords:["transportation","blue-square","mrt","underground","tube"],char:"\ud83d\ude87",fitzpatrick_scale:!1,category:"travel_and_places"},tram:{keywords:["transportation","vehicle"],char:"\ud83d\ude8a",fitzpatrick_scale:!1,category:"travel_and_places"},station:{keywords:["transportation","vehicle","public"],char:"\ud83d\ude89",fitzpatrick_scale:!1,category:"travel_and_places"},flying_saucer:{keywords:["transportation","vehicle","ufo"],char:"\ud83d\udef8",fitzpatrick_scale:!1,category:"travel_and_places"},helicopter:{keywords:["transportation","vehicle","fly"],char:"\ud83d\ude81",fitzpatrick_scale:!1,category:"travel_and_places"},small_airplane:{keywords:["flight","transportation","fly","vehicle"],char:"\ud83d\udee9",fitzpatrick_scale:!1,category:"travel_and_places"},airplane:{keywords:["vehicle","transportation","flight","fly"],char:"\u2708\ufe0f",fitzpatrick_scale:!1,category:"travel_and_places"},flight_departure:{keywords:["airport","flight","landing"],char:"\ud83d\udeeb",fitzpatrick_scale:!1,category:"travel_and_places"},flight_arrival:{keywords:["airport","flight","boarding"],char:"\ud83d\udeec",fitzpatrick_scale:!1,category:"travel_and_places"},sailboat:{keywords:["ship","summer","transportation","water","sailing"],char:"\u26f5",fitzpatrick_scale:!1,category:"travel_and_places"},motor_boat:{keywords:["ship"],char:"\ud83d\udee5",fitzpatrick_scale:!1,category:"travel_and_places"},speedboat:{keywords:["ship","transportation","vehicle","summer"],char:"\ud83d\udea4",fitzpatrick_scale:!1,category:"travel_and_places"},ferry:{keywords:["boat","ship","yacht"],char:"\u26f4",fitzpatrick_scale:!1,category:"travel_and_places"},passenger_ship:{keywords:["yacht","cruise","ferry"],char:"\ud83d\udef3",fitzpatrick_scale:!1,category:"travel_and_places"},rocket:{keywords:["launch","ship","staffmode","NASA","outer space","outer_space","fly"],char:"\ud83d\ude80",fitzpatrick_scale:!1,category:"travel_and_places"},artificial_satellite:{keywords:["communication","gps","orbit","spaceflight","NASA","ISS"],char:"\ud83d\udef0",fitzpatrick_scale:!1,category:"travel_and_places"},seat:{keywords:["sit","airplane","transport","bus","flight","fly"],char:"\ud83d\udcba",fitzpatrick_scale:!1,category:"travel_and_places"},canoe:{keywords:["boat","paddle","water","ship"],char:"\ud83d\udef6",fitzpatrick_scale:!1,category:"travel_and_places"},anchor:{keywords:["ship","ferry","sea","boat"],char:"\u2693",fitzpatrick_scale:!1,category:"travel_and_places"},construction:{keywords:["wip","progress","caution","warning"],char:"\ud83d\udea7",fitzpatrick_scale:!1,category:"travel_and_places"},fuelpump:{keywords:["gas station","petroleum"],char:"\u26fd",fitzpatrick_scale:!1,category:"travel_and_places"},busstop:{keywords:["transportation","wait"],char:"\ud83d\ude8f",fitzpatrick_scale:!1,category:"travel_and_places"},vertical_traffic_light:{keywords:["transportation","driving"],char:"\ud83d\udea6",fitzpatrick_scale:!1,category:"travel_and_places"},traffic_light:{keywords:["transportation","signal"],char:"\ud83d\udea5",fitzpatrick_scale:!1,category:"travel_and_places"},checkered_flag:{keywords:["contest","finishline","race","gokart"],char:"\ud83c\udfc1",fitzpatrick_scale:!1,category:"travel_and_places"},ship:{keywords:["transportation","titanic","deploy"],char:"\ud83d\udea2",fitzpatrick_scale:!1,category:"travel_and_places"},ferris_wheel:{keywords:["photo","carnival","londoneye"],char:"\ud83c\udfa1",fitzpatrick_scale:!1,category:"travel_and_places"},roller_coaster:{keywords:["carnival","playground","photo","fun"],char:"\ud83c\udfa2",fitzpatrick_scale:!1,category:"travel_and_places"},carousel_horse:{keywords:["photo","carnival"],char:"\ud83c\udfa0",fitzpatrick_scale:!1,category:"travel_and_places"},building_construction:{keywords:["wip","working","progress"],char:"\ud83c\udfd7",fitzpatrick_scale:!1,category:"travel_and_places"},foggy:{keywords:["photo","mountain"],char:"\ud83c\udf01",fitzpatrick_scale:!1,category:"travel_and_places"},tokyo_tower:{keywords:["photo","japanese"],char:"\ud83d\uddfc",fitzpatrick_scale:!1,category:"travel_and_places"},factory:{keywords:["building","industry","pollution","smoke"],char:"\ud83c\udfed",fitzpatrick_scale:!1,category:"travel_and_places"},fountain:{keywords:["photo","summer","water","fresh"],char:"\u26f2",fitzpatrick_scale:!1,category:"travel_and_places"},rice_scene:{keywords:["photo","japan","asia","tsukimi"],char:"\ud83c\udf91",fitzpatrick_scale:!1,category:"travel_and_places"},mountain:{keywords:["photo","nature","environment"],char:"\u26f0",fitzpatrick_scale:!1,category:"travel_and_places"},mountain_snow:{keywords:["photo","nature","environment","winter","cold"],char:"\ud83c\udfd4",fitzpatrick_scale:!1,category:"travel_and_places"},mount_fuji:{keywords:["photo","mountain","nature","japanese"],char:"\ud83d\uddfb",fitzpatrick_scale:!1,category:"travel_and_places"},volcano:{keywords:["photo","nature","disaster"],char:"\ud83c\udf0b",fitzpatrick_scale:!1,category:"travel_and_places"},japan:{keywords:["nation","country","japanese","asia"],char:"\ud83d\uddfe",fitzpatrick_scale:!1,category:"travel_and_places"},camping:{keywords:["photo","outdoors","tent"],char:"\ud83c\udfd5",fitzpatrick_scale:!1,category:"travel_and_places"},tent:{keywords:["photo","camping","outdoors"],char:"\u26fa",fitzpatrick_scale:!1,category:"travel_and_places"},national_park:{keywords:["photo","environment","nature"],char:"\ud83c\udfde",fitzpatrick_scale:!1,category:"travel_and_places"},motorway:{keywords:["road","cupertino","interstate","highway"],char:"\ud83d\udee3",fitzpatrick_scale:!1,category:"travel_and_places"},railway_track:{keywords:["train","transportation"],char:"\ud83d\udee4",fitzpatrick_scale:!1,category:"travel_and_places"},sunrise:{keywords:["morning","view","vacation","photo"],char:"\ud83c\udf05",fitzpatrick_scale:!1,category:"travel_and_places"},sunrise_over_mountains:{keywords:["view","vacation","photo"],char:"\ud83c\udf04",fitzpatrick_scale:!1,category:"travel_and_places"},desert:{keywords:["photo","warm","saharah"],char:"\ud83c\udfdc",fitzpatrick_scale:!1,category:"travel_and_places"},beach_umbrella:{keywords:["weather","summer","sunny","sand","mojito"],char:"\ud83c\udfd6",fitzpatrick_scale:!1,category:"travel_and_places"},desert_island:{keywords:["photo","tropical","mojito"],char:"\ud83c\udfdd",fitzpatrick_scale:!1,category:"travel_and_places"},city_sunrise:{keywords:["photo","good morning","dawn"],char:"\ud83c\udf07",fitzpatrick_scale:!1,category:"travel_and_places"},city_sunset:{keywords:["photo","evening","sky","buildings"],char:"\ud83c\udf06",fitzpatrick_scale:!1,category:"travel_and_places"},cityscape:{keywords:["photo","night life","urban"],char:"\ud83c\udfd9",fitzpatrick_scale:!1,category:"travel_and_places"},night_with_stars:{keywords:["evening","city","downtown"],char:"\ud83c\udf03",fitzpatrick_scale:!1,category:"travel_and_places"},bridge_at_night:{keywords:["photo","sanfrancisco"],char:"\ud83c\udf09",fitzpatrick_scale:!1,category:"travel_and_places"},milky_way:{keywords:["photo","space","stars"],char:"\ud83c\udf0c",fitzpatrick_scale:!1,category:"travel_and_places"},stars:{keywords:["night","photo"],char:"\ud83c\udf20",fitzpatrick_scale:!1,category:"travel_and_places"},sparkler:{keywords:["stars","night","shine"],char:"\ud83c\udf87",fitzpatrick_scale:!1,category:"travel_and_places"},fireworks:{keywords:["photo","festival","carnival","congratulations"],char:"\ud83c\udf86",fitzpatrick_scale:!1,category:"travel_and_places"},rainbow:{keywords:["nature","happy","unicorn_face","photo","sky","spring"],char:"\ud83c\udf08",fitzpatrick_scale:!1,category:"travel_and_places"},houses:{keywords:["buildings","photo"],char:"\ud83c\udfd8",fitzpatrick_scale:!1,category:"travel_and_places"},european_castle:{keywords:["building","royalty","history"],char:"\ud83c\udff0",fitzpatrick_scale:!1,category:"travel_and_places"},japanese_castle:{keywords:["photo","building"],char:"\ud83c\udfef",fitzpatrick_scale:!1,category:"travel_and_places"},stadium:{keywords:["photo","place","sports","concert","venue"],char:"\ud83c\udfdf",fitzpatrick_scale:!1,category:"travel_and_places"},statue_of_liberty:{keywords:["american","newyork"],char:"\ud83d\uddfd",fitzpatrick_scale:!1,category:"travel_and_places"},house:{keywords:["building","home"],char:"\ud83c\udfe0",fitzpatrick_scale:!1,category:"travel_and_places"},house_with_garden:{keywords:["home","plant","nature"],char:"\ud83c\udfe1",fitzpatrick_scale:!1,category:"travel_and_places"},derelict_house:{keywords:["abandon","evict","broken","building"],char:"\ud83c\udfda",fitzpatrick_scale:!1,category:"travel_and_places"},office:{keywords:["building","bureau","work"],char:"\ud83c\udfe2",fitzpatrick_scale:!1,category:"travel_and_places"},department_store:{keywords:["building","shopping","mall"],char:"\ud83c\udfec",fitzpatrick_scale:!1,category:"travel_and_places"},post_office:{keywords:["building","envelope","communication"],char:"\ud83c\udfe3",fitzpatrick_scale:!1,category:"travel_and_places"},european_post_office:{keywords:["building","email"],char:"\ud83c\udfe4",fitzpatrick_scale:!1,category:"travel_and_places"},hospital:{keywords:["building","health","surgery","doctor"],char:"\ud83c\udfe5",fitzpatrick_scale:!1,category:"travel_and_places"},bank:{keywords:["building","money","sales","cash","business","enterprise"],char:"\ud83c\udfe6",fitzpatrick_scale:!1,category:"travel_and_places"},hotel:{keywords:["building","accomodation","checkin"],char:"\ud83c\udfe8",fitzpatrick_scale:!1,category:"travel_and_places"},convenience_store:{keywords:["building","shopping","groceries"],char:"\ud83c\udfea",fitzpatrick_scale:!1,category:"travel_and_places"},school:{keywords:["building","student","education","learn","teach"],char:"\ud83c\udfeb",fitzpatrick_scale:!1,category:"travel_and_places"},love_hotel:{keywords:["like","affection","dating"],char:"\ud83c\udfe9",fitzpatrick_scale:!1,category:"travel_and_places"},wedding:{keywords:["love","like","affection","couple","marriage","bride","groom"],char:"\ud83d\udc92",fitzpatrick_scale:!1,category:"travel_and_places"},classical_building:{keywords:["art","culture","history"],char:"\ud83c\udfdb",fitzpatrick_scale:!1,category:"travel_and_places"},church:{keywords:["building","religion","christ"],char:"\u26ea",fitzpatrick_scale:!1,category:"travel_and_places"},mosque:{keywords:["islam","worship","minaret"],char:"\ud83d\udd4c",fitzpatrick_scale:!1,category:"travel_and_places"},synagogue:{keywords:["judaism","worship","temple","jewish"],char:"\ud83d\udd4d",fitzpatrick_scale:!1,category:"travel_and_places"},kaaba:{keywords:["mecca","mosque","islam"],char:"\ud83d\udd4b",fitzpatrick_scale:!1,category:"travel_and_places"},shinto_shrine:{keywords:["temple","japan","kyoto"],char:"\u26e9",fitzpatrick_scale:!1,category:"travel_and_places"},watch:{keywords:["time","accessories"],char:"\u231a",fitzpatrick_scale:!1,category:"objects"},iphone:{keywords:["technology","apple","gadgets","dial"],char:"\ud83d\udcf1",fitzpatrick_scale:!1,category:"objects"},calling:{keywords:["iphone","incoming"],char:"\ud83d\udcf2",fitzpatrick_scale:!1,category:"objects"},computer:{keywords:["technology","laptop","screen","display","monitor"],char:"\ud83d\udcbb",fitzpatrick_scale:!1,category:"objects"},keyboard:{keywords:["technology","computer","type","input","text"],char:"\u2328",fitzpatrick_scale:!1,category:"objects"},desktop_computer:{keywords:["technology","computing","screen"],char:"\ud83d\udda5",fitzpatrick_scale:!1,category:"objects"},printer:{keywords:["paper","ink"],char:"\ud83d\udda8",fitzpatrick_scale:!1,category:"objects"},computer_mouse:{keywords:["click"],char:"\ud83d\uddb1",fitzpatrick_scale:!1,category:"objects"},trackball:{keywords:["technology","trackpad"],char:"\ud83d\uddb2",fitzpatrick_scale:!1,category:"objects"},joystick:{keywords:["game","play"],char:"\ud83d\udd79",fitzpatrick_scale:!1,category:"objects"},clamp:{keywords:["tool"],char:"\ud83d\udddc",fitzpatrick_scale:!1,category:"objects"},minidisc:{keywords:["technology","record","data","disk","90s"],char:"\ud83d\udcbd",fitzpatrick_scale:!1,category:"objects"},floppy_disk:{keywords:["oldschool","technology","save","90s","80s"],char:"\ud83d\udcbe",fitzpatrick_scale:!1,category:"objects"},cd:{keywords:["technology","dvd","disk","disc","90s"],char:"\ud83d\udcbf",fitzpatrick_scale:!1,category:"objects"},dvd:{keywords:["cd","disk","disc"],char:"\ud83d\udcc0",fitzpatrick_scale:!1,category:"objects"},vhs:{keywords:["record","video","oldschool","90s","80s"],char:"\ud83d\udcfc",fitzpatrick_scale:!1,category:"objects"},camera:{keywords:["gadgets","photography"],char:"\ud83d\udcf7",fitzpatrick_scale:!1,category:"objects"},camera_flash:{keywords:["photography","gadgets"],char:"\ud83d\udcf8",fitzpatrick_scale:!1,category:"objects"},video_camera:{keywords:["film","record"],char:"\ud83d\udcf9",fitzpatrick_scale:!1,category:"objects"},movie_camera:{keywords:["film","record"],char:"\ud83c\udfa5",fitzpatrick_scale:!1,category:"objects"},film_projector:{keywords:["video","tape","record","movie"],char:"\ud83d\udcfd",fitzpatrick_scale:!1,category:"objects"},film_strip:{keywords:["movie"],char:"\ud83c\udf9e",fitzpatrick_scale:!1,category:"objects"},telephone_receiver:{keywords:["technology","communication","dial"],char:"\ud83d\udcde",fitzpatrick_scale:!1,category:"objects"},phone:{keywords:["technology","communication","dial","telephone"],char:"\u260e\ufe0f",fitzpatrick_scale:!1,category:"objects"},pager:{keywords:["bbcall","oldschool","90s"],char:"\ud83d\udcdf",fitzpatrick_scale:!1,category:"objects"},fax:{keywords:["communication","technology"],char:"\ud83d\udce0",fitzpatrick_scale:!1,category:"objects"},tv:{keywords:["technology","program","oldschool","show","television"],char:"\ud83d\udcfa",fitzpatrick_scale:!1,category:"objects"},radio:{keywords:["communication","music","podcast","program"],char:"\ud83d\udcfb",fitzpatrick_scale:!1,category:"objects"},studio_microphone:{keywords:["sing","recording","artist","talkshow"],char:"\ud83c\udf99",fitzpatrick_scale:!1,category:"objects"},level_slider:{keywords:["scale"],char:"\ud83c\udf9a",fitzpatrick_scale:!1,category:"objects"},control_knobs:{keywords:["dial"],char:"\ud83c\udf9b",fitzpatrick_scale:!1,category:"objects"},compass:{keywords:["magnetic","navigation","orienteering"],char:"\ud83e\udded",fitzpatrick_scale:!1,category:"objects"},stopwatch:{keywords:["time","deadline"],char:"\u23f1",fitzpatrick_scale:!1,category:"objects"},timer_clock:{keywords:["alarm"],char:"\u23f2",fitzpatrick_scale:!1,category:"objects"},alarm_clock:{keywords:["time","wake"],char:"\u23f0",fitzpatrick_scale:!1,category:"objects"},mantelpiece_clock:{keywords:["time"],char:"\ud83d\udd70",fitzpatrick_scale:!1,category:"objects"},hourglass_flowing_sand:{keywords:["oldschool","time","countdown"],char:"\u23f3",fitzpatrick_scale:!1,category:"objects"},hourglass:{keywords:["time","clock","oldschool","limit","exam","quiz","test"],char:"\u231b",fitzpatrick_scale:!1,category:"objects"},satellite:{keywords:["communication","future","radio","space"],char:"\ud83d\udce1",fitzpatrick_scale:!1,category:"objects"},battery:{keywords:["power","energy","sustain"],char:"\ud83d\udd0b",fitzpatrick_scale:!1,category:"objects"},electric_plug:{keywords:["charger","power"],char:"\ud83d\udd0c",fitzpatrick_scale:!1,category:"objects"},bulb:{keywords:["light","electricity","idea"],char:"\ud83d\udca1",fitzpatrick_scale:!1,category:"objects"},flashlight:{keywords:["dark","camping","sight","night"],char:"\ud83d\udd26",fitzpatrick_scale:!1,category:"objects"},candle:{keywords:["fire","wax"],char:"\ud83d\udd6f",fitzpatrick_scale:!1,category:"objects"},fire_extinguisher:{keywords:["quench"],char:"\ud83e\uddef",fitzpatrick_scale:!1,category:"objects"},wastebasket:{keywords:["bin","trash","rubbish","garbage","toss"],char:"\ud83d\uddd1",fitzpatrick_scale:!1,category:"objects"},oil_drum:{keywords:["barrell"],char:"\ud83d\udee2",fitzpatrick_scale:!1,category:"objects"},money_with_wings:{keywords:["dollar","bills","payment","sale"],char:"\ud83d\udcb8",fitzpatrick_scale:!1,category:"objects"},dollar:{keywords:["money","sales","bill","currency"],char:"\ud83d\udcb5",fitzpatrick_scale:!1,category:"objects"},yen:{keywords:["money","sales","japanese","dollar","currency"],char:"\ud83d\udcb4",fitzpatrick_scale:!1,category:"objects"},euro:{keywords:["money","sales","dollar","currency"],char:"\ud83d\udcb6",fitzpatrick_scale:!1,category:"objects"},pound:{keywords:["british","sterling","money","sales","bills","uk","england","currency"],char:"\ud83d\udcb7",fitzpatrick_scale:!1,category:"objects"},moneybag:{keywords:["dollar","payment","coins","sale"],char:"\ud83d\udcb0",fitzpatrick_scale:!1,category:"objects"},credit_card:{keywords:["money","sales","dollar","bill","payment","shopping"],char:"\ud83d\udcb3",fitzpatrick_scale:!1,category:"objects"},gem:{keywords:["blue","ruby","diamond","jewelry"],char:"\ud83d\udc8e",fitzpatrick_scale:!1,category:"objects"},balance_scale:{keywords:["law","fairness","weight"],char:"\u2696",fitzpatrick_scale:!1,category:"objects"},toolbox:{keywords:["tools","diy","fix","maintainer","mechanic"],char:"\ud83e\uddf0",fitzpatrick_scale:!1,category:"objects"},wrench:{keywords:["tools","diy","ikea","fix","maintainer"],char:"\ud83d\udd27",fitzpatrick_scale:!1,category:"objects"},hammer:{keywords:["tools","build","create"],char:"\ud83d\udd28",fitzpatrick_scale:!1,category:"objects"},hammer_and_pick:{keywords:["tools","build","create"],char:"\u2692",fitzpatrick_scale:!1,category:"objects"},hammer_and_wrench:{keywords:["tools","build","create"],char:"\ud83d\udee0",fitzpatrick_scale:!1,category:"objects"},pick:{keywords:["tools","dig"],char:"\u26cf",fitzpatrick_scale:!1,category:"objects"},nut_and_bolt:{keywords:["handy","tools","fix"],char:"\ud83d\udd29",fitzpatrick_scale:!1,category:"objects"},gear:{keywords:["cog"],char:"\u2699",fitzpatrick_scale:!1,category:"objects"},brick:{keywords:["bricks"],char:"\ud83e\uddf1",fitzpatrick_scale:!1,category:"objects"},chains:{keywords:["lock","arrest"],char:"\u26d3",fitzpatrick_scale:!1,category:"objects"},magnet:{keywords:["attraction","magnetic"],char:"\ud83e\uddf2",fitzpatrick_scale:!1,category:"objects"},gun:{keywords:["violence","weapon","pistol","revolver"],char:"\ud83d\udd2b",fitzpatrick_scale:!1,category:"objects"},bomb:{keywords:["boom","explode","explosion","terrorism"],char:"\ud83d\udca3",fitzpatrick_scale:!1,category:"objects"},firecracker:{keywords:["dynamite","boom","explode","explosion","explosive"],char:"\ud83e\udde8",fitzpatrick_scale:!1,category:"objects"},hocho:{keywords:["knife","blade","cutlery","kitchen","weapon"],char:"\ud83d\udd2a",fitzpatrick_scale:!1,category:"objects"},dagger:{keywords:["weapon"],char:"\ud83d\udde1",fitzpatrick_scale:!1,category:"objects"},crossed_swords:{keywords:["weapon"],char:"\u2694",fitzpatrick_scale:!1,category:"objects"},shield:{keywords:["protection","security"],char:"\ud83d\udee1",fitzpatrick_scale:!1,category:"objects"},smoking:{keywords:["kills","tobacco","cigarette","joint","smoke"],char:"\ud83d\udeac",fitzpatrick_scale:!1,category:"objects"},skull_and_crossbones:{keywords:["poison","danger","deadly","scary","death","pirate","evil"],char:"\u2620",fitzpatrick_scale:!1,category:"objects"},coffin:{keywords:["vampire","dead","die","death","rip","graveyard","cemetery","casket","funeral","box"],char:"\u26b0",fitzpatrick_scale:!1,category:"objects"},funeral_urn:{keywords:["dead","die","death","rip","ashes"],char:"\u26b1",fitzpatrick_scale:!1,category:"objects"},amphora:{keywords:["vase","jar"],char:"\ud83c\udffa",fitzpatrick_scale:!1,category:"objects"},crystal_ball:{keywords:["disco","party","magic","circus","fortune_teller"],char:"\ud83d\udd2e",fitzpatrick_scale:!1,category:"objects"},prayer_beads:{keywords:["dhikr","religious"],char:"\ud83d\udcff",fitzpatrick_scale:!1,category:"objects"},nazar_amulet:{keywords:["bead","charm"],char:"\ud83e\uddff",fitzpatrick_scale:!1,category:"objects"},barber:{keywords:["hair","salon","style"],char:"\ud83d\udc88",fitzpatrick_scale:!1,category:"objects"},alembic:{keywords:["distilling","science","experiment","chemistry"],char:"\u2697",fitzpatrick_scale:!1,category:"objects"},telescope:{keywords:["stars","space","zoom","science","astronomy"],char:"\ud83d\udd2d",fitzpatrick_scale:!1,category:"objects"},microscope:{keywords:["laboratory","experiment","zoomin","science","study"],char:"\ud83d\udd2c",fitzpatrick_scale:!1,category:"objects"},hole:{keywords:["embarrassing"],char:"\ud83d\udd73",fitzpatrick_scale:!1,category:"objects"},pill:{keywords:["health","medicine","doctor","pharmacy","drug"],char:"\ud83d\udc8a",fitzpatrick_scale:!1,category:"objects"},syringe:{keywords:["health","hospital","drugs","blood","medicine","needle","doctor","nurse"],char:"\ud83d\udc89",fitzpatrick_scale:!1,category:"objects"},dna:{keywords:["biologist","genetics","life"],char:"\ud83e\uddec",fitzpatrick_scale:!1,category:"objects"},microbe:{keywords:["amoeba","bacteria","germs"],char:"\ud83e\udda0",fitzpatrick_scale:!1,category:"objects"},petri_dish:{keywords:["bacteria","biology","culture","lab"],char:"\ud83e\uddeb",fitzpatrick_scale:!1,category:"objects"},test_tube:{keywords:["chemistry","experiment","lab","science"],char:"\ud83e\uddea",fitzpatrick_scale:!1,category:"objects"},thermometer:{keywords:["weather","temperature","hot","cold"],char:"\ud83c\udf21",fitzpatrick_scale:!1,category:"objects"},broom:{keywords:["cleaning","sweeping","witch"],char:"\ud83e\uddf9",fitzpatrick_scale:!1,category:"objects"},basket:{keywords:["laundry"],char:"\ud83e\uddfa",fitzpatrick_scale:!1,category:"objects"},toilet_paper:{keywords:["roll"],char:"\ud83e\uddfb",fitzpatrick_scale:!1,category:"objects"},label:{keywords:["sale","tag"],char:"\ud83c\udff7",fitzpatrick_scale:!1,category:"objects"},bookmark:{keywords:["favorite","label","save"],char:"\ud83d\udd16",fitzpatrick_scale:!1,category:"objects"},toilet:{keywords:["restroom","wc","washroom","bathroom","potty"],char:"\ud83d\udebd",fitzpatrick_scale:!1,category:"objects"},shower:{keywords:["clean","water","bathroom"],char:"\ud83d\udebf",fitzpatrick_scale:!1,category:"objects"},bathtub:{keywords:["clean","shower","bathroom"],char:"\ud83d\udec1",fitzpatrick_scale:!1,category:"objects"},soap:{keywords:["bar","bathing","cleaning","lather"],char:"\ud83e\uddfc",fitzpatrick_scale:!1,category:"objects"},sponge:{keywords:["absorbing","cleaning","porous"],char:"\ud83e\uddfd",fitzpatrick_scale:!1,category:"objects"},lotion_bottle:{keywords:["moisturizer","sunscreen"],char:"\ud83e\uddf4",fitzpatrick_scale:!1,category:"objects"},key:{keywords:["lock","door","password"],char:"\ud83d\udd11",fitzpatrick_scale:!1,category:"objects"},old_key:{keywords:["lock","door","password"],char:"\ud83d\udddd",fitzpatrick_scale:!1,category:"objects"},couch_and_lamp:{keywords:["read","chill"],char:"\ud83d\udecb",fitzpatrick_scale:!1,category:"objects"},sleeping_bed:{keywords:["bed","rest"],char:"\ud83d\udecc",fitzpatrick_scale:!0,category:"objects"},bed:{keywords:["sleep","rest"],char:"\ud83d\udecf",fitzpatrick_scale:!1,category:"objects"},door:{keywords:["house","entry","exit"],char:"\ud83d\udeaa",fitzpatrick_scale:!1,category:"objects"},bellhop_bell:{keywords:["service"],char:"\ud83d\udece",fitzpatrick_scale:!1,category:"objects"},teddy_bear:{keywords:["plush","stuffed"],char:"\ud83e\uddf8",fitzpatrick_scale:!1,category:"objects"},framed_picture:{keywords:["photography"],char:"\ud83d\uddbc",fitzpatrick_scale:!1,category:"objects"},world_map:{keywords:["location","direction"],char:"\ud83d\uddfa",fitzpatrick_scale:!1,category:"objects"},parasol_on_ground:{keywords:["weather","summer"],char:"\u26f1",fitzpatrick_scale:!1,category:"objects"},moyai:{keywords:["rock","easter island","moai"],char:"\ud83d\uddff",fitzpatrick_scale:!1,category:"objects"},shopping:{keywords:["mall","buy","purchase"],char:"\ud83d\udecd",fitzpatrick_scale:!1,category:"objects"},shopping_cart:{keywords:["trolley"],char:"\ud83d\uded2",fitzpatrick_scale:!1,category:"objects"},balloon:{keywords:["party","celebration","birthday","circus"],char:"\ud83c\udf88",fitzpatrick_scale:!1,category:"objects"},flags:{keywords:["fish","japanese","koinobori","carp","banner"],char:"\ud83c\udf8f",fitzpatrick_scale:!1,category:"objects"},ribbon:{keywords:["decoration","pink","girl","bowtie"],char:"\ud83c\udf80",fitzpatrick_scale:!1,category:"objects"},gift:{keywords:["present","birthday","christmas","xmas"],char:"\ud83c\udf81",fitzpatrick_scale:!1,category:"objects"},confetti_ball:{keywords:["festival","party","birthday","circus"],char:"\ud83c\udf8a",fitzpatrick_scale:!1,category:"objects"},tada:{keywords:["party","congratulations","birthday","magic","circus","celebration"],char:"\ud83c\udf89",fitzpatrick_scale:!1,category:"objects"},dolls:{keywords:["japanese","toy","kimono"],char:"\ud83c\udf8e",fitzpatrick_scale:!1,category:"objects"},wind_chime:{keywords:["nature","ding","spring","bell"],char:"\ud83c\udf90",fitzpatrick_scale:!1,category:"objects"},crossed_flags:{keywords:["japanese","nation","country","border"],char:"\ud83c\udf8c",fitzpatrick_scale:!1,category:"objects"},izakaya_lantern:{keywords:["light","paper","halloween","spooky"],char:"\ud83c\udfee",fitzpatrick_scale:!1,category:"objects"},red_envelope:{keywords:["gift"],char:"\ud83e\udde7",fitzpatrick_scale:!1,category:"objects"},email:{keywords:["letter","postal","inbox","communication"],char:"\u2709\ufe0f",fitzpatrick_scale:!1,category:"objects"},envelope_with_arrow:{keywords:["email","communication"],char:"\ud83d\udce9",fitzpatrick_scale:!1,category:"objects"},incoming_envelope:{keywords:["email","inbox"],char:"\ud83d\udce8",fitzpatrick_scale:!1,category:"objects"},"e-mail":{keywords:["communication","inbox"],char:"\ud83d\udce7",fitzpatrick_scale:!1,category:"objects"},love_letter:{keywords:["email","like","affection","envelope","valentines"],char:"\ud83d\udc8c",fitzpatrick_scale:!1,category:"objects"},postbox:{keywords:["email","letter","envelope"],char:"\ud83d\udcee",fitzpatrick_scale:!1,category:"objects"},mailbox_closed:{keywords:["email","communication","inbox"],char:"\ud83d\udcea",fitzpatrick_scale:!1,category:"objects"},mailbox:{keywords:["email","inbox","communication"],char:"\ud83d\udceb",fitzpatrick_scale:!1,category:"objects"},mailbox_with_mail:{keywords:["email","inbox","communication"],char:"\ud83d\udcec",fitzpatrick_scale:!1,category:"objects"},mailbox_with_no_mail:{keywords:["email","inbox"],char:"\ud83d\udced",fitzpatrick_scale:!1,category:"objects"},package:{keywords:["mail","gift","cardboard","box","moving"],char:"\ud83d\udce6",fitzpatrick_scale:!1,category:"objects"},postal_horn:{keywords:["instrument","music"],char:"\ud83d\udcef",fitzpatrick_scale:!1,category:"objects"},inbox_tray:{keywords:["email","documents"],char:"\ud83d\udce5",fitzpatrick_scale:!1,category:"objects"},outbox_tray:{keywords:["inbox","email"],char:"\ud83d\udce4",fitzpatrick_scale:!1,category:"objects"},scroll:{keywords:["documents","ancient","history","paper"],char:"\ud83d\udcdc",fitzpatrick_scale:!1,category:"objects"},page_with_curl:{keywords:["documents","office","paper"],char:"\ud83d\udcc3",fitzpatrick_scale:!1,category:"objects"},bookmark_tabs:{keywords:["favorite","save","order","tidy"],char:"\ud83d\udcd1",fitzpatrick_scale:!1,category:"objects"},receipt:{keywords:["accounting","expenses"],char:"\ud83e\uddfe",fitzpatrick_scale:!1,category:"objects"},bar_chart:{keywords:["graph","presentation","stats"],char:"\ud83d\udcca",fitzpatrick_scale:!1,category:"objects"},chart_with_upwards_trend:{keywords:["graph","presentation","stats","recovery","business","economics","money","sales","good","success"],char:"\ud83d\udcc8",fitzpatrick_scale:!1,category:"objects"},chart_with_downwards_trend:{keywords:["graph","presentation","stats","recession","business","economics","money","sales","bad","failure"],char:"\ud83d\udcc9",fitzpatrick_scale:!1,category:"objects"},page_facing_up:{keywords:["documents","office","paper","information"],char:"\ud83d\udcc4",fitzpatrick_scale:!1,category:"objects"},date:{keywords:["calendar","schedule"],char:"\ud83d\udcc5",fitzpatrick_scale:!1,category:"objects"},calendar:{keywords:["schedule","date","planning"],char:"\ud83d\udcc6",fitzpatrick_scale:!1,category:"objects"},spiral_calendar:{keywords:["date","schedule","planning"],char:"\ud83d\uddd3",fitzpatrick_scale:!1,category:"objects"},card_index:{keywords:["business","stationery"],char:"\ud83d\udcc7",fitzpatrick_scale:!1,category:"objects"},card_file_box:{keywords:["business","stationery"],char:"\ud83d\uddc3",fitzpatrick_scale:!1,category:"objects"},ballot_box:{keywords:["election","vote"],char:"\ud83d\uddf3",fitzpatrick_scale:!1,category:"objects"},file_cabinet:{keywords:["filing","organizing"],char:"\ud83d\uddc4",fitzpatrick_scale:!1,category:"objects"},clipboard:{keywords:["stationery","documents"],char:"\ud83d\udccb",fitzpatrick_scale:!1,category:"objects"},spiral_notepad:{keywords:["memo","stationery"],char:"\ud83d\uddd2",fitzpatrick_scale:!1,category:"objects"},file_folder:{keywords:["documents","business","office"],char:"\ud83d\udcc1",fitzpatrick_scale:!1,category:"objects"},open_file_folder:{keywords:["documents","load"],char:"\ud83d\udcc2",fitzpatrick_scale:!1,category:"objects"},card_index_dividers:{keywords:["organizing","business","stationery"],char:"\ud83d\uddc2",fitzpatrick_scale:!1,category:"objects"},newspaper_roll:{keywords:["press","headline"],char:"\ud83d\uddde",fitzpatrick_scale:!1,category:"objects"},newspaper:{keywords:["press","headline"],char:"\ud83d\udcf0",fitzpatrick_scale:!1,category:"objects"},notebook:{keywords:["stationery","record","notes","paper","study"],char:"\ud83d\udcd3",fitzpatrick_scale:!1,category:"objects"},closed_book:{keywords:["read","library","knowledge","textbook","learn"],char:"\ud83d\udcd5",fitzpatrick_scale:!1,category:"objects"},green_book:{keywords:["read","library","knowledge","study"],char:"\ud83d\udcd7",fitzpatrick_scale:!1,category:"objects"},blue_book:{keywords:["read","library","knowledge","learn","study"],char:"\ud83d\udcd8",fitzpatrick_scale:!1,category:"objects"},orange_book:{keywords:["read","library","knowledge","textbook","study"],char:"\ud83d\udcd9",fitzpatrick_scale:!1,category:"objects"},notebook_with_decorative_cover:{keywords:["classroom","notes","record","paper","study"],char:"\ud83d\udcd4",fitzpatrick_scale:!1,category:"objects"},ledger:{keywords:["notes","paper"],char:"\ud83d\udcd2",fitzpatrick_scale:!1,category:"objects"},books:{keywords:["literature","library","study"],char:"\ud83d\udcda",fitzpatrick_scale:!1,category:"objects"},open_book:{keywords:["book","read","library","knowledge","literature","learn","study"],char:"\ud83d\udcd6",fitzpatrick_scale:!1,category:"objects"},safety_pin:{keywords:["diaper"],char:"\ud83e\uddf7",fitzpatrick_scale:!1,category:"objects"},link:{keywords:["rings","url"],char:"\ud83d\udd17",fitzpatrick_scale:!1,category:"objects"},paperclip:{keywords:["documents","stationery"],char:"\ud83d\udcce",fitzpatrick_scale:!1,category:"objects"},paperclips:{keywords:["documents","stationery"],char:"\ud83d\udd87",fitzpatrick_scale:!1,category:"objects"},scissors:{keywords:["stationery","cut"],char:"\u2702\ufe0f",fitzpatrick_scale:!1,category:"objects"},triangular_ruler:{keywords:["stationery","math","architect","sketch"],char:"\ud83d\udcd0",fitzpatrick_scale:!1,category:"objects"},straight_ruler:{keywords:["stationery","calculate","length","math","school","drawing","architect","sketch"],char:"\ud83d\udccf",fitzpatrick_scale:!1,category:"objects"},abacus:{keywords:["calculation"],char:"\ud83e\uddee",fitzpatrick_scale:!1,category:"objects"},pushpin:{keywords:["stationery","mark","here"],char:"\ud83d\udccc",fitzpatrick_scale:!1,category:"objects"},round_pushpin:{keywords:["stationery","location","map","here"],char:"\ud83d\udccd",fitzpatrick_scale:!1,category:"objects"},triangular_flag_on_post:{keywords:["mark","milestone","place"],char:"\ud83d\udea9",fitzpatrick_scale:!1,category:"objects"},white_flag:{keywords:["losing","loser","lost","surrender","give up","fail"],char:"\ud83c\udff3",fitzpatrick_scale:!1,category:"objects"},black_flag:{keywords:["pirate"],char:"\ud83c\udff4",fitzpatrick_scale:!1,category:"objects"},rainbow_flag:{keywords:["flag","rainbow","pride","gay","lgbt","glbt","queer","homosexual","lesbian","bisexual","transgender"],char:"\ud83c\udff3\ufe0f\u200d\ud83c\udf08",fitzpatrick_scale:!1,category:"objects"},closed_lock_with_key:{keywords:["security","privacy"],char:"\ud83d\udd10",fitzpatrick_scale:!1,category:"objects"},lock:{keywords:["security","password","padlock"],char:"\ud83d\udd12",fitzpatrick_scale:!1,category:"objects"},unlock:{keywords:["privacy","security"],char:"\ud83d\udd13",fitzpatrick_scale:!1,category:"objects"},lock_with_ink_pen:{keywords:["security","secret"],char:"\ud83d\udd0f",fitzpatrick_scale:!1,category:"objects"},pen:{keywords:["stationery","writing","write"],char:"\ud83d\udd8a",fitzpatrick_scale:!1,category:"objects"},fountain_pen:{keywords:["stationery","writing","write"],char:"\ud83d\udd8b",fitzpatrick_scale:!1,category:"objects"},black_nib:{keywords:["pen","stationery","writing","write"],char:"\u2712\ufe0f",fitzpatrick_scale:!1,category:"objects"},memo:{keywords:["write","documents","stationery","pencil","paper","writing","legal","exam","quiz","test","study","compose"],char:"\ud83d\udcdd",fitzpatrick_scale:!1,category:"objects"},pencil2:{keywords:["stationery","write","paper","writing","school","study"],char:"\u270f\ufe0f",fitzpatrick_scale:!1,category:"objects"},crayon:{keywords:["drawing","creativity"],char:"\ud83d\udd8d",fitzpatrick_scale:!1,category:"objects"},paintbrush:{keywords:["drawing","creativity","art"],char:"\ud83d\udd8c",fitzpatrick_scale:!1,category:"objects"},mag:{keywords:["search","zoom","find","detective"],char:"\ud83d\udd0d",fitzpatrick_scale:!1,category:"objects"},mag_right:{keywords:["search","zoom","find","detective"],char:"\ud83d\udd0e",fitzpatrick_scale:!1,category:"objects"},heart:{keywords:["love","like","valentines"],char:"\u2764\ufe0f",fitzpatrick_scale:!1,category:"symbols"},orange_heart:{keywords:["love","like","affection","valentines"],char:"\ud83e\udde1",fitzpatrick_scale:!1,category:"symbols"},yellow_heart:{keywords:["love","like","affection","valentines"],char:"\ud83d\udc9b",fitzpatrick_scale:!1,category:"symbols"},green_heart:{keywords:["love","like","affection","valentines"],char:"\ud83d\udc9a",fitzpatrick_scale:!1,category:"symbols"},blue_heart:{keywords:["love","like","affection","valentines"],char:"\ud83d\udc99",fitzpatrick_scale:!1,category:"symbols"},purple_heart:{keywords:["love","like","affection","valentines"],char:"\ud83d\udc9c",fitzpatrick_scale:!1,category:"symbols"},black_heart:{keywords:["evil"],char:"\ud83d\udda4",fitzpatrick_scale:!1,category:"symbols"},broken_heart:{keywords:["sad","sorry","break","heart","heartbreak"],char:"\ud83d\udc94",fitzpatrick_scale:!1,category:"symbols"},heavy_heart_exclamation:{keywords:["decoration","love"],char:"\u2763",fitzpatrick_scale:!1,category:"symbols"},two_hearts:{keywords:["love","like","affection","valentines","heart"],char:"\ud83d\udc95",fitzpatrick_scale:!1,category:"symbols"},revolving_hearts:{keywords:["love","like","affection","valentines"],char:"\ud83d\udc9e",fitzpatrick_scale:!1,category:"symbols"},heartbeat:{keywords:["love","like","affection","valentines","pink","heart"],char:"\ud83d\udc93",fitzpatrick_scale:!1,category:"symbols"},heartpulse:{keywords:["like","love","affection","valentines","pink"],char:"\ud83d\udc97",fitzpatrick_scale:!1,category:"symbols"},sparkling_heart:{keywords:["love","like","affection","valentines"],char:"\ud83d\udc96",fitzpatrick_scale:!1,category:"symbols"},cupid:{keywords:["love","like","heart","affection","valentines"],char:"\ud83d\udc98",fitzpatrick_scale:!1,category:"symbols"},gift_heart:{keywords:["love","valentines"],char:"\ud83d\udc9d",fitzpatrick_scale:!1,category:"symbols"},heart_decoration:{keywords:["purple-square","love","like"],char:"\ud83d\udc9f",fitzpatrick_scale:!1,category:"symbols"},peace_symbol:{keywords:["hippie"],char:"\u262e",fitzpatrick_scale:!1,category:"symbols"},latin_cross:{keywords:["christianity"],char:"\u271d",fitzpatrick_scale:!1,category:"symbols"},star_and_crescent:{keywords:["islam"],char:"\u262a",fitzpatrick_scale:!1,category:"symbols"},om:{keywords:["hinduism","buddhism","sikhism","jainism"],char:"\ud83d\udd49",fitzpatrick_scale:!1,category:"symbols"},wheel_of_dharma:{keywords:["hinduism","buddhism","sikhism","jainism"],char:"\u2638",fitzpatrick_scale:!1,category:"symbols"},star_of_david:{keywords:["judaism"],char:"\u2721",fitzpatrick_scale:!1,category:"symbols"},six_pointed_star:{keywords:["purple-square","religion","jewish","hexagram"],char:"\ud83d\udd2f",fitzpatrick_scale:!1,category:"symbols"},menorah:{keywords:["hanukkah","candles","jewish"],char:"\ud83d\udd4e",fitzpatrick_scale:!1,category:"symbols"},yin_yang:{keywords:["balance"],char:"\u262f",fitzpatrick_scale:!1,category:"symbols"},orthodox_cross:{keywords:["suppedaneum","religion"],char:"\u2626",fitzpatrick_scale:!1,category:"symbols"},place_of_worship:{keywords:["religion","church","temple","prayer"],char:"\ud83d\uded0",fitzpatrick_scale:!1,category:"symbols"},ophiuchus:{keywords:["sign","purple-square","constellation","astrology"],char:"\u26ce",fitzpatrick_scale:!1,category:"symbols"},aries:{keywords:["sign","purple-square","zodiac","astrology"],char:"\u2648",fitzpatrick_scale:!1,category:"symbols"},taurus:{keywords:["purple-square","sign","zodiac","astrology"],char:"\u2649",fitzpatrick_scale:!1,category:"symbols"},gemini:{keywords:["sign","zodiac","purple-square","astrology"],char:"\u264a",fitzpatrick_scale:!1,category:"symbols"},cancer:{keywords:["sign","zodiac","purple-square","astrology"],char:"\u264b",fitzpatrick_scale:!1,category:"symbols"},leo:{keywords:["sign","purple-square","zodiac","astrology"],char:"\u264c",fitzpatrick_scale:!1,category:"symbols"},virgo:{keywords:["sign","zodiac","purple-square","astrology"],char:"\u264d",fitzpatrick_scale:!1,category:"symbols"},libra:{keywords:["sign","purple-square","zodiac","astrology"],char:"\u264e",fitzpatrick_scale:!1,category:"symbols"},scorpius:{keywords:["sign","zodiac","purple-square","astrology","scorpio"],char:"\u264f",fitzpatrick_scale:!1,category:"symbols"},sagittarius:{keywords:["sign","zodiac","purple-square","astrology"],char:"\u2650",fitzpatrick_scale:!1,category:"symbols"},capricorn:{keywords:["sign","zodiac","purple-square","astrology"],char:"\u2651",fitzpatrick_scale:!1,category:"symbols"},aquarius:{keywords:["sign","purple-square","zodiac","astrology"],char:"\u2652",fitzpatrick_scale:!1,category:"symbols"},pisces:{keywords:["purple-square","sign","zodiac","astrology"],char:"\u2653",fitzpatrick_scale:!1,category:"symbols"},id:{keywords:["purple-square","words"],char:"\ud83c\udd94",fitzpatrick_scale:!1,category:"symbols"},atom_symbol:{keywords:["science","physics","chemistry"],char:"\u269b",fitzpatrick_scale:!1,category:"symbols"},u7a7a:{keywords:["kanji","japanese","chinese","empty","sky","blue-square"],char:"\ud83c\ude33",fitzpatrick_scale:!1,category:"symbols"},u5272:{keywords:["cut","divide","chinese","kanji","pink-square"],char:"\ud83c\ude39",fitzpatrick_scale:!1,category:"symbols"},radioactive:{keywords:["nuclear","danger"],char:"\u2622",fitzpatrick_scale:!1,category:"symbols"},biohazard:{keywords:["danger"],char:"\u2623",fitzpatrick_scale:!1,category:"symbols"},mobile_phone_off:{keywords:["mute","orange-square","silence","quiet"],char:"\ud83d\udcf4",fitzpatrick_scale:!1,category:"symbols"},vibration_mode:{keywords:["orange-square","phone"],char:"\ud83d\udcf3",fitzpatrick_scale:!1,category:"symbols"},u6709:{keywords:["orange-square","chinese","have","kanji"],char:"\ud83c\ude36",fitzpatrick_scale:!1,category:"symbols"},u7121:{keywords:["nothing","chinese","kanji","japanese","orange-square"],char:"\ud83c\ude1a",fitzpatrick_scale:!1,category:"symbols"},u7533:{keywords:["chinese","japanese","kanji","orange-square"],char:"\ud83c\ude38",fitzpatrick_scale:!1,category:"symbols"},u55b6:{keywords:["japanese","opening hours","orange-square"],char:"\ud83c\ude3a",fitzpatrick_scale:!1,category:"symbols"},u6708:{keywords:["chinese","month","moon","japanese","orange-square","kanji"],char:"\ud83c\ude37\ufe0f",fitzpatrick_scale:!1,category:"symbols"},eight_pointed_black_star:{keywords:["orange-square","shape","polygon"],char:"\u2734\ufe0f",fitzpatrick_scale:!1,category:"symbols"},vs:{keywords:["words","orange-square"],char:"\ud83c\udd9a",fitzpatrick_scale:!1,category:"symbols"},accept:{keywords:["ok","good","chinese","kanji","agree","yes","orange-circle"],char:"\ud83c\ude51",fitzpatrick_scale:!1,category:"symbols"},white_flower:{keywords:["japanese","spring"],char:"\ud83d\udcae",fitzpatrick_scale:!1,category:"symbols"},ideograph_advantage:{keywords:["chinese","kanji","obtain","get","circle"],char:"\ud83c\ude50",fitzpatrick_scale:!1,category:"symbols"},secret:{keywords:["privacy","chinese","sshh","kanji","red-circle"],char:"\u3299\ufe0f",fitzpatrick_scale:!1,category:"symbols"},congratulations:{keywords:["chinese","kanji","japanese","red-circle"],char:"\u3297\ufe0f",fitzpatrick_scale:!1,category:"symbols"},u5408:{keywords:["japanese","chinese","join","kanji","red-square"],char:"\ud83c\ude34",fitzpatrick_scale:!1,category:"symbols"},u6e80:{keywords:["full","chinese","japanese","red-square","kanji"],char:"\ud83c\ude35",fitzpatrick_scale:!1,category:"symbols"},u7981:{keywords:["kanji","japanese","chinese","forbidden","limit","restricted","red-square"],char:"\ud83c\ude32",fitzpatrick_scale:!1,category:"symbols"},a:{keywords:["red-square","alphabet","letter"],char:"\ud83c\udd70\ufe0f",fitzpatrick_scale:!1,category:"symbols"},b:{keywords:["red-square","alphabet","letter"],char:"\ud83c\udd71\ufe0f",fitzpatrick_scale:!1,category:"symbols"},ab:{keywords:["red-square","alphabet"],char:"\ud83c\udd8e",fitzpatrick_scale:!1,category:"symbols"},cl:{keywords:["alphabet","words","red-square"],char:"\ud83c\udd91",fitzpatrick_scale:!1,category:"symbols"},o2:{keywords:["alphabet","red-square","letter"],char:"\ud83c\udd7e\ufe0f",fitzpatrick_scale:!1,category:"symbols"},sos:{keywords:["help","red-square","words","emergency","911"],char:"\ud83c\udd98",fitzpatrick_scale:!1,category:"symbols"},no_entry:{keywords:["limit","security","privacy","bad","denied","stop","circle"],char:"\u26d4",fitzpatrick_scale:!1,category:"symbols"},name_badge:{keywords:["fire","forbid"],char:"\ud83d\udcdb",fitzpatrick_scale:!1,category:"symbols"},no_entry_sign:{keywords:["forbid","stop","limit","denied","disallow","circle"],char:"\ud83d\udeab",fitzpatrick_scale:!1,category:"symbols"},x:{keywords:["no","delete","remove","cancel","red"],char:"\u274c",fitzpatrick_scale:!1,category:"symbols"},o:{keywords:["circle","round"],char:"\u2b55",fitzpatrick_scale:!1,category:"symbols"},stop_sign:{keywords:["stop"],char:"\ud83d\uded1",fitzpatrick_scale:!1,category:"symbols"},anger:{keywords:["angry","mad"],char:"\ud83d\udca2",fitzpatrick_scale:!1,category:"symbols"},hotsprings:{keywords:["bath","warm","relax"],char:"\u2668\ufe0f",fitzpatrick_scale:!1,category:"symbols"},no_pedestrians:{keywords:["rules","crossing","walking","circle"],char:"\ud83d\udeb7",fitzpatrick_scale:!1,category:"symbols"},do_not_litter:{keywords:["trash","bin","garbage","circle"],char:"\ud83d\udeaf",fitzpatrick_scale:!1,category:"symbols"},no_bicycles:{keywords:["cyclist","prohibited","circle"],char:"\ud83d\udeb3",fitzpatrick_scale:!1,category:"symbols"},"non-potable_water":{keywords:["drink","faucet","tap","circle"],char:"\ud83d\udeb1",fitzpatrick_scale:!1,category:"symbols"},underage:{keywords:["18","drink","pub","night","minor","circle"],char:"\ud83d\udd1e",fitzpatrick_scale:!1,category:"symbols"},no_mobile_phones:{keywords:["iphone","mute","circle"],char:"\ud83d\udcf5",fitzpatrick_scale:!1,category:"symbols"},exclamation:{keywords:["heavy_exclamation_mark","danger","surprise","punctuation","wow","warning"],char:"\u2757",fitzpatrick_scale:!1,category:"symbols"},grey_exclamation:{keywords:["surprise","punctuation","gray","wow","warning"],char:"\u2755",fitzpatrick_scale:!1,category:"symbols"},question:{keywords:["doubt","confused"],char:"\u2753",fitzpatrick_scale:!1,category:"symbols"},grey_question:{keywords:["doubts","gray","huh","confused"],char:"\u2754",fitzpatrick_scale:!1,category:"symbols"},bangbang:{keywords:["exclamation","surprise"],char:"\u203c\ufe0f",fitzpatrick_scale:!1,category:"symbols"},interrobang:{keywords:["wat","punctuation","surprise"],char:"\u2049\ufe0f",fitzpatrick_scale:!1,category:"symbols"},100:{keywords:["score","perfect","numbers","century","exam","quiz","test","pass","hundred"],char:"\ud83d\udcaf",fitzpatrick_scale:!1,category:"symbols"},low_brightness:{keywords:["sun","afternoon","warm","summer"],char:"\ud83d\udd05",fitzpatrick_scale:!1,category:"symbols"},high_brightness:{keywords:["sun","light"],char:"\ud83d\udd06",fitzpatrick_scale:!1,category:"symbols"},trident:{keywords:["weapon","spear"],char:"\ud83d\udd31",fitzpatrick_scale:!1,category:"symbols"},fleur_de_lis:{keywords:["decorative","scout"],char:"\u269c",fitzpatrick_scale:!1,category:"symbols"},part_alternation_mark:{keywords:["graph","presentation","stats","business","economics","bad"],char:"\u303d\ufe0f",fitzpatrick_scale:!1,category:"symbols"},warning:{keywords:["exclamation","wip","alert","error","problem","issue"],char:"\u26a0\ufe0f",fitzpatrick_scale:!1,category:"symbols"},children_crossing:{keywords:["school","warning","danger","sign","driving","yellow-diamond"],char:"\ud83d\udeb8",fitzpatrick_scale:!1,category:"symbols"},beginner:{keywords:["badge","shield"],char:"\ud83d\udd30",fitzpatrick_scale:!1,category:"symbols"},recycle:{keywords:["arrow","environment","garbage","trash"],char:"\u267b\ufe0f",fitzpatrick_scale:!1,category:"symbols"},u6307:{keywords:["chinese","point","green-square","kanji"],char:"\ud83c\ude2f",fitzpatrick_scale:!1,category:"symbols"},chart:{keywords:["green-square","graph","presentation","stats"],char:"\ud83d\udcb9",fitzpatrick_scale:!1,category:"symbols"},sparkle:{keywords:["stars","green-square","awesome","good","fireworks"],char:"\u2747\ufe0f",fitzpatrick_scale:!1,category:"symbols"},eight_spoked_asterisk:{keywords:["star","sparkle","green-square"],char:"\u2733\ufe0f",fitzpatrick_scale:!1,category:"symbols"},negative_squared_cross_mark:{keywords:["x","green-square","no","deny"],char:"\u274e",fitzpatrick_scale:!1,category:"symbols"},white_check_mark:{keywords:["green-square","ok","agree","vote","election","answer","tick"],char:"\u2705",fitzpatrick_scale:!1,category:"symbols"},diamond_shape_with_a_dot_inside:{keywords:["jewel","blue","gem","crystal","fancy"],char:"\ud83d\udca0",fitzpatrick_scale:!1,category:"symbols"},cyclone:{keywords:["weather","swirl","blue","cloud","vortex","spiral","whirlpool","spin","tornado","hurricane","typhoon"],char:"\ud83c\udf00",fitzpatrick_scale:!1,category:"symbols"},loop:{keywords:["tape","cassette"],char:"\u27bf",fitzpatrick_scale:!1,category:"symbols"},globe_with_meridians:{keywords:["earth","international","world","internet","interweb","i18n"],char:"\ud83c\udf10",fitzpatrick_scale:!1,category:"symbols"},m:{keywords:["alphabet","blue-circle","letter"],char:"\u24c2\ufe0f",fitzpatrick_scale:!1,category:"symbols"},atm:{keywords:["money","sales","cash","blue-square","payment","bank"],char:"\ud83c\udfe7",fitzpatrick_scale:!1,category:"symbols"},sa:{keywords:["japanese","blue-square","katakana"],char:"\ud83c\ude02\ufe0f",fitzpatrick_scale:!1,category:"symbols"},passport_control:{keywords:["custom","blue-square"],char:"\ud83d\udec2",fitzpatrick_scale:!1,category:"symbols"},customs:{keywords:["passport","border","blue-square"],char:"\ud83d\udec3",fitzpatrick_scale:!1,category:"symbols"},baggage_claim:{keywords:["blue-square","airport","transport"],char:"\ud83d\udec4",fitzpatrick_scale:!1,category:"symbols"},left_luggage:{keywords:["blue-square","travel"],char:"\ud83d\udec5",fitzpatrick_scale:!1,category:"symbols"},wheelchair:{keywords:["blue-square","disabled","a11y","accessibility"],char:"\u267f",fitzpatrick_scale:!1,category:"symbols"},no_smoking:{keywords:["cigarette","blue-square","smell","smoke"],char:"\ud83d\udead",fitzpatrick_scale:!1,category:"symbols"},wc:{keywords:["toilet","restroom","blue-square"],char:"\ud83d\udebe",fitzpatrick_scale:!1,category:"symbols"},parking:{keywords:["cars","blue-square","alphabet","letter"],char:"\ud83c\udd7f\ufe0f",fitzpatrick_scale:!1,category:"symbols"},potable_water:{keywords:["blue-square","liquid","restroom","cleaning","faucet"],char:"\ud83d\udeb0",fitzpatrick_scale:!1,category:"symbols"},mens:{keywords:["toilet","restroom","wc","blue-square","gender","male"],char:"\ud83d\udeb9",fitzpatrick_scale:!1,category:"symbols"},womens:{keywords:["purple-square","woman","female","toilet","loo","restroom","gender"],char:"\ud83d\udeba",fitzpatrick_scale:!1,category:"symbols"},baby_symbol:{keywords:["orange-square","child"],char:"\ud83d\udebc",fitzpatrick_scale:!1,category:"symbols"},restroom:{keywords:["blue-square","toilet","refresh","wc","gender"],char:"\ud83d\udebb",fitzpatrick_scale:!1,category:"symbols"},put_litter_in_its_place:{keywords:["blue-square","sign","human","info"],char:"\ud83d\udeae",fitzpatrick_scale:!1,category:"symbols"},cinema:{keywords:["blue-square","record","film","movie","curtain","stage","theater"],char:"\ud83c\udfa6",fitzpatrick_scale:!1,category:"symbols"},signal_strength:{keywords:["blue-square","reception","phone","internet","connection","wifi","bluetooth","bars"],char:"\ud83d\udcf6",fitzpatrick_scale:!1,category:"symbols"},koko:{keywords:["blue-square","here","katakana","japanese","destination"],char:"\ud83c\ude01",fitzpatrick_scale:!1,category:"symbols"},ng:{keywords:["blue-square","words","shape","icon"],char:"\ud83c\udd96",fitzpatrick_scale:!1,category:"symbols"},ok:{keywords:["good","agree","yes","blue-square"],char:"\ud83c\udd97",fitzpatrick_scale:!1,category:"symbols"},up:{keywords:["blue-square","above","high"],char:"\ud83c\udd99",fitzpatrick_scale:!1,category:"symbols"},cool:{keywords:["words","blue-square"],char:"\ud83c\udd92",fitzpatrick_scale:!1,category:"symbols"},new:{keywords:["blue-square","words","start"],char:"\ud83c\udd95",fitzpatrick_scale:!1,category:"symbols"},free:{keywords:["blue-square","words"],char:"\ud83c\udd93",fitzpatrick_scale:!1,category:"symbols"},zero:{keywords:["0","numbers","blue-square","null"],char:"0\ufe0f\u20e3",fitzpatrick_scale:!1,category:"symbols"},one:{keywords:["blue-square","numbers","1"],char:"1\ufe0f\u20e3",fitzpatrick_scale:!1,category:"symbols"},two:{keywords:["numbers","2","prime","blue-square"],char:"2\ufe0f\u20e3",fitzpatrick_scale:!1,category:"symbols"},three:{keywords:["3","numbers","prime","blue-square"],char:"3\ufe0f\u20e3",fitzpatrick_scale:!1,category:"symbols"},four:{keywords:["4","numbers","blue-square"],char:"4\ufe0f\u20e3",fitzpatrick_scale:!1,category:"symbols"},five:{keywords:["5","numbers","blue-square","prime"],char:"5\ufe0f\u20e3",fitzpatrick_scale:!1,category:"symbols"},six:{keywords:["6","numbers","blue-square"],char:"6\ufe0f\u20e3",fitzpatrick_scale:!1,category:"symbols"},seven:{keywords:["7","numbers","blue-square","prime"],char:"7\ufe0f\u20e3",fitzpatrick_scale:!1,category:"symbols"},eight:{keywords:["8","blue-square","numbers"],char:"8\ufe0f\u20e3",fitzpatrick_scale:!1,category:"symbols"},nine:{keywords:["blue-square","numbers","9"],char:"9\ufe0f\u20e3",fitzpatrick_scale:!1,category:"symbols"},keycap_ten:{keywords:["numbers","10","blue-square"],char:"\ud83d\udd1f",fitzpatrick_scale:!1,category:"symbols"},asterisk:{keywords:["star","keycap"],char:"*\u20e3",fitzpatrick_scale:!1,category:"symbols"},1234:{keywords:["numbers","blue-square"],char:"\ud83d\udd22",fitzpatrick_scale:!1,category:"symbols"},eject_button:{keywords:["blue-square"],char:"\u23cf\ufe0f",fitzpatrick_scale:!1,category:"symbols"},arrow_forward:{keywords:["blue-square","right","direction","play"],char:"\u25b6\ufe0f",fitzpatrick_scale:!1,category:"symbols"},pause_button:{keywords:["pause","blue-square"],char:"\u23f8",fitzpatrick_scale:!1,category:"symbols"},next_track_button:{keywords:["forward","next","blue-square"],char:"\u23ed",fitzpatrick_scale:!1,category:"symbols"},stop_button:{keywords:["blue-square"],char:"\u23f9",fitzpatrick_scale:!1,category:"symbols"},record_button:{keywords:["blue-square"],char:"\u23fa",fitzpatrick_scale:!1,category:"symbols"},play_or_pause_button:{keywords:["blue-square","play","pause"],char:"\u23ef",fitzpatrick_scale:!1,category:"symbols"},previous_track_button:{keywords:["backward"],char:"\u23ee",fitzpatrick_scale:!1,category:"symbols"},fast_forward:{keywords:["blue-square","play","speed","continue"],char:"\u23e9",fitzpatrick_scale:!1,category:"symbols"},rewind:{keywords:["play","blue-square"],char:"\u23ea",fitzpatrick_scale:!1,category:"symbols"},twisted_rightwards_arrows:{keywords:["blue-square","shuffle","music","random"],char:"\ud83d\udd00",fitzpatrick_scale:!1,category:"symbols"},repeat:{keywords:["loop","record"],char:"\ud83d\udd01",fitzpatrick_scale:!1,category:"symbols"},repeat_one:{keywords:["blue-square","loop"],char:"\ud83d\udd02",fitzpatrick_scale:!1,category:"symbols"},arrow_backward:{keywords:["blue-square","left","direction"],char:"\u25c0\ufe0f",fitzpatrick_scale:!1,category:"symbols"},arrow_up_small:{keywords:["blue-square","triangle","direction","point","forward","top"],char:"\ud83d\udd3c",fitzpatrick_scale:!1,category:"symbols"},arrow_down_small:{keywords:["blue-square","direction","bottom"],char:"\ud83d\udd3d",fitzpatrick_scale:!1,category:"symbols"},arrow_double_up:{keywords:["blue-square","direction","top"],char:"\u23eb",fitzpatrick_scale:!1,category:"symbols"},arrow_double_down:{keywords:["blue-square","direction","bottom"],char:"\u23ec",fitzpatrick_scale:!1,category:"symbols"},arrow_right:{keywords:["blue-square","next"],char:"\u27a1\ufe0f",fitzpatrick_scale:!1,category:"symbols"},arrow_left:{keywords:["blue-square","previous","back"],char:"\u2b05\ufe0f",fitzpatrick_scale:!1,category:"symbols"},arrow_up:{keywords:["blue-square","continue","top","direction"],char:"\u2b06\ufe0f",fitzpatrick_scale:!1,category:"symbols"},arrow_down:{keywords:["blue-square","direction","bottom"],char:"\u2b07\ufe0f",fitzpatrick_scale:!1,category:"symbols"},arrow_upper_right:{keywords:["blue-square","point","direction","diagonal","northeast"],char:"\u2197\ufe0f",fitzpatrick_scale:!1,category:"symbols"},arrow_lower_right:{keywords:["blue-square","direction","diagonal","southeast"],char:"\u2198\ufe0f",fitzpatrick_scale:!1,category:"symbols"},arrow_lower_left:{keywords:["blue-square","direction","diagonal","southwest"],char:"\u2199\ufe0f",fitzpatrick_scale:!1,category:"symbols"},arrow_upper_left:{keywords:["blue-square","point","direction","diagonal","northwest"],char:"\u2196\ufe0f",fitzpatrick_scale:!1,category:"symbols"},arrow_up_down:{keywords:["blue-square","direction","way","vertical"],char:"\u2195\ufe0f",fitzpatrick_scale:!1,category:"symbols"},left_right_arrow:{keywords:["shape","direction","horizontal","sideways"],char:"\u2194\ufe0f",fitzpatrick_scale:!1,category:"symbols"},arrows_counterclockwise:{keywords:["blue-square","sync","cycle"],char:"\ud83d\udd04",fitzpatrick_scale:!1,category:"symbols"},arrow_right_hook:{keywords:["blue-square","return","rotate","direction"],char:"\u21aa\ufe0f",fitzpatrick_scale:!1,category:"symbols"},leftwards_arrow_with_hook:{keywords:["back","return","blue-square","undo","enter"],char:"\u21a9\ufe0f",fitzpatrick_scale:!1,category:"symbols"},arrow_heading_up:{keywords:["blue-square","direction","top"],char:"\u2934\ufe0f",fitzpatrick_scale:!1,category:"symbols"},arrow_heading_down:{keywords:["blue-square","direction","bottom"],char:"\u2935\ufe0f",fitzpatrick_scale:!1,category:"symbols"},hash:{keywords:["symbol","blue-square","twitter"],char:"#\ufe0f\u20e3",fitzpatrick_scale:!1,category:"symbols"},information_source:{keywords:["blue-square","alphabet","letter"],char:"\u2139\ufe0f",fitzpatrick_scale:!1,category:"symbols"},abc:{keywords:["blue-square","alphabet"],char:"\ud83d\udd24",fitzpatrick_scale:!1,category:"symbols"},abcd:{keywords:["blue-square","alphabet"],char:"\ud83d\udd21",fitzpatrick_scale:!1,category:"symbols"},capital_abcd:{keywords:["alphabet","words","blue-square"],char:"\ud83d\udd20",fitzpatrick_scale:!1,category:"symbols"},symbols:{keywords:["blue-square","music","note","ampersand","percent","glyphs","characters"],char:"\ud83d\udd23",fitzpatrick_scale:!1,category:"symbols"},musical_note:{keywords:["score","tone","sound"],char:"\ud83c\udfb5",fitzpatrick_scale:!1,category:"symbols"},notes:{keywords:["music","score"],char:"\ud83c\udfb6",fitzpatrick_scale:!1,category:"symbols"},wavy_dash:{keywords:["draw","line","moustache","mustache","squiggle","scribble"],char:"\u3030\ufe0f",fitzpatrick_scale:!1,category:"symbols"},curly_loop:{keywords:["scribble","draw","shape","squiggle"],char:"\u27b0",fitzpatrick_scale:!1,category:"symbols"},heavy_check_mark:{keywords:["ok","nike","answer","yes","tick"],char:"\u2714\ufe0f",fitzpatrick_scale:!1,category:"symbols"},arrows_clockwise:{keywords:["sync","cycle","round","repeat"],char:"\ud83d\udd03",fitzpatrick_scale:!1,category:"symbols"},heavy_plus_sign:{keywords:["math","calculation","addition","more","increase"],char:"\u2795",fitzpatrick_scale:!1,category:"symbols"},heavy_minus_sign:{keywords:["math","calculation","subtract","less"],char:"\u2796",fitzpatrick_scale:!1,category:"symbols"},heavy_division_sign:{keywords:["divide","math","calculation"],char:"\u2797",fitzpatrick_scale:!1,category:"symbols"},heavy_multiplication_x:{keywords:["math","calculation"],char:"\u2716\ufe0f",fitzpatrick_scale:!1,category:"symbols"},infinity:{keywords:["forever"],char:"\u267e",fitzpatrick_scale:!1,category:"symbols"},heavy_dollar_sign:{keywords:["money","sales","payment","currency","buck"],char:"\ud83d\udcb2",fitzpatrick_scale:!1,category:"symbols"},currency_exchange:{keywords:["money","sales","dollar","travel"],char:"\ud83d\udcb1",fitzpatrick_scale:!1,category:"symbols"},copyright:{keywords:["ip","license","circle","law","legal"],char:"\xa9\ufe0f",fitzpatrick_scale:!1,category:"symbols"},registered:{keywords:["alphabet","circle"],char:"\xae\ufe0f",fitzpatrick_scale:!1,category:"symbols"},tm:{keywords:["trademark","brand","law","legal"],char:"\u2122\ufe0f",fitzpatrick_scale:!1,category:"symbols"},end:{keywords:["words","arrow"],char:"\ud83d\udd1a",fitzpatrick_scale:!1,category:"symbols"},back:{keywords:["arrow","words","return"],char:"\ud83d\udd19",fitzpatrick_scale:!1,category:"symbols"},on:{keywords:["arrow","words"],char:"\ud83d\udd1b",fitzpatrick_scale:!1,category:"symbols"},top:{keywords:["words","blue-square"],char:"\ud83d\udd1d",fitzpatrick_scale:!1,category:"symbols"},soon:{keywords:["arrow","words"],char:"\ud83d\udd1c",fitzpatrick_scale:!1,category:"symbols"},ballot_box_with_check:{keywords:["ok","agree","confirm","black-square","vote","election","yes","tick"],char:"\u2611\ufe0f",fitzpatrick_scale:!1,category:"symbols"},radio_button:{keywords:["input","old","music","circle"],char:"\ud83d\udd18",fitzpatrick_scale:!1,category:"symbols"},white_circle:{keywords:["shape","round"],char:"\u26aa",fitzpatrick_scale:!1,category:"symbols"},black_circle:{keywords:["shape","button","round"],char:"\u26ab",fitzpatrick_scale:!1,category:"symbols"},red_circle:{keywords:["shape","error","danger"],char:"\ud83d\udd34",fitzpatrick_scale:!1,category:"symbols"},large_blue_circle:{keywords:["shape","icon","button"],char:"\ud83d\udd35",fitzpatrick_scale:!1,category:"symbols"},small_orange_diamond:{keywords:["shape","jewel","gem"],char:"\ud83d\udd38",fitzpatrick_scale:!1,category:"symbols"},small_blue_diamond:{keywords:["shape","jewel","gem"],char:"\ud83d\udd39",fitzpatrick_scale:!1,category:"symbols"},large_orange_diamond:{keywords:["shape","jewel","gem"],char:"\ud83d\udd36",fitzpatrick_scale:!1,category:"symbols"},large_blue_diamond:{keywords:["shape","jewel","gem"],char:"\ud83d\udd37",fitzpatrick_scale:!1,category:"symbols"},small_red_triangle:{keywords:["shape","direction","up","top"],char:"\ud83d\udd3a",fitzpatrick_scale:!1,category:"symbols"},black_small_square:{keywords:["shape","icon"],char:"\u25aa\ufe0f",fitzpatrick_scale:!1,category:"symbols"},white_small_square:{keywords:["shape","icon"],char:"\u25ab\ufe0f",fitzpatrick_scale:!1,category:"symbols"},black_large_square:{keywords:["shape","icon","button"],char:"\u2b1b",fitzpatrick_scale:!1,category:"symbols"},white_large_square:{keywords:["shape","icon","stone","button"],char:"\u2b1c",fitzpatrick_scale:!1,category:"symbols"},small_red_triangle_down:{keywords:["shape","direction","bottom"],char:"\ud83d\udd3b",fitzpatrick_scale:!1,category:"symbols"},black_medium_square:{keywords:["shape","button","icon"],char:"\u25fc\ufe0f",fitzpatrick_scale:!1,category:"symbols"},white_medium_square:{keywords:["shape","stone","icon"],char:"\u25fb\ufe0f",fitzpatrick_scale:!1,category:"symbols"},black_medium_small_square:{keywords:["icon","shape","button"],char:"\u25fe",fitzpatrick_scale:!1,category:"symbols"},white_medium_small_square:{keywords:["shape","stone","icon","button"],char:"\u25fd",fitzpatrick_scale:!1,category:"symbols"},black_square_button:{keywords:["shape","input","frame"],char:"\ud83d\udd32",fitzpatrick_scale:!1,category:"symbols"},white_square_button:{keywords:["shape","input"],char:"\ud83d\udd33",fitzpatrick_scale:!1,category:"symbols"},speaker:{keywords:["sound","volume","silence","broadcast"],char:"\ud83d\udd08",fitzpatrick_scale:!1,category:"symbols"},sound:{keywords:["volume","speaker","broadcast"],char:"\ud83d\udd09",fitzpatrick_scale:!1,category:"symbols"},loud_sound:{keywords:["volume","noise","noisy","speaker","broadcast"],char:"\ud83d\udd0a",fitzpatrick_scale:!1,category:"symbols"},mute:{keywords:["sound","volume","silence","quiet"],char:"\ud83d\udd07",fitzpatrick_scale:!1,category:"symbols"},mega:{keywords:["sound","speaker","volume"],char:"\ud83d\udce3",fitzpatrick_scale:!1,category:"symbols"},loudspeaker:{keywords:["volume","sound"],char:"\ud83d\udce2",fitzpatrick_scale:!1,category:"symbols"},bell:{keywords:["sound","notification","christmas","xmas","chime"],char:"\ud83d\udd14",fitzpatrick_scale:!1,category:"symbols"},no_bell:{keywords:["sound","volume","mute","quiet","silent"],char:"\ud83d\udd15",fitzpatrick_scale:!1,category:"symbols"},black_joker:{keywords:["poker","cards","game","play","magic"],char:"\ud83c\udccf",fitzpatrick_scale:!1,category:"symbols"},mahjong:{keywords:["game","play","chinese","kanji"],char:"\ud83c\udc04",fitzpatrick_scale:!1,category:"symbols"},spades:{keywords:["poker","cards","suits","magic"],char:"\u2660\ufe0f",fitzpatrick_scale:!1,category:"symbols"},clubs:{keywords:["poker","cards","magic","suits"],char:"\u2663\ufe0f",fitzpatrick_scale:!1,category:"symbols"},hearts:{keywords:["poker","cards","magic","suits"],char:"\u2665\ufe0f",fitzpatrick_scale:!1,category:"symbols"},diamonds:{keywords:["poker","cards","magic","suits"],char:"\u2666\ufe0f",fitzpatrick_scale:!1,category:"symbols"},flower_playing_cards:{keywords:["game","sunset","red"],char:"\ud83c\udfb4",fitzpatrick_scale:!1,category:"symbols"},thought_balloon:{keywords:["bubble","cloud","speech","thinking","dream"],char:"\ud83d\udcad",fitzpatrick_scale:!1,category:"symbols"},right_anger_bubble:{keywords:["caption","speech","thinking","mad"],char:"\ud83d\uddef",fitzpatrick_scale:!1,category:"symbols"},speech_balloon:{keywords:["bubble","words","message","talk","chatting"],char:"\ud83d\udcac",fitzpatrick_scale:!1,category:"symbols"},left_speech_bubble:{keywords:["words","message","talk","chatting"],char:"\ud83d\udde8",fitzpatrick_scale:!1,category:"symbols"},clock1:{keywords:["time","late","early","schedule"],char:"\ud83d\udd50",fitzpatrick_scale:!1,category:"symbols"},clock2:{keywords:["time","late","early","schedule"],char:"\ud83d\udd51",fitzpatrick_scale:!1,category:"symbols"},clock3:{keywords:["time","late","early","schedule"],char:"\ud83d\udd52",fitzpatrick_scale:!1,category:"symbols"},clock4:{keywords:["time","late","early","schedule"],char:"\ud83d\udd53",fitzpatrick_scale:!1,category:"symbols"},clock5:{keywords:["time","late","early","schedule"],char:"\ud83d\udd54",fitzpatrick_scale:!1,category:"symbols"},clock6:{keywords:["time","late","early","schedule","dawn","dusk"],char:"\ud83d\udd55",fitzpatrick_scale:!1,category:"symbols"},clock7:{keywords:["time","late","early","schedule"],char:"\ud83d\udd56",fitzpatrick_scale:!1,category:"symbols"},clock8:{keywords:["time","late","early","schedule"],char:"\ud83d\udd57",fitzpatrick_scale:!1,category:"symbols"},clock9:{keywords:["time","late","early","schedule"],char:"\ud83d\udd58",fitzpatrick_scale:!1,category:"symbols"},clock10:{keywords:["time","late","early","schedule"],char:"\ud83d\udd59",fitzpatrick_scale:!1,category:"symbols"},clock11:{keywords:["time","late","early","schedule"],char:"\ud83d\udd5a",fitzpatrick_scale:!1,category:"symbols"},clock12:{keywords:["time","noon","midnight","midday","late","early","schedule"],char:"\ud83d\udd5b",fitzpatrick_scale:!1,category:"symbols"},clock130:{keywords:["time","late","early","schedule"],char:"\ud83d\udd5c",fitzpatrick_scale:!1,category:"symbols"},clock230:{keywords:["time","late","early","schedule"],char:"\ud83d\udd5d",fitzpatrick_scale:!1,category:"symbols"},clock330:{keywords:["time","late","early","schedule"],char:"\ud83d\udd5e",fitzpatrick_scale:!1,category:"symbols"},clock430:{keywords:["time","late","early","schedule"],char:"\ud83d\udd5f",fitzpatrick_scale:!1,category:"symbols"},clock530:{keywords:["time","late","early","schedule"],char:"\ud83d\udd60",fitzpatrick_scale:!1,category:"symbols"},clock630:{keywords:["time","late","early","schedule"],char:"\ud83d\udd61",fitzpatrick_scale:!1,category:"symbols"},clock730:{keywords:["time","late","early","schedule"],char:"\ud83d\udd62",fitzpatrick_scale:!1,category:"symbols"},clock830:{keywords:["time","late","early","schedule"],char:"\ud83d\udd63",fitzpatrick_scale:!1,category:"symbols"},clock930:{keywords:["time","late","early","schedule"],char:"\ud83d\udd64",fitzpatrick_scale:!1,category:"symbols"},clock1030:{keywords:["time","late","early","schedule"],char:"\ud83d\udd65",fitzpatrick_scale:!1,category:"symbols"},clock1130:{keywords:["time","late","early","schedule"],char:"\ud83d\udd66",fitzpatrick_scale:!1,category:"symbols"},clock1230:{keywords:["time","late","early","schedule"],char:"\ud83d\udd67",fitzpatrick_scale:!1,category:"symbols"},afghanistan:{keywords:["af","flag","nation","country","banner"],char:"\ud83c\udde6\ud83c\uddeb",fitzpatrick_scale:!1,category:"flags"},aland_islands:{keywords:["\xc5land","islands","flag","nation","country","banner"],char:"\ud83c\udde6\ud83c\uddfd",fitzpatrick_scale:!1,category:"flags"},albania:{keywords:["al","flag","nation","country","banner"],char:"\ud83c\udde6\ud83c\uddf1",fitzpatrick_scale:!1,category:"flags"},algeria:{keywords:["dz","flag","nation","country","banner"],char:"\ud83c\udde9\ud83c\uddff",fitzpatrick_scale:!1,category:"flags"},american_samoa:{keywords:["american","ws","flag","nation","country","banner"],char:"\ud83c\udde6\ud83c\uddf8",fitzpatrick_scale:!1,category:"flags"},andorra:{keywords:["ad","flag","nation","country","banner"],char:"\ud83c\udde6\ud83c\udde9",fitzpatrick_scale:!1,category:"flags"},angola:{keywords:["ao","flag","nation","country","banner"],char:"\ud83c\udde6\ud83c\uddf4",fitzpatrick_scale:!1,category:"flags"},anguilla:{keywords:["ai","flag","nation","country","banner"],char:"\ud83c\udde6\ud83c\uddee",fitzpatrick_scale:!1,category:"flags"},antarctica:{keywords:["aq","flag","nation","country","banner"],char:"\ud83c\udde6\ud83c\uddf6",fitzpatrick_scale:!1,category:"flags"},antigua_barbuda:{keywords:["antigua","barbuda","flag","nation","country","banner"],char:"\ud83c\udde6\ud83c\uddec",fitzpatrick_scale:!1,category:"flags"},argentina:{keywords:["ar","flag","nation","country","banner"],char:"\ud83c\udde6\ud83c\uddf7",fitzpatrick_scale:!1,category:"flags"},armenia:{keywords:["am","flag","nation","country","banner"],char:"\ud83c\udde6\ud83c\uddf2",fitzpatrick_scale:!1,category:"flags"},aruba:{keywords:["aw","flag","nation","country","banner"],char:"\ud83c\udde6\ud83c\uddfc",fitzpatrick_scale:!1,category:"flags"},australia:{keywords:["au","flag","nation","country","banner"],char:"\ud83c\udde6\ud83c\uddfa",fitzpatrick_scale:!1,category:"flags"},austria:{keywords:["at","flag","nation","country","banner"],char:"\ud83c\udde6\ud83c\uddf9",fitzpatrick_scale:!1,category:"flags"},azerbaijan:{keywords:["az","flag","nation","country","banner"],char:"\ud83c\udde6\ud83c\uddff",fitzpatrick_scale:!1,category:"flags"},bahamas:{keywords:["bs","flag","nation","country","banner"],char:"\ud83c\udde7\ud83c\uddf8",fitzpatrick_scale:!1,category:"flags"},bahrain:{keywords:["bh","flag","nation","country","banner"],char:"\ud83c\udde7\ud83c\udded",fitzpatrick_scale:!1,category:"flags"},bangladesh:{keywords:["bd","flag","nation","country","banner"],char:"\ud83c\udde7\ud83c\udde9",fitzpatrick_scale:!1,category:"flags"},barbados:{keywords:["bb","flag","nation","country","banner"],char:"\ud83c\udde7\ud83c\udde7",fitzpatrick_scale:!1,category:"flags"},belarus:{keywords:["by","flag","nation","country","banner"],char:"\ud83c\udde7\ud83c\uddfe",fitzpatrick_scale:!1,category:"flags"},belgium:{keywords:["be","flag","nation","country","banner"],char:"\ud83c\udde7\ud83c\uddea",fitzpatrick_scale:!1,category:"flags"},belize:{keywords:["bz","flag","nation","country","banner"],char:"\ud83c\udde7\ud83c\uddff",fitzpatrick_scale:!1,category:"flags"},benin:{keywords:["bj","flag","nation","country","banner"],char:"\ud83c\udde7\ud83c\uddef",fitzpatrick_scale:!1,category:"flags"},bermuda:{keywords:["bm","flag","nation","country","banner"],char:"\ud83c\udde7\ud83c\uddf2",fitzpatrick_scale:!1,category:"flags"},bhutan:{keywords:["bt","flag","nation","country","banner"],char:"\ud83c\udde7\ud83c\uddf9",fitzpatrick_scale:!1,category:"flags"},bolivia:{keywords:["bo","flag","nation","country","banner"],char:"\ud83c\udde7\ud83c\uddf4",fitzpatrick_scale:!1,category:"flags"},caribbean_netherlands:{keywords:["bonaire","flag","nation","country","banner"],char:"\ud83c\udde7\ud83c\uddf6",fitzpatrick_scale:!1,category:"flags"},bosnia_herzegovina:{keywords:["bosnia","herzegovina","flag","nation","country","banner"],char:"\ud83c\udde7\ud83c\udde6",fitzpatrick_scale:!1,category:"flags"},botswana:{keywords:["bw","flag","nation","country","banner"],char:"\ud83c\udde7\ud83c\uddfc",fitzpatrick_scale:!1,category:"flags"},brazil:{keywords:["br","flag","nation","country","banner"],char:"\ud83c\udde7\ud83c\uddf7",fitzpatrick_scale:!1,category:"flags"},british_indian_ocean_territory:{keywords:["british","indian","ocean","territory","flag","nation","country","banner"],char:"\ud83c\uddee\ud83c\uddf4",fitzpatrick_scale:!1,category:"flags"},british_virgin_islands:{keywords:["british","virgin","islands","bvi","flag","nation","country","banner"],char:"\ud83c\uddfb\ud83c\uddec",fitzpatrick_scale:!1,category:"flags"},brunei:{keywords:["bn","darussalam","flag","nation","country","banner"],char:"\ud83c\udde7\ud83c\uddf3",fitzpatrick_scale:!1,category:"flags"},bulgaria:{keywords:["bg","flag","nation","country","banner"],char:"\ud83c\udde7\ud83c\uddec",fitzpatrick_scale:!1,category:"flags"},burkina_faso:{keywords:["burkina","faso","flag","nation","country","banner"],char:"\ud83c\udde7\ud83c\uddeb",fitzpatrick_scale:!1,category:"flags"},burundi:{keywords:["bi","flag","nation","country","banner"],char:"\ud83c\udde7\ud83c\uddee",fitzpatrick_scale:!1,category:"flags"},cape_verde:{keywords:["cabo","verde","flag","nation","country","banner"],char:"\ud83c\udde8\ud83c\uddfb",fitzpatrick_scale:!1,category:"flags"},cambodia:{keywords:["kh","flag","nation","country","banner"],char:"\ud83c\uddf0\ud83c\udded",fitzpatrick_scale:!1,category:"flags"},cameroon:{keywords:["cm","flag","nation","country","banner"],char:"\ud83c\udde8\ud83c\uddf2",fitzpatrick_scale:!1,category:"flags"},canada:{keywords:["ca","flag","nation","country","banner"],char:"\ud83c\udde8\ud83c\udde6",fitzpatrick_scale:!1,category:"flags"},canary_islands:{keywords:["canary","islands","flag","nation","country","banner"],char:"\ud83c\uddee\ud83c\udde8",fitzpatrick_scale:!1,category:"flags"},cayman_islands:{keywords:["cayman","islands","flag","nation","country","banner"],char:"\ud83c\uddf0\ud83c\uddfe",fitzpatrick_scale:!1,category:"flags"},central_african_republic:{keywords:["central","african","republic","flag","nation","country","banner"],char:"\ud83c\udde8\ud83c\uddeb",fitzpatrick_scale:!1,category:"flags"},chad:{keywords:["td","flag","nation","country","banner"],char:"\ud83c\uddf9\ud83c\udde9",fitzpatrick_scale:!1,category:"flags"},chile:{keywords:["flag","nation","country","banner"],char:"\ud83c\udde8\ud83c\uddf1",fitzpatrick_scale:!1,category:"flags"},cn:{keywords:["china","chinese","prc","flag","country","nation","banner"],char:"\ud83c\udde8\ud83c\uddf3",fitzpatrick_scale:!1,category:"flags"},christmas_island:{keywords:["christmas","island","flag","nation","country","banner"],char:"\ud83c\udde8\ud83c\uddfd",fitzpatrick_scale:!1,category:"flags"},cocos_islands:{keywords:["cocos","keeling","islands","flag","nation","country","banner"],char:"\ud83c\udde8\ud83c\udde8",fitzpatrick_scale:!1,category:"flags"},colombia:{keywords:["co","flag","nation","country","banner"],char:"\ud83c\udde8\ud83c\uddf4",fitzpatrick_scale:!1,category:"flags"},comoros:{keywords:["km","flag","nation","country","banner"],char:"\ud83c\uddf0\ud83c\uddf2",fitzpatrick_scale:!1,category:"flags"},congo_brazzaville:{keywords:["congo","flag","nation","country","banner"],char:"\ud83c\udde8\ud83c\uddec",fitzpatrick_scale:!1,category:"flags"},congo_kinshasa:{keywords:["congo","democratic","republic","flag","nation","country","banner"],char:"\ud83c\udde8\ud83c\udde9",fitzpatrick_scale:!1,category:"flags"},cook_islands:{keywords:["cook","islands","flag","nation","country","banner"],char:"\ud83c\udde8\ud83c\uddf0",fitzpatrick_scale:!1,category:"flags"},costa_rica:{keywords:["costa","rica","flag","nation","country","banner"],char:"\ud83c\udde8\ud83c\uddf7",fitzpatrick_scale:!1,category:"flags"},croatia:{keywords:["hr","flag","nation","country","banner"],char:"\ud83c\udded\ud83c\uddf7",fitzpatrick_scale:!1,category:"flags"},cuba:{keywords:["cu","flag","nation","country","banner"],char:"\ud83c\udde8\ud83c\uddfa",fitzpatrick_scale:!1,category:"flags"},curacao:{keywords:["cura\xe7ao","flag","nation","country","banner"],char:"\ud83c\udde8\ud83c\uddfc",fitzpatrick_scale:!1,category:"flags"},cyprus:{keywords:["cy","flag","nation","country","banner"],char:"\ud83c\udde8\ud83c\uddfe",fitzpatrick_scale:!1,category:"flags"},czech_republic:{keywords:["cz","flag","nation","country","banner"],char:"\ud83c\udde8\ud83c\uddff",fitzpatrick_scale:!1,category:"flags"},denmark:{keywords:["dk","flag","nation","country","banner"],char:"\ud83c\udde9\ud83c\uddf0",fitzpatrick_scale:!1,category:"flags"},djibouti:{keywords:["dj","flag","nation","country","banner"],char:"\ud83c\udde9\ud83c\uddef",fitzpatrick_scale:!1,category:"flags"},dominica:{keywords:["dm","flag","nation","country","banner"],char:"\ud83c\udde9\ud83c\uddf2",fitzpatrick_scale:!1,category:"flags"},dominican_republic:{keywords:["dominican","republic","flag","nation","country","banner"],char:"\ud83c\udde9\ud83c\uddf4",fitzpatrick_scale:!1,category:"flags"},ecuador:{keywords:["ec","flag","nation","country","banner"],char:"\ud83c\uddea\ud83c\udde8",fitzpatrick_scale:!1,category:"flags"},egypt:{keywords:["eg","flag","nation","country","banner"],char:"\ud83c\uddea\ud83c\uddec",fitzpatrick_scale:!1,category:"flags"},el_salvador:{keywords:["el","salvador","flag","nation","country","banner"],char:"\ud83c\uddf8\ud83c\uddfb",fitzpatrick_scale:!1,category:"flags"},equatorial_guinea:{keywords:["equatorial","gn","flag","nation","country","banner"],char:"\ud83c\uddec\ud83c\uddf6",fitzpatrick_scale:!1,category:"flags"},eritrea:{keywords:["er","flag","nation","country","banner"],char:"\ud83c\uddea\ud83c\uddf7",fitzpatrick_scale:!1,category:"flags"},estonia:{keywords:["ee","flag","nation","country","banner"],char:"\ud83c\uddea\ud83c\uddea",fitzpatrick_scale:!1,category:"flags"},ethiopia:{keywords:["et","flag","nation","country","banner"],char:"\ud83c\uddea\ud83c\uddf9",fitzpatrick_scale:!1,category:"flags"},eu:{keywords:["european","union","flag","banner"],char:"\ud83c\uddea\ud83c\uddfa",fitzpatrick_scale:!1,category:"flags"},falkland_islands:{keywords:["falkland","islands","malvinas","flag","nation","country","banner"],char:"\ud83c\uddeb\ud83c\uddf0",fitzpatrick_scale:!1,category:"flags"},faroe_islands:{keywords:["faroe","islands","flag","nation","country","banner"],char:"\ud83c\uddeb\ud83c\uddf4",fitzpatrick_scale:!1,category:"flags"},fiji:{keywords:["fj","flag","nation","country","banner"],char:"\ud83c\uddeb\ud83c\uddef",fitzpatrick_scale:!1,category:"flags"},finland:{keywords:["fi","flag","nation","country","banner"],char:"\ud83c\uddeb\ud83c\uddee",fitzpatrick_scale:!1,category:"flags"},fr:{keywords:["banner","flag","nation","france","french","country"],char:"\ud83c\uddeb\ud83c\uddf7",fitzpatrick_scale:!1,category:"flags"},french_guiana:{keywords:["french","guiana","flag","nation","country","banner"],char:"\ud83c\uddec\ud83c\uddeb",fitzpatrick_scale:!1,category:"flags"},french_polynesia:{keywords:["french","polynesia","flag","nation","country","banner"],char:"\ud83c\uddf5\ud83c\uddeb",fitzpatrick_scale:!1,category:"flags"},french_southern_territories:{keywords:["french","southern","territories","flag","nation","country","banner"],char:"\ud83c\uddf9\ud83c\uddeb",fitzpatrick_scale:!1,category:"flags"},gabon:{keywords:["ga","flag","nation","country","banner"],char:"\ud83c\uddec\ud83c\udde6",fitzpatrick_scale:!1,category:"flags"},gambia:{keywords:["gm","flag","nation","country","banner"],char:"\ud83c\uddec\ud83c\uddf2",fitzpatrick_scale:!1,category:"flags"},georgia:{keywords:["ge","flag","nation","country","banner"],char:"\ud83c\uddec\ud83c\uddea",fitzpatrick_scale:!1,category:"flags"},de:{keywords:["german","nation","flag","country","banner"],char:"\ud83c\udde9\ud83c\uddea",fitzpatrick_scale:!1,category:"flags"},ghana:{keywords:["gh","flag","nation","country","banner"],char:"\ud83c\uddec\ud83c\udded",fitzpatrick_scale:!1,category:"flags"},gibraltar:{keywords:["gi","flag","nation","country","banner"],char:"\ud83c\uddec\ud83c\uddee",fitzpatrick_scale:!1,category:"flags"},greece:{keywords:["gr","flag","nation","country","banner"],char:"\ud83c\uddec\ud83c\uddf7",fitzpatrick_scale:!1,category:"flags"},greenland:{keywords:["gl","flag","nation","country","banner"],char:"\ud83c\uddec\ud83c\uddf1",fitzpatrick_scale:!1,category:"flags"},grenada:{keywords:["gd","flag","nation","country","banner"],char:"\ud83c\uddec\ud83c\udde9",fitzpatrick_scale:!1,category:"flags"},guadeloupe:{keywords:["gp","flag","nation","country","banner"],char:"\ud83c\uddec\ud83c\uddf5",fitzpatrick_scale:!1,category:"flags"},guam:{keywords:["gu","flag","nation","country","banner"],char:"\ud83c\uddec\ud83c\uddfa",fitzpatrick_scale:!1,category:"flags"},guatemala:{keywords:["gt","flag","nation","country","banner"],char:"\ud83c\uddec\ud83c\uddf9",fitzpatrick_scale:!1,category:"flags"},guernsey:{keywords:["gg","flag","nation","country","banner"],char:"\ud83c\uddec\ud83c\uddec",fitzpatrick_scale:!1,category:"flags"},guinea:{keywords:["gn","flag","nation","country","banner"],char:"\ud83c\uddec\ud83c\uddf3",fitzpatrick_scale:!1,category:"flags"},guinea_bissau:{keywords:["gw","bissau","flag","nation","country","banner"],char:"\ud83c\uddec\ud83c\uddfc",fitzpatrick_scale:!1,category:"flags"},guyana:{keywords:["gy","flag","nation","country","banner"],char:"\ud83c\uddec\ud83c\uddfe",fitzpatrick_scale:!1,category:"flags"},haiti:{keywords:["ht","flag","nation","country","banner"],char:"\ud83c\udded\ud83c\uddf9",fitzpatrick_scale:!1,category:"flags"},honduras:{keywords:["hn","flag","nation","country","banner"],char:"\ud83c\udded\ud83c\uddf3",fitzpatrick_scale:!1,category:"flags"},hong_kong:{keywords:["hong","kong","flag","nation","country","banner"],char:"\ud83c\udded\ud83c\uddf0",fitzpatrick_scale:!1,category:"flags"},hungary:{keywords:["hu","flag","nation","country","banner"],char:"\ud83c\udded\ud83c\uddfa",fitzpatrick_scale:!1,category:"flags"},iceland:{keywords:["is","flag","nation","country","banner"],char:"\ud83c\uddee\ud83c\uddf8",fitzpatrick_scale:!1,category:"flags"},india:{keywords:["in","flag","nation","country","banner"],char:"\ud83c\uddee\ud83c\uddf3",fitzpatrick_scale:!1,category:"flags"},indonesia:{keywords:["flag","nation","country","banner"],char:"\ud83c\uddee\ud83c\udde9",fitzpatrick_scale:!1,category:"flags"},iran:{keywords:["iran,","islamic","republic","flag","nation","country","banner"],char:"\ud83c\uddee\ud83c\uddf7",fitzpatrick_scale:!1,category:"flags"},iraq:{keywords:["iq","flag","nation","country","banner"],char:"\ud83c\uddee\ud83c\uddf6",fitzpatrick_scale:!1,category:"flags"},ireland:{keywords:["ie","flag","nation","country","banner"],char:"\ud83c\uddee\ud83c\uddea",fitzpatrick_scale:!1,category:"flags"},isle_of_man:{keywords:["isle","man","flag","nation","country","banner"],char:"\ud83c\uddee\ud83c\uddf2",fitzpatrick_scale:!1,category:"flags"},israel:{keywords:["il","flag","nation","country","banner"],char:"\ud83c\uddee\ud83c\uddf1",fitzpatrick_scale:!1,category:"flags"},it:{keywords:["italy","flag","nation","country","banner"],char:"\ud83c\uddee\ud83c\uddf9",fitzpatrick_scale:!1,category:"flags"},cote_divoire:{keywords:["ivory","coast","flag","nation","country","banner"],char:"\ud83c\udde8\ud83c\uddee",fitzpatrick_scale:!1,category:"flags"},jamaica:{keywords:["jm","flag","nation","country","banner"],char:"\ud83c\uddef\ud83c\uddf2",fitzpatrick_scale:!1,category:"flags"},jp:{keywords:["japanese","nation","flag","country","banner"],char:"\ud83c\uddef\ud83c\uddf5",fitzpatrick_scale:!1,category:"flags"},jersey:{keywords:["je","flag","nation","country","banner"],char:"\ud83c\uddef\ud83c\uddea",fitzpatrick_scale:!1,category:"flags"},jordan:{keywords:["jo","flag","nation","country","banner"],char:"\ud83c\uddef\ud83c\uddf4",fitzpatrick_scale:!1,category:"flags"},kazakhstan:{keywords:["kz","flag","nation","country","banner"],char:"\ud83c\uddf0\ud83c\uddff",fitzpatrick_scale:!1,category:"flags"},kenya:{keywords:["ke","flag","nation","country","banner"],char:"\ud83c\uddf0\ud83c\uddea",fitzpatrick_scale:!1,category:"flags"},kiribati:{keywords:["ki","flag","nation","country","banner"],char:"\ud83c\uddf0\ud83c\uddee",fitzpatrick_scale:!1,category:"flags"},kosovo:{keywords:["xk","flag","nation","country","banner"],char:"\ud83c\uddfd\ud83c\uddf0",fitzpatrick_scale:!1,category:"flags"},kuwait:{keywords:["kw","flag","nation","country","banner"],char:"\ud83c\uddf0\ud83c\uddfc",fitzpatrick_scale:!1,category:"flags"},kyrgyzstan:{keywords:["kg","flag","nation","country","banner"],char:"\ud83c\uddf0\ud83c\uddec",fitzpatrick_scale:!1,category:"flags"},laos:{keywords:["lao","democratic","republic","flag","nation","country","banner"],char:"\ud83c\uddf1\ud83c\udde6",fitzpatrick_scale:!1,category:"flags"},latvia:{keywords:["lv","flag","nation","country","banner"],char:"\ud83c\uddf1\ud83c\uddfb",fitzpatrick_scale:!1,category:"flags"},lebanon:{keywords:["lb","flag","nation","country","banner"],char:"\ud83c\uddf1\ud83c\udde7",fitzpatrick_scale:!1,category:"flags"},lesotho:{keywords:["ls","flag","nation","country","banner"],char:"\ud83c\uddf1\ud83c\uddf8",fitzpatrick_scale:!1,category:"flags"},liberia:{keywords:["lr","flag","nation","country","banner"],char:"\ud83c\uddf1\ud83c\uddf7",fitzpatrick_scale:!1,category:"flags"},libya:{keywords:["ly","flag","nation","country","banner"],char:"\ud83c\uddf1\ud83c\uddfe",fitzpatrick_scale:!1,category:"flags"},liechtenstein:{keywords:["li","flag","nation","country","banner"],char:"\ud83c\uddf1\ud83c\uddee",fitzpatrick_scale:!1,category:"flags"},lithuania:{keywords:["lt","flag","nation","country","banner"],char:"\ud83c\uddf1\ud83c\uddf9",fitzpatrick_scale:!1,category:"flags"},luxembourg:{keywords:["lu","flag","nation","country","banner"],char:"\ud83c\uddf1\ud83c\uddfa",fitzpatrick_scale:!1,category:"flags"},macau:{keywords:["macao","flag","nation","country","banner"],char:"\ud83c\uddf2\ud83c\uddf4",fitzpatrick_scale:!1,category:"flags"},macedonia:{keywords:["macedonia,","flag","nation","country","banner"],char:"\ud83c\uddf2\ud83c\uddf0",fitzpatrick_scale:!1,category:"flags"},madagascar:{keywords:["mg","flag","nation","country","banner"],char:"\ud83c\uddf2\ud83c\uddec",fitzpatrick_scale:!1,category:"flags"},malawi:{keywords:["mw","flag","nation","country","banner"],char:"\ud83c\uddf2\ud83c\uddfc",fitzpatrick_scale:!1,category:"flags"},malaysia:{keywords:["my","flag","nation","country","banner"],char:"\ud83c\uddf2\ud83c\uddfe",fitzpatrick_scale:!1,category:"flags"},maldives:{keywords:["mv","flag","nation","country","banner"],char:"\ud83c\uddf2\ud83c\uddfb",fitzpatrick_scale:!1,category:"flags"},mali:{keywords:["ml","flag","nation","country","banner"],char:"\ud83c\uddf2\ud83c\uddf1",fitzpatrick_scale:!1,category:"flags"},malta:{keywords:["mt","flag","nation","country","banner"],char:"\ud83c\uddf2\ud83c\uddf9",fitzpatrick_scale:!1,category:"flags"},marshall_islands:{keywords:["marshall","islands","flag","nation","country","banner"],char:"\ud83c\uddf2\ud83c\udded",fitzpatrick_scale:!1,category:"flags"},martinique:{keywords:["mq","flag","nation","country","banner"],char:"\ud83c\uddf2\ud83c\uddf6",fitzpatrick_scale:!1,category:"flags"},mauritania:{keywords:["mr","flag","nation","country","banner"],char:"\ud83c\uddf2\ud83c\uddf7",fitzpatrick_scale:!1,category:"flags"},mauritius:{keywords:["mu","flag","nation","country","banner"],char:"\ud83c\uddf2\ud83c\uddfa",fitzpatrick_scale:!1,category:"flags"},mayotte:{keywords:["yt","flag","nation","country","banner"],char:"\ud83c\uddfe\ud83c\uddf9",fitzpatrick_scale:!1,category:"flags"},mexico:{keywords:["mx","flag","nation","country","banner"],char:"\ud83c\uddf2\ud83c\uddfd",fitzpatrick_scale:!1,category:"flags"},micronesia:{keywords:["micronesia,","federated","states","flag","nation","country","banner"],char:"\ud83c\uddeb\ud83c\uddf2",fitzpatrick_scale:!1,category:"flags"},moldova:{keywords:["moldova,","republic","flag","nation","country","banner"],char:"\ud83c\uddf2\ud83c\udde9",fitzpatrick_scale:!1,category:"flags"},monaco:{keywords:["mc","flag","nation","country","banner"],char:"\ud83c\uddf2\ud83c\udde8",fitzpatrick_scale:!1,category:"flags"},mongolia:{keywords:["mn","flag","nation","country","banner"],char:"\ud83c\uddf2\ud83c\uddf3",fitzpatrick_scale:!1,category:"flags"},montenegro:{keywords:["me","flag","nation","country","banner"],char:"\ud83c\uddf2\ud83c\uddea",fitzpatrick_scale:!1,category:"flags"},montserrat:{keywords:["ms","flag","nation","country","banner"],char:"\ud83c\uddf2\ud83c\uddf8",fitzpatrick_scale:!1,category:"flags"},morocco:{keywords:["ma","flag","nation","country","banner"],char:"\ud83c\uddf2\ud83c\udde6",fitzpatrick_scale:!1,category:"flags"},mozambique:{keywords:["mz","flag","nation","country","banner"],char:"\ud83c\uddf2\ud83c\uddff",fitzpatrick_scale:!1,category:"flags"},myanmar:{keywords:["mm","flag","nation","country","banner"],char:"\ud83c\uddf2\ud83c\uddf2",fitzpatrick_scale:!1,category:"flags"},namibia:{keywords:["na","flag","nation","country","banner"],char:"\ud83c\uddf3\ud83c\udde6",fitzpatrick_scale:!1,category:"flags"},nauru:{keywords:["nr","flag","nation","country","banner"],char:"\ud83c\uddf3\ud83c\uddf7",fitzpatrick_scale:!1,category:"flags"},nepal:{keywords:["np","flag","nation","country","banner"],char:"\ud83c\uddf3\ud83c\uddf5",fitzpatrick_scale:!1,category:"flags"},netherlands:{keywords:["nl","flag","nation","country","banner"],char:"\ud83c\uddf3\ud83c\uddf1",fitzpatrick_scale:!1,category:"flags"},new_caledonia:{keywords:["new","caledonia","flag","nation","country","banner"],char:"\ud83c\uddf3\ud83c\udde8",fitzpatrick_scale:!1,category:"flags"},new_zealand:{keywords:["new","zealand","flag","nation","country","banner"],char:"\ud83c\uddf3\ud83c\uddff",fitzpatrick_scale:!1,category:"flags"},nicaragua:{keywords:["ni","flag","nation","country","banner"],char:"\ud83c\uddf3\ud83c\uddee",fitzpatrick_scale:!1,category:"flags"},niger:{keywords:["ne","flag","nation","country","banner"],char:"\ud83c\uddf3\ud83c\uddea",fitzpatrick_scale:!1,category:"flags"},nigeria:{keywords:["flag","nation","country","banner"],char:"\ud83c\uddf3\ud83c\uddec",fitzpatrick_scale:!1,category:"flags"},niue:{keywords:["nu","flag","nation","country","banner"],char:"\ud83c\uddf3\ud83c\uddfa",fitzpatrick_scale:!1,category:"flags"},norfolk_island:{keywords:["norfolk","island","flag","nation","country","banner"],char:"\ud83c\uddf3\ud83c\uddeb",fitzpatrick_scale:!1,category:"flags"},northern_mariana_islands:{keywords:["northern","mariana","islands","flag","nation","country","banner"],char:"\ud83c\uddf2\ud83c\uddf5",fitzpatrick_scale:!1,category:"flags"},north_korea:{keywords:["north","korea","nation","flag","country","banner"],char:"\ud83c\uddf0\ud83c\uddf5",fitzpatrick_scale:!1,category:"flags"},norway:{keywords:["no","flag","nation","country","banner"],char:"\ud83c\uddf3\ud83c\uddf4",fitzpatrick_scale:!1,category:"flags"},oman:{keywords:["om_symbol","flag","nation","country","banner"],char:"\ud83c\uddf4\ud83c\uddf2",fitzpatrick_scale:!1,category:"flags"},pakistan:{keywords:["pk","flag","nation","country","banner"],char:"\ud83c\uddf5\ud83c\uddf0",fitzpatrick_scale:!1,category:"flags"},palau:{keywords:["pw","flag","nation","country","banner"],char:"\ud83c\uddf5\ud83c\uddfc",fitzpatrick_scale:!1,category:"flags"},palestinian_territories:{keywords:["palestine","palestinian","territories","flag","nation","country","banner"],char:"\ud83c\uddf5\ud83c\uddf8",fitzpatrick_scale:!1,category:"flags"},panama:{keywords:["pa","flag","nation","country","banner"],char:"\ud83c\uddf5\ud83c\udde6",fitzpatrick_scale:!1,category:"flags"},papua_new_guinea:{keywords:["papua","new","guinea","flag","nation","country","banner"],char:"\ud83c\uddf5\ud83c\uddec",fitzpatrick_scale:!1,category:"flags"},paraguay:{keywords:["py","flag","nation","country","banner"],char:"\ud83c\uddf5\ud83c\uddfe",fitzpatrick_scale:!1,category:"flags"},peru:{keywords:["pe","flag","nation","country","banner"],char:"\ud83c\uddf5\ud83c\uddea",fitzpatrick_scale:!1,category:"flags"},philippines:{keywords:["ph","flag","nation","country","banner"],char:"\ud83c\uddf5\ud83c\udded",fitzpatrick_scale:!1,category:"flags"},pitcairn_islands:{keywords:["pitcairn","flag","nation","country","banner"],char:"\ud83c\uddf5\ud83c\uddf3",fitzpatrick_scale:!1,category:"flags"},poland:{keywords:["pl","flag","nation","country","banner"],char:"\ud83c\uddf5\ud83c\uddf1",fitzpatrick_scale:!1,category:"flags"},portugal:{keywords:["pt","flag","nation","country","banner"],char:"\ud83c\uddf5\ud83c\uddf9",fitzpatrick_scale:!1,category:"flags"},puerto_rico:{keywords:["puerto","rico","flag","nation","country","banner"],char:"\ud83c\uddf5\ud83c\uddf7",fitzpatrick_scale:!1,category:"flags"},qatar:{keywords:["qa","flag","nation","country","banner"],char:"\ud83c\uddf6\ud83c\udde6",fitzpatrick_scale:!1,category:"flags"},reunion:{keywords:["r\xe9union","flag","nation","country","banner"],char:"\ud83c\uddf7\ud83c\uddea",fitzpatrick_scale:!1,category:"flags"},romania:{keywords:["ro","flag","nation","country","banner"],char:"\ud83c\uddf7\ud83c\uddf4",fitzpatrick_scale:!1,category:"flags"},ru:{keywords:["russian","federation","flag","nation","country","banner"],char:"\ud83c\uddf7\ud83c\uddfa",fitzpatrick_scale:!1,category:"flags"},rwanda:{keywords:["rw","flag","nation","country","banner"],char:"\ud83c\uddf7\ud83c\uddfc",fitzpatrick_scale:!1,category:"flags"},st_barthelemy:{keywords:["saint","barth\xe9lemy","flag","nation","country","banner"],char:"\ud83c\udde7\ud83c\uddf1",fitzpatrick_scale:!1,category:"flags"},st_helena:{keywords:["saint","helena","ascension","tristan","cunha","flag","nation","country","banner"],char:"\ud83c\uddf8\ud83c\udded",fitzpatrick_scale:!1,category:"flags"},st_kitts_nevis:{keywords:["saint","kitts","nevis","flag","nation","country","banner"],char:"\ud83c\uddf0\ud83c\uddf3",fitzpatrick_scale:!1,category:"flags"},st_lucia:{keywords:["saint","lucia","flag","nation","country","banner"],char:"\ud83c\uddf1\ud83c\udde8",fitzpatrick_scale:!1,category:"flags"},st_pierre_miquelon:{keywords:["saint","pierre","miquelon","flag","nation","country","banner"],char:"\ud83c\uddf5\ud83c\uddf2",fitzpatrick_scale:!1,category:"flags"},st_vincent_grenadines:{keywords:["saint","vincent","grenadines","flag","nation","country","banner"],char:"\ud83c\uddfb\ud83c\udde8",fitzpatrick_scale:!1,category:"flags"},samoa:{keywords:["ws","flag","nation","country","banner"],char:"\ud83c\uddfc\ud83c\uddf8",fitzpatrick_scale:!1,category:"flags"},san_marino:{keywords:["san","marino","flag","nation","country","banner"],char:"\ud83c\uddf8\ud83c\uddf2",fitzpatrick_scale:!1,category:"flags"},sao_tome_principe:{keywords:["sao","tome","principe","flag","nation","country","banner"],char:"\ud83c\uddf8\ud83c\uddf9",fitzpatrick_scale:!1,category:"flags"},saudi_arabia:{keywords:["flag","nation","country","banner"],char:"\ud83c\uddf8\ud83c\udde6",fitzpatrick_scale:!1,category:"flags"},senegal:{keywords:["sn","flag","nation","country","banner"],char:"\ud83c\uddf8\ud83c\uddf3",fitzpatrick_scale:!1,category:"flags"},serbia:{keywords:["rs","flag","nation","country","banner"],char:"\ud83c\uddf7\ud83c\uddf8",fitzpatrick_scale:!1,category:"flags"},seychelles:{keywords:["sc","flag","nation","country","banner"],char:"\ud83c\uddf8\ud83c\udde8",fitzpatrick_scale:!1,category:"flags"},sierra_leone:{keywords:["sierra","leone","flag","nation","country","banner"],char:"\ud83c\uddf8\ud83c\uddf1",fitzpatrick_scale:!1,category:"flags"},singapore:{keywords:["sg","flag","nation","country","banner"],char:"\ud83c\uddf8\ud83c\uddec",fitzpatrick_scale:!1,category:"flags"},sint_maarten:{keywords:["sint","maarten","dutch","flag","nation","country","banner"],char:"\ud83c\uddf8\ud83c\uddfd",fitzpatrick_scale:!1,category:"flags"},slovakia:{keywords:["sk","flag","nation","country","banner"],char:"\ud83c\uddf8\ud83c\uddf0",fitzpatrick_scale:!1,category:"flags"},slovenia:{keywords:["si","flag","nation","country","banner"],char:"\ud83c\uddf8\ud83c\uddee",fitzpatrick_scale:!1,category:"flags"},solomon_islands:{keywords:["solomon","islands","flag","nation","country","banner"],char:"\ud83c\uddf8\ud83c\udde7",fitzpatrick_scale:!1,category:"flags"},somalia:{keywords:["so","flag","nation","country","banner"],char:"\ud83c\uddf8\ud83c\uddf4",fitzpatrick_scale:!1,category:"flags"},south_africa:{keywords:["south","africa","flag","nation","country","banner"],char:"\ud83c\uddff\ud83c\udde6",fitzpatrick_scale:!1,category:"flags"},south_georgia_south_sandwich_islands:{keywords:["south","georgia","sandwich","islands","flag","nation","country","banner"],char:"\ud83c\uddec\ud83c\uddf8",fitzpatrick_scale:!1,category:"flags"},kr:{keywords:["south","korea","nation","flag","country","banner"],char:"\ud83c\uddf0\ud83c\uddf7",fitzpatrick_scale:!1,category:"flags"},south_sudan:{keywords:["south","sd","flag","nation","country","banner"],char:"\ud83c\uddf8\ud83c\uddf8",fitzpatrick_scale:!1,category:"flags"},es:{keywords:["spain","flag","nation","country","banner"],char:"\ud83c\uddea\ud83c\uddf8",fitzpatrick_scale:!1,category:"flags"},sri_lanka:{keywords:["sri","lanka","flag","nation","country","banner"],char:"\ud83c\uddf1\ud83c\uddf0",fitzpatrick_scale:!1,category:"flags"},sudan:{keywords:["sd","flag","nation","country","banner"],char:"\ud83c\uddf8\ud83c\udde9",fitzpatrick_scale:!1,category:"flags"},suriname:{keywords:["sr","flag","nation","country","banner"],char:"\ud83c\uddf8\ud83c\uddf7",fitzpatrick_scale:!1,category:"flags"},swaziland:{keywords:["sz","flag","nation","country","banner"],char:"\ud83c\uddf8\ud83c\uddff",fitzpatrick_scale:!1,category:"flags"},sweden:{keywords:["se","flag","nation","country","banner"],char:"\ud83c\uddf8\ud83c\uddea",fitzpatrick_scale:!1,category:"flags"},switzerland:{keywords:["ch","flag","nation","country","banner"],char:"\ud83c\udde8\ud83c\udded",fitzpatrick_scale:!1,category:"flags"},syria:{keywords:["syrian","arab","republic","flag","nation","country","banner"],char:"\ud83c\uddf8\ud83c\uddfe",fitzpatrick_scale:!1,category:"flags"},taiwan:{keywords:["tw","flag","nation","country","banner"],char:"\ud83c\uddf9\ud83c\uddfc",fitzpatrick_scale:!1,category:"flags"},tajikistan:{keywords:["tj","flag","nation","country","banner"],char:"\ud83c\uddf9\ud83c\uddef",fitzpatrick_scale:!1,category:"flags"},tanzania:{keywords:["tanzania,","united","republic","flag","nation","country","banner"],char:"\ud83c\uddf9\ud83c\uddff",fitzpatrick_scale:!1,category:"flags"},thailand:{keywords:["th","flag","nation","country","banner"],char:"\ud83c\uddf9\ud83c\udded",fitzpatrick_scale:!1,category:"flags"},timor_leste:{keywords:["timor","leste","flag","nation","country","banner"],char:"\ud83c\uddf9\ud83c\uddf1",fitzpatrick_scale:!1,category:"flags"},togo:{keywords:["tg","flag","nation","country","banner"],char:"\ud83c\uddf9\ud83c\uddec",fitzpatrick_scale:!1,category:"flags"},tokelau:{keywords:["tk","flag","nation","country","banner"],char:"\ud83c\uddf9\ud83c\uddf0",fitzpatrick_scale:!1,category:"flags"},tonga:{keywords:["to","flag","nation","country","banner"],char:"\ud83c\uddf9\ud83c\uddf4",fitzpatrick_scale:!1,category:"flags"},trinidad_tobago:{keywords:["trinidad","tobago","flag","nation","country","banner"],char:"\ud83c\uddf9\ud83c\uddf9",fitzpatrick_scale:!1,category:"flags"},tunisia:{keywords:["tn","flag","nation","country","banner"],char:"\ud83c\uddf9\ud83c\uddf3",fitzpatrick_scale:!1,category:"flags"},tr:{keywords:["turkey","flag","nation","country","banner"],char:"\ud83c\uddf9\ud83c\uddf7",fitzpatrick_scale:!1,category:"flags"},turkmenistan:{keywords:["flag","nation","country","banner"],char:"\ud83c\uddf9\ud83c\uddf2",fitzpatrick_scale:!1,category:"flags"},turks_caicos_islands:{keywords:["turks","caicos","islands","flag","nation","country","banner"],char:"\ud83c\uddf9\ud83c\udde8",fitzpatrick_scale:!1,category:"flags"},tuvalu:{keywords:["flag","nation","country","banner"],char:"\ud83c\uddf9\ud83c\uddfb",fitzpatrick_scale:!1,category:"flags"},uganda:{keywords:["ug","flag","nation","country","banner"],char:"\ud83c\uddfa\ud83c\uddec",fitzpatrick_scale:!1,category:"flags"},ukraine:{keywords:["ua","flag","nation","country","banner"],char:"\ud83c\uddfa\ud83c\udde6",fitzpatrick_scale:!1,category:"flags"},united_arab_emirates:{keywords:["united","arab","emirates","flag","nation","country","banner"],char:"\ud83c\udde6\ud83c\uddea",fitzpatrick_scale:!1,category:"flags"},uk:{keywords:["united","kingdom","great","britain","northern","ireland","flag","nation","country","banner","british","UK","english","england","union jack"],char:"\ud83c\uddec\ud83c\udde7",fitzpatrick_scale:!1,category:"flags"},england:{keywords:["flag","english"],char:"\ud83c\udff4\udb40\udc67\udb40\udc62\udb40\udc65\udb40\udc6e\udb40\udc67\udb40\udc7f",fitzpatrick_scale:!1,category:"flags"},scotland:{keywords:["flag","scottish"],char:"\ud83c\udff4\udb40\udc67\udb40\udc62\udb40\udc73\udb40\udc63\udb40\udc74\udb40\udc7f",fitzpatrick_scale:!1,category:"flags"},wales:{keywords:["flag","welsh"],char:"\ud83c\udff4\udb40\udc67\udb40\udc62\udb40\udc77\udb40\udc6c\udb40\udc73\udb40\udc7f",fitzpatrick_scale:!1,category:"flags"},us:{keywords:["united","states","america","flag","nation","country","banner"],char:"\ud83c\uddfa\ud83c\uddf8",fitzpatrick_scale:!1,category:"flags"},us_virgin_islands:{keywords:["virgin","islands","us","flag","nation","country","banner"],char:"\ud83c\uddfb\ud83c\uddee",fitzpatrick_scale:!1,category:"flags"},uruguay:{keywords:["uy","flag","nation","country","banner"],char:"\ud83c\uddfa\ud83c\uddfe",fitzpatrick_scale:!1,category:"flags"},uzbekistan:{keywords:["uz","flag","nation","country","banner"],char:"\ud83c\uddfa\ud83c\uddff",fitzpatrick_scale:!1,category:"flags"},vanuatu:{keywords:["vu","flag","nation","country","banner"],char:"\ud83c\uddfb\ud83c\uddfa",fitzpatrick_scale:!1,category:"flags"},vatican_city:{keywords:["vatican","city","flag","nation","country","banner"],char:"\ud83c\uddfb\ud83c\udde6",fitzpatrick_scale:!1,category:"flags"},venezuela:{keywords:["ve","bolivarian","republic","flag","nation","country","banner"],char:"\ud83c\uddfb\ud83c\uddea",fitzpatrick_scale:!1,category:"flags"},vietnam:{keywords:["viet","nam","flag","nation","country","banner"],char:"\ud83c\uddfb\ud83c\uddf3",fitzpatrick_scale:!1,category:"flags"},wallis_futuna:{keywords:["wallis","futuna","flag","nation","country","banner"],char:"\ud83c\uddfc\ud83c\uddeb",fitzpatrick_scale:!1,category:"flags"},western_sahara:{keywords:["western","sahara","flag","nation","country","banner"],char:"\ud83c\uddea\ud83c\udded",fitzpatrick_scale:!1,category:"flags"},yemen:{keywords:["ye","flag","nation","country","banner"],char:"\ud83c\uddfe\ud83c\uddea",fitzpatrick_scale:!1,category:"flags"},zambia:{keywords:["zm","flag","nation","country","banner"],char:"\ud83c\uddff\ud83c\uddf2",fitzpatrick_scale:!1,category:"flags"},zimbabwe:{keywords:["zw","flag","nation","country","banner"],char:"\ud83c\uddff\ud83c\uddfc",fitzpatrick_scale:!1,category:"flags"},united_nations:{keywords:["un","flag","banner"],char:"\ud83c\uddfa\ud83c\uddf3",fitzpatrick_scale:!1,category:"flags"},pirate_flag:{keywords:["skull","crossbones","flag","banner"],char:"\ud83c\udff4\u200d\u2620\ufe0f",fitzpatrick_scale:!1,category:"flags"}}); \ No newline at end of file diff --git a/website/admin/tinymce/plugins/emoticons/js/emojis.min.js b/website/admin/tinymce/plugins/emoticons/js/emojis.min.js new file mode 100644 index 0000000..fd14058 --- /dev/null +++ b/website/admin/tinymce/plugins/emoticons/js/emojis.min.js @@ -0,0 +1 @@ +window.tinymce.Resource.add("tinymce.plugins.emoticons",{grinning:{keywords:["face","smile","happy","joy",":D","grin"],char:"\ud83d\ude00",fitzpatrick_scale:!1,category:"people"},grimacing:{keywords:["face","grimace","teeth"],char:"\ud83d\ude2c",fitzpatrick_scale:!1,category:"people"},grin:{keywords:["face","happy","smile","joy","kawaii"],char:"\ud83d\ude01",fitzpatrick_scale:!1,category:"people"},joy:{keywords:["face","cry","tears","weep","happy","happytears","haha"],char:"\ud83d\ude02",fitzpatrick_scale:!1,category:"people"},rofl:{keywords:["face","rolling","floor","laughing","lol","haha"],char:"\ud83e\udd23",fitzpatrick_scale:!1,category:"people"},partying:{keywords:["face","celebration","woohoo"],char:"\ud83e\udd73",fitzpatrick_scale:!1,category:"people"},smiley:{keywords:["face","happy","joy","haha",":D",":)","smile","funny"],char:"\ud83d\ude03",fitzpatrick_scale:!1,category:"people"},smile:{keywords:["face","happy","joy","funny","haha","laugh","like",":D",":)"],char:"\ud83d\ude04",fitzpatrick_scale:!1,category:"people"},sweat_smile:{keywords:["face","hot","happy","laugh","sweat","smile","relief"],char:"\ud83d\ude05",fitzpatrick_scale:!1,category:"people"},laughing:{keywords:["happy","joy","lol","satisfied","haha","face","glad","XD","laugh"],char:"\ud83d\ude06",fitzpatrick_scale:!1,category:"people"},innocent:{keywords:["face","angel","heaven","halo"],char:"\ud83d\ude07",fitzpatrick_scale:!1,category:"people"},wink:{keywords:["face","happy","mischievous","secret",";)","smile","eye"],char:"\ud83d\ude09",fitzpatrick_scale:!1,category:"people"},blush:{keywords:["face","smile","happy","flushed","crush","embarrassed","shy","joy"],char:"\ud83d\ude0a",fitzpatrick_scale:!1,category:"people"},slightly_smiling_face:{keywords:["face","smile"],char:"\ud83d\ude42",fitzpatrick_scale:!1,category:"people"},upside_down_face:{keywords:["face","flipped","silly","smile"],char:"\ud83d\ude43",fitzpatrick_scale:!1,category:"people"},relaxed:{keywords:["face","blush","massage","happiness"],char:"\u263a\ufe0f",fitzpatrick_scale:!1,category:"people"},yum:{keywords:["happy","joy","tongue","smile","face","silly","yummy","nom","delicious","savouring"],char:"\ud83d\ude0b",fitzpatrick_scale:!1,category:"people"},relieved:{keywords:["face","relaxed","phew","massage","happiness"],char:"\ud83d\ude0c",fitzpatrick_scale:!1,category:"people"},heart_eyes:{keywords:["face","love","like","affection","valentines","infatuation","crush","heart"],char:"\ud83d\ude0d",fitzpatrick_scale:!1,category:"people"},smiling_face_with_three_hearts:{keywords:["face","love","like","affection","valentines","infatuation","crush","hearts","adore"],char:"\ud83e\udd70",fitzpatrick_scale:!1,category:"people"},kissing_heart:{keywords:["face","love","like","affection","valentines","infatuation","kiss"],char:"\ud83d\ude18",fitzpatrick_scale:!1,category:"people"},kissing:{keywords:["love","like","face","3","valentines","infatuation","kiss"],char:"\ud83d\ude17",fitzpatrick_scale:!1,category:"people"},kissing_smiling_eyes:{keywords:["face","affection","valentines","infatuation","kiss"],char:"\ud83d\ude19",fitzpatrick_scale:!1,category:"people"},kissing_closed_eyes:{keywords:["face","love","like","affection","valentines","infatuation","kiss"],char:"\ud83d\ude1a",fitzpatrick_scale:!1,category:"people"},stuck_out_tongue_winking_eye:{keywords:["face","prank","childish","playful","mischievous","smile","wink","tongue"],char:"\ud83d\ude1c",fitzpatrick_scale:!1,category:"people"},zany:{keywords:["face","goofy","crazy"],char:"\ud83e\udd2a",fitzpatrick_scale:!1,category:"people"},raised_eyebrow:{keywords:["face","distrust","scepticism","disapproval","disbelief","surprise"],char:"\ud83e\udd28",fitzpatrick_scale:!1,category:"people"},monocle:{keywords:["face","stuffy","wealthy"],char:"\ud83e\uddd0",fitzpatrick_scale:!1,category:"people"},stuck_out_tongue_closed_eyes:{keywords:["face","prank","playful","mischievous","smile","tongue"],char:"\ud83d\ude1d",fitzpatrick_scale:!1,category:"people"},stuck_out_tongue:{keywords:["face","prank","childish","playful","mischievous","smile","tongue"],char:"\ud83d\ude1b",fitzpatrick_scale:!1,category:"people"},money_mouth_face:{keywords:["face","rich","dollar","money"],char:"\ud83e\udd11",fitzpatrick_scale:!1,category:"people"},nerd_face:{keywords:["face","nerdy","geek","dork"],char:"\ud83e\udd13",fitzpatrick_scale:!1,category:"people"},sunglasses:{keywords:["face","cool","smile","summer","beach","sunglass"],char:"\ud83d\ude0e",fitzpatrick_scale:!1,category:"people"},star_struck:{keywords:["face","smile","starry","eyes","grinning"],char:"\ud83e\udd29",fitzpatrick_scale:!1,category:"people"},clown_face:{keywords:["face"],char:"\ud83e\udd21",fitzpatrick_scale:!1,category:"people"},cowboy_hat_face:{keywords:["face","cowgirl","hat"],char:"\ud83e\udd20",fitzpatrick_scale:!1,category:"people"},hugs:{keywords:["face","smile","hug"],char:"\ud83e\udd17",fitzpatrick_scale:!1,category:"people"},smirk:{keywords:["face","smile","mean","prank","smug","sarcasm"],char:"\ud83d\ude0f",fitzpatrick_scale:!1,category:"people"},no_mouth:{keywords:["face","hellokitty"],char:"\ud83d\ude36",fitzpatrick_scale:!1,category:"people"},neutral_face:{keywords:["indifference","meh",":|","neutral"],char:"\ud83d\ude10",fitzpatrick_scale:!1,category:"people"},expressionless:{keywords:["face","indifferent","-_-","meh","deadpan"],char:"\ud83d\ude11",fitzpatrick_scale:!1,category:"people"},unamused:{keywords:["indifference","bored","straight face","serious","sarcasm","unimpressed","skeptical","dubious","side_eye"],char:"\ud83d\ude12",fitzpatrick_scale:!1,category:"people"},roll_eyes:{keywords:["face","eyeroll","frustrated"],char:"\ud83d\ude44",fitzpatrick_scale:!1,category:"people"},thinking:{keywords:["face","hmmm","think","consider"],char:"\ud83e\udd14",fitzpatrick_scale:!1,category:"people"},lying_face:{keywords:["face","lie","pinocchio"],char:"\ud83e\udd25",fitzpatrick_scale:!1,category:"people"},hand_over_mouth:{keywords:["face","whoops","shock","surprise"],char:"\ud83e\udd2d",fitzpatrick_scale:!1,category:"people"},shushing:{keywords:["face","quiet","shhh"],char:"\ud83e\udd2b",fitzpatrick_scale:!1,category:"people"},symbols_over_mouth:{keywords:["face","swearing","cursing","cussing","profanity","expletive"],char:"\ud83e\udd2c",fitzpatrick_scale:!1,category:"people"},exploding_head:{keywords:["face","shocked","mind","blown"],char:"\ud83e\udd2f",fitzpatrick_scale:!1,category:"people"},flushed:{keywords:["face","blush","shy","flattered"],char:"\ud83d\ude33",fitzpatrick_scale:!1,category:"people"},disappointed:{keywords:["face","sad","upset","depressed",":("],char:"\ud83d\ude1e",fitzpatrick_scale:!1,category:"people"},worried:{keywords:["face","concern","nervous",":("],char:"\ud83d\ude1f",fitzpatrick_scale:!1,category:"people"},angry:{keywords:["mad","face","annoyed","frustrated"],char:"\ud83d\ude20",fitzpatrick_scale:!1,category:"people"},rage:{keywords:["angry","mad","hate","despise"],char:"\ud83d\ude21",fitzpatrick_scale:!1,category:"people"},pensive:{keywords:["face","sad","depressed","upset"],char:"\ud83d\ude14",fitzpatrick_scale:!1,category:"people"},confused:{keywords:["face","indifference","huh","weird","hmmm",":/"],char:"\ud83d\ude15",fitzpatrick_scale:!1,category:"people"},slightly_frowning_face:{keywords:["face","frowning","disappointed","sad","upset"],char:"\ud83d\ude41",fitzpatrick_scale:!1,category:"people"},frowning_face:{keywords:["face","sad","upset","frown"],char:"\u2639",fitzpatrick_scale:!1,category:"people"},persevere:{keywords:["face","sick","no","upset","oops"],char:"\ud83d\ude23",fitzpatrick_scale:!1,category:"people"},confounded:{keywords:["face","confused","sick","unwell","oops",":S"],char:"\ud83d\ude16",fitzpatrick_scale:!1,category:"people"},tired_face:{keywords:["sick","whine","upset","frustrated"],char:"\ud83d\ude2b",fitzpatrick_scale:!1,category:"people"},weary:{keywords:["face","tired","sleepy","sad","frustrated","upset"],char:"\ud83d\ude29",fitzpatrick_scale:!1,category:"people"},pleading:{keywords:["face","begging","mercy"],char:"\ud83e\udd7a",fitzpatrick_scale:!1,category:"people"},triumph:{keywords:["face","gas","phew","proud","pride"],char:"\ud83d\ude24",fitzpatrick_scale:!1,category:"people"},open_mouth:{keywords:["face","surprise","impressed","wow","whoa",":O"],char:"\ud83d\ude2e",fitzpatrick_scale:!1,category:"people"},scream:{keywords:["face","munch","scared","omg"],char:"\ud83d\ude31",fitzpatrick_scale:!1,category:"people"},fearful:{keywords:["face","scared","terrified","nervous","oops","huh"],char:"\ud83d\ude28",fitzpatrick_scale:!1,category:"people"},cold_sweat:{keywords:["face","nervous","sweat"],char:"\ud83d\ude30",fitzpatrick_scale:!1,category:"people"},hushed:{keywords:["face","woo","shh"],char:"\ud83d\ude2f",fitzpatrick_scale:!1,category:"people"},frowning:{keywords:["face","aw","what"],char:"\ud83d\ude26",fitzpatrick_scale:!1,category:"people"},anguished:{keywords:["face","stunned","nervous"],char:"\ud83d\ude27",fitzpatrick_scale:!1,category:"people"},cry:{keywords:["face","tears","sad","depressed","upset",":'("],char:"\ud83d\ude22",fitzpatrick_scale:!1,category:"people"},disappointed_relieved:{keywords:["face","phew","sweat","nervous"],char:"\ud83d\ude25",fitzpatrick_scale:!1,category:"people"},drooling_face:{keywords:["face"],char:"\ud83e\udd24",fitzpatrick_scale:!1,category:"people"},sleepy:{keywords:["face","tired","rest","nap"],char:"\ud83d\ude2a",fitzpatrick_scale:!1,category:"people"},sweat:{keywords:["face","hot","sad","tired","exercise"],char:"\ud83d\ude13",fitzpatrick_scale:!1,category:"people"},hot:{keywords:["face","feverish","heat","red","sweating"],char:"\ud83e\udd75",fitzpatrick_scale:!1,category:"people"},cold:{keywords:["face","blue","freezing","frozen","frostbite","icicles"],char:"\ud83e\udd76",fitzpatrick_scale:!1,category:"people"},sob:{keywords:["face","cry","tears","sad","upset","depressed"],char:"\ud83d\ude2d",fitzpatrick_scale:!1,category:"people"},dizzy_face:{keywords:["spent","unconscious","xox","dizzy"],char:"\ud83d\ude35",fitzpatrick_scale:!1,category:"people"},astonished:{keywords:["face","xox","surprised","poisoned"],char:"\ud83d\ude32",fitzpatrick_scale:!1,category:"people"},zipper_mouth_face:{keywords:["face","sealed","zipper","secret"],char:"\ud83e\udd10",fitzpatrick_scale:!1,category:"people"},nauseated_face:{keywords:["face","vomit","gross","green","sick","throw up","ill"],char:"\ud83e\udd22",fitzpatrick_scale:!1,category:"people"},sneezing_face:{keywords:["face","gesundheit","sneeze","sick","allergy"],char:"\ud83e\udd27",fitzpatrick_scale:!1,category:"people"},vomiting:{keywords:["face","sick"],char:"\ud83e\udd2e",fitzpatrick_scale:!1,category:"people"},mask:{keywords:["face","sick","ill","disease"],char:"\ud83d\ude37",fitzpatrick_scale:!1,category:"people"},face_with_thermometer:{keywords:["sick","temperature","thermometer","cold","fever"],char:"\ud83e\udd12",fitzpatrick_scale:!1,category:"people"},face_with_head_bandage:{keywords:["injured","clumsy","bandage","hurt"],char:"\ud83e\udd15",fitzpatrick_scale:!1,category:"people"},woozy:{keywords:["face","dizzy","intoxicated","tipsy","wavy"],char:"\ud83e\udd74",fitzpatrick_scale:!1,category:"people"},sleeping:{keywords:["face","tired","sleepy","night","zzz"],char:"\ud83d\ude34",fitzpatrick_scale:!1,category:"people"},zzz:{keywords:["sleepy","tired","dream"],char:"\ud83d\udca4",fitzpatrick_scale:!1,category:"people"},poop:{keywords:["hankey","shitface","fail","turd","shit"],char:"\ud83d\udca9",fitzpatrick_scale:!1,category:"people"},smiling_imp:{keywords:["devil","horns"],char:"\ud83d\ude08",fitzpatrick_scale:!1,category:"people"},imp:{keywords:["devil","angry","horns"],char:"\ud83d\udc7f",fitzpatrick_scale:!1,category:"people"},japanese_ogre:{keywords:["monster","red","mask","halloween","scary","creepy","devil","demon","japanese","ogre"],char:"\ud83d\udc79",fitzpatrick_scale:!1,category:"people"},japanese_goblin:{keywords:["red","evil","mask","monster","scary","creepy","japanese","goblin"],char:"\ud83d\udc7a",fitzpatrick_scale:!1,category:"people"},skull:{keywords:["dead","skeleton","creepy","death"],char:"\ud83d\udc80",fitzpatrick_scale:!1,category:"people"},ghost:{keywords:["halloween","spooky","scary"],char:"\ud83d\udc7b",fitzpatrick_scale:!1,category:"people"},alien:{keywords:["UFO","paul","weird","outer_space"],char:"\ud83d\udc7d",fitzpatrick_scale:!1,category:"people"},robot:{keywords:["computer","machine","bot"],char:"\ud83e\udd16",fitzpatrick_scale:!1,category:"people"},smiley_cat:{keywords:["animal","cats","happy","smile"],char:"\ud83d\ude3a",fitzpatrick_scale:!1,category:"people"},smile_cat:{keywords:["animal","cats","smile"],char:"\ud83d\ude38",fitzpatrick_scale:!1,category:"people"},joy_cat:{keywords:["animal","cats","haha","happy","tears"],char:"\ud83d\ude39",fitzpatrick_scale:!1,category:"people"},heart_eyes_cat:{keywords:["animal","love","like","affection","cats","valentines","heart"],char:"\ud83d\ude3b",fitzpatrick_scale:!1,category:"people"},smirk_cat:{keywords:["animal","cats","smirk"],char:"\ud83d\ude3c",fitzpatrick_scale:!1,category:"people"},kissing_cat:{keywords:["animal","cats","kiss"],char:"\ud83d\ude3d",fitzpatrick_scale:!1,category:"people"},scream_cat:{keywords:["animal","cats","munch","scared","scream"],char:"\ud83d\ude40",fitzpatrick_scale:!1,category:"people"},crying_cat_face:{keywords:["animal","tears","weep","sad","cats","upset","cry"],char:"\ud83d\ude3f",fitzpatrick_scale:!1,category:"people"},pouting_cat:{keywords:["animal","cats"],char:"\ud83d\ude3e",fitzpatrick_scale:!1,category:"people"},palms_up:{keywords:["hands","gesture","cupped","prayer"],char:"\ud83e\udd32",fitzpatrick_scale:!0,category:"people"},raised_hands:{keywords:["gesture","hooray","yea","celebration","hands"],char:"\ud83d\ude4c",fitzpatrick_scale:!0,category:"people"},clap:{keywords:["hands","praise","applause","congrats","yay"],char:"\ud83d\udc4f",fitzpatrick_scale:!0,category:"people"},wave:{keywords:["hands","gesture","goodbye","solong","farewell","hello","hi","palm"],char:"\ud83d\udc4b",fitzpatrick_scale:!0,category:"people"},call_me_hand:{keywords:["hands","gesture"],char:"\ud83e\udd19",fitzpatrick_scale:!0,category:"people"},"+1":{keywords:["thumbsup","yes","awesome","good","agree","accept","cool","hand","like"],char:"\ud83d\udc4d",fitzpatrick_scale:!0,category:"people"},"-1":{keywords:["thumbsdown","no","dislike","hand"],char:"\ud83d\udc4e",fitzpatrick_scale:!0,category:"people"},facepunch:{keywords:["angry","violence","fist","hit","attack","hand"],char:"\ud83d\udc4a",fitzpatrick_scale:!0,category:"people"},fist:{keywords:["fingers","hand","grasp"],char:"\u270a",fitzpatrick_scale:!0,category:"people"},fist_left:{keywords:["hand","fistbump"],char:"\ud83e\udd1b",fitzpatrick_scale:!0,category:"people"},fist_right:{keywords:["hand","fistbump"],char:"\ud83e\udd1c",fitzpatrick_scale:!0,category:"people"},v:{keywords:["fingers","ohyeah","hand","peace","victory","two"],char:"\u270c",fitzpatrick_scale:!0,category:"people"},ok_hand:{keywords:["fingers","limbs","perfect","ok","okay"],char:"\ud83d\udc4c",fitzpatrick_scale:!0,category:"people"},raised_hand:{keywords:["fingers","stop","highfive","palm","ban"],char:"\u270b",fitzpatrick_scale:!0,category:"people"},raised_back_of_hand:{keywords:["fingers","raised","backhand"],char:"\ud83e\udd1a",fitzpatrick_scale:!0,category:"people"},open_hands:{keywords:["fingers","butterfly","hands","open"],char:"\ud83d\udc50",fitzpatrick_scale:!0,category:"people"},muscle:{keywords:["arm","flex","hand","summer","strong","biceps"],char:"\ud83d\udcaa",fitzpatrick_scale:!0,category:"people"},pray:{keywords:["please","hope","wish","namaste","highfive"],char:"\ud83d\ude4f",fitzpatrick_scale:!0,category:"people"},foot:{keywords:["kick","stomp"],char:"\ud83e\uddb6",fitzpatrick_scale:!0,category:"people"},leg:{keywords:["kick","limb"],char:"\ud83e\uddb5",fitzpatrick_scale:!0,category:"people"},handshake:{keywords:["agreement","shake"],char:"\ud83e\udd1d",fitzpatrick_scale:!1,category:"people"},point_up:{keywords:["hand","fingers","direction","up"],char:"\u261d",fitzpatrick_scale:!0,category:"people"},point_up_2:{keywords:["fingers","hand","direction","up"],char:"\ud83d\udc46",fitzpatrick_scale:!0,category:"people"},point_down:{keywords:["fingers","hand","direction","down"],char:"\ud83d\udc47",fitzpatrick_scale:!0,category:"people"},point_left:{keywords:["direction","fingers","hand","left"],char:"\ud83d\udc48",fitzpatrick_scale:!0,category:"people"},point_right:{keywords:["fingers","hand","direction","right"],char:"\ud83d\udc49",fitzpatrick_scale:!0,category:"people"},fu:{keywords:["hand","fingers","rude","middle","flipping"],char:"\ud83d\udd95",fitzpatrick_scale:!0,category:"people"},raised_hand_with_fingers_splayed:{keywords:["hand","fingers","palm"],char:"\ud83d\udd90",fitzpatrick_scale:!0,category:"people"},love_you:{keywords:["hand","fingers","gesture"],char:"\ud83e\udd1f",fitzpatrick_scale:!0,category:"people"},metal:{keywords:["hand","fingers","evil_eye","sign_of_horns","rock_on"],char:"\ud83e\udd18",fitzpatrick_scale:!0,category:"people"},crossed_fingers:{keywords:["good","lucky"],char:"\ud83e\udd1e",fitzpatrick_scale:!0,category:"people"},vulcan_salute:{keywords:["hand","fingers","spock","star trek"],char:"\ud83d\udd96",fitzpatrick_scale:!0,category:"people"},writing_hand:{keywords:["lower_left_ballpoint_pen","stationery","write","compose"],char:"\u270d",fitzpatrick_scale:!0,category:"people"},selfie:{keywords:["camera","phone"],char:"\ud83e\udd33",fitzpatrick_scale:!0,category:"people"},nail_care:{keywords:["beauty","manicure","finger","fashion","nail"],char:"\ud83d\udc85",fitzpatrick_scale:!0,category:"people"},lips:{keywords:["mouth","kiss"],char:"\ud83d\udc44",fitzpatrick_scale:!1,category:"people"},tooth:{keywords:["teeth","dentist"],char:"\ud83e\uddb7",fitzpatrick_scale:!1,category:"people"},tongue:{keywords:["mouth","playful"],char:"\ud83d\udc45",fitzpatrick_scale:!1,category:"people"},ear:{keywords:["face","hear","sound","listen"],char:"\ud83d\udc42",fitzpatrick_scale:!0,category:"people"},nose:{keywords:["smell","sniff"],char:"\ud83d\udc43",fitzpatrick_scale:!0,category:"people"},eye:{keywords:["face","look","see","watch","stare"],char:"\ud83d\udc41",fitzpatrick_scale:!1,category:"people"},eyes:{keywords:["look","watch","stalk","peek","see"],char:"\ud83d\udc40",fitzpatrick_scale:!1,category:"people"},brain:{keywords:["smart","intelligent"],char:"\ud83e\udde0",fitzpatrick_scale:!1,category:"people"},bust_in_silhouette:{keywords:["user","person","human"],char:"\ud83d\udc64",fitzpatrick_scale:!1,category:"people"},busts_in_silhouette:{keywords:["user","person","human","group","team"],char:"\ud83d\udc65",fitzpatrick_scale:!1,category:"people"},speaking_head:{keywords:["user","person","human","sing","say","talk"],char:"\ud83d\udde3",fitzpatrick_scale:!1,category:"people"},baby:{keywords:["child","boy","girl","toddler"],char:"\ud83d\udc76",fitzpatrick_scale:!0,category:"people"},child:{keywords:["gender-neutral","young"],char:"\ud83e\uddd2",fitzpatrick_scale:!0,category:"people"},boy:{keywords:["man","male","guy","teenager"],char:"\ud83d\udc66",fitzpatrick_scale:!0,category:"people"},girl:{keywords:["female","woman","teenager"],char:"\ud83d\udc67",fitzpatrick_scale:!0,category:"people"},adult:{keywords:["gender-neutral","person"],char:"\ud83e\uddd1",fitzpatrick_scale:!0,category:"people"},man:{keywords:["mustache","father","dad","guy","classy","sir","moustache"],char:"\ud83d\udc68",fitzpatrick_scale:!0,category:"people"},woman:{keywords:["female","girls","lady"],char:"\ud83d\udc69",fitzpatrick_scale:!0,category:"people"},blonde_woman:{keywords:["woman","female","girl","blonde","person"],char:"\ud83d\udc71\u200d\u2640\ufe0f",fitzpatrick_scale:!0,category:"people"},blonde_man:{keywords:["man","male","boy","blonde","guy","person"],char:"\ud83d\udc71",fitzpatrick_scale:!0,category:"people"},bearded_person:{keywords:["person","bewhiskered"],char:"\ud83e\uddd4",fitzpatrick_scale:!0,category:"people"},older_adult:{keywords:["human","elder","senior","gender-neutral"],char:"\ud83e\uddd3",fitzpatrick_scale:!0,category:"people"},older_man:{keywords:["human","male","men","old","elder","senior"],char:"\ud83d\udc74",fitzpatrick_scale:!0,category:"people"},older_woman:{keywords:["human","female","women","lady","old","elder","senior"],char:"\ud83d\udc75",fitzpatrick_scale:!0,category:"people"},man_with_gua_pi_mao:{keywords:["male","boy","chinese"],char:"\ud83d\udc72",fitzpatrick_scale:!0,category:"people"},woman_with_headscarf:{keywords:["female","hijab","mantilla","tichel"],char:"\ud83e\uddd5",fitzpatrick_scale:!0,category:"people"},woman_with_turban:{keywords:["female","indian","hinduism","arabs","woman"],char:"\ud83d\udc73\u200d\u2640\ufe0f",fitzpatrick_scale:!0,category:"people"},man_with_turban:{keywords:["male","indian","hinduism","arabs"],char:"\ud83d\udc73",fitzpatrick_scale:!0,category:"people"},policewoman:{keywords:["woman","police","law","legal","enforcement","arrest","911","female"],char:"\ud83d\udc6e\u200d\u2640\ufe0f",fitzpatrick_scale:!0,category:"people"},policeman:{keywords:["man","police","law","legal","enforcement","arrest","911"],char:"\ud83d\udc6e",fitzpatrick_scale:!0,category:"people"},construction_worker_woman:{keywords:["female","human","wip","build","construction","worker","labor","woman"],char:"\ud83d\udc77\u200d\u2640\ufe0f",fitzpatrick_scale:!0,category:"people"},construction_worker_man:{keywords:["male","human","wip","guy","build","construction","worker","labor"],char:"\ud83d\udc77",fitzpatrick_scale:!0,category:"people"},guardswoman:{keywords:["uk","gb","british","female","royal","woman"],char:"\ud83d\udc82\u200d\u2640\ufe0f",fitzpatrick_scale:!0,category:"people"},guardsman:{keywords:["uk","gb","british","male","guy","royal"],char:"\ud83d\udc82",fitzpatrick_scale:!0,category:"people"},female_detective:{keywords:["human","spy","detective","female","woman"],char:"\ud83d\udd75\ufe0f\u200d\u2640\ufe0f",fitzpatrick_scale:!0,category:"people"},male_detective:{keywords:["human","spy","detective"],char:"\ud83d\udd75",fitzpatrick_scale:!0,category:"people"},woman_health_worker:{keywords:["doctor","nurse","therapist","healthcare","woman","human"],char:"\ud83d\udc69\u200d\u2695\ufe0f",fitzpatrick_scale:!0,category:"people"},man_health_worker:{keywords:["doctor","nurse","therapist","healthcare","man","human"],char:"\ud83d\udc68\u200d\u2695\ufe0f",fitzpatrick_scale:!0,category:"people"},woman_farmer:{keywords:["rancher","gardener","woman","human"],char:"\ud83d\udc69\u200d\ud83c\udf3e",fitzpatrick_scale:!0,category:"people"},man_farmer:{keywords:["rancher","gardener","man","human"],char:"\ud83d\udc68\u200d\ud83c\udf3e",fitzpatrick_scale:!0,category:"people"},woman_cook:{keywords:["chef","woman","human"],char:"\ud83d\udc69\u200d\ud83c\udf73",fitzpatrick_scale:!0,category:"people"},man_cook:{keywords:["chef","man","human"],char:"\ud83d\udc68\u200d\ud83c\udf73",fitzpatrick_scale:!0,category:"people"},woman_student:{keywords:["graduate","woman","human"],char:"\ud83d\udc69\u200d\ud83c\udf93",fitzpatrick_scale:!0,category:"people"},man_student:{keywords:["graduate","man","human"],char:"\ud83d\udc68\u200d\ud83c\udf93",fitzpatrick_scale:!0,category:"people"},woman_singer:{keywords:["rockstar","entertainer","woman","human"],char:"\ud83d\udc69\u200d\ud83c\udfa4",fitzpatrick_scale:!0,category:"people"},man_singer:{keywords:["rockstar","entertainer","man","human"],char:"\ud83d\udc68\u200d\ud83c\udfa4",fitzpatrick_scale:!0,category:"people"},woman_teacher:{keywords:["instructor","professor","woman","human"],char:"\ud83d\udc69\u200d\ud83c\udfeb",fitzpatrick_scale:!0,category:"people"},man_teacher:{keywords:["instructor","professor","man","human"],char:"\ud83d\udc68\u200d\ud83c\udfeb",fitzpatrick_scale:!0,category:"people"},woman_factory_worker:{keywords:["assembly","industrial","woman","human"],char:"\ud83d\udc69\u200d\ud83c\udfed",fitzpatrick_scale:!0,category:"people"},man_factory_worker:{keywords:["assembly","industrial","man","human"],char:"\ud83d\udc68\u200d\ud83c\udfed",fitzpatrick_scale:!0,category:"people"},woman_technologist:{keywords:["coder","developer","engineer","programmer","software","woman","human","laptop","computer"],char:"\ud83d\udc69\u200d\ud83d\udcbb",fitzpatrick_scale:!0,category:"people"},man_technologist:{keywords:["coder","developer","engineer","programmer","software","man","human","laptop","computer"],char:"\ud83d\udc68\u200d\ud83d\udcbb",fitzpatrick_scale:!0,category:"people"},woman_office_worker:{keywords:["business","manager","woman","human"],char:"\ud83d\udc69\u200d\ud83d\udcbc",fitzpatrick_scale:!0,category:"people"},man_office_worker:{keywords:["business","manager","man","human"],char:"\ud83d\udc68\u200d\ud83d\udcbc",fitzpatrick_scale:!0,category:"people"},woman_mechanic:{keywords:["plumber","woman","human","wrench"],char:"\ud83d\udc69\u200d\ud83d\udd27",fitzpatrick_scale:!0,category:"people"},man_mechanic:{keywords:["plumber","man","human","wrench"],char:"\ud83d\udc68\u200d\ud83d\udd27",fitzpatrick_scale:!0,category:"people"},woman_scientist:{keywords:["biologist","chemist","engineer","physicist","woman","human"],char:"\ud83d\udc69\u200d\ud83d\udd2c",fitzpatrick_scale:!0,category:"people"},man_scientist:{keywords:["biologist","chemist","engineer","physicist","man","human"],char:"\ud83d\udc68\u200d\ud83d\udd2c",fitzpatrick_scale:!0,category:"people"},woman_artist:{keywords:["painter","woman","human"],char:"\ud83d\udc69\u200d\ud83c\udfa8",fitzpatrick_scale:!0,category:"people"},man_artist:{keywords:["painter","man","human"],char:"\ud83d\udc68\u200d\ud83c\udfa8",fitzpatrick_scale:!0,category:"people"},woman_firefighter:{keywords:["fireman","woman","human"],char:"\ud83d\udc69\u200d\ud83d\ude92",fitzpatrick_scale:!0,category:"people"},man_firefighter:{keywords:["fireman","man","human"],char:"\ud83d\udc68\u200d\ud83d\ude92",fitzpatrick_scale:!0,category:"people"},woman_pilot:{keywords:["aviator","plane","woman","human"],char:"\ud83d\udc69\u200d\u2708\ufe0f",fitzpatrick_scale:!0,category:"people"},man_pilot:{keywords:["aviator","plane","man","human"],char:"\ud83d\udc68\u200d\u2708\ufe0f",fitzpatrick_scale:!0,category:"people"},woman_astronaut:{keywords:["space","rocket","woman","human"],char:"\ud83d\udc69\u200d\ud83d\ude80",fitzpatrick_scale:!0,category:"people"},man_astronaut:{keywords:["space","rocket","man","human"],char:"\ud83d\udc68\u200d\ud83d\ude80",fitzpatrick_scale:!0,category:"people"},woman_judge:{keywords:["justice","court","woman","human"],char:"\ud83d\udc69\u200d\u2696\ufe0f",fitzpatrick_scale:!0,category:"people"},man_judge:{keywords:["justice","court","man","human"],char:"\ud83d\udc68\u200d\u2696\ufe0f",fitzpatrick_scale:!0,category:"people"},woman_superhero:{keywords:["woman","female","good","heroine","superpowers"],char:"\ud83e\uddb8\u200d\u2640\ufe0f",fitzpatrick_scale:!0,category:"people"},man_superhero:{keywords:["man","male","good","hero","superpowers"],char:"\ud83e\uddb8\u200d\u2642\ufe0f",fitzpatrick_scale:!0,category:"people"},woman_supervillain:{keywords:["woman","female","evil","bad","criminal","heroine","superpowers"],char:"\ud83e\uddb9\u200d\u2640\ufe0f",fitzpatrick_scale:!0,category:"people"},man_supervillain:{keywords:["man","male","evil","bad","criminal","hero","superpowers"],char:"\ud83e\uddb9\u200d\u2642\ufe0f",fitzpatrick_scale:!0,category:"people"},mrs_claus:{keywords:["woman","female","xmas","mother christmas"],char:"\ud83e\udd36",fitzpatrick_scale:!0,category:"people"},santa:{keywords:["festival","man","male","xmas","father christmas"],char:"\ud83c\udf85",fitzpatrick_scale:!0,category:"people"},sorceress:{keywords:["woman","female","mage","witch"],char:"\ud83e\uddd9\u200d\u2640\ufe0f",fitzpatrick_scale:!0,category:"people"},wizard:{keywords:["man","male","mage","sorcerer"],char:"\ud83e\uddd9\u200d\u2642\ufe0f",fitzpatrick_scale:!0,category:"people"},woman_elf:{keywords:["woman","female"],char:"\ud83e\udddd\u200d\u2640\ufe0f",fitzpatrick_scale:!0,category:"people"},man_elf:{keywords:["man","male"],char:"\ud83e\udddd\u200d\u2642\ufe0f",fitzpatrick_scale:!0,category:"people"},woman_vampire:{keywords:["woman","female"],char:"\ud83e\udddb\u200d\u2640\ufe0f",fitzpatrick_scale:!0,category:"people"},man_vampire:{keywords:["man","male","dracula"],char:"\ud83e\udddb\u200d\u2642\ufe0f",fitzpatrick_scale:!0,category:"people"},woman_zombie:{keywords:["woman","female","undead","walking dead"],char:"\ud83e\udddf\u200d\u2640\ufe0f",fitzpatrick_scale:!1,category:"people"},man_zombie:{keywords:["man","male","dracula","undead","walking dead"],char:"\ud83e\udddf\u200d\u2642\ufe0f",fitzpatrick_scale:!1,category:"people"},woman_genie:{keywords:["woman","female"],char:"\ud83e\uddde\u200d\u2640\ufe0f",fitzpatrick_scale:!1,category:"people"},man_genie:{keywords:["man","male"],char:"\ud83e\uddde\u200d\u2642\ufe0f",fitzpatrick_scale:!1,category:"people"},mermaid:{keywords:["woman","female","merwoman","ariel"],char:"\ud83e\udddc\u200d\u2640\ufe0f",fitzpatrick_scale:!0,category:"people"},merman:{keywords:["man","male","triton"],char:"\ud83e\udddc\u200d\u2642\ufe0f",fitzpatrick_scale:!0,category:"people"},woman_fairy:{keywords:["woman","female"],char:"\ud83e\uddda\u200d\u2640\ufe0f",fitzpatrick_scale:!0,category:"people"},man_fairy:{keywords:["man","male"],char:"\ud83e\uddda\u200d\u2642\ufe0f",fitzpatrick_scale:!0,category:"people"},angel:{keywords:["heaven","wings","halo"],char:"\ud83d\udc7c",fitzpatrick_scale:!0,category:"people"},pregnant_woman:{keywords:["baby"],char:"\ud83e\udd30",fitzpatrick_scale:!0,category:"people"},breastfeeding:{keywords:["nursing","baby"],char:"\ud83e\udd31",fitzpatrick_scale:!0,category:"people"},princess:{keywords:["girl","woman","female","blond","crown","royal","queen"],char:"\ud83d\udc78",fitzpatrick_scale:!0,category:"people"},prince:{keywords:["boy","man","male","crown","royal","king"],char:"\ud83e\udd34",fitzpatrick_scale:!0,category:"people"},bride_with_veil:{keywords:["couple","marriage","wedding","woman","bride"],char:"\ud83d\udc70",fitzpatrick_scale:!0,category:"people"},man_in_tuxedo:{keywords:["couple","marriage","wedding","groom"],char:"\ud83e\udd35",fitzpatrick_scale:!0,category:"people"},running_woman:{keywords:["woman","walking","exercise","race","running","female"],char:"\ud83c\udfc3\u200d\u2640\ufe0f",fitzpatrick_scale:!0,category:"people"},running_man:{keywords:["man","walking","exercise","race","running"],char:"\ud83c\udfc3",fitzpatrick_scale:!0,category:"people"},walking_woman:{keywords:["human","feet","steps","woman","female"],char:"\ud83d\udeb6\u200d\u2640\ufe0f",fitzpatrick_scale:!0,category:"people"},walking_man:{keywords:["human","feet","steps"],char:"\ud83d\udeb6",fitzpatrick_scale:!0,category:"people"},dancer:{keywords:["female","girl","woman","fun"],char:"\ud83d\udc83",fitzpatrick_scale:!0,category:"people"},man_dancing:{keywords:["male","boy","fun","dancer"],char:"\ud83d\udd7a",fitzpatrick_scale:!0,category:"people"},dancing_women:{keywords:["female","bunny","women","girls"],char:"\ud83d\udc6f",fitzpatrick_scale:!1,category:"people"},dancing_men:{keywords:["male","bunny","men","boys"],char:"\ud83d\udc6f\u200d\u2642\ufe0f",fitzpatrick_scale:!1,category:"people"},couple:{keywords:["pair","people","human","love","date","dating","like","affection","valentines","marriage"],char:"\ud83d\udc6b",fitzpatrick_scale:!1,category:"people"},two_men_holding_hands:{keywords:["pair","couple","love","like","bromance","friendship","people","human"],char:"\ud83d\udc6c",fitzpatrick_scale:!1,category:"people"},two_women_holding_hands:{keywords:["pair","friendship","couple","love","like","female","people","human"],char:"\ud83d\udc6d",fitzpatrick_scale:!1,category:"people"},bowing_woman:{keywords:["woman","female","girl"],char:"\ud83d\ude47\u200d\u2640\ufe0f",fitzpatrick_scale:!0,category:"people"},bowing_man:{keywords:["man","male","boy"],char:"\ud83d\ude47",fitzpatrick_scale:!0,category:"people"},man_facepalming:{keywords:["man","male","boy","disbelief"],char:"\ud83e\udd26\u200d\u2642\ufe0f",fitzpatrick_scale:!0,category:"people"},woman_facepalming:{keywords:["woman","female","girl","disbelief"],char:"\ud83e\udd26\u200d\u2640\ufe0f",fitzpatrick_scale:!0,category:"people"},woman_shrugging:{keywords:["woman","female","girl","confused","indifferent","doubt"],char:"\ud83e\udd37",fitzpatrick_scale:!0,category:"people"},man_shrugging:{keywords:["man","male","boy","confused","indifferent","doubt"],char:"\ud83e\udd37\u200d\u2642\ufe0f",fitzpatrick_scale:!0,category:"people"},tipping_hand_woman:{keywords:["female","girl","woman","human","information"],char:"\ud83d\udc81",fitzpatrick_scale:!0,category:"people"},tipping_hand_man:{keywords:["male","boy","man","human","information"],char:"\ud83d\udc81\u200d\u2642\ufe0f",fitzpatrick_scale:!0,category:"people"},no_good_woman:{keywords:["female","girl","woman","nope"],char:"\ud83d\ude45",fitzpatrick_scale:!0,category:"people"},no_good_man:{keywords:["male","boy","man","nope"],char:"\ud83d\ude45\u200d\u2642\ufe0f",fitzpatrick_scale:!0,category:"people"},ok_woman:{keywords:["women","girl","female","pink","human","woman"],char:"\ud83d\ude46",fitzpatrick_scale:!0,category:"people"},ok_man:{keywords:["men","boy","male","blue","human","man"],char:"\ud83d\ude46\u200d\u2642\ufe0f",fitzpatrick_scale:!0,category:"people"},raising_hand_woman:{keywords:["female","girl","woman"],char:"\ud83d\ude4b",fitzpatrick_scale:!0,category:"people"},raising_hand_man:{keywords:["male","boy","man"],char:"\ud83d\ude4b\u200d\u2642\ufe0f",fitzpatrick_scale:!0,category:"people"},pouting_woman:{keywords:["female","girl","woman"],char:"\ud83d\ude4e",fitzpatrick_scale:!0,category:"people"},pouting_man:{keywords:["male","boy","man"],char:"\ud83d\ude4e\u200d\u2642\ufe0f",fitzpatrick_scale:!0,category:"people"},frowning_woman:{keywords:["female","girl","woman","sad","depressed","discouraged","unhappy"],char:"\ud83d\ude4d",fitzpatrick_scale:!0,category:"people"},frowning_man:{keywords:["male","boy","man","sad","depressed","discouraged","unhappy"],char:"\ud83d\ude4d\u200d\u2642\ufe0f",fitzpatrick_scale:!0,category:"people"},haircut_woman:{keywords:["female","girl","woman"],char:"\ud83d\udc87",fitzpatrick_scale:!0,category:"people"},haircut_man:{keywords:["male","boy","man"],char:"\ud83d\udc87\u200d\u2642\ufe0f",fitzpatrick_scale:!0,category:"people"},massage_woman:{keywords:["female","girl","woman","head"],char:"\ud83d\udc86",fitzpatrick_scale:!0,category:"people"},massage_man:{keywords:["male","boy","man","head"],char:"\ud83d\udc86\u200d\u2642\ufe0f",fitzpatrick_scale:!0,category:"people"},woman_in_steamy_room:{keywords:["female","woman","spa","steamroom","sauna"],char:"\ud83e\uddd6\u200d\u2640\ufe0f",fitzpatrick_scale:!0,category:"people"},man_in_steamy_room:{keywords:["male","man","spa","steamroom","sauna"],char:"\ud83e\uddd6\u200d\u2642\ufe0f",fitzpatrick_scale:!0,category:"people"},couple_with_heart_woman_man:{keywords:["pair","love","like","affection","human","dating","valentines","marriage"],char:"\ud83d\udc91",fitzpatrick_scale:!1,category:"people"},couple_with_heart_woman_woman:{keywords:["pair","love","like","affection","human","dating","valentines","marriage"],char:"\ud83d\udc69\u200d\u2764\ufe0f\u200d\ud83d\udc69",fitzpatrick_scale:!1,category:"people"},couple_with_heart_man_man:{keywords:["pair","love","like","affection","human","dating","valentines","marriage"],char:"\ud83d\udc68\u200d\u2764\ufe0f\u200d\ud83d\udc68",fitzpatrick_scale:!1,category:"people"},couplekiss_man_woman:{keywords:["pair","valentines","love","like","dating","marriage"],char:"\ud83d\udc8f",fitzpatrick_scale:!1,category:"people"},couplekiss_woman_woman:{keywords:["pair","valentines","love","like","dating","marriage"],char:"\ud83d\udc69\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc69",fitzpatrick_scale:!1,category:"people"},couplekiss_man_man:{keywords:["pair","valentines","love","like","dating","marriage"],char:"\ud83d\udc68\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68",fitzpatrick_scale:!1,category:"people"},family_man_woman_boy:{keywords:["home","parents","child","mom","dad","father","mother","people","human"],char:"\ud83d\udc6a",fitzpatrick_scale:!1,category:"people"},family_man_woman_girl:{keywords:["home","parents","people","human","child"],char:"\ud83d\udc68\u200d\ud83d\udc69\u200d\ud83d\udc67",fitzpatrick_scale:!1,category:"people"},family_man_woman_girl_boy:{keywords:["home","parents","people","human","children"],char:"\ud83d\udc68\u200d\ud83d\udc69\u200d\ud83d\udc67\u200d\ud83d\udc66",fitzpatrick_scale:!1,category:"people"},family_man_woman_boy_boy:{keywords:["home","parents","people","human","children"],char:"\ud83d\udc68\u200d\ud83d\udc69\u200d\ud83d\udc66\u200d\ud83d\udc66",fitzpatrick_scale:!1,category:"people"},family_man_woman_girl_girl:{keywords:["home","parents","people","human","children"],char:"\ud83d\udc68\u200d\ud83d\udc69\u200d\ud83d\udc67\u200d\ud83d\udc67",fitzpatrick_scale:!1,category:"people"},family_woman_woman_boy:{keywords:["home","parents","people","human","children"],char:"\ud83d\udc69\u200d\ud83d\udc69\u200d\ud83d\udc66",fitzpatrick_scale:!1,category:"people"},family_woman_woman_girl:{keywords:["home","parents","people","human","children"],char:"\ud83d\udc69\u200d\ud83d\udc69\u200d\ud83d\udc67",fitzpatrick_scale:!1,category:"people"},family_woman_woman_girl_boy:{keywords:["home","parents","people","human","children"],char:"\ud83d\udc69\u200d\ud83d\udc69\u200d\ud83d\udc67\u200d\ud83d\udc66",fitzpatrick_scale:!1,category:"people"},family_woman_woman_boy_boy:{keywords:["home","parents","people","human","children"],char:"\ud83d\udc69\u200d\ud83d\udc69\u200d\ud83d\udc66\u200d\ud83d\udc66",fitzpatrick_scale:!1,category:"people"},family_woman_woman_girl_girl:{keywords:["home","parents","people","human","children"],char:"\ud83d\udc69\u200d\ud83d\udc69\u200d\ud83d\udc67\u200d\ud83d\udc67",fitzpatrick_scale:!1,category:"people"},family_man_man_boy:{keywords:["home","parents","people","human","children"],char:"\ud83d\udc68\u200d\ud83d\udc68\u200d\ud83d\udc66",fitzpatrick_scale:!1,category:"people"},family_man_man_girl:{keywords:["home","parents","people","human","children"],char:"\ud83d\udc68\u200d\ud83d\udc68\u200d\ud83d\udc67",fitzpatrick_scale:!1,category:"people"},family_man_man_girl_boy:{keywords:["home","parents","people","human","children"],char:"\ud83d\udc68\u200d\ud83d\udc68\u200d\ud83d\udc67\u200d\ud83d\udc66",fitzpatrick_scale:!1,category:"people"},family_man_man_boy_boy:{keywords:["home","parents","people","human","children"],char:"\ud83d\udc68\u200d\ud83d\udc68\u200d\ud83d\udc66\u200d\ud83d\udc66",fitzpatrick_scale:!1,category:"people"},family_man_man_girl_girl:{keywords:["home","parents","people","human","children"],char:"\ud83d\udc68\u200d\ud83d\udc68\u200d\ud83d\udc67\u200d\ud83d\udc67",fitzpatrick_scale:!1,category:"people"},family_woman_boy:{keywords:["home","parent","people","human","child"],char:"\ud83d\udc69\u200d\ud83d\udc66",fitzpatrick_scale:!1,category:"people"},family_woman_girl:{keywords:["home","parent","people","human","child"],char:"\ud83d\udc69\u200d\ud83d\udc67",fitzpatrick_scale:!1,category:"people"},family_woman_girl_boy:{keywords:["home","parent","people","human","children"],char:"\ud83d\udc69\u200d\ud83d\udc67\u200d\ud83d\udc66",fitzpatrick_scale:!1,category:"people"},family_woman_boy_boy:{keywords:["home","parent","people","human","children"],char:"\ud83d\udc69\u200d\ud83d\udc66\u200d\ud83d\udc66",fitzpatrick_scale:!1,category:"people"},family_woman_girl_girl:{keywords:["home","parent","people","human","children"],char:"\ud83d\udc69\u200d\ud83d\udc67\u200d\ud83d\udc67",fitzpatrick_scale:!1,category:"people"},family_man_boy:{keywords:["home","parent","people","human","child"],char:"\ud83d\udc68\u200d\ud83d\udc66",fitzpatrick_scale:!1,category:"people"},family_man_girl:{keywords:["home","parent","people","human","child"],char:"\ud83d\udc68\u200d\ud83d\udc67",fitzpatrick_scale:!1,category:"people"},family_man_girl_boy:{keywords:["home","parent","people","human","children"],char:"\ud83d\udc68\u200d\ud83d\udc67\u200d\ud83d\udc66",fitzpatrick_scale:!1,category:"people"},family_man_boy_boy:{keywords:["home","parent","people","human","children"],char:"\ud83d\udc68\u200d\ud83d\udc66\u200d\ud83d\udc66",fitzpatrick_scale:!1,category:"people"},family_man_girl_girl:{keywords:["home","parent","people","human","children"],char:"\ud83d\udc68\u200d\ud83d\udc67\u200d\ud83d\udc67",fitzpatrick_scale:!1,category:"people"},yarn:{keywords:["ball","crochet","knit"],char:"\ud83e\uddf6",fitzpatrick_scale:!1,category:"people"},thread:{keywords:["needle","sewing","spool","string"],char:"\ud83e\uddf5",fitzpatrick_scale:!1,category:"people"},coat:{keywords:["jacket"],char:"\ud83e\udde5",fitzpatrick_scale:!1,category:"people"},labcoat:{keywords:["doctor","experiment","scientist","chemist"],char:"\ud83e\udd7c",fitzpatrick_scale:!1,category:"people"},womans_clothes:{keywords:["fashion","shopping_bags","female"],char:"\ud83d\udc5a",fitzpatrick_scale:!1,category:"people"},tshirt:{keywords:["fashion","cloth","casual","shirt","tee"],char:"\ud83d\udc55",fitzpatrick_scale:!1,category:"people"},jeans:{keywords:["fashion","shopping"],char:"\ud83d\udc56",fitzpatrick_scale:!1,category:"people"},necktie:{keywords:["shirt","suitup","formal","fashion","cloth","business"],char:"\ud83d\udc54",fitzpatrick_scale:!1,category:"people"},dress:{keywords:["clothes","fashion","shopping"],char:"\ud83d\udc57",fitzpatrick_scale:!1,category:"people"},bikini:{keywords:["swimming","female","woman","girl","fashion","beach","summer"],char:"\ud83d\udc59",fitzpatrick_scale:!1,category:"people"},kimono:{keywords:["dress","fashion","women","female","japanese"],char:"\ud83d\udc58",fitzpatrick_scale:!1,category:"people"},lipstick:{keywords:["female","girl","fashion","woman"],char:"\ud83d\udc84",fitzpatrick_scale:!1,category:"people"},kiss:{keywords:["face","lips","love","like","affection","valentines"],char:"\ud83d\udc8b",fitzpatrick_scale:!1,category:"people"},footprints:{keywords:["feet","tracking","walking","beach"],char:"\ud83d\udc63",fitzpatrick_scale:!1,category:"people"},flat_shoe:{keywords:["ballet","slip-on","slipper"],char:"\ud83e\udd7f",fitzpatrick_scale:!1,category:"people"},high_heel:{keywords:["fashion","shoes","female","pumps","stiletto"],char:"\ud83d\udc60",fitzpatrick_scale:!1,category:"people"},sandal:{keywords:["shoes","fashion","flip flops"],char:"\ud83d\udc61",fitzpatrick_scale:!1,category:"people"},boot:{keywords:["shoes","fashion"],char:"\ud83d\udc62",fitzpatrick_scale:!1,category:"people"},mans_shoe:{keywords:["fashion","male"],char:"\ud83d\udc5e",fitzpatrick_scale:!1,category:"people"},athletic_shoe:{keywords:["shoes","sports","sneakers"],char:"\ud83d\udc5f",fitzpatrick_scale:!1,category:"people"},hiking_boot:{keywords:["backpacking","camping","hiking"],char:"\ud83e\udd7e",fitzpatrick_scale:!1,category:"people"},socks:{keywords:["stockings","clothes"],char:"\ud83e\udde6",fitzpatrick_scale:!1,category:"people"},gloves:{keywords:["hands","winter","clothes"],char:"\ud83e\udde4",fitzpatrick_scale:!1,category:"people"},scarf:{keywords:["neck","winter","clothes"],char:"\ud83e\udde3",fitzpatrick_scale:!1,category:"people"},womans_hat:{keywords:["fashion","accessories","female","lady","spring"],char:"\ud83d\udc52",fitzpatrick_scale:!1,category:"people"},tophat:{keywords:["magic","gentleman","classy","circus"],char:"\ud83c\udfa9",fitzpatrick_scale:!1,category:"people"},billed_hat:{keywords:["cap","baseball"],char:"\ud83e\udde2",fitzpatrick_scale:!1,category:"people"},rescue_worker_helmet:{keywords:["construction","build"],char:"\u26d1",fitzpatrick_scale:!1,category:"people"},mortar_board:{keywords:["school","college","degree","university","graduation","cap","hat","legal","learn","education"],char:"\ud83c\udf93",fitzpatrick_scale:!1,category:"people"},crown:{keywords:["king","kod","leader","royalty","lord"],char:"\ud83d\udc51",fitzpatrick_scale:!1,category:"people"},school_satchel:{keywords:["student","education","bag","backpack"],char:"\ud83c\udf92",fitzpatrick_scale:!1,category:"people"},luggage:{keywords:["packing","travel"],char:"\ud83e\uddf3",fitzpatrick_scale:!1,category:"people"},pouch:{keywords:["bag","accessories","shopping"],char:"\ud83d\udc5d",fitzpatrick_scale:!1,category:"people"},purse:{keywords:["fashion","accessories","money","sales","shopping"],char:"\ud83d\udc5b",fitzpatrick_scale:!1,category:"people"},handbag:{keywords:["fashion","accessory","accessories","shopping"],char:"\ud83d\udc5c",fitzpatrick_scale:!1,category:"people"},briefcase:{keywords:["business","documents","work","law","legal","job","career"],char:"\ud83d\udcbc",fitzpatrick_scale:!1,category:"people"},eyeglasses:{keywords:["fashion","accessories","eyesight","nerdy","dork","geek"],char:"\ud83d\udc53",fitzpatrick_scale:!1,category:"people"},dark_sunglasses:{keywords:["face","cool","accessories"],char:"\ud83d\udd76",fitzpatrick_scale:!1,category:"people"},goggles:{keywords:["eyes","protection","safety"],char:"\ud83e\udd7d",fitzpatrick_scale:!1,category:"people"},ring:{keywords:["wedding","propose","marriage","valentines","diamond","fashion","jewelry","gem","engagement"],char:"\ud83d\udc8d",fitzpatrick_scale:!1,category:"people"},closed_umbrella:{keywords:["weather","rain","drizzle"],char:"\ud83c\udf02",fitzpatrick_scale:!1,category:"people"},dog:{keywords:["animal","friend","nature","woof","puppy","pet","faithful"],char:"\ud83d\udc36",fitzpatrick_scale:!1,category:"animals_and_nature"},cat:{keywords:["animal","meow","nature","pet","kitten"],char:"\ud83d\udc31",fitzpatrick_scale:!1,category:"animals_and_nature"},mouse:{keywords:["animal","nature","cheese_wedge","rodent"],char:"\ud83d\udc2d",fitzpatrick_scale:!1,category:"animals_and_nature"},hamster:{keywords:["animal","nature"],char:"\ud83d\udc39",fitzpatrick_scale:!1,category:"animals_and_nature"},rabbit:{keywords:["animal","nature","pet","spring","magic","bunny"],char:"\ud83d\udc30",fitzpatrick_scale:!1,category:"animals_and_nature"},fox_face:{keywords:["animal","nature","face"],char:"\ud83e\udd8a",fitzpatrick_scale:!1,category:"animals_and_nature"},bear:{keywords:["animal","nature","wild"],char:"\ud83d\udc3b",fitzpatrick_scale:!1,category:"animals_and_nature"},panda_face:{keywords:["animal","nature","panda"],char:"\ud83d\udc3c",fitzpatrick_scale:!1,category:"animals_and_nature"},koala:{keywords:["animal","nature"],char:"\ud83d\udc28",fitzpatrick_scale:!1,category:"animals_and_nature"},tiger:{keywords:["animal","cat","danger","wild","nature","roar"],char:"\ud83d\udc2f",fitzpatrick_scale:!1,category:"animals_and_nature"},lion:{keywords:["animal","nature"],char:"\ud83e\udd81",fitzpatrick_scale:!1,category:"animals_and_nature"},cow:{keywords:["beef","ox","animal","nature","moo","milk"],char:"\ud83d\udc2e",fitzpatrick_scale:!1,category:"animals_and_nature"},pig:{keywords:["animal","oink","nature"],char:"\ud83d\udc37",fitzpatrick_scale:!1,category:"animals_and_nature"},pig_nose:{keywords:["animal","oink"],char:"\ud83d\udc3d",fitzpatrick_scale:!1,category:"animals_and_nature"},frog:{keywords:["animal","nature","croak","toad"],char:"\ud83d\udc38",fitzpatrick_scale:!1,category:"animals_and_nature"},squid:{keywords:["animal","nature","ocean","sea"],char:"\ud83e\udd91",fitzpatrick_scale:!1,category:"animals_and_nature"},octopus:{keywords:["animal","creature","ocean","sea","nature","beach"],char:"\ud83d\udc19",fitzpatrick_scale:!1,category:"animals_and_nature"},shrimp:{keywords:["animal","ocean","nature","seafood"],char:"\ud83e\udd90",fitzpatrick_scale:!1,category:"animals_and_nature"},monkey_face:{keywords:["animal","nature","circus"],char:"\ud83d\udc35",fitzpatrick_scale:!1,category:"animals_and_nature"},gorilla:{keywords:["animal","nature","circus"],char:"\ud83e\udd8d",fitzpatrick_scale:!1,category:"animals_and_nature"},see_no_evil:{keywords:["monkey","animal","nature","haha"],char:"\ud83d\ude48",fitzpatrick_scale:!1,category:"animals_and_nature"},hear_no_evil:{keywords:["animal","monkey","nature"],char:"\ud83d\ude49",fitzpatrick_scale:!1,category:"animals_and_nature"},speak_no_evil:{keywords:["monkey","animal","nature","omg"],char:"\ud83d\ude4a",fitzpatrick_scale:!1,category:"animals_and_nature"},monkey:{keywords:["animal","nature","banana","circus"],char:"\ud83d\udc12",fitzpatrick_scale:!1,category:"animals_and_nature"},chicken:{keywords:["animal","cluck","nature","bird"],char:"\ud83d\udc14",fitzpatrick_scale:!1,category:"animals_and_nature"},penguin:{keywords:["animal","nature"],char:"\ud83d\udc27",fitzpatrick_scale:!1,category:"animals_and_nature"},bird:{keywords:["animal","nature","fly","tweet","spring"],char:"\ud83d\udc26",fitzpatrick_scale:!1,category:"animals_and_nature"},baby_chick:{keywords:["animal","chicken","bird"],char:"\ud83d\udc24",fitzpatrick_scale:!1,category:"animals_and_nature"},hatching_chick:{keywords:["animal","chicken","egg","born","baby","bird"],char:"\ud83d\udc23",fitzpatrick_scale:!1,category:"animals_and_nature"},hatched_chick:{keywords:["animal","chicken","baby","bird"],char:"\ud83d\udc25",fitzpatrick_scale:!1,category:"animals_and_nature"},duck:{keywords:["animal","nature","bird","mallard"],char:"\ud83e\udd86",fitzpatrick_scale:!1,category:"animals_and_nature"},eagle:{keywords:["animal","nature","bird"],char:"\ud83e\udd85",fitzpatrick_scale:!1,category:"animals_and_nature"},owl:{keywords:["animal","nature","bird","hoot"],char:"\ud83e\udd89",fitzpatrick_scale:!1,category:"animals_and_nature"},bat:{keywords:["animal","nature","blind","vampire"],char:"\ud83e\udd87",fitzpatrick_scale:!1,category:"animals_and_nature"},wolf:{keywords:["animal","nature","wild"],char:"\ud83d\udc3a",fitzpatrick_scale:!1,category:"animals_and_nature"},boar:{keywords:["animal","nature"],char:"\ud83d\udc17",fitzpatrick_scale:!1,category:"animals_and_nature"},horse:{keywords:["animal","brown","nature"],char:"\ud83d\udc34",fitzpatrick_scale:!1,category:"animals_and_nature"},unicorn:{keywords:["animal","nature","mystical"],char:"\ud83e\udd84",fitzpatrick_scale:!1,category:"animals_and_nature"},honeybee:{keywords:["animal","insect","nature","bug","spring","honey"],char:"\ud83d\udc1d",fitzpatrick_scale:!1,category:"animals_and_nature"},bug:{keywords:["animal","insect","nature","worm"],char:"\ud83d\udc1b",fitzpatrick_scale:!1,category:"animals_and_nature"},butterfly:{keywords:["animal","insect","nature","caterpillar"],char:"\ud83e\udd8b",fitzpatrick_scale:!1,category:"animals_and_nature"},snail:{keywords:["slow","animal","shell"],char:"\ud83d\udc0c",fitzpatrick_scale:!1,category:"animals_and_nature"},beetle:{keywords:["animal","insect","nature","ladybug"],char:"\ud83d\udc1e",fitzpatrick_scale:!1,category:"animals_and_nature"},ant:{keywords:["animal","insect","nature","bug"],char:"\ud83d\udc1c",fitzpatrick_scale:!1,category:"animals_and_nature"},grasshopper:{keywords:["animal","cricket","chirp"],char:"\ud83e\udd97",fitzpatrick_scale:!1,category:"animals_and_nature"},spider:{keywords:["animal","arachnid"],char:"\ud83d\udd77",fitzpatrick_scale:!1,category:"animals_and_nature"},scorpion:{keywords:["animal","arachnid"],char:"\ud83e\udd82",fitzpatrick_scale:!1,category:"animals_and_nature"},crab:{keywords:["animal","crustacean"],char:"\ud83e\udd80",fitzpatrick_scale:!1,category:"animals_and_nature"},snake:{keywords:["animal","evil","nature","hiss","python"],char:"\ud83d\udc0d",fitzpatrick_scale:!1,category:"animals_and_nature"},lizard:{keywords:["animal","nature","reptile"],char:"\ud83e\udd8e",fitzpatrick_scale:!1,category:"animals_and_nature"},"t-rex":{keywords:["animal","nature","dinosaur","tyrannosaurus","extinct"],char:"\ud83e\udd96",fitzpatrick_scale:!1,category:"animals_and_nature"},sauropod:{keywords:["animal","nature","dinosaur","brachiosaurus","brontosaurus","diplodocus","extinct"],char:"\ud83e\udd95",fitzpatrick_scale:!1,category:"animals_and_nature"},turtle:{keywords:["animal","slow","nature","tortoise"],char:"\ud83d\udc22",fitzpatrick_scale:!1,category:"animals_and_nature"},tropical_fish:{keywords:["animal","swim","ocean","beach","nemo"],char:"\ud83d\udc20",fitzpatrick_scale:!1,category:"animals_and_nature"},fish:{keywords:["animal","food","nature"],char:"\ud83d\udc1f",fitzpatrick_scale:!1,category:"animals_and_nature"},blowfish:{keywords:["animal","nature","food","sea","ocean"],char:"\ud83d\udc21",fitzpatrick_scale:!1,category:"animals_and_nature"},dolphin:{keywords:["animal","nature","fish","sea","ocean","flipper","fins","beach"],char:"\ud83d\udc2c",fitzpatrick_scale:!1,category:"animals_and_nature"},shark:{keywords:["animal","nature","fish","sea","ocean","jaws","fins","beach"],char:"\ud83e\udd88",fitzpatrick_scale:!1,category:"animals_and_nature"},whale:{keywords:["animal","nature","sea","ocean"],char:"\ud83d\udc33",fitzpatrick_scale:!1,category:"animals_and_nature"},whale2:{keywords:["animal","nature","sea","ocean"],char:"\ud83d\udc0b",fitzpatrick_scale:!1,category:"animals_and_nature"},crocodile:{keywords:["animal","nature","reptile","lizard","alligator"],char:"\ud83d\udc0a",fitzpatrick_scale:!1,category:"animals_and_nature"},leopard:{keywords:["animal","nature"],char:"\ud83d\udc06",fitzpatrick_scale:!1,category:"animals_and_nature"},zebra:{keywords:["animal","nature","stripes","safari"],char:"\ud83e\udd93",fitzpatrick_scale:!1,category:"animals_and_nature"},tiger2:{keywords:["animal","nature","roar"],char:"\ud83d\udc05",fitzpatrick_scale:!1,category:"animals_and_nature"},water_buffalo:{keywords:["animal","nature","ox","cow"],char:"\ud83d\udc03",fitzpatrick_scale:!1,category:"animals_and_nature"},ox:{keywords:["animal","cow","beef"],char:"\ud83d\udc02",fitzpatrick_scale:!1,category:"animals_and_nature"},cow2:{keywords:["beef","ox","animal","nature","moo","milk"],char:"\ud83d\udc04",fitzpatrick_scale:!1,category:"animals_and_nature"},deer:{keywords:["animal","nature","horns","venison"],char:"\ud83e\udd8c",fitzpatrick_scale:!1,category:"animals_and_nature"},dromedary_camel:{keywords:["animal","hot","desert","hump"],char:"\ud83d\udc2a",fitzpatrick_scale:!1,category:"animals_and_nature"},camel:{keywords:["animal","nature","hot","desert","hump"],char:"\ud83d\udc2b",fitzpatrick_scale:!1,category:"animals_and_nature"},giraffe:{keywords:["animal","nature","spots","safari"],char:"\ud83e\udd92",fitzpatrick_scale:!1,category:"animals_and_nature"},elephant:{keywords:["animal","nature","nose","th","circus"],char:"\ud83d\udc18",fitzpatrick_scale:!1,category:"animals_and_nature"},rhinoceros:{keywords:["animal","nature","horn"],char:"\ud83e\udd8f",fitzpatrick_scale:!1,category:"animals_and_nature"},goat:{keywords:["animal","nature"],char:"\ud83d\udc10",fitzpatrick_scale:!1,category:"animals_and_nature"},ram:{keywords:["animal","sheep","nature"],char:"\ud83d\udc0f",fitzpatrick_scale:!1,category:"animals_and_nature"},sheep:{keywords:["animal","nature","wool","shipit"],char:"\ud83d\udc11",fitzpatrick_scale:!1,category:"animals_and_nature"},racehorse:{keywords:["animal","gamble","luck"],char:"\ud83d\udc0e",fitzpatrick_scale:!1,category:"animals_and_nature"},pig2:{keywords:["animal","nature"],char:"\ud83d\udc16",fitzpatrick_scale:!1,category:"animals_and_nature"},rat:{keywords:["animal","mouse","rodent"],char:"\ud83d\udc00",fitzpatrick_scale:!1,category:"animals_and_nature"},mouse2:{keywords:["animal","nature","rodent"],char:"\ud83d\udc01",fitzpatrick_scale:!1,category:"animals_and_nature"},rooster:{keywords:["animal","nature","chicken"],char:"\ud83d\udc13",fitzpatrick_scale:!1,category:"animals_and_nature"},turkey:{keywords:["animal","bird"],char:"\ud83e\udd83",fitzpatrick_scale:!1,category:"animals_and_nature"},dove:{keywords:["animal","bird"],char:"\ud83d\udd4a",fitzpatrick_scale:!1,category:"animals_and_nature"},dog2:{keywords:["animal","nature","friend","doge","pet","faithful"],char:"\ud83d\udc15",fitzpatrick_scale:!1,category:"animals_and_nature"},poodle:{keywords:["dog","animal","101","nature","pet"],char:"\ud83d\udc29",fitzpatrick_scale:!1,category:"animals_and_nature"},cat2:{keywords:["animal","meow","pet","cats"],char:"\ud83d\udc08",fitzpatrick_scale:!1,category:"animals_and_nature"},rabbit2:{keywords:["animal","nature","pet","magic","spring"],char:"\ud83d\udc07",fitzpatrick_scale:!1,category:"animals_and_nature"},chipmunk:{keywords:["animal","nature","rodent","squirrel"],char:"\ud83d\udc3f",fitzpatrick_scale:!1,category:"animals_and_nature"},hedgehog:{keywords:["animal","nature","spiny"],char:"\ud83e\udd94",fitzpatrick_scale:!1,category:"animals_and_nature"},raccoon:{keywords:["animal","nature"],char:"\ud83e\udd9d",fitzpatrick_scale:!1,category:"animals_and_nature"},llama:{keywords:["animal","nature","alpaca"],char:"\ud83e\udd99",fitzpatrick_scale:!1,category:"animals_and_nature"},hippopotamus:{keywords:["animal","nature"],char:"\ud83e\udd9b",fitzpatrick_scale:!1,category:"animals_and_nature"},kangaroo:{keywords:["animal","nature","australia","joey","hop","marsupial"],char:"\ud83e\udd98",fitzpatrick_scale:!1,category:"animals_and_nature"},badger:{keywords:["animal","nature","honey"],char:"\ud83e\udda1",fitzpatrick_scale:!1,category:"animals_and_nature"},swan:{keywords:["animal","nature","bird"],char:"\ud83e\udda2",fitzpatrick_scale:!1,category:"animals_and_nature"},peacock:{keywords:["animal","nature","peahen","bird"],char:"\ud83e\udd9a",fitzpatrick_scale:!1,category:"animals_and_nature"},parrot:{keywords:["animal","nature","bird","pirate","talk"],char:"\ud83e\udd9c",fitzpatrick_scale:!1,category:"animals_and_nature"},lobster:{keywords:["animal","nature","bisque","claws","seafood"],char:"\ud83e\udd9e",fitzpatrick_scale:!1,category:"animals_and_nature"},mosquito:{keywords:["animal","nature","insect","malaria"],char:"\ud83e\udd9f",fitzpatrick_scale:!1,category:"animals_and_nature"},paw_prints:{keywords:["animal","tracking","footprints","dog","cat","pet","feet"],char:"\ud83d\udc3e",fitzpatrick_scale:!1,category:"animals_and_nature"},dragon:{keywords:["animal","myth","nature","chinese","green"],char:"\ud83d\udc09",fitzpatrick_scale:!1,category:"animals_and_nature"},dragon_face:{keywords:["animal","myth","nature","chinese","green"],char:"\ud83d\udc32",fitzpatrick_scale:!1,category:"animals_and_nature"},cactus:{keywords:["vegetable","plant","nature"],char:"\ud83c\udf35",fitzpatrick_scale:!1,category:"animals_and_nature"},christmas_tree:{keywords:["festival","vacation","december","xmas","celebration"],char:"\ud83c\udf84",fitzpatrick_scale:!1,category:"animals_and_nature"},evergreen_tree:{keywords:["plant","nature"],char:"\ud83c\udf32",fitzpatrick_scale:!1,category:"animals_and_nature"},deciduous_tree:{keywords:["plant","nature"],char:"\ud83c\udf33",fitzpatrick_scale:!1,category:"animals_and_nature"},palm_tree:{keywords:["plant","vegetable","nature","summer","beach","mojito","tropical"],char:"\ud83c\udf34",fitzpatrick_scale:!1,category:"animals_and_nature"},seedling:{keywords:["plant","nature","grass","lawn","spring"],char:"\ud83c\udf31",fitzpatrick_scale:!1,category:"animals_and_nature"},herb:{keywords:["vegetable","plant","medicine","weed","grass","lawn"],char:"\ud83c\udf3f",fitzpatrick_scale:!1,category:"animals_and_nature"},shamrock:{keywords:["vegetable","plant","nature","irish","clover"],char:"\u2618",fitzpatrick_scale:!1,category:"animals_and_nature"},four_leaf_clover:{keywords:["vegetable","plant","nature","lucky","irish"],char:"\ud83c\udf40",fitzpatrick_scale:!1,category:"animals_and_nature"},bamboo:{keywords:["plant","nature","vegetable","panda","pine_decoration"],char:"\ud83c\udf8d",fitzpatrick_scale:!1,category:"animals_and_nature"},tanabata_tree:{keywords:["plant","nature","branch","summer"],char:"\ud83c\udf8b",fitzpatrick_scale:!1,category:"animals_and_nature"},leaves:{keywords:["nature","plant","tree","vegetable","grass","lawn","spring"],char:"\ud83c\udf43",fitzpatrick_scale:!1,category:"animals_and_nature"},fallen_leaf:{keywords:["nature","plant","vegetable","leaves"],char:"\ud83c\udf42",fitzpatrick_scale:!1,category:"animals_and_nature"},maple_leaf:{keywords:["nature","plant","vegetable","ca","fall"],char:"\ud83c\udf41",fitzpatrick_scale:!1,category:"animals_and_nature"},ear_of_rice:{keywords:["nature","plant"],char:"\ud83c\udf3e",fitzpatrick_scale:!1,category:"animals_and_nature"},hibiscus:{keywords:["plant","vegetable","flowers","beach"],char:"\ud83c\udf3a",fitzpatrick_scale:!1,category:"animals_and_nature"},sunflower:{keywords:["nature","plant","fall"],char:"\ud83c\udf3b",fitzpatrick_scale:!1,category:"animals_and_nature"},rose:{keywords:["flowers","valentines","love","spring"],char:"\ud83c\udf39",fitzpatrick_scale:!1,category:"animals_and_nature"},wilted_flower:{keywords:["plant","nature","flower"],char:"\ud83e\udd40",fitzpatrick_scale:!1,category:"animals_and_nature"},tulip:{keywords:["flowers","plant","nature","summer","spring"],char:"\ud83c\udf37",fitzpatrick_scale:!1,category:"animals_and_nature"},blossom:{keywords:["nature","flowers","yellow"],char:"\ud83c\udf3c",fitzpatrick_scale:!1,category:"animals_and_nature"},cherry_blossom:{keywords:["nature","plant","spring","flower"],char:"\ud83c\udf38",fitzpatrick_scale:!1,category:"animals_and_nature"},bouquet:{keywords:["flowers","nature","spring"],char:"\ud83d\udc90",fitzpatrick_scale:!1,category:"animals_and_nature"},mushroom:{keywords:["plant","vegetable"],char:"\ud83c\udf44",fitzpatrick_scale:!1,category:"animals_and_nature"},chestnut:{keywords:["food","squirrel"],char:"\ud83c\udf30",fitzpatrick_scale:!1,category:"animals_and_nature"},jack_o_lantern:{keywords:["halloween","light","pumpkin","creepy","fall"],char:"\ud83c\udf83",fitzpatrick_scale:!1,category:"animals_and_nature"},shell:{keywords:["nature","sea","beach"],char:"\ud83d\udc1a",fitzpatrick_scale:!1,category:"animals_and_nature"},spider_web:{keywords:["animal","insect","arachnid","silk"],char:"\ud83d\udd78",fitzpatrick_scale:!1,category:"animals_and_nature"},earth_americas:{keywords:["globe","world","USA","international"],char:"\ud83c\udf0e",fitzpatrick_scale:!1,category:"animals_and_nature"},earth_africa:{keywords:["globe","world","international"],char:"\ud83c\udf0d",fitzpatrick_scale:!1,category:"animals_and_nature"},earth_asia:{keywords:["globe","world","east","international"],char:"\ud83c\udf0f",fitzpatrick_scale:!1,category:"animals_and_nature"},full_moon:{keywords:["nature","yellow","twilight","planet","space","night","evening","sleep"],char:"\ud83c\udf15",fitzpatrick_scale:!1,category:"animals_and_nature"},waning_gibbous_moon:{keywords:["nature","twilight","planet","space","night","evening","sleep","waxing_gibbous_moon"],char:"\ud83c\udf16",fitzpatrick_scale:!1,category:"animals_and_nature"},last_quarter_moon:{keywords:["nature","twilight","planet","space","night","evening","sleep"],char:"\ud83c\udf17",fitzpatrick_scale:!1,category:"animals_and_nature"},waning_crescent_moon:{keywords:["nature","twilight","planet","space","night","evening","sleep"],char:"\ud83c\udf18",fitzpatrick_scale:!1,category:"animals_and_nature"},new_moon:{keywords:["nature","twilight","planet","space","night","evening","sleep"],char:"\ud83c\udf11",fitzpatrick_scale:!1,category:"animals_and_nature"},waxing_crescent_moon:{keywords:["nature","twilight","planet","space","night","evening","sleep"],char:"\ud83c\udf12",fitzpatrick_scale:!1,category:"animals_and_nature"},first_quarter_moon:{keywords:["nature","twilight","planet","space","night","evening","sleep"],char:"\ud83c\udf13",fitzpatrick_scale:!1,category:"animals_and_nature"},waxing_gibbous_moon:{keywords:["nature","night","sky","gray","twilight","planet","space","evening","sleep"],char:"\ud83c\udf14",fitzpatrick_scale:!1,category:"animals_and_nature"},new_moon_with_face:{keywords:["nature","twilight","planet","space","night","evening","sleep"],char:"\ud83c\udf1a",fitzpatrick_scale:!1,category:"animals_and_nature"},full_moon_with_face:{keywords:["nature","twilight","planet","space","night","evening","sleep"],char:"\ud83c\udf1d",fitzpatrick_scale:!1,category:"animals_and_nature"},first_quarter_moon_with_face:{keywords:["nature","twilight","planet","space","night","evening","sleep"],char:"\ud83c\udf1b",fitzpatrick_scale:!1,category:"animals_and_nature"},last_quarter_moon_with_face:{keywords:["nature","twilight","planet","space","night","evening","sleep"],char:"\ud83c\udf1c",fitzpatrick_scale:!1,category:"animals_and_nature"},sun_with_face:{keywords:["nature","morning","sky"],char:"\ud83c\udf1e",fitzpatrick_scale:!1,category:"animals_and_nature"},crescent_moon:{keywords:["night","sleep","sky","evening","magic"],char:"\ud83c\udf19",fitzpatrick_scale:!1,category:"animals_and_nature"},star:{keywords:["night","yellow"],char:"\u2b50",fitzpatrick_scale:!1,category:"animals_and_nature"},star2:{keywords:["night","sparkle","awesome","good","magic"],char:"\ud83c\udf1f",fitzpatrick_scale:!1,category:"animals_and_nature"},dizzy:{keywords:["star","sparkle","shoot","magic"],char:"\ud83d\udcab",fitzpatrick_scale:!1,category:"animals_and_nature"},sparkles:{keywords:["stars","shine","shiny","cool","awesome","good","magic"],char:"\u2728",fitzpatrick_scale:!1,category:"animals_and_nature"},comet:{keywords:["space"],char:"\u2604",fitzpatrick_scale:!1,category:"animals_and_nature"},sunny:{keywords:["weather","nature","brightness","summer","beach","spring"],char:"\u2600\ufe0f",fitzpatrick_scale:!1,category:"animals_and_nature"},sun_behind_small_cloud:{keywords:["weather"],char:"\ud83c\udf24",fitzpatrick_scale:!1,category:"animals_and_nature"},partly_sunny:{keywords:["weather","nature","cloudy","morning","fall","spring"],char:"\u26c5",fitzpatrick_scale:!1,category:"animals_and_nature"},sun_behind_large_cloud:{keywords:["weather"],char:"\ud83c\udf25",fitzpatrick_scale:!1,category:"animals_and_nature"},sun_behind_rain_cloud:{keywords:["weather"],char:"\ud83c\udf26",fitzpatrick_scale:!1,category:"animals_and_nature"},cloud:{keywords:["weather","sky"],char:"\u2601\ufe0f",fitzpatrick_scale:!1,category:"animals_and_nature"},cloud_with_rain:{keywords:["weather"],char:"\ud83c\udf27",fitzpatrick_scale:!1,category:"animals_and_nature"},cloud_with_lightning_and_rain:{keywords:["weather","lightning"],char:"\u26c8",fitzpatrick_scale:!1,category:"animals_and_nature"},cloud_with_lightning:{keywords:["weather","thunder"],char:"\ud83c\udf29",fitzpatrick_scale:!1,category:"animals_and_nature"},zap:{keywords:["thunder","weather","lightning bolt","fast"],char:"\u26a1",fitzpatrick_scale:!1,category:"animals_and_nature"},fire:{keywords:["hot","cook","flame"],char:"\ud83d\udd25",fitzpatrick_scale:!1,category:"animals_and_nature"},boom:{keywords:["bomb","explode","explosion","collision","blown"],char:"\ud83d\udca5",fitzpatrick_scale:!1,category:"animals_and_nature"},snowflake:{keywords:["winter","season","cold","weather","christmas","xmas"],char:"\u2744\ufe0f",fitzpatrick_scale:!1,category:"animals_and_nature"},cloud_with_snow:{keywords:["weather"],char:"\ud83c\udf28",fitzpatrick_scale:!1,category:"animals_and_nature"},snowman:{keywords:["winter","season","cold","weather","christmas","xmas","frozen","without_snow"],char:"\u26c4",fitzpatrick_scale:!1,category:"animals_and_nature"},snowman_with_snow:{keywords:["winter","season","cold","weather","christmas","xmas","frozen"],char:"\u2603",fitzpatrick_scale:!1,category:"animals_and_nature"},wind_face:{keywords:["gust","air"],char:"\ud83c\udf2c",fitzpatrick_scale:!1,category:"animals_and_nature"},dash:{keywords:["wind","air","fast","shoo","fart","smoke","puff"],char:"\ud83d\udca8",fitzpatrick_scale:!1,category:"animals_and_nature"},tornado:{keywords:["weather","cyclone","twister"],char:"\ud83c\udf2a",fitzpatrick_scale:!1,category:"animals_and_nature"},fog:{keywords:["weather"],char:"\ud83c\udf2b",fitzpatrick_scale:!1,category:"animals_and_nature"},open_umbrella:{keywords:["weather","spring"],char:"\u2602",fitzpatrick_scale:!1,category:"animals_and_nature"},umbrella:{keywords:["rainy","weather","spring"],char:"\u2614",fitzpatrick_scale:!1,category:"animals_and_nature"},droplet:{keywords:["water","drip","faucet","spring"],char:"\ud83d\udca7",fitzpatrick_scale:!1,category:"animals_and_nature"},sweat_drops:{keywords:["water","drip","oops"],char:"\ud83d\udca6",fitzpatrick_scale:!1,category:"animals_and_nature"},ocean:{keywords:["sea","water","wave","nature","tsunami","disaster"],char:"\ud83c\udf0a",fitzpatrick_scale:!1,category:"animals_and_nature"},green_apple:{keywords:["fruit","nature"],char:"\ud83c\udf4f",fitzpatrick_scale:!1,category:"food_and_drink"},apple:{keywords:["fruit","mac","school"],char:"\ud83c\udf4e",fitzpatrick_scale:!1,category:"food_and_drink"},pear:{keywords:["fruit","nature","food"],char:"\ud83c\udf50",fitzpatrick_scale:!1,category:"food_and_drink"},tangerine:{keywords:["food","fruit","nature","orange"],char:"\ud83c\udf4a",fitzpatrick_scale:!1,category:"food_and_drink"},lemon:{keywords:["fruit","nature"],char:"\ud83c\udf4b",fitzpatrick_scale:!1,category:"food_and_drink"},banana:{keywords:["fruit","food","monkey"],char:"\ud83c\udf4c",fitzpatrick_scale:!1,category:"food_and_drink"},watermelon:{keywords:["fruit","food","picnic","summer"],char:"\ud83c\udf49",fitzpatrick_scale:!1,category:"food_and_drink"},grapes:{keywords:["fruit","food","wine"],char:"\ud83c\udf47",fitzpatrick_scale:!1,category:"food_and_drink"},strawberry:{keywords:["fruit","food","nature"],char:"\ud83c\udf53",fitzpatrick_scale:!1,category:"food_and_drink"},melon:{keywords:["fruit","nature","food"],char:"\ud83c\udf48",fitzpatrick_scale:!1,category:"food_and_drink"},cherries:{keywords:["food","fruit"],char:"\ud83c\udf52",fitzpatrick_scale:!1,category:"food_and_drink"},peach:{keywords:["fruit","nature","food"],char:"\ud83c\udf51",fitzpatrick_scale:!1,category:"food_and_drink"},pineapple:{keywords:["fruit","nature","food"],char:"\ud83c\udf4d",fitzpatrick_scale:!1,category:"food_and_drink"},coconut:{keywords:["fruit","nature","food","palm"],char:"\ud83e\udd65",fitzpatrick_scale:!1,category:"food_and_drink"},kiwi_fruit:{keywords:["fruit","food"],char:"\ud83e\udd5d",fitzpatrick_scale:!1,category:"food_and_drink"},mango:{keywords:["fruit","food","tropical"],char:"\ud83e\udd6d",fitzpatrick_scale:!1,category:"food_and_drink"},avocado:{keywords:["fruit","food"],char:"\ud83e\udd51",fitzpatrick_scale:!1,category:"food_and_drink"},broccoli:{keywords:["fruit","food","vegetable"],char:"\ud83e\udd66",fitzpatrick_scale:!1,category:"food_and_drink"},tomato:{keywords:["fruit","vegetable","nature","food"],char:"\ud83c\udf45",fitzpatrick_scale:!1,category:"food_and_drink"},eggplant:{keywords:["vegetable","nature","food","aubergine"],char:"\ud83c\udf46",fitzpatrick_scale:!1,category:"food_and_drink"},cucumber:{keywords:["fruit","food","pickle"],char:"\ud83e\udd52",fitzpatrick_scale:!1,category:"food_and_drink"},carrot:{keywords:["vegetable","food","orange"],char:"\ud83e\udd55",fitzpatrick_scale:!1,category:"food_and_drink"},hot_pepper:{keywords:["food","spicy","chilli","chili"],char:"\ud83c\udf36",fitzpatrick_scale:!1,category:"food_and_drink"},potato:{keywords:["food","tuber","vegatable","starch"],char:"\ud83e\udd54",fitzpatrick_scale:!1,category:"food_and_drink"},corn:{keywords:["food","vegetable","plant"],char:"\ud83c\udf3d",fitzpatrick_scale:!1,category:"food_and_drink"},leafy_greens:{keywords:["food","vegetable","plant","bok choy","cabbage","kale","lettuce"],char:"\ud83e\udd6c",fitzpatrick_scale:!1,category:"food_and_drink"},sweet_potato:{keywords:["food","nature"],char:"\ud83c\udf60",fitzpatrick_scale:!1,category:"food_and_drink"},peanuts:{keywords:["food","nut"],char:"\ud83e\udd5c",fitzpatrick_scale:!1,category:"food_and_drink"},honey_pot:{keywords:["bees","sweet","kitchen"],char:"\ud83c\udf6f",fitzpatrick_scale:!1,category:"food_and_drink"},croissant:{keywords:["food","bread","french"],char:"\ud83e\udd50",fitzpatrick_scale:!1,category:"food_and_drink"},bread:{keywords:["food","wheat","breakfast","toast"],char:"\ud83c\udf5e",fitzpatrick_scale:!1,category:"food_and_drink"},baguette_bread:{keywords:["food","bread","french"],char:"\ud83e\udd56",fitzpatrick_scale:!1,category:"food_and_drink"},bagel:{keywords:["food","bread","bakery","schmear"],char:"\ud83e\udd6f",fitzpatrick_scale:!1,category:"food_and_drink"},pretzel:{keywords:["food","bread","twisted"],char:"\ud83e\udd68",fitzpatrick_scale:!1,category:"food_and_drink"},cheese:{keywords:["food","chadder"],char:"\ud83e\uddc0",fitzpatrick_scale:!1,category:"food_and_drink"},egg:{keywords:["food","chicken","breakfast"],char:"\ud83e\udd5a",fitzpatrick_scale:!1,category:"food_and_drink"},bacon:{keywords:["food","breakfast","pork","pig","meat"],char:"\ud83e\udd53",fitzpatrick_scale:!1,category:"food_and_drink"},steak:{keywords:["food","cow","meat","cut","chop","lambchop","porkchop"],char:"\ud83e\udd69",fitzpatrick_scale:!1,category:"food_and_drink"},pancakes:{keywords:["food","breakfast","flapjacks","hotcakes"],char:"\ud83e\udd5e",fitzpatrick_scale:!1,category:"food_and_drink"},poultry_leg:{keywords:["food","meat","drumstick","bird","chicken","turkey"],char:"\ud83c\udf57",fitzpatrick_scale:!1,category:"food_and_drink"},meat_on_bone:{keywords:["good","food","drumstick"],char:"\ud83c\udf56",fitzpatrick_scale:!1,category:"food_and_drink"},bone:{keywords:["skeleton"],char:"\ud83e\uddb4",fitzpatrick_scale:!1,category:"food_and_drink"},fried_shrimp:{keywords:["food","animal","appetizer","summer"],char:"\ud83c\udf64",fitzpatrick_scale:!1,category:"food_and_drink"},fried_egg:{keywords:["food","breakfast","kitchen","egg"],char:"\ud83c\udf73",fitzpatrick_scale:!1,category:"food_and_drink"},hamburger:{keywords:["meat","fast food","beef","cheeseburger","mcdonalds","burger king"],char:"\ud83c\udf54",fitzpatrick_scale:!1,category:"food_and_drink"},fries:{keywords:["chips","snack","fast food"],char:"\ud83c\udf5f",fitzpatrick_scale:!1,category:"food_and_drink"},stuffed_flatbread:{keywords:["food","flatbread","stuffed","gyro"],char:"\ud83e\udd59",fitzpatrick_scale:!1,category:"food_and_drink"},hotdog:{keywords:["food","frankfurter"],char:"\ud83c\udf2d",fitzpatrick_scale:!1,category:"food_and_drink"},pizza:{keywords:["food","party"],char:"\ud83c\udf55",fitzpatrick_scale:!1,category:"food_and_drink"},sandwich:{keywords:["food","lunch","bread"],char:"\ud83e\udd6a",fitzpatrick_scale:!1,category:"food_and_drink"},canned_food:{keywords:["food","soup"],char:"\ud83e\udd6b",fitzpatrick_scale:!1,category:"food_and_drink"},spaghetti:{keywords:["food","italian","noodle"],char:"\ud83c\udf5d",fitzpatrick_scale:!1,category:"food_and_drink"},taco:{keywords:["food","mexican"],char:"\ud83c\udf2e",fitzpatrick_scale:!1,category:"food_and_drink"},burrito:{keywords:["food","mexican"],char:"\ud83c\udf2f",fitzpatrick_scale:!1,category:"food_and_drink"},green_salad:{keywords:["food","healthy","lettuce"],char:"\ud83e\udd57",fitzpatrick_scale:!1,category:"food_and_drink"},shallow_pan_of_food:{keywords:["food","cooking","casserole","paella"],char:"\ud83e\udd58",fitzpatrick_scale:!1,category:"food_and_drink"},ramen:{keywords:["food","japanese","noodle","chopsticks"],char:"\ud83c\udf5c",fitzpatrick_scale:!1,category:"food_and_drink"},stew:{keywords:["food","meat","soup"],char:"\ud83c\udf72",fitzpatrick_scale:!1,category:"food_and_drink"},fish_cake:{keywords:["food","japan","sea","beach","narutomaki","pink","swirl","kamaboko","surimi","ramen"],char:"\ud83c\udf65",fitzpatrick_scale:!1,category:"food_and_drink"},fortune_cookie:{keywords:["food","prophecy"],char:"\ud83e\udd60",fitzpatrick_scale:!1,category:"food_and_drink"},sushi:{keywords:["food","fish","japanese","rice"],char:"\ud83c\udf63",fitzpatrick_scale:!1,category:"food_and_drink"},bento:{keywords:["food","japanese","box"],char:"\ud83c\udf71",fitzpatrick_scale:!1,category:"food_and_drink"},curry:{keywords:["food","spicy","hot","indian"],char:"\ud83c\udf5b",fitzpatrick_scale:!1,category:"food_and_drink"},rice_ball:{keywords:["food","japanese"],char:"\ud83c\udf59",fitzpatrick_scale:!1,category:"food_and_drink"},rice:{keywords:["food","china","asian"],char:"\ud83c\udf5a",fitzpatrick_scale:!1,category:"food_and_drink"},rice_cracker:{keywords:["food","japanese"],char:"\ud83c\udf58",fitzpatrick_scale:!1,category:"food_and_drink"},oden:{keywords:["food","japanese"],char:"\ud83c\udf62",fitzpatrick_scale:!1,category:"food_and_drink"},dango:{keywords:["food","dessert","sweet","japanese","barbecue","meat"],char:"\ud83c\udf61",fitzpatrick_scale:!1,category:"food_and_drink"},shaved_ice:{keywords:["hot","dessert","summer"],char:"\ud83c\udf67",fitzpatrick_scale:!1,category:"food_and_drink"},ice_cream:{keywords:["food","hot","dessert"],char:"\ud83c\udf68",fitzpatrick_scale:!1,category:"food_and_drink"},icecream:{keywords:["food","hot","dessert","summer"],char:"\ud83c\udf66",fitzpatrick_scale:!1,category:"food_and_drink"},pie:{keywords:["food","dessert","pastry"],char:"\ud83e\udd67",fitzpatrick_scale:!1,category:"food_and_drink"},cake:{keywords:["food","dessert"],char:"\ud83c\udf70",fitzpatrick_scale:!1,category:"food_and_drink"},cupcake:{keywords:["food","dessert","bakery","sweet"],char:"\ud83e\uddc1",fitzpatrick_scale:!1,category:"food_and_drink"},moon_cake:{keywords:["food","autumn"],char:"\ud83e\udd6e",fitzpatrick_scale:!1,category:"food_and_drink"},birthday:{keywords:["food","dessert","cake"],char:"\ud83c\udf82",fitzpatrick_scale:!1,category:"food_and_drink"},custard:{keywords:["dessert","food"],char:"\ud83c\udf6e",fitzpatrick_scale:!1,category:"food_and_drink"},candy:{keywords:["snack","dessert","sweet","lolly"],char:"\ud83c\udf6c",fitzpatrick_scale:!1,category:"food_and_drink"},lollipop:{keywords:["food","snack","candy","sweet"],char:"\ud83c\udf6d",fitzpatrick_scale:!1,category:"food_and_drink"},chocolate_bar:{keywords:["food","snack","dessert","sweet"],char:"\ud83c\udf6b",fitzpatrick_scale:!1,category:"food_and_drink"},popcorn:{keywords:["food","movie theater","films","snack"],char:"\ud83c\udf7f",fitzpatrick_scale:!1,category:"food_and_drink"},dumpling:{keywords:["food","empanada","pierogi","potsticker"],char:"\ud83e\udd5f",fitzpatrick_scale:!1,category:"food_and_drink"},doughnut:{keywords:["food","dessert","snack","sweet","donut"],char:"\ud83c\udf69",fitzpatrick_scale:!1,category:"food_and_drink"},cookie:{keywords:["food","snack","oreo","chocolate","sweet","dessert"],char:"\ud83c\udf6a",fitzpatrick_scale:!1,category:"food_and_drink"},milk_glass:{keywords:["beverage","drink","cow"],char:"\ud83e\udd5b",fitzpatrick_scale:!1,category:"food_and_drink"},beer:{keywords:["relax","beverage","drink","drunk","party","pub","summer","alcohol","booze"],char:"\ud83c\udf7a",fitzpatrick_scale:!1,category:"food_and_drink"},beers:{keywords:["relax","beverage","drink","drunk","party","pub","summer","alcohol","booze"],char:"\ud83c\udf7b",fitzpatrick_scale:!1,category:"food_and_drink"},clinking_glasses:{keywords:["beverage","drink","party","alcohol","celebrate","cheers","wine","champagne","toast"],char:"\ud83e\udd42",fitzpatrick_scale:!1,category:"food_and_drink"},wine_glass:{keywords:["drink","beverage","drunk","alcohol","booze"],char:"\ud83c\udf77",fitzpatrick_scale:!1,category:"food_and_drink"},tumbler_glass:{keywords:["drink","beverage","drunk","alcohol","liquor","booze","bourbon","scotch","whisky","glass","shot"],char:"\ud83e\udd43",fitzpatrick_scale:!1,category:"food_and_drink"},cocktail:{keywords:["drink","drunk","alcohol","beverage","booze","mojito"],char:"\ud83c\udf78",fitzpatrick_scale:!1,category:"food_and_drink"},tropical_drink:{keywords:["beverage","cocktail","summer","beach","alcohol","booze","mojito"],char:"\ud83c\udf79",fitzpatrick_scale:!1,category:"food_and_drink"},champagne:{keywords:["drink","wine","bottle","celebration"],char:"\ud83c\udf7e",fitzpatrick_scale:!1,category:"food_and_drink"},sake:{keywords:["wine","drink","drunk","beverage","japanese","alcohol","booze"],char:"\ud83c\udf76",fitzpatrick_scale:!1,category:"food_and_drink"},tea:{keywords:["drink","bowl","breakfast","green","british"],char:"\ud83c\udf75",fitzpatrick_scale:!1,category:"food_and_drink"},cup_with_straw:{keywords:["drink","soda"],char:"\ud83e\udd64",fitzpatrick_scale:!1,category:"food_and_drink"},coffee:{keywords:["beverage","caffeine","latte","espresso"],char:"\u2615",fitzpatrick_scale:!1,category:"food_and_drink"},baby_bottle:{keywords:["food","container","milk"],char:"\ud83c\udf7c",fitzpatrick_scale:!1,category:"food_and_drink"},salt:{keywords:["condiment","shaker"],char:"\ud83e\uddc2",fitzpatrick_scale:!1,category:"food_and_drink"},spoon:{keywords:["cutlery","kitchen","tableware"],char:"\ud83e\udd44",fitzpatrick_scale:!1,category:"food_and_drink"},fork_and_knife:{keywords:["cutlery","kitchen"],char:"\ud83c\udf74",fitzpatrick_scale:!1,category:"food_and_drink"},plate_with_cutlery:{keywords:["food","eat","meal","lunch","dinner","restaurant"],char:"\ud83c\udf7d",fitzpatrick_scale:!1,category:"food_and_drink"},bowl_with_spoon:{keywords:["food","breakfast","cereal","oatmeal","porridge"],char:"\ud83e\udd63",fitzpatrick_scale:!1,category:"food_and_drink"},takeout_box:{keywords:["food","leftovers"],char:"\ud83e\udd61",fitzpatrick_scale:!1,category:"food_and_drink"},chopsticks:{keywords:["food"],char:"\ud83e\udd62",fitzpatrick_scale:!1,category:"food_and_drink"},soccer:{keywords:["sports","football"],char:"\u26bd",fitzpatrick_scale:!1,category:"activity"},basketball:{keywords:["sports","balls","NBA"],char:"\ud83c\udfc0",fitzpatrick_scale:!1,category:"activity"},football:{keywords:["sports","balls","NFL"],char:"\ud83c\udfc8",fitzpatrick_scale:!1,category:"activity"},baseball:{keywords:["sports","balls"],char:"\u26be",fitzpatrick_scale:!1,category:"activity"},softball:{keywords:["sports","balls"],char:"\ud83e\udd4e",fitzpatrick_scale:!1,category:"activity"},tennis:{keywords:["sports","balls","green"],char:"\ud83c\udfbe",fitzpatrick_scale:!1,category:"activity"},volleyball:{keywords:["sports","balls"],char:"\ud83c\udfd0",fitzpatrick_scale:!1,category:"activity"},rugby_football:{keywords:["sports","team"],char:"\ud83c\udfc9",fitzpatrick_scale:!1,category:"activity"},flying_disc:{keywords:["sports","frisbee","ultimate"],char:"\ud83e\udd4f",fitzpatrick_scale:!1,category:"activity"},"8ball":{keywords:["pool","hobby","game","luck","magic"],char:"\ud83c\udfb1",fitzpatrick_scale:!1,category:"activity"},golf:{keywords:["sports","business","flag","hole","summer"],char:"\u26f3",fitzpatrick_scale:!1,category:"activity"},golfing_woman:{keywords:["sports","business","woman","female"],char:"\ud83c\udfcc\ufe0f\u200d\u2640\ufe0f",fitzpatrick_scale:!1,category:"activity"},golfing_man:{keywords:["sports","business"],char:"\ud83c\udfcc",fitzpatrick_scale:!0,category:"activity"},ping_pong:{keywords:["sports","pingpong"],char:"\ud83c\udfd3",fitzpatrick_scale:!1,category:"activity"},badminton:{keywords:["sports"],char:"\ud83c\udff8",fitzpatrick_scale:!1,category:"activity"},goal_net:{keywords:["sports"],char:"\ud83e\udd45",fitzpatrick_scale:!1,category:"activity"},ice_hockey:{keywords:["sports"],char:"\ud83c\udfd2",fitzpatrick_scale:!1,category:"activity"},field_hockey:{keywords:["sports"],char:"\ud83c\udfd1",fitzpatrick_scale:!1,category:"activity"},lacrosse:{keywords:["sports","ball","stick"],char:"\ud83e\udd4d",fitzpatrick_scale:!1,category:"activity"},cricket:{keywords:["sports"],char:"\ud83c\udfcf",fitzpatrick_scale:!1,category:"activity"},ski:{keywords:["sports","winter","cold","snow"],char:"\ud83c\udfbf",fitzpatrick_scale:!1,category:"activity"},skier:{keywords:["sports","winter","snow"],char:"\u26f7",fitzpatrick_scale:!1,category:"activity"},snowboarder:{keywords:["sports","winter"],char:"\ud83c\udfc2",fitzpatrick_scale:!0,category:"activity"},person_fencing:{keywords:["sports","fencing","sword"],char:"\ud83e\udd3a",fitzpatrick_scale:!1,category:"activity"},women_wrestling:{keywords:["sports","wrestlers"],char:"\ud83e\udd3c\u200d\u2640\ufe0f",fitzpatrick_scale:!1,category:"activity"},men_wrestling:{keywords:["sports","wrestlers"],char:"\ud83e\udd3c\u200d\u2642\ufe0f",fitzpatrick_scale:!1,category:"activity"},woman_cartwheeling:{keywords:["gymnastics"],char:"\ud83e\udd38\u200d\u2640\ufe0f",fitzpatrick_scale:!0,category:"activity"},man_cartwheeling:{keywords:["gymnastics"],char:"\ud83e\udd38\u200d\u2642\ufe0f",fitzpatrick_scale:!0,category:"activity"},woman_playing_handball:{keywords:["sports"],char:"\ud83e\udd3e\u200d\u2640\ufe0f",fitzpatrick_scale:!0,category:"activity"},man_playing_handball:{keywords:["sports"],char:"\ud83e\udd3e\u200d\u2642\ufe0f",fitzpatrick_scale:!0,category:"activity"},ice_skate:{keywords:["sports"],char:"\u26f8",fitzpatrick_scale:!1,category:"activity"},curling_stone:{keywords:["sports"],char:"\ud83e\udd4c",fitzpatrick_scale:!1,category:"activity"},skateboard:{keywords:["board"],char:"\ud83d\udef9",fitzpatrick_scale:!1,category:"activity"},sled:{keywords:["sleigh","luge","toboggan"],char:"\ud83d\udef7",fitzpatrick_scale:!1,category:"activity"},bow_and_arrow:{keywords:["sports"],char:"\ud83c\udff9",fitzpatrick_scale:!1,category:"activity"},fishing_pole_and_fish:{keywords:["food","hobby","summer"],char:"\ud83c\udfa3",fitzpatrick_scale:!1,category:"activity"},boxing_glove:{keywords:["sports","fighting"],char:"\ud83e\udd4a",fitzpatrick_scale:!1,category:"activity"},martial_arts_uniform:{keywords:["judo","karate","taekwondo"],char:"\ud83e\udd4b",fitzpatrick_scale:!1,category:"activity"},rowing_woman:{keywords:["sports","hobby","water","ship","woman","female"],char:"\ud83d\udea3\u200d\u2640\ufe0f",fitzpatrick_scale:!0,category:"activity"},rowing_man:{keywords:["sports","hobby","water","ship"],char:"\ud83d\udea3",fitzpatrick_scale:!0,category:"activity"},climbing_woman:{keywords:["sports","hobby","woman","female","rock"],char:"\ud83e\uddd7\u200d\u2640\ufe0f",fitzpatrick_scale:!0,category:"activity"},climbing_man:{keywords:["sports","hobby","man","male","rock"],char:"\ud83e\uddd7\u200d\u2642\ufe0f",fitzpatrick_scale:!0,category:"activity"},swimming_woman:{keywords:["sports","exercise","human","athlete","water","summer","woman","female"],char:"\ud83c\udfca\u200d\u2640\ufe0f",fitzpatrick_scale:!0,category:"activity"},swimming_man:{keywords:["sports","exercise","human","athlete","water","summer"],char:"\ud83c\udfca",fitzpatrick_scale:!0,category:"activity"},woman_playing_water_polo:{keywords:["sports","pool"],char:"\ud83e\udd3d\u200d\u2640\ufe0f",fitzpatrick_scale:!0,category:"activity"},man_playing_water_polo:{keywords:["sports","pool"],char:"\ud83e\udd3d\u200d\u2642\ufe0f",fitzpatrick_scale:!0,category:"activity"},woman_in_lotus_position:{keywords:["woman","female","meditation","yoga","serenity","zen","mindfulness"],char:"\ud83e\uddd8\u200d\u2640\ufe0f",fitzpatrick_scale:!0,category:"activity"},man_in_lotus_position:{keywords:["man","male","meditation","yoga","serenity","zen","mindfulness"],char:"\ud83e\uddd8\u200d\u2642\ufe0f",fitzpatrick_scale:!0,category:"activity"},surfing_woman:{keywords:["sports","ocean","sea","summer","beach","woman","female"],char:"\ud83c\udfc4\u200d\u2640\ufe0f",fitzpatrick_scale:!0,category:"activity"},surfing_man:{keywords:["sports","ocean","sea","summer","beach"],char:"\ud83c\udfc4",fitzpatrick_scale:!0,category:"activity"},bath:{keywords:["clean","shower","bathroom"],char:"\ud83d\udec0",fitzpatrick_scale:!0,category:"activity"},basketball_woman:{keywords:["sports","human","woman","female"],char:"\u26f9\ufe0f\u200d\u2640\ufe0f",fitzpatrick_scale:!0,category:"activity"},basketball_man:{keywords:["sports","human"],char:"\u26f9",fitzpatrick_scale:!0,category:"activity"},weight_lifting_woman:{keywords:["sports","training","exercise","woman","female"],char:"\ud83c\udfcb\ufe0f\u200d\u2640\ufe0f",fitzpatrick_scale:!0,category:"activity"},weight_lifting_man:{keywords:["sports","training","exercise"],char:"\ud83c\udfcb",fitzpatrick_scale:!0,category:"activity"},biking_woman:{keywords:["sports","bike","exercise","hipster","woman","female"],char:"\ud83d\udeb4\u200d\u2640\ufe0f",fitzpatrick_scale:!0,category:"activity"},biking_man:{keywords:["sports","bike","exercise","hipster"],char:"\ud83d\udeb4",fitzpatrick_scale:!0,category:"activity"},mountain_biking_woman:{keywords:["transportation","sports","human","race","bike","woman","female"],char:"\ud83d\udeb5\u200d\u2640\ufe0f",fitzpatrick_scale:!0,category:"activity"},mountain_biking_man:{keywords:["transportation","sports","human","race","bike"],char:"\ud83d\udeb5",fitzpatrick_scale:!0,category:"activity"},horse_racing:{keywords:["animal","betting","competition","gambling","luck"],char:"\ud83c\udfc7",fitzpatrick_scale:!0,category:"activity"},business_suit_levitating:{keywords:["suit","business","levitate","hover","jump"],char:"\ud83d\udd74",fitzpatrick_scale:!0,category:"activity"},trophy:{keywords:["win","award","contest","place","ftw","ceremony"],char:"\ud83c\udfc6",fitzpatrick_scale:!1,category:"activity"},running_shirt_with_sash:{keywords:["play","pageant"],char:"\ud83c\udfbd",fitzpatrick_scale:!1,category:"activity"},medal_sports:{keywords:["award","winning"],char:"\ud83c\udfc5",fitzpatrick_scale:!1,category:"activity"},medal_military:{keywords:["award","winning","army"],char:"\ud83c\udf96",fitzpatrick_scale:!1,category:"activity"},"1st_place_medal":{keywords:["award","winning","first"],char:"\ud83e\udd47",fitzpatrick_scale:!1,category:"activity"},"2nd_place_medal":{keywords:["award","second"],char:"\ud83e\udd48",fitzpatrick_scale:!1,category:"activity"},"3rd_place_medal":{keywords:["award","third"],char:"\ud83e\udd49",fitzpatrick_scale:!1,category:"activity"},reminder_ribbon:{keywords:["sports","cause","support","awareness"],char:"\ud83c\udf97",fitzpatrick_scale:!1,category:"activity"},rosette:{keywords:["flower","decoration","military"],char:"\ud83c\udff5",fitzpatrick_scale:!1,category:"activity"},ticket:{keywords:["event","concert","pass"],char:"\ud83c\udfab",fitzpatrick_scale:!1,category:"activity"},tickets:{keywords:["sports","concert","entrance"],char:"\ud83c\udf9f",fitzpatrick_scale:!1,category:"activity"},performing_arts:{keywords:["acting","theater","drama"],char:"\ud83c\udfad",fitzpatrick_scale:!1,category:"activity"},art:{keywords:["design","paint","draw","colors"],char:"\ud83c\udfa8",fitzpatrick_scale:!1,category:"activity"},circus_tent:{keywords:["festival","carnival","party"],char:"\ud83c\udfaa",fitzpatrick_scale:!1,category:"activity"},woman_juggling:{keywords:["juggle","balance","skill","multitask"],char:"\ud83e\udd39\u200d\u2640\ufe0f",fitzpatrick_scale:!0,category:"activity"},man_juggling:{keywords:["juggle","balance","skill","multitask"],char:"\ud83e\udd39\u200d\u2642\ufe0f",fitzpatrick_scale:!0,category:"activity"},microphone:{keywords:["sound","music","PA","sing","talkshow"],char:"\ud83c\udfa4",fitzpatrick_scale:!1,category:"activity"},headphones:{keywords:["music","score","gadgets"],char:"\ud83c\udfa7",fitzpatrick_scale:!1,category:"activity"},musical_score:{keywords:["treble","clef","compose"],char:"\ud83c\udfbc",fitzpatrick_scale:!1,category:"activity"},musical_keyboard:{keywords:["piano","instrument","compose"],char:"\ud83c\udfb9",fitzpatrick_scale:!1,category:"activity"},drum:{keywords:["music","instrument","drumsticks","snare"],char:"\ud83e\udd41",fitzpatrick_scale:!1,category:"activity"},saxophone:{keywords:["music","instrument","jazz","blues"],char:"\ud83c\udfb7",fitzpatrick_scale:!1,category:"activity"},trumpet:{keywords:["music","brass"],char:"\ud83c\udfba",fitzpatrick_scale:!1,category:"activity"},guitar:{keywords:["music","instrument"],char:"\ud83c\udfb8",fitzpatrick_scale:!1,category:"activity"},violin:{keywords:["music","instrument","orchestra","symphony"],char:"\ud83c\udfbb",fitzpatrick_scale:!1,category:"activity"},clapper:{keywords:["movie","film","record"],char:"\ud83c\udfac",fitzpatrick_scale:!1,category:"activity"},video_game:{keywords:["play","console","PS4","controller"],char:"\ud83c\udfae",fitzpatrick_scale:!1,category:"activity"},space_invader:{keywords:["game","arcade","play"],char:"\ud83d\udc7e",fitzpatrick_scale:!1,category:"activity"},dart:{keywords:["game","play","bar","target","bullseye"],char:"\ud83c\udfaf",fitzpatrick_scale:!1,category:"activity"},game_die:{keywords:["dice","random","tabletop","play","luck"],char:"\ud83c\udfb2",fitzpatrick_scale:!1,category:"activity"},chess_pawn:{keywords:["expendable"],char:"\u265f",fitzpatrick_scale:!1,category:"activity"},slot_machine:{keywords:["bet","gamble","vegas","fruit machine","luck","casino"],char:"\ud83c\udfb0",fitzpatrick_scale:!1,category:"activity"},jigsaw:{keywords:["interlocking","puzzle","piece"],char:"\ud83e\udde9",fitzpatrick_scale:!1,category:"activity"},bowling:{keywords:["sports","fun","play"],char:"\ud83c\udfb3",fitzpatrick_scale:!1,category:"activity"},red_car:{keywords:["red","transportation","vehicle"],char:"\ud83d\ude97",fitzpatrick_scale:!1,category:"travel_and_places"},taxi:{keywords:["uber","vehicle","cars","transportation"],char:"\ud83d\ude95",fitzpatrick_scale:!1,category:"travel_and_places"},blue_car:{keywords:["transportation","vehicle"],char:"\ud83d\ude99",fitzpatrick_scale:!1,category:"travel_and_places"},bus:{keywords:["car","vehicle","transportation"],char:"\ud83d\ude8c",fitzpatrick_scale:!1,category:"travel_and_places"},trolleybus:{keywords:["bart","transportation","vehicle"],char:"\ud83d\ude8e",fitzpatrick_scale:!1,category:"travel_and_places"},racing_car:{keywords:["sports","race","fast","formula","f1"],char:"\ud83c\udfce",fitzpatrick_scale:!1,category:"travel_and_places"},police_car:{keywords:["vehicle","cars","transportation","law","legal","enforcement"],char:"\ud83d\ude93",fitzpatrick_scale:!1,category:"travel_and_places"},ambulance:{keywords:["health","911","hospital"],char:"\ud83d\ude91",fitzpatrick_scale:!1,category:"travel_and_places"},fire_engine:{keywords:["transportation","cars","vehicle"],char:"\ud83d\ude92",fitzpatrick_scale:!1,category:"travel_and_places"},minibus:{keywords:["vehicle","car","transportation"],char:"\ud83d\ude90",fitzpatrick_scale:!1,category:"travel_and_places"},truck:{keywords:["cars","transportation"],char:"\ud83d\ude9a",fitzpatrick_scale:!1,category:"travel_and_places"},articulated_lorry:{keywords:["vehicle","cars","transportation","express"],char:"\ud83d\ude9b",fitzpatrick_scale:!1,category:"travel_and_places"},tractor:{keywords:["vehicle","car","farming","agriculture"],char:"\ud83d\ude9c",fitzpatrick_scale:!1,category:"travel_and_places"},kick_scooter:{keywords:["vehicle","kick","razor"],char:"\ud83d\udef4",fitzpatrick_scale:!1,category:"travel_and_places"},motorcycle:{keywords:["race","sports","fast"],char:"\ud83c\udfcd",fitzpatrick_scale:!1,category:"travel_and_places"},bike:{keywords:["sports","bicycle","exercise","hipster"],char:"\ud83d\udeb2",fitzpatrick_scale:!1,category:"travel_and_places"},motor_scooter:{keywords:["vehicle","vespa","sasha"],char:"\ud83d\udef5",fitzpatrick_scale:!1,category:"travel_and_places"},rotating_light:{keywords:["police","ambulance","911","emergency","alert","error","pinged","law","legal"],char:"\ud83d\udea8",fitzpatrick_scale:!1,category:"travel_and_places"},oncoming_police_car:{keywords:["vehicle","law","legal","enforcement","911"],char:"\ud83d\ude94",fitzpatrick_scale:!1,category:"travel_and_places"},oncoming_bus:{keywords:["vehicle","transportation"],char:"\ud83d\ude8d",fitzpatrick_scale:!1,category:"travel_and_places"},oncoming_automobile:{keywords:["car","vehicle","transportation"],char:"\ud83d\ude98",fitzpatrick_scale:!1,category:"travel_and_places"},oncoming_taxi:{keywords:["vehicle","cars","uber"],char:"\ud83d\ude96",fitzpatrick_scale:!1,category:"travel_and_places"},aerial_tramway:{keywords:["transportation","vehicle","ski"],char:"\ud83d\udea1",fitzpatrick_scale:!1,category:"travel_and_places"},mountain_cableway:{keywords:["transportation","vehicle","ski"],char:"\ud83d\udea0",fitzpatrick_scale:!1,category:"travel_and_places"},suspension_railway:{keywords:["vehicle","transportation"],char:"\ud83d\ude9f",fitzpatrick_scale:!1,category:"travel_and_places"},railway_car:{keywords:["transportation","vehicle"],char:"\ud83d\ude83",fitzpatrick_scale:!1,category:"travel_and_places"},train:{keywords:["transportation","vehicle","carriage","public","travel"],char:"\ud83d\ude8b",fitzpatrick_scale:!1,category:"travel_and_places"},monorail:{keywords:["transportation","vehicle"],char:"\ud83d\ude9d",fitzpatrick_scale:!1,category:"travel_and_places"},bullettrain_side:{keywords:["transportation","vehicle"],char:"\ud83d\ude84",fitzpatrick_scale:!1,category:"travel_and_places"},bullettrain_front:{keywords:["transportation","vehicle","speed","fast","public","travel"],char:"\ud83d\ude85",fitzpatrick_scale:!1,category:"travel_and_places"},light_rail:{keywords:["transportation","vehicle"],char:"\ud83d\ude88",fitzpatrick_scale:!1,category:"travel_and_places"},mountain_railway:{keywords:["transportation","vehicle"],char:"\ud83d\ude9e",fitzpatrick_scale:!1,category:"travel_and_places"},steam_locomotive:{keywords:["transportation","vehicle","train"],char:"\ud83d\ude82",fitzpatrick_scale:!1,category:"travel_and_places"},train2:{keywords:["transportation","vehicle"],char:"\ud83d\ude86",fitzpatrick_scale:!1,category:"travel_and_places"},metro:{keywords:["transportation","blue-square","mrt","underground","tube"],char:"\ud83d\ude87",fitzpatrick_scale:!1,category:"travel_and_places"},tram:{keywords:["transportation","vehicle"],char:"\ud83d\ude8a",fitzpatrick_scale:!1,category:"travel_and_places"},station:{keywords:["transportation","vehicle","public"],char:"\ud83d\ude89",fitzpatrick_scale:!1,category:"travel_and_places"},flying_saucer:{keywords:["transportation","vehicle","ufo"],char:"\ud83d\udef8",fitzpatrick_scale:!1,category:"travel_and_places"},helicopter:{keywords:["transportation","vehicle","fly"],char:"\ud83d\ude81",fitzpatrick_scale:!1,category:"travel_and_places"},small_airplane:{keywords:["flight","transportation","fly","vehicle"],char:"\ud83d\udee9",fitzpatrick_scale:!1,category:"travel_and_places"},airplane:{keywords:["vehicle","transportation","flight","fly"],char:"\u2708\ufe0f",fitzpatrick_scale:!1,category:"travel_and_places"},flight_departure:{keywords:["airport","flight","landing"],char:"\ud83d\udeeb",fitzpatrick_scale:!1,category:"travel_and_places"},flight_arrival:{keywords:["airport","flight","boarding"],char:"\ud83d\udeec",fitzpatrick_scale:!1,category:"travel_and_places"},sailboat:{keywords:["ship","summer","transportation","water","sailing"],char:"\u26f5",fitzpatrick_scale:!1,category:"travel_and_places"},motor_boat:{keywords:["ship"],char:"\ud83d\udee5",fitzpatrick_scale:!1,category:"travel_and_places"},speedboat:{keywords:["ship","transportation","vehicle","summer"],char:"\ud83d\udea4",fitzpatrick_scale:!1,category:"travel_and_places"},ferry:{keywords:["boat","ship","yacht"],char:"\u26f4",fitzpatrick_scale:!1,category:"travel_and_places"},passenger_ship:{keywords:["yacht","cruise","ferry"],char:"\ud83d\udef3",fitzpatrick_scale:!1,category:"travel_and_places"},rocket:{keywords:["launch","ship","staffmode","NASA","outer space","outer_space","fly"],char:"\ud83d\ude80",fitzpatrick_scale:!1,category:"travel_and_places"},artificial_satellite:{keywords:["communication","gps","orbit","spaceflight","NASA","ISS"],char:"\ud83d\udef0",fitzpatrick_scale:!1,category:"travel_and_places"},seat:{keywords:["sit","airplane","transport","bus","flight","fly"],char:"\ud83d\udcba",fitzpatrick_scale:!1,category:"travel_and_places"},canoe:{keywords:["boat","paddle","water","ship"],char:"\ud83d\udef6",fitzpatrick_scale:!1,category:"travel_and_places"},anchor:{keywords:["ship","ferry","sea","boat"],char:"\u2693",fitzpatrick_scale:!1,category:"travel_and_places"},construction:{keywords:["wip","progress","caution","warning"],char:"\ud83d\udea7",fitzpatrick_scale:!1,category:"travel_and_places"},fuelpump:{keywords:["gas station","petroleum"],char:"\u26fd",fitzpatrick_scale:!1,category:"travel_and_places"},busstop:{keywords:["transportation","wait"],char:"\ud83d\ude8f",fitzpatrick_scale:!1,category:"travel_and_places"},vertical_traffic_light:{keywords:["transportation","driving"],char:"\ud83d\udea6",fitzpatrick_scale:!1,category:"travel_and_places"},traffic_light:{keywords:["transportation","signal"],char:"\ud83d\udea5",fitzpatrick_scale:!1,category:"travel_and_places"},checkered_flag:{keywords:["contest","finishline","race","gokart"],char:"\ud83c\udfc1",fitzpatrick_scale:!1,category:"travel_and_places"},ship:{keywords:["transportation","titanic","deploy"],char:"\ud83d\udea2",fitzpatrick_scale:!1,category:"travel_and_places"},ferris_wheel:{keywords:["photo","carnival","londoneye"],char:"\ud83c\udfa1",fitzpatrick_scale:!1,category:"travel_and_places"},roller_coaster:{keywords:["carnival","playground","photo","fun"],char:"\ud83c\udfa2",fitzpatrick_scale:!1,category:"travel_and_places"},carousel_horse:{keywords:["photo","carnival"],char:"\ud83c\udfa0",fitzpatrick_scale:!1,category:"travel_and_places"},building_construction:{keywords:["wip","working","progress"],char:"\ud83c\udfd7",fitzpatrick_scale:!1,category:"travel_and_places"},foggy:{keywords:["photo","mountain"],char:"\ud83c\udf01",fitzpatrick_scale:!1,category:"travel_and_places"},tokyo_tower:{keywords:["photo","japanese"],char:"\ud83d\uddfc",fitzpatrick_scale:!1,category:"travel_and_places"},factory:{keywords:["building","industry","pollution","smoke"],char:"\ud83c\udfed",fitzpatrick_scale:!1,category:"travel_and_places"},fountain:{keywords:["photo","summer","water","fresh"],char:"\u26f2",fitzpatrick_scale:!1,category:"travel_and_places"},rice_scene:{keywords:["photo","japan","asia","tsukimi"],char:"\ud83c\udf91",fitzpatrick_scale:!1,category:"travel_and_places"},mountain:{keywords:["photo","nature","environment"],char:"\u26f0",fitzpatrick_scale:!1,category:"travel_and_places"},mountain_snow:{keywords:["photo","nature","environment","winter","cold"],char:"\ud83c\udfd4",fitzpatrick_scale:!1,category:"travel_and_places"},mount_fuji:{keywords:["photo","mountain","nature","japanese"],char:"\ud83d\uddfb",fitzpatrick_scale:!1,category:"travel_and_places"},volcano:{keywords:["photo","nature","disaster"],char:"\ud83c\udf0b",fitzpatrick_scale:!1,category:"travel_and_places"},japan:{keywords:["nation","country","japanese","asia"],char:"\ud83d\uddfe",fitzpatrick_scale:!1,category:"travel_and_places"},camping:{keywords:["photo","outdoors","tent"],char:"\ud83c\udfd5",fitzpatrick_scale:!1,category:"travel_and_places"},tent:{keywords:["photo","camping","outdoors"],char:"\u26fa",fitzpatrick_scale:!1,category:"travel_and_places"},national_park:{keywords:["photo","environment","nature"],char:"\ud83c\udfde",fitzpatrick_scale:!1,category:"travel_and_places"},motorway:{keywords:["road","cupertino","interstate","highway"],char:"\ud83d\udee3",fitzpatrick_scale:!1,category:"travel_and_places"},railway_track:{keywords:["train","transportation"],char:"\ud83d\udee4",fitzpatrick_scale:!1,category:"travel_and_places"},sunrise:{keywords:["morning","view","vacation","photo"],char:"\ud83c\udf05",fitzpatrick_scale:!1,category:"travel_and_places"},sunrise_over_mountains:{keywords:["view","vacation","photo"],char:"\ud83c\udf04",fitzpatrick_scale:!1,category:"travel_and_places"},desert:{keywords:["photo","warm","saharah"],char:"\ud83c\udfdc",fitzpatrick_scale:!1,category:"travel_and_places"},beach_umbrella:{keywords:["weather","summer","sunny","sand","mojito"],char:"\ud83c\udfd6",fitzpatrick_scale:!1,category:"travel_and_places"},desert_island:{keywords:["photo","tropical","mojito"],char:"\ud83c\udfdd",fitzpatrick_scale:!1,category:"travel_and_places"},city_sunrise:{keywords:["photo","good morning","dawn"],char:"\ud83c\udf07",fitzpatrick_scale:!1,category:"travel_and_places"},city_sunset:{keywords:["photo","evening","sky","buildings"],char:"\ud83c\udf06",fitzpatrick_scale:!1,category:"travel_and_places"},cityscape:{keywords:["photo","night life","urban"],char:"\ud83c\udfd9",fitzpatrick_scale:!1,category:"travel_and_places"},night_with_stars:{keywords:["evening","city","downtown"],char:"\ud83c\udf03",fitzpatrick_scale:!1,category:"travel_and_places"},bridge_at_night:{keywords:["photo","sanfrancisco"],char:"\ud83c\udf09",fitzpatrick_scale:!1,category:"travel_and_places"},milky_way:{keywords:["photo","space","stars"],char:"\ud83c\udf0c",fitzpatrick_scale:!1,category:"travel_and_places"},stars:{keywords:["night","photo"],char:"\ud83c\udf20",fitzpatrick_scale:!1,category:"travel_and_places"},sparkler:{keywords:["stars","night","shine"],char:"\ud83c\udf87",fitzpatrick_scale:!1,category:"travel_and_places"},fireworks:{keywords:["photo","festival","carnival","congratulations"],char:"\ud83c\udf86",fitzpatrick_scale:!1,category:"travel_and_places"},rainbow:{keywords:["nature","happy","unicorn_face","photo","sky","spring"],char:"\ud83c\udf08",fitzpatrick_scale:!1,category:"travel_and_places"},houses:{keywords:["buildings","photo"],char:"\ud83c\udfd8",fitzpatrick_scale:!1,category:"travel_and_places"},european_castle:{keywords:["building","royalty","history"],char:"\ud83c\udff0",fitzpatrick_scale:!1,category:"travel_and_places"},japanese_castle:{keywords:["photo","building"],char:"\ud83c\udfef",fitzpatrick_scale:!1,category:"travel_and_places"},stadium:{keywords:["photo","place","sports","concert","venue"],char:"\ud83c\udfdf",fitzpatrick_scale:!1,category:"travel_and_places"},statue_of_liberty:{keywords:["american","newyork"],char:"\ud83d\uddfd",fitzpatrick_scale:!1,category:"travel_and_places"},house:{keywords:["building","home"],char:"\ud83c\udfe0",fitzpatrick_scale:!1,category:"travel_and_places"},house_with_garden:{keywords:["home","plant","nature"],char:"\ud83c\udfe1",fitzpatrick_scale:!1,category:"travel_and_places"},derelict_house:{keywords:["abandon","evict","broken","building"],char:"\ud83c\udfda",fitzpatrick_scale:!1,category:"travel_and_places"},office:{keywords:["building","bureau","work"],char:"\ud83c\udfe2",fitzpatrick_scale:!1,category:"travel_and_places"},department_store:{keywords:["building","shopping","mall"],char:"\ud83c\udfec",fitzpatrick_scale:!1,category:"travel_and_places"},post_office:{keywords:["building","envelope","communication"],char:"\ud83c\udfe3",fitzpatrick_scale:!1,category:"travel_and_places"},european_post_office:{keywords:["building","email"],char:"\ud83c\udfe4",fitzpatrick_scale:!1,category:"travel_and_places"},hospital:{keywords:["building","health","surgery","doctor"],char:"\ud83c\udfe5",fitzpatrick_scale:!1,category:"travel_and_places"},bank:{keywords:["building","money","sales","cash","business","enterprise"],char:"\ud83c\udfe6",fitzpatrick_scale:!1,category:"travel_and_places"},hotel:{keywords:["building","accomodation","checkin"],char:"\ud83c\udfe8",fitzpatrick_scale:!1,category:"travel_and_places"},convenience_store:{keywords:["building","shopping","groceries"],char:"\ud83c\udfea",fitzpatrick_scale:!1,category:"travel_and_places"},school:{keywords:["building","student","education","learn","teach"],char:"\ud83c\udfeb",fitzpatrick_scale:!1,category:"travel_and_places"},love_hotel:{keywords:["like","affection","dating"],char:"\ud83c\udfe9",fitzpatrick_scale:!1,category:"travel_and_places"},wedding:{keywords:["love","like","affection","couple","marriage","bride","groom"],char:"\ud83d\udc92",fitzpatrick_scale:!1,category:"travel_and_places"},classical_building:{keywords:["art","culture","history"],char:"\ud83c\udfdb",fitzpatrick_scale:!1,category:"travel_and_places"},church:{keywords:["building","religion","christ"],char:"\u26ea",fitzpatrick_scale:!1,category:"travel_and_places"},mosque:{keywords:["islam","worship","minaret"],char:"\ud83d\udd4c",fitzpatrick_scale:!1,category:"travel_and_places"},synagogue:{keywords:["judaism","worship","temple","jewish"],char:"\ud83d\udd4d",fitzpatrick_scale:!1,category:"travel_and_places"},kaaba:{keywords:["mecca","mosque","islam"],char:"\ud83d\udd4b",fitzpatrick_scale:!1,category:"travel_and_places"},shinto_shrine:{keywords:["temple","japan","kyoto"],char:"\u26e9",fitzpatrick_scale:!1,category:"travel_and_places"},watch:{keywords:["time","accessories"],char:"\u231a",fitzpatrick_scale:!1,category:"objects"},iphone:{keywords:["technology","apple","gadgets","dial"],char:"\ud83d\udcf1",fitzpatrick_scale:!1,category:"objects"},calling:{keywords:["iphone","incoming"],char:"\ud83d\udcf2",fitzpatrick_scale:!1,category:"objects"},computer:{keywords:["technology","laptop","screen","display","monitor"],char:"\ud83d\udcbb",fitzpatrick_scale:!1,category:"objects"},keyboard:{keywords:["technology","computer","type","input","text"],char:"\u2328",fitzpatrick_scale:!1,category:"objects"},desktop_computer:{keywords:["technology","computing","screen"],char:"\ud83d\udda5",fitzpatrick_scale:!1,category:"objects"},printer:{keywords:["paper","ink"],char:"\ud83d\udda8",fitzpatrick_scale:!1,category:"objects"},computer_mouse:{keywords:["click"],char:"\ud83d\uddb1",fitzpatrick_scale:!1,category:"objects"},trackball:{keywords:["technology","trackpad"],char:"\ud83d\uddb2",fitzpatrick_scale:!1,category:"objects"},joystick:{keywords:["game","play"],char:"\ud83d\udd79",fitzpatrick_scale:!1,category:"objects"},clamp:{keywords:["tool"],char:"\ud83d\udddc",fitzpatrick_scale:!1,category:"objects"},minidisc:{keywords:["technology","record","data","disk","90s"],char:"\ud83d\udcbd",fitzpatrick_scale:!1,category:"objects"},floppy_disk:{keywords:["oldschool","technology","save","90s","80s"],char:"\ud83d\udcbe",fitzpatrick_scale:!1,category:"objects"},cd:{keywords:["technology","dvd","disk","disc","90s"],char:"\ud83d\udcbf",fitzpatrick_scale:!1,category:"objects"},dvd:{keywords:["cd","disk","disc"],char:"\ud83d\udcc0",fitzpatrick_scale:!1,category:"objects"},vhs:{keywords:["record","video","oldschool","90s","80s"],char:"\ud83d\udcfc",fitzpatrick_scale:!1,category:"objects"},camera:{keywords:["gadgets","photography"],char:"\ud83d\udcf7",fitzpatrick_scale:!1,category:"objects"},camera_flash:{keywords:["photography","gadgets"],char:"\ud83d\udcf8",fitzpatrick_scale:!1,category:"objects"},video_camera:{keywords:["film","record"],char:"\ud83d\udcf9",fitzpatrick_scale:!1,category:"objects"},movie_camera:{keywords:["film","record"],char:"\ud83c\udfa5",fitzpatrick_scale:!1,category:"objects"},film_projector:{keywords:["video","tape","record","movie"],char:"\ud83d\udcfd",fitzpatrick_scale:!1,category:"objects"},film_strip:{keywords:["movie"],char:"\ud83c\udf9e",fitzpatrick_scale:!1,category:"objects"},telephone_receiver:{keywords:["technology","communication","dial"],char:"\ud83d\udcde",fitzpatrick_scale:!1,category:"objects"},phone:{keywords:["technology","communication","dial","telephone"],char:"\u260e\ufe0f",fitzpatrick_scale:!1,category:"objects"},pager:{keywords:["bbcall","oldschool","90s"],char:"\ud83d\udcdf",fitzpatrick_scale:!1,category:"objects"},fax:{keywords:["communication","technology"],char:"\ud83d\udce0",fitzpatrick_scale:!1,category:"objects"},tv:{keywords:["technology","program","oldschool","show","television"],char:"\ud83d\udcfa",fitzpatrick_scale:!1,category:"objects"},radio:{keywords:["communication","music","podcast","program"],char:"\ud83d\udcfb",fitzpatrick_scale:!1,category:"objects"},studio_microphone:{keywords:["sing","recording","artist","talkshow"],char:"\ud83c\udf99",fitzpatrick_scale:!1,category:"objects"},level_slider:{keywords:["scale"],char:"\ud83c\udf9a",fitzpatrick_scale:!1,category:"objects"},control_knobs:{keywords:["dial"],char:"\ud83c\udf9b",fitzpatrick_scale:!1,category:"objects"},compass:{keywords:["magnetic","navigation","orienteering"],char:"\ud83e\udded",fitzpatrick_scale:!1,category:"objects"},stopwatch:{keywords:["time","deadline"],char:"\u23f1",fitzpatrick_scale:!1,category:"objects"},timer_clock:{keywords:["alarm"],char:"\u23f2",fitzpatrick_scale:!1,category:"objects"},alarm_clock:{keywords:["time","wake"],char:"\u23f0",fitzpatrick_scale:!1,category:"objects"},mantelpiece_clock:{keywords:["time"],char:"\ud83d\udd70",fitzpatrick_scale:!1,category:"objects"},hourglass_flowing_sand:{keywords:["oldschool","time","countdown"],char:"\u23f3",fitzpatrick_scale:!1,category:"objects"},hourglass:{keywords:["time","clock","oldschool","limit","exam","quiz","test"],char:"\u231b",fitzpatrick_scale:!1,category:"objects"},satellite:{keywords:["communication","future","radio","space"],char:"\ud83d\udce1",fitzpatrick_scale:!1,category:"objects"},battery:{keywords:["power","energy","sustain"],char:"\ud83d\udd0b",fitzpatrick_scale:!1,category:"objects"},electric_plug:{keywords:["charger","power"],char:"\ud83d\udd0c",fitzpatrick_scale:!1,category:"objects"},bulb:{keywords:["light","electricity","idea"],char:"\ud83d\udca1",fitzpatrick_scale:!1,category:"objects"},flashlight:{keywords:["dark","camping","sight","night"],char:"\ud83d\udd26",fitzpatrick_scale:!1,category:"objects"},candle:{keywords:["fire","wax"],char:"\ud83d\udd6f",fitzpatrick_scale:!1,category:"objects"},fire_extinguisher:{keywords:["quench"],char:"\ud83e\uddef",fitzpatrick_scale:!1,category:"objects"},wastebasket:{keywords:["bin","trash","rubbish","garbage","toss"],char:"\ud83d\uddd1",fitzpatrick_scale:!1,category:"objects"},oil_drum:{keywords:["barrell"],char:"\ud83d\udee2",fitzpatrick_scale:!1,category:"objects"},money_with_wings:{keywords:["dollar","bills","payment","sale"],char:"\ud83d\udcb8",fitzpatrick_scale:!1,category:"objects"},dollar:{keywords:["money","sales","bill","currency"],char:"\ud83d\udcb5",fitzpatrick_scale:!1,category:"objects"},yen:{keywords:["money","sales","japanese","dollar","currency"],char:"\ud83d\udcb4",fitzpatrick_scale:!1,category:"objects"},euro:{keywords:["money","sales","dollar","currency"],char:"\ud83d\udcb6",fitzpatrick_scale:!1,category:"objects"},pound:{keywords:["british","sterling","money","sales","bills","uk","england","currency"],char:"\ud83d\udcb7",fitzpatrick_scale:!1,category:"objects"},moneybag:{keywords:["dollar","payment","coins","sale"],char:"\ud83d\udcb0",fitzpatrick_scale:!1,category:"objects"},credit_card:{keywords:["money","sales","dollar","bill","payment","shopping"],char:"\ud83d\udcb3",fitzpatrick_scale:!1,category:"objects"},gem:{keywords:["blue","ruby","diamond","jewelry"],char:"\ud83d\udc8e",fitzpatrick_scale:!1,category:"objects"},balance_scale:{keywords:["law","fairness","weight"],char:"\u2696",fitzpatrick_scale:!1,category:"objects"},toolbox:{keywords:["tools","diy","fix","maintainer","mechanic"],char:"\ud83e\uddf0",fitzpatrick_scale:!1,category:"objects"},wrench:{keywords:["tools","diy","ikea","fix","maintainer"],char:"\ud83d\udd27",fitzpatrick_scale:!1,category:"objects"},hammer:{keywords:["tools","build","create"],char:"\ud83d\udd28",fitzpatrick_scale:!1,category:"objects"},hammer_and_pick:{keywords:["tools","build","create"],char:"\u2692",fitzpatrick_scale:!1,category:"objects"},hammer_and_wrench:{keywords:["tools","build","create"],char:"\ud83d\udee0",fitzpatrick_scale:!1,category:"objects"},pick:{keywords:["tools","dig"],char:"\u26cf",fitzpatrick_scale:!1,category:"objects"},nut_and_bolt:{keywords:["handy","tools","fix"],char:"\ud83d\udd29",fitzpatrick_scale:!1,category:"objects"},gear:{keywords:["cog"],char:"\u2699",fitzpatrick_scale:!1,category:"objects"},brick:{keywords:["bricks"],char:"\ud83e\uddf1",fitzpatrick_scale:!1,category:"objects"},chains:{keywords:["lock","arrest"],char:"\u26d3",fitzpatrick_scale:!1,category:"objects"},magnet:{keywords:["attraction","magnetic"],char:"\ud83e\uddf2",fitzpatrick_scale:!1,category:"objects"},gun:{keywords:["violence","weapon","pistol","revolver"],char:"\ud83d\udd2b",fitzpatrick_scale:!1,category:"objects"},bomb:{keywords:["boom","explode","explosion","terrorism"],char:"\ud83d\udca3",fitzpatrick_scale:!1,category:"objects"},firecracker:{keywords:["dynamite","boom","explode","explosion","explosive"],char:"\ud83e\udde8",fitzpatrick_scale:!1,category:"objects"},hocho:{keywords:["knife","blade","cutlery","kitchen","weapon"],char:"\ud83d\udd2a",fitzpatrick_scale:!1,category:"objects"},dagger:{keywords:["weapon"],char:"\ud83d\udde1",fitzpatrick_scale:!1,category:"objects"},crossed_swords:{keywords:["weapon"],char:"\u2694",fitzpatrick_scale:!1,category:"objects"},shield:{keywords:["protection","security"],char:"\ud83d\udee1",fitzpatrick_scale:!1,category:"objects"},smoking:{keywords:["kills","tobacco","cigarette","joint","smoke"],char:"\ud83d\udeac",fitzpatrick_scale:!1,category:"objects"},skull_and_crossbones:{keywords:["poison","danger","deadly","scary","death","pirate","evil"],char:"\u2620",fitzpatrick_scale:!1,category:"objects"},coffin:{keywords:["vampire","dead","die","death","rip","graveyard","cemetery","casket","funeral","box"],char:"\u26b0",fitzpatrick_scale:!1,category:"objects"},funeral_urn:{keywords:["dead","die","death","rip","ashes"],char:"\u26b1",fitzpatrick_scale:!1,category:"objects"},amphora:{keywords:["vase","jar"],char:"\ud83c\udffa",fitzpatrick_scale:!1,category:"objects"},crystal_ball:{keywords:["disco","party","magic","circus","fortune_teller"],char:"\ud83d\udd2e",fitzpatrick_scale:!1,category:"objects"},prayer_beads:{keywords:["dhikr","religious"],char:"\ud83d\udcff",fitzpatrick_scale:!1,category:"objects"},nazar_amulet:{keywords:["bead","charm"],char:"\ud83e\uddff",fitzpatrick_scale:!1,category:"objects"},barber:{keywords:["hair","salon","style"],char:"\ud83d\udc88",fitzpatrick_scale:!1,category:"objects"},alembic:{keywords:["distilling","science","experiment","chemistry"],char:"\u2697",fitzpatrick_scale:!1,category:"objects"},telescope:{keywords:["stars","space","zoom","science","astronomy"],char:"\ud83d\udd2d",fitzpatrick_scale:!1,category:"objects"},microscope:{keywords:["laboratory","experiment","zoomin","science","study"],char:"\ud83d\udd2c",fitzpatrick_scale:!1,category:"objects"},hole:{keywords:["embarrassing"],char:"\ud83d\udd73",fitzpatrick_scale:!1,category:"objects"},pill:{keywords:["health","medicine","doctor","pharmacy","drug"],char:"\ud83d\udc8a",fitzpatrick_scale:!1,category:"objects"},syringe:{keywords:["health","hospital","drugs","blood","medicine","needle","doctor","nurse"],char:"\ud83d\udc89",fitzpatrick_scale:!1,category:"objects"},dna:{keywords:["biologist","genetics","life"],char:"\ud83e\uddec",fitzpatrick_scale:!1,category:"objects"},microbe:{keywords:["amoeba","bacteria","germs"],char:"\ud83e\udda0",fitzpatrick_scale:!1,category:"objects"},petri_dish:{keywords:["bacteria","biology","culture","lab"],char:"\ud83e\uddeb",fitzpatrick_scale:!1,category:"objects"},test_tube:{keywords:["chemistry","experiment","lab","science"],char:"\ud83e\uddea",fitzpatrick_scale:!1,category:"objects"},thermometer:{keywords:["weather","temperature","hot","cold"],char:"\ud83c\udf21",fitzpatrick_scale:!1,category:"objects"},broom:{keywords:["cleaning","sweeping","witch"],char:"\ud83e\uddf9",fitzpatrick_scale:!1,category:"objects"},basket:{keywords:["laundry"],char:"\ud83e\uddfa",fitzpatrick_scale:!1,category:"objects"},toilet_paper:{keywords:["roll"],char:"\ud83e\uddfb",fitzpatrick_scale:!1,category:"objects"},label:{keywords:["sale","tag"],char:"\ud83c\udff7",fitzpatrick_scale:!1,category:"objects"},bookmark:{keywords:["favorite","label","save"],char:"\ud83d\udd16",fitzpatrick_scale:!1,category:"objects"},toilet:{keywords:["restroom","wc","washroom","bathroom","potty"],char:"\ud83d\udebd",fitzpatrick_scale:!1,category:"objects"},shower:{keywords:["clean","water","bathroom"],char:"\ud83d\udebf",fitzpatrick_scale:!1,category:"objects"},bathtub:{keywords:["clean","shower","bathroom"],char:"\ud83d\udec1",fitzpatrick_scale:!1,category:"objects"},soap:{keywords:["bar","bathing","cleaning","lather"],char:"\ud83e\uddfc",fitzpatrick_scale:!1,category:"objects"},sponge:{keywords:["absorbing","cleaning","porous"],char:"\ud83e\uddfd",fitzpatrick_scale:!1,category:"objects"},lotion_bottle:{keywords:["moisturizer","sunscreen"],char:"\ud83e\uddf4",fitzpatrick_scale:!1,category:"objects"},key:{keywords:["lock","door","password"],char:"\ud83d\udd11",fitzpatrick_scale:!1,category:"objects"},old_key:{keywords:["lock","door","password"],char:"\ud83d\udddd",fitzpatrick_scale:!1,category:"objects"},couch_and_lamp:{keywords:["read","chill"],char:"\ud83d\udecb",fitzpatrick_scale:!1,category:"objects"},sleeping_bed:{keywords:["bed","rest"],char:"\ud83d\udecc",fitzpatrick_scale:!0,category:"objects"},bed:{keywords:["sleep","rest"],char:"\ud83d\udecf",fitzpatrick_scale:!1,category:"objects"},door:{keywords:["house","entry","exit"],char:"\ud83d\udeaa",fitzpatrick_scale:!1,category:"objects"},bellhop_bell:{keywords:["service"],char:"\ud83d\udece",fitzpatrick_scale:!1,category:"objects"},teddy_bear:{keywords:["plush","stuffed"],char:"\ud83e\uddf8",fitzpatrick_scale:!1,category:"objects"},framed_picture:{keywords:["photography"],char:"\ud83d\uddbc",fitzpatrick_scale:!1,category:"objects"},world_map:{keywords:["location","direction"],char:"\ud83d\uddfa",fitzpatrick_scale:!1,category:"objects"},parasol_on_ground:{keywords:["weather","summer"],char:"\u26f1",fitzpatrick_scale:!1,category:"objects"},moyai:{keywords:["rock","easter island","moai"],char:"\ud83d\uddff",fitzpatrick_scale:!1,category:"objects"},shopping:{keywords:["mall","buy","purchase"],char:"\ud83d\udecd",fitzpatrick_scale:!1,category:"objects"},shopping_cart:{keywords:["trolley"],char:"\ud83d\uded2",fitzpatrick_scale:!1,category:"objects"},balloon:{keywords:["party","celebration","birthday","circus"],char:"\ud83c\udf88",fitzpatrick_scale:!1,category:"objects"},flags:{keywords:["fish","japanese","koinobori","carp","banner"],char:"\ud83c\udf8f",fitzpatrick_scale:!1,category:"objects"},ribbon:{keywords:["decoration","pink","girl","bowtie"],char:"\ud83c\udf80",fitzpatrick_scale:!1,category:"objects"},gift:{keywords:["present","birthday","christmas","xmas"],char:"\ud83c\udf81",fitzpatrick_scale:!1,category:"objects"},confetti_ball:{keywords:["festival","party","birthday","circus"],char:"\ud83c\udf8a",fitzpatrick_scale:!1,category:"objects"},tada:{keywords:["party","congratulations","birthday","magic","circus","celebration"],char:"\ud83c\udf89",fitzpatrick_scale:!1,category:"objects"},dolls:{keywords:["japanese","toy","kimono"],char:"\ud83c\udf8e",fitzpatrick_scale:!1,category:"objects"},wind_chime:{keywords:["nature","ding","spring","bell"],char:"\ud83c\udf90",fitzpatrick_scale:!1,category:"objects"},crossed_flags:{keywords:["japanese","nation","country","border"],char:"\ud83c\udf8c",fitzpatrick_scale:!1,category:"objects"},izakaya_lantern:{keywords:["light","paper","halloween","spooky"],char:"\ud83c\udfee",fitzpatrick_scale:!1,category:"objects"},red_envelope:{keywords:["gift"],char:"\ud83e\udde7",fitzpatrick_scale:!1,category:"objects"},email:{keywords:["letter","postal","inbox","communication"],char:"\u2709\ufe0f",fitzpatrick_scale:!1,category:"objects"},envelope_with_arrow:{keywords:["email","communication"],char:"\ud83d\udce9",fitzpatrick_scale:!1,category:"objects"},incoming_envelope:{keywords:["email","inbox"],char:"\ud83d\udce8",fitzpatrick_scale:!1,category:"objects"},"e-mail":{keywords:["communication","inbox"],char:"\ud83d\udce7",fitzpatrick_scale:!1,category:"objects"},love_letter:{keywords:["email","like","affection","envelope","valentines"],char:"\ud83d\udc8c",fitzpatrick_scale:!1,category:"objects"},postbox:{keywords:["email","letter","envelope"],char:"\ud83d\udcee",fitzpatrick_scale:!1,category:"objects"},mailbox_closed:{keywords:["email","communication","inbox"],char:"\ud83d\udcea",fitzpatrick_scale:!1,category:"objects"},mailbox:{keywords:["email","inbox","communication"],char:"\ud83d\udceb",fitzpatrick_scale:!1,category:"objects"},mailbox_with_mail:{keywords:["email","inbox","communication"],char:"\ud83d\udcec",fitzpatrick_scale:!1,category:"objects"},mailbox_with_no_mail:{keywords:["email","inbox"],char:"\ud83d\udced",fitzpatrick_scale:!1,category:"objects"},package:{keywords:["mail","gift","cardboard","box","moving"],char:"\ud83d\udce6",fitzpatrick_scale:!1,category:"objects"},postal_horn:{keywords:["instrument","music"],char:"\ud83d\udcef",fitzpatrick_scale:!1,category:"objects"},inbox_tray:{keywords:["email","documents"],char:"\ud83d\udce5",fitzpatrick_scale:!1,category:"objects"},outbox_tray:{keywords:["inbox","email"],char:"\ud83d\udce4",fitzpatrick_scale:!1,category:"objects"},scroll:{keywords:["documents","ancient","history","paper"],char:"\ud83d\udcdc",fitzpatrick_scale:!1,category:"objects"},page_with_curl:{keywords:["documents","office","paper"],char:"\ud83d\udcc3",fitzpatrick_scale:!1,category:"objects"},bookmark_tabs:{keywords:["favorite","save","order","tidy"],char:"\ud83d\udcd1",fitzpatrick_scale:!1,category:"objects"},receipt:{keywords:["accounting","expenses"],char:"\ud83e\uddfe",fitzpatrick_scale:!1,category:"objects"},bar_chart:{keywords:["graph","presentation","stats"],char:"\ud83d\udcca",fitzpatrick_scale:!1,category:"objects"},chart_with_upwards_trend:{keywords:["graph","presentation","stats","recovery","business","economics","money","sales","good","success"],char:"\ud83d\udcc8",fitzpatrick_scale:!1,category:"objects"},chart_with_downwards_trend:{keywords:["graph","presentation","stats","recession","business","economics","money","sales","bad","failure"],char:"\ud83d\udcc9",fitzpatrick_scale:!1,category:"objects"},page_facing_up:{keywords:["documents","office","paper","information"],char:"\ud83d\udcc4",fitzpatrick_scale:!1,category:"objects"},date:{keywords:["calendar","schedule"],char:"\ud83d\udcc5",fitzpatrick_scale:!1,category:"objects"},calendar:{keywords:["schedule","date","planning"],char:"\ud83d\udcc6",fitzpatrick_scale:!1,category:"objects"},spiral_calendar:{keywords:["date","schedule","planning"],char:"\ud83d\uddd3",fitzpatrick_scale:!1,category:"objects"},card_index:{keywords:["business","stationery"],char:"\ud83d\udcc7",fitzpatrick_scale:!1,category:"objects"},card_file_box:{keywords:["business","stationery"],char:"\ud83d\uddc3",fitzpatrick_scale:!1,category:"objects"},ballot_box:{keywords:["election","vote"],char:"\ud83d\uddf3",fitzpatrick_scale:!1,category:"objects"},file_cabinet:{keywords:["filing","organizing"],char:"\ud83d\uddc4",fitzpatrick_scale:!1,category:"objects"},clipboard:{keywords:["stationery","documents"],char:"\ud83d\udccb",fitzpatrick_scale:!1,category:"objects"},spiral_notepad:{keywords:["memo","stationery"],char:"\ud83d\uddd2",fitzpatrick_scale:!1,category:"objects"},file_folder:{keywords:["documents","business","office"],char:"\ud83d\udcc1",fitzpatrick_scale:!1,category:"objects"},open_file_folder:{keywords:["documents","load"],char:"\ud83d\udcc2",fitzpatrick_scale:!1,category:"objects"},card_index_dividers:{keywords:["organizing","business","stationery"],char:"\ud83d\uddc2",fitzpatrick_scale:!1,category:"objects"},newspaper_roll:{keywords:["press","headline"],char:"\ud83d\uddde",fitzpatrick_scale:!1,category:"objects"},newspaper:{keywords:["press","headline"],char:"\ud83d\udcf0",fitzpatrick_scale:!1,category:"objects"},notebook:{keywords:["stationery","record","notes","paper","study"],char:"\ud83d\udcd3",fitzpatrick_scale:!1,category:"objects"},closed_book:{keywords:["read","library","knowledge","textbook","learn"],char:"\ud83d\udcd5",fitzpatrick_scale:!1,category:"objects"},green_book:{keywords:["read","library","knowledge","study"],char:"\ud83d\udcd7",fitzpatrick_scale:!1,category:"objects"},blue_book:{keywords:["read","library","knowledge","learn","study"],char:"\ud83d\udcd8",fitzpatrick_scale:!1,category:"objects"},orange_book:{keywords:["read","library","knowledge","textbook","study"],char:"\ud83d\udcd9",fitzpatrick_scale:!1,category:"objects"},notebook_with_decorative_cover:{keywords:["classroom","notes","record","paper","study"],char:"\ud83d\udcd4",fitzpatrick_scale:!1,category:"objects"},ledger:{keywords:["notes","paper"],char:"\ud83d\udcd2",fitzpatrick_scale:!1,category:"objects"},books:{keywords:["literature","library","study"],char:"\ud83d\udcda",fitzpatrick_scale:!1,category:"objects"},open_book:{keywords:["book","read","library","knowledge","literature","learn","study"],char:"\ud83d\udcd6",fitzpatrick_scale:!1,category:"objects"},safety_pin:{keywords:["diaper"],char:"\ud83e\uddf7",fitzpatrick_scale:!1,category:"objects"},link:{keywords:["rings","url"],char:"\ud83d\udd17",fitzpatrick_scale:!1,category:"objects"},paperclip:{keywords:["documents","stationery"],char:"\ud83d\udcce",fitzpatrick_scale:!1,category:"objects"},paperclips:{keywords:["documents","stationery"],char:"\ud83d\udd87",fitzpatrick_scale:!1,category:"objects"},scissors:{keywords:["stationery","cut"],char:"\u2702\ufe0f",fitzpatrick_scale:!1,category:"objects"},triangular_ruler:{keywords:["stationery","math","architect","sketch"],char:"\ud83d\udcd0",fitzpatrick_scale:!1,category:"objects"},straight_ruler:{keywords:["stationery","calculate","length","math","school","drawing","architect","sketch"],char:"\ud83d\udccf",fitzpatrick_scale:!1,category:"objects"},abacus:{keywords:["calculation"],char:"\ud83e\uddee",fitzpatrick_scale:!1,category:"objects"},pushpin:{keywords:["stationery","mark","here"],char:"\ud83d\udccc",fitzpatrick_scale:!1,category:"objects"},round_pushpin:{keywords:["stationery","location","map","here"],char:"\ud83d\udccd",fitzpatrick_scale:!1,category:"objects"},triangular_flag_on_post:{keywords:["mark","milestone","place"],char:"\ud83d\udea9",fitzpatrick_scale:!1,category:"objects"},white_flag:{keywords:["losing","loser","lost","surrender","give up","fail"],char:"\ud83c\udff3",fitzpatrick_scale:!1,category:"objects"},black_flag:{keywords:["pirate"],char:"\ud83c\udff4",fitzpatrick_scale:!1,category:"objects"},rainbow_flag:{keywords:["flag","rainbow","pride","gay","lgbt","glbt","queer","homosexual","lesbian","bisexual","transgender"],char:"\ud83c\udff3\ufe0f\u200d\ud83c\udf08",fitzpatrick_scale:!1,category:"objects"},closed_lock_with_key:{keywords:["security","privacy"],char:"\ud83d\udd10",fitzpatrick_scale:!1,category:"objects"},lock:{keywords:["security","password","padlock"],char:"\ud83d\udd12",fitzpatrick_scale:!1,category:"objects"},unlock:{keywords:["privacy","security"],char:"\ud83d\udd13",fitzpatrick_scale:!1,category:"objects"},lock_with_ink_pen:{keywords:["security","secret"],char:"\ud83d\udd0f",fitzpatrick_scale:!1,category:"objects"},pen:{keywords:["stationery","writing","write"],char:"\ud83d\udd8a",fitzpatrick_scale:!1,category:"objects"},fountain_pen:{keywords:["stationery","writing","write"],char:"\ud83d\udd8b",fitzpatrick_scale:!1,category:"objects"},black_nib:{keywords:["pen","stationery","writing","write"],char:"\u2712\ufe0f",fitzpatrick_scale:!1,category:"objects"},memo:{keywords:["write","documents","stationery","pencil","paper","writing","legal","exam","quiz","test","study","compose"],char:"\ud83d\udcdd",fitzpatrick_scale:!1,category:"objects"},pencil2:{keywords:["stationery","write","paper","writing","school","study"],char:"\u270f\ufe0f",fitzpatrick_scale:!1,category:"objects"},crayon:{keywords:["drawing","creativity"],char:"\ud83d\udd8d",fitzpatrick_scale:!1,category:"objects"},paintbrush:{keywords:["drawing","creativity","art"],char:"\ud83d\udd8c",fitzpatrick_scale:!1,category:"objects"},mag:{keywords:["search","zoom","find","detective"],char:"\ud83d\udd0d",fitzpatrick_scale:!1,category:"objects"},mag_right:{keywords:["search","zoom","find","detective"],char:"\ud83d\udd0e",fitzpatrick_scale:!1,category:"objects"},heart:{keywords:["love","like","valentines"],char:"\u2764\ufe0f",fitzpatrick_scale:!1,category:"symbols"},orange_heart:{keywords:["love","like","affection","valentines"],char:"\ud83e\udde1",fitzpatrick_scale:!1,category:"symbols"},yellow_heart:{keywords:["love","like","affection","valentines"],char:"\ud83d\udc9b",fitzpatrick_scale:!1,category:"symbols"},green_heart:{keywords:["love","like","affection","valentines"],char:"\ud83d\udc9a",fitzpatrick_scale:!1,category:"symbols"},blue_heart:{keywords:["love","like","affection","valentines"],char:"\ud83d\udc99",fitzpatrick_scale:!1,category:"symbols"},purple_heart:{keywords:["love","like","affection","valentines"],char:"\ud83d\udc9c",fitzpatrick_scale:!1,category:"symbols"},black_heart:{keywords:["evil"],char:"\ud83d\udda4",fitzpatrick_scale:!1,category:"symbols"},broken_heart:{keywords:["sad","sorry","break","heart","heartbreak"],char:"\ud83d\udc94",fitzpatrick_scale:!1,category:"symbols"},heavy_heart_exclamation:{keywords:["decoration","love"],char:"\u2763",fitzpatrick_scale:!1,category:"symbols"},two_hearts:{keywords:["love","like","affection","valentines","heart"],char:"\ud83d\udc95",fitzpatrick_scale:!1,category:"symbols"},revolving_hearts:{keywords:["love","like","affection","valentines"],char:"\ud83d\udc9e",fitzpatrick_scale:!1,category:"symbols"},heartbeat:{keywords:["love","like","affection","valentines","pink","heart"],char:"\ud83d\udc93",fitzpatrick_scale:!1,category:"symbols"},heartpulse:{keywords:["like","love","affection","valentines","pink"],char:"\ud83d\udc97",fitzpatrick_scale:!1,category:"symbols"},sparkling_heart:{keywords:["love","like","affection","valentines"],char:"\ud83d\udc96",fitzpatrick_scale:!1,category:"symbols"},cupid:{keywords:["love","like","heart","affection","valentines"],char:"\ud83d\udc98",fitzpatrick_scale:!1,category:"symbols"},gift_heart:{keywords:["love","valentines"],char:"\ud83d\udc9d",fitzpatrick_scale:!1,category:"symbols"},heart_decoration:{keywords:["purple-square","love","like"],char:"\ud83d\udc9f",fitzpatrick_scale:!1,category:"symbols"},peace_symbol:{keywords:["hippie"],char:"\u262e",fitzpatrick_scale:!1,category:"symbols"},latin_cross:{keywords:["christianity"],char:"\u271d",fitzpatrick_scale:!1,category:"symbols"},star_and_crescent:{keywords:["islam"],char:"\u262a",fitzpatrick_scale:!1,category:"symbols"},om:{keywords:["hinduism","buddhism","sikhism","jainism"],char:"\ud83d\udd49",fitzpatrick_scale:!1,category:"symbols"},wheel_of_dharma:{keywords:["hinduism","buddhism","sikhism","jainism"],char:"\u2638",fitzpatrick_scale:!1,category:"symbols"},star_of_david:{keywords:["judaism"],char:"\u2721",fitzpatrick_scale:!1,category:"symbols"},six_pointed_star:{keywords:["purple-square","religion","jewish","hexagram"],char:"\ud83d\udd2f",fitzpatrick_scale:!1,category:"symbols"},menorah:{keywords:["hanukkah","candles","jewish"],char:"\ud83d\udd4e",fitzpatrick_scale:!1,category:"symbols"},yin_yang:{keywords:["balance"],char:"\u262f",fitzpatrick_scale:!1,category:"symbols"},orthodox_cross:{keywords:["suppedaneum","religion"],char:"\u2626",fitzpatrick_scale:!1,category:"symbols"},place_of_worship:{keywords:["religion","church","temple","prayer"],char:"\ud83d\uded0",fitzpatrick_scale:!1,category:"symbols"},ophiuchus:{keywords:["sign","purple-square","constellation","astrology"],char:"\u26ce",fitzpatrick_scale:!1,category:"symbols"},aries:{keywords:["sign","purple-square","zodiac","astrology"],char:"\u2648",fitzpatrick_scale:!1,category:"symbols"},taurus:{keywords:["purple-square","sign","zodiac","astrology"],char:"\u2649",fitzpatrick_scale:!1,category:"symbols"},gemini:{keywords:["sign","zodiac","purple-square","astrology"],char:"\u264a",fitzpatrick_scale:!1,category:"symbols"},cancer:{keywords:["sign","zodiac","purple-square","astrology"],char:"\u264b",fitzpatrick_scale:!1,category:"symbols"},leo:{keywords:["sign","purple-square","zodiac","astrology"],char:"\u264c",fitzpatrick_scale:!1,category:"symbols"},virgo:{keywords:["sign","zodiac","purple-square","astrology"],char:"\u264d",fitzpatrick_scale:!1,category:"symbols"},libra:{keywords:["sign","purple-square","zodiac","astrology"],char:"\u264e",fitzpatrick_scale:!1,category:"symbols"},scorpius:{keywords:["sign","zodiac","purple-square","astrology","scorpio"],char:"\u264f",fitzpatrick_scale:!1,category:"symbols"},sagittarius:{keywords:["sign","zodiac","purple-square","astrology"],char:"\u2650",fitzpatrick_scale:!1,category:"symbols"},capricorn:{keywords:["sign","zodiac","purple-square","astrology"],char:"\u2651",fitzpatrick_scale:!1,category:"symbols"},aquarius:{keywords:["sign","purple-square","zodiac","astrology"],char:"\u2652",fitzpatrick_scale:!1,category:"symbols"},pisces:{keywords:["purple-square","sign","zodiac","astrology"],char:"\u2653",fitzpatrick_scale:!1,category:"symbols"},id:{keywords:["purple-square","words"],char:"\ud83c\udd94",fitzpatrick_scale:!1,category:"symbols"},atom_symbol:{keywords:["science","physics","chemistry"],char:"\u269b",fitzpatrick_scale:!1,category:"symbols"},u7a7a:{keywords:["kanji","japanese","chinese","empty","sky","blue-square"],char:"\ud83c\ude33",fitzpatrick_scale:!1,category:"symbols"},u5272:{keywords:["cut","divide","chinese","kanji","pink-square"],char:"\ud83c\ude39",fitzpatrick_scale:!1,category:"symbols"},radioactive:{keywords:["nuclear","danger"],char:"\u2622",fitzpatrick_scale:!1,category:"symbols"},biohazard:{keywords:["danger"],char:"\u2623",fitzpatrick_scale:!1,category:"symbols"},mobile_phone_off:{keywords:["mute","orange-square","silence","quiet"],char:"\ud83d\udcf4",fitzpatrick_scale:!1,category:"symbols"},vibration_mode:{keywords:["orange-square","phone"],char:"\ud83d\udcf3",fitzpatrick_scale:!1,category:"symbols"},u6709:{keywords:["orange-square","chinese","have","kanji"],char:"\ud83c\ude36",fitzpatrick_scale:!1,category:"symbols"},u7121:{keywords:["nothing","chinese","kanji","japanese","orange-square"],char:"\ud83c\ude1a",fitzpatrick_scale:!1,category:"symbols"},u7533:{keywords:["chinese","japanese","kanji","orange-square"],char:"\ud83c\ude38",fitzpatrick_scale:!1,category:"symbols"},u55b6:{keywords:["japanese","opening hours","orange-square"],char:"\ud83c\ude3a",fitzpatrick_scale:!1,category:"symbols"},u6708:{keywords:["chinese","month","moon","japanese","orange-square","kanji"],char:"\ud83c\ude37\ufe0f",fitzpatrick_scale:!1,category:"symbols"},eight_pointed_black_star:{keywords:["orange-square","shape","polygon"],char:"\u2734\ufe0f",fitzpatrick_scale:!1,category:"symbols"},vs:{keywords:["words","orange-square"],char:"\ud83c\udd9a",fitzpatrick_scale:!1,category:"symbols"},accept:{keywords:["ok","good","chinese","kanji","agree","yes","orange-circle"],char:"\ud83c\ude51",fitzpatrick_scale:!1,category:"symbols"},white_flower:{keywords:["japanese","spring"],char:"\ud83d\udcae",fitzpatrick_scale:!1,category:"symbols"},ideograph_advantage:{keywords:["chinese","kanji","obtain","get","circle"],char:"\ud83c\ude50",fitzpatrick_scale:!1,category:"symbols"},secret:{keywords:["privacy","chinese","sshh","kanji","red-circle"],char:"\u3299\ufe0f",fitzpatrick_scale:!1,category:"symbols"},congratulations:{keywords:["chinese","kanji","japanese","red-circle"],char:"\u3297\ufe0f",fitzpatrick_scale:!1,category:"symbols"},u5408:{keywords:["japanese","chinese","join","kanji","red-square"],char:"\ud83c\ude34",fitzpatrick_scale:!1,category:"symbols"},u6e80:{keywords:["full","chinese","japanese","red-square","kanji"],char:"\ud83c\ude35",fitzpatrick_scale:!1,category:"symbols"},u7981:{keywords:["kanji","japanese","chinese","forbidden","limit","restricted","red-square"],char:"\ud83c\ude32",fitzpatrick_scale:!1,category:"symbols"},a:{keywords:["red-square","alphabet","letter"],char:"\ud83c\udd70\ufe0f",fitzpatrick_scale:!1,category:"symbols"},b:{keywords:["red-square","alphabet","letter"],char:"\ud83c\udd71\ufe0f",fitzpatrick_scale:!1,category:"symbols"},ab:{keywords:["red-square","alphabet"],char:"\ud83c\udd8e",fitzpatrick_scale:!1,category:"symbols"},cl:{keywords:["alphabet","words","red-square"],char:"\ud83c\udd91",fitzpatrick_scale:!1,category:"symbols"},o2:{keywords:["alphabet","red-square","letter"],char:"\ud83c\udd7e\ufe0f",fitzpatrick_scale:!1,category:"symbols"},sos:{keywords:["help","red-square","words","emergency","911"],char:"\ud83c\udd98",fitzpatrick_scale:!1,category:"symbols"},no_entry:{keywords:["limit","security","privacy","bad","denied","stop","circle"],char:"\u26d4",fitzpatrick_scale:!1,category:"symbols"},name_badge:{keywords:["fire","forbid"],char:"\ud83d\udcdb",fitzpatrick_scale:!1,category:"symbols"},no_entry_sign:{keywords:["forbid","stop","limit","denied","disallow","circle"],char:"\ud83d\udeab",fitzpatrick_scale:!1,category:"symbols"},x:{keywords:["no","delete","remove","cancel","red"],char:"\u274c",fitzpatrick_scale:!1,category:"symbols"},o:{keywords:["circle","round"],char:"\u2b55",fitzpatrick_scale:!1,category:"symbols"},stop_sign:{keywords:["stop"],char:"\ud83d\uded1",fitzpatrick_scale:!1,category:"symbols"},anger:{keywords:["angry","mad"],char:"\ud83d\udca2",fitzpatrick_scale:!1,category:"symbols"},hotsprings:{keywords:["bath","warm","relax"],char:"\u2668\ufe0f",fitzpatrick_scale:!1,category:"symbols"},no_pedestrians:{keywords:["rules","crossing","walking","circle"],char:"\ud83d\udeb7",fitzpatrick_scale:!1,category:"symbols"},do_not_litter:{keywords:["trash","bin","garbage","circle"],char:"\ud83d\udeaf",fitzpatrick_scale:!1,category:"symbols"},no_bicycles:{keywords:["cyclist","prohibited","circle"],char:"\ud83d\udeb3",fitzpatrick_scale:!1,category:"symbols"},"non-potable_water":{keywords:["drink","faucet","tap","circle"],char:"\ud83d\udeb1",fitzpatrick_scale:!1,category:"symbols"},underage:{keywords:["18","drink","pub","night","minor","circle"],char:"\ud83d\udd1e",fitzpatrick_scale:!1,category:"symbols"},no_mobile_phones:{keywords:["iphone","mute","circle"],char:"\ud83d\udcf5",fitzpatrick_scale:!1,category:"symbols"},exclamation:{keywords:["heavy_exclamation_mark","danger","surprise","punctuation","wow","warning"],char:"\u2757",fitzpatrick_scale:!1,category:"symbols"},grey_exclamation:{keywords:["surprise","punctuation","gray","wow","warning"],char:"\u2755",fitzpatrick_scale:!1,category:"symbols"},question:{keywords:["doubt","confused"],char:"\u2753",fitzpatrick_scale:!1,category:"symbols"},grey_question:{keywords:["doubts","gray","huh","confused"],char:"\u2754",fitzpatrick_scale:!1,category:"symbols"},bangbang:{keywords:["exclamation","surprise"],char:"\u203c\ufe0f",fitzpatrick_scale:!1,category:"symbols"},interrobang:{keywords:["wat","punctuation","surprise"],char:"\u2049\ufe0f",fitzpatrick_scale:!1,category:"symbols"},100:{keywords:["score","perfect","numbers","century","exam","quiz","test","pass","hundred"],char:"\ud83d\udcaf",fitzpatrick_scale:!1,category:"symbols"},low_brightness:{keywords:["sun","afternoon","warm","summer"],char:"\ud83d\udd05",fitzpatrick_scale:!1,category:"symbols"},high_brightness:{keywords:["sun","light"],char:"\ud83d\udd06",fitzpatrick_scale:!1,category:"symbols"},trident:{keywords:["weapon","spear"],char:"\ud83d\udd31",fitzpatrick_scale:!1,category:"symbols"},fleur_de_lis:{keywords:["decorative","scout"],char:"\u269c",fitzpatrick_scale:!1,category:"symbols"},part_alternation_mark:{keywords:["graph","presentation","stats","business","economics","bad"],char:"\u303d\ufe0f",fitzpatrick_scale:!1,category:"symbols"},warning:{keywords:["exclamation","wip","alert","error","problem","issue"],char:"\u26a0\ufe0f",fitzpatrick_scale:!1,category:"symbols"},children_crossing:{keywords:["school","warning","danger","sign","driving","yellow-diamond"],char:"\ud83d\udeb8",fitzpatrick_scale:!1,category:"symbols"},beginner:{keywords:["badge","shield"],char:"\ud83d\udd30",fitzpatrick_scale:!1,category:"symbols"},recycle:{keywords:["arrow","environment","garbage","trash"],char:"\u267b\ufe0f",fitzpatrick_scale:!1,category:"symbols"},u6307:{keywords:["chinese","point","green-square","kanji"],char:"\ud83c\ude2f",fitzpatrick_scale:!1,category:"symbols"},chart:{keywords:["green-square","graph","presentation","stats"],char:"\ud83d\udcb9",fitzpatrick_scale:!1,category:"symbols"},sparkle:{keywords:["stars","green-square","awesome","good","fireworks"],char:"\u2747\ufe0f",fitzpatrick_scale:!1,category:"symbols"},eight_spoked_asterisk:{keywords:["star","sparkle","green-square"],char:"\u2733\ufe0f",fitzpatrick_scale:!1,category:"symbols"},negative_squared_cross_mark:{keywords:["x","green-square","no","deny"],char:"\u274e",fitzpatrick_scale:!1,category:"symbols"},white_check_mark:{keywords:["green-square","ok","agree","vote","election","answer","tick"],char:"\u2705",fitzpatrick_scale:!1,category:"symbols"},diamond_shape_with_a_dot_inside:{keywords:["jewel","blue","gem","crystal","fancy"],char:"\ud83d\udca0",fitzpatrick_scale:!1,category:"symbols"},cyclone:{keywords:["weather","swirl","blue","cloud","vortex","spiral","whirlpool","spin","tornado","hurricane","typhoon"],char:"\ud83c\udf00",fitzpatrick_scale:!1,category:"symbols"},loop:{keywords:["tape","cassette"],char:"\u27bf",fitzpatrick_scale:!1,category:"symbols"},globe_with_meridians:{keywords:["earth","international","world","internet","interweb","i18n"],char:"\ud83c\udf10",fitzpatrick_scale:!1,category:"symbols"},m:{keywords:["alphabet","blue-circle","letter"],char:"\u24c2\ufe0f",fitzpatrick_scale:!1,category:"symbols"},atm:{keywords:["money","sales","cash","blue-square","payment","bank"],char:"\ud83c\udfe7",fitzpatrick_scale:!1,category:"symbols"},sa:{keywords:["japanese","blue-square","katakana"],char:"\ud83c\ude02\ufe0f",fitzpatrick_scale:!1,category:"symbols"},passport_control:{keywords:["custom","blue-square"],char:"\ud83d\udec2",fitzpatrick_scale:!1,category:"symbols"},customs:{keywords:["passport","border","blue-square"],char:"\ud83d\udec3",fitzpatrick_scale:!1,category:"symbols"},baggage_claim:{keywords:["blue-square","airport","transport"],char:"\ud83d\udec4",fitzpatrick_scale:!1,category:"symbols"},left_luggage:{keywords:["blue-square","travel"],char:"\ud83d\udec5",fitzpatrick_scale:!1,category:"symbols"},wheelchair:{keywords:["blue-square","disabled","a11y","accessibility"],char:"\u267f",fitzpatrick_scale:!1,category:"symbols"},no_smoking:{keywords:["cigarette","blue-square","smell","smoke"],char:"\ud83d\udead",fitzpatrick_scale:!1,category:"symbols"},wc:{keywords:["toilet","restroom","blue-square"],char:"\ud83d\udebe",fitzpatrick_scale:!1,category:"symbols"},parking:{keywords:["cars","blue-square","alphabet","letter"],char:"\ud83c\udd7f\ufe0f",fitzpatrick_scale:!1,category:"symbols"},potable_water:{keywords:["blue-square","liquid","restroom","cleaning","faucet"],char:"\ud83d\udeb0",fitzpatrick_scale:!1,category:"symbols"},mens:{keywords:["toilet","restroom","wc","blue-square","gender","male"],char:"\ud83d\udeb9",fitzpatrick_scale:!1,category:"symbols"},womens:{keywords:["purple-square","woman","female","toilet","loo","restroom","gender"],char:"\ud83d\udeba",fitzpatrick_scale:!1,category:"symbols"},baby_symbol:{keywords:["orange-square","child"],char:"\ud83d\udebc",fitzpatrick_scale:!1,category:"symbols"},restroom:{keywords:["blue-square","toilet","refresh","wc","gender"],char:"\ud83d\udebb",fitzpatrick_scale:!1,category:"symbols"},put_litter_in_its_place:{keywords:["blue-square","sign","human","info"],char:"\ud83d\udeae",fitzpatrick_scale:!1,category:"symbols"},cinema:{keywords:["blue-square","record","film","movie","curtain","stage","theater"],char:"\ud83c\udfa6",fitzpatrick_scale:!1,category:"symbols"},signal_strength:{keywords:["blue-square","reception","phone","internet","connection","wifi","bluetooth","bars"],char:"\ud83d\udcf6",fitzpatrick_scale:!1,category:"symbols"},koko:{keywords:["blue-square","here","katakana","japanese","destination"],char:"\ud83c\ude01",fitzpatrick_scale:!1,category:"symbols"},ng:{keywords:["blue-square","words","shape","icon"],char:"\ud83c\udd96",fitzpatrick_scale:!1,category:"symbols"},ok:{keywords:["good","agree","yes","blue-square"],char:"\ud83c\udd97",fitzpatrick_scale:!1,category:"symbols"},up:{keywords:["blue-square","above","high"],char:"\ud83c\udd99",fitzpatrick_scale:!1,category:"symbols"},cool:{keywords:["words","blue-square"],char:"\ud83c\udd92",fitzpatrick_scale:!1,category:"symbols"},new:{keywords:["blue-square","words","start"],char:"\ud83c\udd95",fitzpatrick_scale:!1,category:"symbols"},free:{keywords:["blue-square","words"],char:"\ud83c\udd93",fitzpatrick_scale:!1,category:"symbols"},zero:{keywords:["0","numbers","blue-square","null"],char:"0\ufe0f\u20e3",fitzpatrick_scale:!1,category:"symbols"},one:{keywords:["blue-square","numbers","1"],char:"1\ufe0f\u20e3",fitzpatrick_scale:!1,category:"symbols"},two:{keywords:["numbers","2","prime","blue-square"],char:"2\ufe0f\u20e3",fitzpatrick_scale:!1,category:"symbols"},three:{keywords:["3","numbers","prime","blue-square"],char:"3\ufe0f\u20e3",fitzpatrick_scale:!1,category:"symbols"},four:{keywords:["4","numbers","blue-square"],char:"4\ufe0f\u20e3",fitzpatrick_scale:!1,category:"symbols"},five:{keywords:["5","numbers","blue-square","prime"],char:"5\ufe0f\u20e3",fitzpatrick_scale:!1,category:"symbols"},six:{keywords:["6","numbers","blue-square"],char:"6\ufe0f\u20e3",fitzpatrick_scale:!1,category:"symbols"},seven:{keywords:["7","numbers","blue-square","prime"],char:"7\ufe0f\u20e3",fitzpatrick_scale:!1,category:"symbols"},eight:{keywords:["8","blue-square","numbers"],char:"8\ufe0f\u20e3",fitzpatrick_scale:!1,category:"symbols"},nine:{keywords:["blue-square","numbers","9"],char:"9\ufe0f\u20e3",fitzpatrick_scale:!1,category:"symbols"},keycap_ten:{keywords:["numbers","10","blue-square"],char:"\ud83d\udd1f",fitzpatrick_scale:!1,category:"symbols"},asterisk:{keywords:["star","keycap"],char:"*\u20e3",fitzpatrick_scale:!1,category:"symbols"},1234:{keywords:["numbers","blue-square"],char:"\ud83d\udd22",fitzpatrick_scale:!1,category:"symbols"},eject_button:{keywords:["blue-square"],char:"\u23cf\ufe0f",fitzpatrick_scale:!1,category:"symbols"},arrow_forward:{keywords:["blue-square","right","direction","play"],char:"\u25b6\ufe0f",fitzpatrick_scale:!1,category:"symbols"},pause_button:{keywords:["pause","blue-square"],char:"\u23f8",fitzpatrick_scale:!1,category:"symbols"},next_track_button:{keywords:["forward","next","blue-square"],char:"\u23ed",fitzpatrick_scale:!1,category:"symbols"},stop_button:{keywords:["blue-square"],char:"\u23f9",fitzpatrick_scale:!1,category:"symbols"},record_button:{keywords:["blue-square"],char:"\u23fa",fitzpatrick_scale:!1,category:"symbols"},play_or_pause_button:{keywords:["blue-square","play","pause"],char:"\u23ef",fitzpatrick_scale:!1,category:"symbols"},previous_track_button:{keywords:["backward"],char:"\u23ee",fitzpatrick_scale:!1,category:"symbols"},fast_forward:{keywords:["blue-square","play","speed","continue"],char:"\u23e9",fitzpatrick_scale:!1,category:"symbols"},rewind:{keywords:["play","blue-square"],char:"\u23ea",fitzpatrick_scale:!1,category:"symbols"},twisted_rightwards_arrows:{keywords:["blue-square","shuffle","music","random"],char:"\ud83d\udd00",fitzpatrick_scale:!1,category:"symbols"},repeat:{keywords:["loop","record"],char:"\ud83d\udd01",fitzpatrick_scale:!1,category:"symbols"},repeat_one:{keywords:["blue-square","loop"],char:"\ud83d\udd02",fitzpatrick_scale:!1,category:"symbols"},arrow_backward:{keywords:["blue-square","left","direction"],char:"\u25c0\ufe0f",fitzpatrick_scale:!1,category:"symbols"},arrow_up_small:{keywords:["blue-square","triangle","direction","point","forward","top"],char:"\ud83d\udd3c",fitzpatrick_scale:!1,category:"symbols"},arrow_down_small:{keywords:["blue-square","direction","bottom"],char:"\ud83d\udd3d",fitzpatrick_scale:!1,category:"symbols"},arrow_double_up:{keywords:["blue-square","direction","top"],char:"\u23eb",fitzpatrick_scale:!1,category:"symbols"},arrow_double_down:{keywords:["blue-square","direction","bottom"],char:"\u23ec",fitzpatrick_scale:!1,category:"symbols"},arrow_right:{keywords:["blue-square","next"],char:"\u27a1\ufe0f",fitzpatrick_scale:!1,category:"symbols"},arrow_left:{keywords:["blue-square","previous","back"],char:"\u2b05\ufe0f",fitzpatrick_scale:!1,category:"symbols"},arrow_up:{keywords:["blue-square","continue","top","direction"],char:"\u2b06\ufe0f",fitzpatrick_scale:!1,category:"symbols"},arrow_down:{keywords:["blue-square","direction","bottom"],char:"\u2b07\ufe0f",fitzpatrick_scale:!1,category:"symbols"},arrow_upper_right:{keywords:["blue-square","point","direction","diagonal","northeast"],char:"\u2197\ufe0f",fitzpatrick_scale:!1,category:"symbols"},arrow_lower_right:{keywords:["blue-square","direction","diagonal","southeast"],char:"\u2198\ufe0f",fitzpatrick_scale:!1,category:"symbols"},arrow_lower_left:{keywords:["blue-square","direction","diagonal","southwest"],char:"\u2199\ufe0f",fitzpatrick_scale:!1,category:"symbols"},arrow_upper_left:{keywords:["blue-square","point","direction","diagonal","northwest"],char:"\u2196\ufe0f",fitzpatrick_scale:!1,category:"symbols"},arrow_up_down:{keywords:["blue-square","direction","way","vertical"],char:"\u2195\ufe0f",fitzpatrick_scale:!1,category:"symbols"},left_right_arrow:{keywords:["shape","direction","horizontal","sideways"],char:"\u2194\ufe0f",fitzpatrick_scale:!1,category:"symbols"},arrows_counterclockwise:{keywords:["blue-square","sync","cycle"],char:"\ud83d\udd04",fitzpatrick_scale:!1,category:"symbols"},arrow_right_hook:{keywords:["blue-square","return","rotate","direction"],char:"\u21aa\ufe0f",fitzpatrick_scale:!1,category:"symbols"},leftwards_arrow_with_hook:{keywords:["back","return","blue-square","undo","enter"],char:"\u21a9\ufe0f",fitzpatrick_scale:!1,category:"symbols"},arrow_heading_up:{keywords:["blue-square","direction","top"],char:"\u2934\ufe0f",fitzpatrick_scale:!1,category:"symbols"},arrow_heading_down:{keywords:["blue-square","direction","bottom"],char:"\u2935\ufe0f",fitzpatrick_scale:!1,category:"symbols"},hash:{keywords:["symbol","blue-square","twitter"],char:"#\ufe0f\u20e3",fitzpatrick_scale:!1,category:"symbols"},information_source:{keywords:["blue-square","alphabet","letter"],char:"\u2139\ufe0f",fitzpatrick_scale:!1,category:"symbols"},abc:{keywords:["blue-square","alphabet"],char:"\ud83d\udd24",fitzpatrick_scale:!1,category:"symbols"},abcd:{keywords:["blue-square","alphabet"],char:"\ud83d\udd21",fitzpatrick_scale:!1,category:"symbols"},capital_abcd:{keywords:["alphabet","words","blue-square"],char:"\ud83d\udd20",fitzpatrick_scale:!1,category:"symbols"},symbols:{keywords:["blue-square","music","note","ampersand","percent","glyphs","characters"],char:"\ud83d\udd23",fitzpatrick_scale:!1,category:"symbols"},musical_note:{keywords:["score","tone","sound"],char:"\ud83c\udfb5",fitzpatrick_scale:!1,category:"symbols"},notes:{keywords:["music","score"],char:"\ud83c\udfb6",fitzpatrick_scale:!1,category:"symbols"},wavy_dash:{keywords:["draw","line","moustache","mustache","squiggle","scribble"],char:"\u3030\ufe0f",fitzpatrick_scale:!1,category:"symbols"},curly_loop:{keywords:["scribble","draw","shape","squiggle"],char:"\u27b0",fitzpatrick_scale:!1,category:"symbols"},heavy_check_mark:{keywords:["ok","nike","answer","yes","tick"],char:"\u2714\ufe0f",fitzpatrick_scale:!1,category:"symbols"},arrows_clockwise:{keywords:["sync","cycle","round","repeat"],char:"\ud83d\udd03",fitzpatrick_scale:!1,category:"symbols"},heavy_plus_sign:{keywords:["math","calculation","addition","more","increase"],char:"\u2795",fitzpatrick_scale:!1,category:"symbols"},heavy_minus_sign:{keywords:["math","calculation","subtract","less"],char:"\u2796",fitzpatrick_scale:!1,category:"symbols"},heavy_division_sign:{keywords:["divide","math","calculation"],char:"\u2797",fitzpatrick_scale:!1,category:"symbols"},heavy_multiplication_x:{keywords:["math","calculation"],char:"\u2716\ufe0f",fitzpatrick_scale:!1,category:"symbols"},infinity:{keywords:["forever"],char:"\u267e",fitzpatrick_scale:!1,category:"symbols"},heavy_dollar_sign:{keywords:["money","sales","payment","currency","buck"],char:"\ud83d\udcb2",fitzpatrick_scale:!1,category:"symbols"},currency_exchange:{keywords:["money","sales","dollar","travel"],char:"\ud83d\udcb1",fitzpatrick_scale:!1,category:"symbols"},copyright:{keywords:["ip","license","circle","law","legal"],char:"\xa9\ufe0f",fitzpatrick_scale:!1,category:"symbols"},registered:{keywords:["alphabet","circle"],char:"\xae\ufe0f",fitzpatrick_scale:!1,category:"symbols"},tm:{keywords:["trademark","brand","law","legal"],char:"\u2122\ufe0f",fitzpatrick_scale:!1,category:"symbols"},end:{keywords:["words","arrow"],char:"\ud83d\udd1a",fitzpatrick_scale:!1,category:"symbols"},back:{keywords:["arrow","words","return"],char:"\ud83d\udd19",fitzpatrick_scale:!1,category:"symbols"},on:{keywords:["arrow","words"],char:"\ud83d\udd1b",fitzpatrick_scale:!1,category:"symbols"},top:{keywords:["words","blue-square"],char:"\ud83d\udd1d",fitzpatrick_scale:!1,category:"symbols"},soon:{keywords:["arrow","words"],char:"\ud83d\udd1c",fitzpatrick_scale:!1,category:"symbols"},ballot_box_with_check:{keywords:["ok","agree","confirm","black-square","vote","election","yes","tick"],char:"\u2611\ufe0f",fitzpatrick_scale:!1,category:"symbols"},radio_button:{keywords:["input","old","music","circle"],char:"\ud83d\udd18",fitzpatrick_scale:!1,category:"symbols"},white_circle:{keywords:["shape","round"],char:"\u26aa",fitzpatrick_scale:!1,category:"symbols"},black_circle:{keywords:["shape","button","round"],char:"\u26ab",fitzpatrick_scale:!1,category:"symbols"},red_circle:{keywords:["shape","error","danger"],char:"\ud83d\udd34",fitzpatrick_scale:!1,category:"symbols"},large_blue_circle:{keywords:["shape","icon","button"],char:"\ud83d\udd35",fitzpatrick_scale:!1,category:"symbols"},small_orange_diamond:{keywords:["shape","jewel","gem"],char:"\ud83d\udd38",fitzpatrick_scale:!1,category:"symbols"},small_blue_diamond:{keywords:["shape","jewel","gem"],char:"\ud83d\udd39",fitzpatrick_scale:!1,category:"symbols"},large_orange_diamond:{keywords:["shape","jewel","gem"],char:"\ud83d\udd36",fitzpatrick_scale:!1,category:"symbols"},large_blue_diamond:{keywords:["shape","jewel","gem"],char:"\ud83d\udd37",fitzpatrick_scale:!1,category:"symbols"},small_red_triangle:{keywords:["shape","direction","up","top"],char:"\ud83d\udd3a",fitzpatrick_scale:!1,category:"symbols"},black_small_square:{keywords:["shape","icon"],char:"\u25aa\ufe0f",fitzpatrick_scale:!1,category:"symbols"},white_small_square:{keywords:["shape","icon"],char:"\u25ab\ufe0f",fitzpatrick_scale:!1,category:"symbols"},black_large_square:{keywords:["shape","icon","button"],char:"\u2b1b",fitzpatrick_scale:!1,category:"symbols"},white_large_square:{keywords:["shape","icon","stone","button"],char:"\u2b1c",fitzpatrick_scale:!1,category:"symbols"},small_red_triangle_down:{keywords:["shape","direction","bottom"],char:"\ud83d\udd3b",fitzpatrick_scale:!1,category:"symbols"},black_medium_square:{keywords:["shape","button","icon"],char:"\u25fc\ufe0f",fitzpatrick_scale:!1,category:"symbols"},white_medium_square:{keywords:["shape","stone","icon"],char:"\u25fb\ufe0f",fitzpatrick_scale:!1,category:"symbols"},black_medium_small_square:{keywords:["icon","shape","button"],char:"\u25fe",fitzpatrick_scale:!1,category:"symbols"},white_medium_small_square:{keywords:["shape","stone","icon","button"],char:"\u25fd",fitzpatrick_scale:!1,category:"symbols"},black_square_button:{keywords:["shape","input","frame"],char:"\ud83d\udd32",fitzpatrick_scale:!1,category:"symbols"},white_square_button:{keywords:["shape","input"],char:"\ud83d\udd33",fitzpatrick_scale:!1,category:"symbols"},speaker:{keywords:["sound","volume","silence","broadcast"],char:"\ud83d\udd08",fitzpatrick_scale:!1,category:"symbols"},sound:{keywords:["volume","speaker","broadcast"],char:"\ud83d\udd09",fitzpatrick_scale:!1,category:"symbols"},loud_sound:{keywords:["volume","noise","noisy","speaker","broadcast"],char:"\ud83d\udd0a",fitzpatrick_scale:!1,category:"symbols"},mute:{keywords:["sound","volume","silence","quiet"],char:"\ud83d\udd07",fitzpatrick_scale:!1,category:"symbols"},mega:{keywords:["sound","speaker","volume"],char:"\ud83d\udce3",fitzpatrick_scale:!1,category:"symbols"},loudspeaker:{keywords:["volume","sound"],char:"\ud83d\udce2",fitzpatrick_scale:!1,category:"symbols"},bell:{keywords:["sound","notification","christmas","xmas","chime"],char:"\ud83d\udd14",fitzpatrick_scale:!1,category:"symbols"},no_bell:{keywords:["sound","volume","mute","quiet","silent"],char:"\ud83d\udd15",fitzpatrick_scale:!1,category:"symbols"},black_joker:{keywords:["poker","cards","game","play","magic"],char:"\ud83c\udccf",fitzpatrick_scale:!1,category:"symbols"},mahjong:{keywords:["game","play","chinese","kanji"],char:"\ud83c\udc04",fitzpatrick_scale:!1,category:"symbols"},spades:{keywords:["poker","cards","suits","magic"],char:"\u2660\ufe0f",fitzpatrick_scale:!1,category:"symbols"},clubs:{keywords:["poker","cards","magic","suits"],char:"\u2663\ufe0f",fitzpatrick_scale:!1,category:"symbols"},hearts:{keywords:["poker","cards","magic","suits"],char:"\u2665\ufe0f",fitzpatrick_scale:!1,category:"symbols"},diamonds:{keywords:["poker","cards","magic","suits"],char:"\u2666\ufe0f",fitzpatrick_scale:!1,category:"symbols"},flower_playing_cards:{keywords:["game","sunset","red"],char:"\ud83c\udfb4",fitzpatrick_scale:!1,category:"symbols"},thought_balloon:{keywords:["bubble","cloud","speech","thinking","dream"],char:"\ud83d\udcad",fitzpatrick_scale:!1,category:"symbols"},right_anger_bubble:{keywords:["caption","speech","thinking","mad"],char:"\ud83d\uddef",fitzpatrick_scale:!1,category:"symbols"},speech_balloon:{keywords:["bubble","words","message","talk","chatting"],char:"\ud83d\udcac",fitzpatrick_scale:!1,category:"symbols"},left_speech_bubble:{keywords:["words","message","talk","chatting"],char:"\ud83d\udde8",fitzpatrick_scale:!1,category:"symbols"},clock1:{keywords:["time","late","early","schedule"],char:"\ud83d\udd50",fitzpatrick_scale:!1,category:"symbols"},clock2:{keywords:["time","late","early","schedule"],char:"\ud83d\udd51",fitzpatrick_scale:!1,category:"symbols"},clock3:{keywords:["time","late","early","schedule"],char:"\ud83d\udd52",fitzpatrick_scale:!1,category:"symbols"},clock4:{keywords:["time","late","early","schedule"],char:"\ud83d\udd53",fitzpatrick_scale:!1,category:"symbols"},clock5:{keywords:["time","late","early","schedule"],char:"\ud83d\udd54",fitzpatrick_scale:!1,category:"symbols"},clock6:{keywords:["time","late","early","schedule","dawn","dusk"],char:"\ud83d\udd55",fitzpatrick_scale:!1,category:"symbols"},clock7:{keywords:["time","late","early","schedule"],char:"\ud83d\udd56",fitzpatrick_scale:!1,category:"symbols"},clock8:{keywords:["time","late","early","schedule"],char:"\ud83d\udd57",fitzpatrick_scale:!1,category:"symbols"},clock9:{keywords:["time","late","early","schedule"],char:"\ud83d\udd58",fitzpatrick_scale:!1,category:"symbols"},clock10:{keywords:["time","late","early","schedule"],char:"\ud83d\udd59",fitzpatrick_scale:!1,category:"symbols"},clock11:{keywords:["time","late","early","schedule"],char:"\ud83d\udd5a",fitzpatrick_scale:!1,category:"symbols"},clock12:{keywords:["time","noon","midnight","midday","late","early","schedule"],char:"\ud83d\udd5b",fitzpatrick_scale:!1,category:"symbols"},clock130:{keywords:["time","late","early","schedule"],char:"\ud83d\udd5c",fitzpatrick_scale:!1,category:"symbols"},clock230:{keywords:["time","late","early","schedule"],char:"\ud83d\udd5d",fitzpatrick_scale:!1,category:"symbols"},clock330:{keywords:["time","late","early","schedule"],char:"\ud83d\udd5e",fitzpatrick_scale:!1,category:"symbols"},clock430:{keywords:["time","late","early","schedule"],char:"\ud83d\udd5f",fitzpatrick_scale:!1,category:"symbols"},clock530:{keywords:["time","late","early","schedule"],char:"\ud83d\udd60",fitzpatrick_scale:!1,category:"symbols"},clock630:{keywords:["time","late","early","schedule"],char:"\ud83d\udd61",fitzpatrick_scale:!1,category:"symbols"},clock730:{keywords:["time","late","early","schedule"],char:"\ud83d\udd62",fitzpatrick_scale:!1,category:"symbols"},clock830:{keywords:["time","late","early","schedule"],char:"\ud83d\udd63",fitzpatrick_scale:!1,category:"symbols"},clock930:{keywords:["time","late","early","schedule"],char:"\ud83d\udd64",fitzpatrick_scale:!1,category:"symbols"},clock1030:{keywords:["time","late","early","schedule"],char:"\ud83d\udd65",fitzpatrick_scale:!1,category:"symbols"},clock1130:{keywords:["time","late","early","schedule"],char:"\ud83d\udd66",fitzpatrick_scale:!1,category:"symbols"},clock1230:{keywords:["time","late","early","schedule"],char:"\ud83d\udd67",fitzpatrick_scale:!1,category:"symbols"},afghanistan:{keywords:["af","flag","nation","country","banner"],char:"\ud83c\udde6\ud83c\uddeb",fitzpatrick_scale:!1,category:"flags"},aland_islands:{keywords:["\xc5land","islands","flag","nation","country","banner"],char:"\ud83c\udde6\ud83c\uddfd",fitzpatrick_scale:!1,category:"flags"},albania:{keywords:["al","flag","nation","country","banner"],char:"\ud83c\udde6\ud83c\uddf1",fitzpatrick_scale:!1,category:"flags"},algeria:{keywords:["dz","flag","nation","country","banner"],char:"\ud83c\udde9\ud83c\uddff",fitzpatrick_scale:!1,category:"flags"},american_samoa:{keywords:["american","ws","flag","nation","country","banner"],char:"\ud83c\udde6\ud83c\uddf8",fitzpatrick_scale:!1,category:"flags"},andorra:{keywords:["ad","flag","nation","country","banner"],char:"\ud83c\udde6\ud83c\udde9",fitzpatrick_scale:!1,category:"flags"},angola:{keywords:["ao","flag","nation","country","banner"],char:"\ud83c\udde6\ud83c\uddf4",fitzpatrick_scale:!1,category:"flags"},anguilla:{keywords:["ai","flag","nation","country","banner"],char:"\ud83c\udde6\ud83c\uddee",fitzpatrick_scale:!1,category:"flags"},antarctica:{keywords:["aq","flag","nation","country","banner"],char:"\ud83c\udde6\ud83c\uddf6",fitzpatrick_scale:!1,category:"flags"},antigua_barbuda:{keywords:["antigua","barbuda","flag","nation","country","banner"],char:"\ud83c\udde6\ud83c\uddec",fitzpatrick_scale:!1,category:"flags"},argentina:{keywords:["ar","flag","nation","country","banner"],char:"\ud83c\udde6\ud83c\uddf7",fitzpatrick_scale:!1,category:"flags"},armenia:{keywords:["am","flag","nation","country","banner"],char:"\ud83c\udde6\ud83c\uddf2",fitzpatrick_scale:!1,category:"flags"},aruba:{keywords:["aw","flag","nation","country","banner"],char:"\ud83c\udde6\ud83c\uddfc",fitzpatrick_scale:!1,category:"flags"},australia:{keywords:["au","flag","nation","country","banner"],char:"\ud83c\udde6\ud83c\uddfa",fitzpatrick_scale:!1,category:"flags"},austria:{keywords:["at","flag","nation","country","banner"],char:"\ud83c\udde6\ud83c\uddf9",fitzpatrick_scale:!1,category:"flags"},azerbaijan:{keywords:["az","flag","nation","country","banner"],char:"\ud83c\udde6\ud83c\uddff",fitzpatrick_scale:!1,category:"flags"},bahamas:{keywords:["bs","flag","nation","country","banner"],char:"\ud83c\udde7\ud83c\uddf8",fitzpatrick_scale:!1,category:"flags"},bahrain:{keywords:["bh","flag","nation","country","banner"],char:"\ud83c\udde7\ud83c\udded",fitzpatrick_scale:!1,category:"flags"},bangladesh:{keywords:["bd","flag","nation","country","banner"],char:"\ud83c\udde7\ud83c\udde9",fitzpatrick_scale:!1,category:"flags"},barbados:{keywords:["bb","flag","nation","country","banner"],char:"\ud83c\udde7\ud83c\udde7",fitzpatrick_scale:!1,category:"flags"},belarus:{keywords:["by","flag","nation","country","banner"],char:"\ud83c\udde7\ud83c\uddfe",fitzpatrick_scale:!1,category:"flags"},belgium:{keywords:["be","flag","nation","country","banner"],char:"\ud83c\udde7\ud83c\uddea",fitzpatrick_scale:!1,category:"flags"},belize:{keywords:["bz","flag","nation","country","banner"],char:"\ud83c\udde7\ud83c\uddff",fitzpatrick_scale:!1,category:"flags"},benin:{keywords:["bj","flag","nation","country","banner"],char:"\ud83c\udde7\ud83c\uddef",fitzpatrick_scale:!1,category:"flags"},bermuda:{keywords:["bm","flag","nation","country","banner"],char:"\ud83c\udde7\ud83c\uddf2",fitzpatrick_scale:!1,category:"flags"},bhutan:{keywords:["bt","flag","nation","country","banner"],char:"\ud83c\udde7\ud83c\uddf9",fitzpatrick_scale:!1,category:"flags"},bolivia:{keywords:["bo","flag","nation","country","banner"],char:"\ud83c\udde7\ud83c\uddf4",fitzpatrick_scale:!1,category:"flags"},caribbean_netherlands:{keywords:["bonaire","flag","nation","country","banner"],char:"\ud83c\udde7\ud83c\uddf6",fitzpatrick_scale:!1,category:"flags"},bosnia_herzegovina:{keywords:["bosnia","herzegovina","flag","nation","country","banner"],char:"\ud83c\udde7\ud83c\udde6",fitzpatrick_scale:!1,category:"flags"},botswana:{keywords:["bw","flag","nation","country","banner"],char:"\ud83c\udde7\ud83c\uddfc",fitzpatrick_scale:!1,category:"flags"},brazil:{keywords:["br","flag","nation","country","banner"],char:"\ud83c\udde7\ud83c\uddf7",fitzpatrick_scale:!1,category:"flags"},british_indian_ocean_territory:{keywords:["british","indian","ocean","territory","flag","nation","country","banner"],char:"\ud83c\uddee\ud83c\uddf4",fitzpatrick_scale:!1,category:"flags"},british_virgin_islands:{keywords:["british","virgin","islands","bvi","flag","nation","country","banner"],char:"\ud83c\uddfb\ud83c\uddec",fitzpatrick_scale:!1,category:"flags"},brunei:{keywords:["bn","darussalam","flag","nation","country","banner"],char:"\ud83c\udde7\ud83c\uddf3",fitzpatrick_scale:!1,category:"flags"},bulgaria:{keywords:["bg","flag","nation","country","banner"],char:"\ud83c\udde7\ud83c\uddec",fitzpatrick_scale:!1,category:"flags"},burkina_faso:{keywords:["burkina","faso","flag","nation","country","banner"],char:"\ud83c\udde7\ud83c\uddeb",fitzpatrick_scale:!1,category:"flags"},burundi:{keywords:["bi","flag","nation","country","banner"],char:"\ud83c\udde7\ud83c\uddee",fitzpatrick_scale:!1,category:"flags"},cape_verde:{keywords:["cabo","verde","flag","nation","country","banner"],char:"\ud83c\udde8\ud83c\uddfb",fitzpatrick_scale:!1,category:"flags"},cambodia:{keywords:["kh","flag","nation","country","banner"],char:"\ud83c\uddf0\ud83c\udded",fitzpatrick_scale:!1,category:"flags"},cameroon:{keywords:["cm","flag","nation","country","banner"],char:"\ud83c\udde8\ud83c\uddf2",fitzpatrick_scale:!1,category:"flags"},canada:{keywords:["ca","flag","nation","country","banner"],char:"\ud83c\udde8\ud83c\udde6",fitzpatrick_scale:!1,category:"flags"},canary_islands:{keywords:["canary","islands","flag","nation","country","banner"],char:"\ud83c\uddee\ud83c\udde8",fitzpatrick_scale:!1,category:"flags"},cayman_islands:{keywords:["cayman","islands","flag","nation","country","banner"],char:"\ud83c\uddf0\ud83c\uddfe",fitzpatrick_scale:!1,category:"flags"},central_african_republic:{keywords:["central","african","republic","flag","nation","country","banner"],char:"\ud83c\udde8\ud83c\uddeb",fitzpatrick_scale:!1,category:"flags"},chad:{keywords:["td","flag","nation","country","banner"],char:"\ud83c\uddf9\ud83c\udde9",fitzpatrick_scale:!1,category:"flags"},chile:{keywords:["flag","nation","country","banner"],char:"\ud83c\udde8\ud83c\uddf1",fitzpatrick_scale:!1,category:"flags"},cn:{keywords:["china","chinese","prc","flag","country","nation","banner"],char:"\ud83c\udde8\ud83c\uddf3",fitzpatrick_scale:!1,category:"flags"},christmas_island:{keywords:["christmas","island","flag","nation","country","banner"],char:"\ud83c\udde8\ud83c\uddfd",fitzpatrick_scale:!1,category:"flags"},cocos_islands:{keywords:["cocos","keeling","islands","flag","nation","country","banner"],char:"\ud83c\udde8\ud83c\udde8",fitzpatrick_scale:!1,category:"flags"},colombia:{keywords:["co","flag","nation","country","banner"],char:"\ud83c\udde8\ud83c\uddf4",fitzpatrick_scale:!1,category:"flags"},comoros:{keywords:["km","flag","nation","country","banner"],char:"\ud83c\uddf0\ud83c\uddf2",fitzpatrick_scale:!1,category:"flags"},congo_brazzaville:{keywords:["congo","flag","nation","country","banner"],char:"\ud83c\udde8\ud83c\uddec",fitzpatrick_scale:!1,category:"flags"},congo_kinshasa:{keywords:["congo","democratic","republic","flag","nation","country","banner"],char:"\ud83c\udde8\ud83c\udde9",fitzpatrick_scale:!1,category:"flags"},cook_islands:{keywords:["cook","islands","flag","nation","country","banner"],char:"\ud83c\udde8\ud83c\uddf0",fitzpatrick_scale:!1,category:"flags"},costa_rica:{keywords:["costa","rica","flag","nation","country","banner"],char:"\ud83c\udde8\ud83c\uddf7",fitzpatrick_scale:!1,category:"flags"},croatia:{keywords:["hr","flag","nation","country","banner"],char:"\ud83c\udded\ud83c\uddf7",fitzpatrick_scale:!1,category:"flags"},cuba:{keywords:["cu","flag","nation","country","banner"],char:"\ud83c\udde8\ud83c\uddfa",fitzpatrick_scale:!1,category:"flags"},curacao:{keywords:["cura\xe7ao","flag","nation","country","banner"],char:"\ud83c\udde8\ud83c\uddfc",fitzpatrick_scale:!1,category:"flags"},cyprus:{keywords:["cy","flag","nation","country","banner"],char:"\ud83c\udde8\ud83c\uddfe",fitzpatrick_scale:!1,category:"flags"},czech_republic:{keywords:["cz","flag","nation","country","banner"],char:"\ud83c\udde8\ud83c\uddff",fitzpatrick_scale:!1,category:"flags"},denmark:{keywords:["dk","flag","nation","country","banner"],char:"\ud83c\udde9\ud83c\uddf0",fitzpatrick_scale:!1,category:"flags"},djibouti:{keywords:["dj","flag","nation","country","banner"],char:"\ud83c\udde9\ud83c\uddef",fitzpatrick_scale:!1,category:"flags"},dominica:{keywords:["dm","flag","nation","country","banner"],char:"\ud83c\udde9\ud83c\uddf2",fitzpatrick_scale:!1,category:"flags"},dominican_republic:{keywords:["dominican","republic","flag","nation","country","banner"],char:"\ud83c\udde9\ud83c\uddf4",fitzpatrick_scale:!1,category:"flags"},ecuador:{keywords:["ec","flag","nation","country","banner"],char:"\ud83c\uddea\ud83c\udde8",fitzpatrick_scale:!1,category:"flags"},egypt:{keywords:["eg","flag","nation","country","banner"],char:"\ud83c\uddea\ud83c\uddec",fitzpatrick_scale:!1,category:"flags"},el_salvador:{keywords:["el","salvador","flag","nation","country","banner"],char:"\ud83c\uddf8\ud83c\uddfb",fitzpatrick_scale:!1,category:"flags"},equatorial_guinea:{keywords:["equatorial","gn","flag","nation","country","banner"],char:"\ud83c\uddec\ud83c\uddf6",fitzpatrick_scale:!1,category:"flags"},eritrea:{keywords:["er","flag","nation","country","banner"],char:"\ud83c\uddea\ud83c\uddf7",fitzpatrick_scale:!1,category:"flags"},estonia:{keywords:["ee","flag","nation","country","banner"],char:"\ud83c\uddea\ud83c\uddea",fitzpatrick_scale:!1,category:"flags"},ethiopia:{keywords:["et","flag","nation","country","banner"],char:"\ud83c\uddea\ud83c\uddf9",fitzpatrick_scale:!1,category:"flags"},eu:{keywords:["european","union","flag","banner"],char:"\ud83c\uddea\ud83c\uddfa",fitzpatrick_scale:!1,category:"flags"},falkland_islands:{keywords:["falkland","islands","malvinas","flag","nation","country","banner"],char:"\ud83c\uddeb\ud83c\uddf0",fitzpatrick_scale:!1,category:"flags"},faroe_islands:{keywords:["faroe","islands","flag","nation","country","banner"],char:"\ud83c\uddeb\ud83c\uddf4",fitzpatrick_scale:!1,category:"flags"},fiji:{keywords:["fj","flag","nation","country","banner"],char:"\ud83c\uddeb\ud83c\uddef",fitzpatrick_scale:!1,category:"flags"},finland:{keywords:["fi","flag","nation","country","banner"],char:"\ud83c\uddeb\ud83c\uddee",fitzpatrick_scale:!1,category:"flags"},fr:{keywords:["banner","flag","nation","france","french","country"],char:"\ud83c\uddeb\ud83c\uddf7",fitzpatrick_scale:!1,category:"flags"},french_guiana:{keywords:["french","guiana","flag","nation","country","banner"],char:"\ud83c\uddec\ud83c\uddeb",fitzpatrick_scale:!1,category:"flags"},french_polynesia:{keywords:["french","polynesia","flag","nation","country","banner"],char:"\ud83c\uddf5\ud83c\uddeb",fitzpatrick_scale:!1,category:"flags"},french_southern_territories:{keywords:["french","southern","territories","flag","nation","country","banner"],char:"\ud83c\uddf9\ud83c\uddeb",fitzpatrick_scale:!1,category:"flags"},gabon:{keywords:["ga","flag","nation","country","banner"],char:"\ud83c\uddec\ud83c\udde6",fitzpatrick_scale:!1,category:"flags"},gambia:{keywords:["gm","flag","nation","country","banner"],char:"\ud83c\uddec\ud83c\uddf2",fitzpatrick_scale:!1,category:"flags"},georgia:{keywords:["ge","flag","nation","country","banner"],char:"\ud83c\uddec\ud83c\uddea",fitzpatrick_scale:!1,category:"flags"},de:{keywords:["german","nation","flag","country","banner"],char:"\ud83c\udde9\ud83c\uddea",fitzpatrick_scale:!1,category:"flags"},ghana:{keywords:["gh","flag","nation","country","banner"],char:"\ud83c\uddec\ud83c\udded",fitzpatrick_scale:!1,category:"flags"},gibraltar:{keywords:["gi","flag","nation","country","banner"],char:"\ud83c\uddec\ud83c\uddee",fitzpatrick_scale:!1,category:"flags"},greece:{keywords:["gr","flag","nation","country","banner"],char:"\ud83c\uddec\ud83c\uddf7",fitzpatrick_scale:!1,category:"flags"},greenland:{keywords:["gl","flag","nation","country","banner"],char:"\ud83c\uddec\ud83c\uddf1",fitzpatrick_scale:!1,category:"flags"},grenada:{keywords:["gd","flag","nation","country","banner"],char:"\ud83c\uddec\ud83c\udde9",fitzpatrick_scale:!1,category:"flags"},guadeloupe:{keywords:["gp","flag","nation","country","banner"],char:"\ud83c\uddec\ud83c\uddf5",fitzpatrick_scale:!1,category:"flags"},guam:{keywords:["gu","flag","nation","country","banner"],char:"\ud83c\uddec\ud83c\uddfa",fitzpatrick_scale:!1,category:"flags"},guatemala:{keywords:["gt","flag","nation","country","banner"],char:"\ud83c\uddec\ud83c\uddf9",fitzpatrick_scale:!1,category:"flags"},guernsey:{keywords:["gg","flag","nation","country","banner"],char:"\ud83c\uddec\ud83c\uddec",fitzpatrick_scale:!1,category:"flags"},guinea:{keywords:["gn","flag","nation","country","banner"],char:"\ud83c\uddec\ud83c\uddf3",fitzpatrick_scale:!1,category:"flags"},guinea_bissau:{keywords:["gw","bissau","flag","nation","country","banner"],char:"\ud83c\uddec\ud83c\uddfc",fitzpatrick_scale:!1,category:"flags"},guyana:{keywords:["gy","flag","nation","country","banner"],char:"\ud83c\uddec\ud83c\uddfe",fitzpatrick_scale:!1,category:"flags"},haiti:{keywords:["ht","flag","nation","country","banner"],char:"\ud83c\udded\ud83c\uddf9",fitzpatrick_scale:!1,category:"flags"},honduras:{keywords:["hn","flag","nation","country","banner"],char:"\ud83c\udded\ud83c\uddf3",fitzpatrick_scale:!1,category:"flags"},hong_kong:{keywords:["hong","kong","flag","nation","country","banner"],char:"\ud83c\udded\ud83c\uddf0",fitzpatrick_scale:!1,category:"flags"},hungary:{keywords:["hu","flag","nation","country","banner"],char:"\ud83c\udded\ud83c\uddfa",fitzpatrick_scale:!1,category:"flags"},iceland:{keywords:["is","flag","nation","country","banner"],char:"\ud83c\uddee\ud83c\uddf8",fitzpatrick_scale:!1,category:"flags"},india:{keywords:["in","flag","nation","country","banner"],char:"\ud83c\uddee\ud83c\uddf3",fitzpatrick_scale:!1,category:"flags"},indonesia:{keywords:["flag","nation","country","banner"],char:"\ud83c\uddee\ud83c\udde9",fitzpatrick_scale:!1,category:"flags"},iran:{keywords:["iran,","islamic","republic","flag","nation","country","banner"],char:"\ud83c\uddee\ud83c\uddf7",fitzpatrick_scale:!1,category:"flags"},iraq:{keywords:["iq","flag","nation","country","banner"],char:"\ud83c\uddee\ud83c\uddf6",fitzpatrick_scale:!1,category:"flags"},ireland:{keywords:["ie","flag","nation","country","banner"],char:"\ud83c\uddee\ud83c\uddea",fitzpatrick_scale:!1,category:"flags"},isle_of_man:{keywords:["isle","man","flag","nation","country","banner"],char:"\ud83c\uddee\ud83c\uddf2",fitzpatrick_scale:!1,category:"flags"},israel:{keywords:["il","flag","nation","country","banner"],char:"\ud83c\uddee\ud83c\uddf1",fitzpatrick_scale:!1,category:"flags"},it:{keywords:["italy","flag","nation","country","banner"],char:"\ud83c\uddee\ud83c\uddf9",fitzpatrick_scale:!1,category:"flags"},cote_divoire:{keywords:["ivory","coast","flag","nation","country","banner"],char:"\ud83c\udde8\ud83c\uddee",fitzpatrick_scale:!1,category:"flags"},jamaica:{keywords:["jm","flag","nation","country","banner"],char:"\ud83c\uddef\ud83c\uddf2",fitzpatrick_scale:!1,category:"flags"},jp:{keywords:["japanese","nation","flag","country","banner"],char:"\ud83c\uddef\ud83c\uddf5",fitzpatrick_scale:!1,category:"flags"},jersey:{keywords:["je","flag","nation","country","banner"],char:"\ud83c\uddef\ud83c\uddea",fitzpatrick_scale:!1,category:"flags"},jordan:{keywords:["jo","flag","nation","country","banner"],char:"\ud83c\uddef\ud83c\uddf4",fitzpatrick_scale:!1,category:"flags"},kazakhstan:{keywords:["kz","flag","nation","country","banner"],char:"\ud83c\uddf0\ud83c\uddff",fitzpatrick_scale:!1,category:"flags"},kenya:{keywords:["ke","flag","nation","country","banner"],char:"\ud83c\uddf0\ud83c\uddea",fitzpatrick_scale:!1,category:"flags"},kiribati:{keywords:["ki","flag","nation","country","banner"],char:"\ud83c\uddf0\ud83c\uddee",fitzpatrick_scale:!1,category:"flags"},kosovo:{keywords:["xk","flag","nation","country","banner"],char:"\ud83c\uddfd\ud83c\uddf0",fitzpatrick_scale:!1,category:"flags"},kuwait:{keywords:["kw","flag","nation","country","banner"],char:"\ud83c\uddf0\ud83c\uddfc",fitzpatrick_scale:!1,category:"flags"},kyrgyzstan:{keywords:["kg","flag","nation","country","banner"],char:"\ud83c\uddf0\ud83c\uddec",fitzpatrick_scale:!1,category:"flags"},laos:{keywords:["lao","democratic","republic","flag","nation","country","banner"],char:"\ud83c\uddf1\ud83c\udde6",fitzpatrick_scale:!1,category:"flags"},latvia:{keywords:["lv","flag","nation","country","banner"],char:"\ud83c\uddf1\ud83c\uddfb",fitzpatrick_scale:!1,category:"flags"},lebanon:{keywords:["lb","flag","nation","country","banner"],char:"\ud83c\uddf1\ud83c\udde7",fitzpatrick_scale:!1,category:"flags"},lesotho:{keywords:["ls","flag","nation","country","banner"],char:"\ud83c\uddf1\ud83c\uddf8",fitzpatrick_scale:!1,category:"flags"},liberia:{keywords:["lr","flag","nation","country","banner"],char:"\ud83c\uddf1\ud83c\uddf7",fitzpatrick_scale:!1,category:"flags"},libya:{keywords:["ly","flag","nation","country","banner"],char:"\ud83c\uddf1\ud83c\uddfe",fitzpatrick_scale:!1,category:"flags"},liechtenstein:{keywords:["li","flag","nation","country","banner"],char:"\ud83c\uddf1\ud83c\uddee",fitzpatrick_scale:!1,category:"flags"},lithuania:{keywords:["lt","flag","nation","country","banner"],char:"\ud83c\uddf1\ud83c\uddf9",fitzpatrick_scale:!1,category:"flags"},luxembourg:{keywords:["lu","flag","nation","country","banner"],char:"\ud83c\uddf1\ud83c\uddfa",fitzpatrick_scale:!1,category:"flags"},macau:{keywords:["macao","flag","nation","country","banner"],char:"\ud83c\uddf2\ud83c\uddf4",fitzpatrick_scale:!1,category:"flags"},macedonia:{keywords:["macedonia,","flag","nation","country","banner"],char:"\ud83c\uddf2\ud83c\uddf0",fitzpatrick_scale:!1,category:"flags"},madagascar:{keywords:["mg","flag","nation","country","banner"],char:"\ud83c\uddf2\ud83c\uddec",fitzpatrick_scale:!1,category:"flags"},malawi:{keywords:["mw","flag","nation","country","banner"],char:"\ud83c\uddf2\ud83c\uddfc",fitzpatrick_scale:!1,category:"flags"},malaysia:{keywords:["my","flag","nation","country","banner"],char:"\ud83c\uddf2\ud83c\uddfe",fitzpatrick_scale:!1,category:"flags"},maldives:{keywords:["mv","flag","nation","country","banner"],char:"\ud83c\uddf2\ud83c\uddfb",fitzpatrick_scale:!1,category:"flags"},mali:{keywords:["ml","flag","nation","country","banner"],char:"\ud83c\uddf2\ud83c\uddf1",fitzpatrick_scale:!1,category:"flags"},malta:{keywords:["mt","flag","nation","country","banner"],char:"\ud83c\uddf2\ud83c\uddf9",fitzpatrick_scale:!1,category:"flags"},marshall_islands:{keywords:["marshall","islands","flag","nation","country","banner"],char:"\ud83c\uddf2\ud83c\udded",fitzpatrick_scale:!1,category:"flags"},martinique:{keywords:["mq","flag","nation","country","banner"],char:"\ud83c\uddf2\ud83c\uddf6",fitzpatrick_scale:!1,category:"flags"},mauritania:{keywords:["mr","flag","nation","country","banner"],char:"\ud83c\uddf2\ud83c\uddf7",fitzpatrick_scale:!1,category:"flags"},mauritius:{keywords:["mu","flag","nation","country","banner"],char:"\ud83c\uddf2\ud83c\uddfa",fitzpatrick_scale:!1,category:"flags"},mayotte:{keywords:["yt","flag","nation","country","banner"],char:"\ud83c\uddfe\ud83c\uddf9",fitzpatrick_scale:!1,category:"flags"},mexico:{keywords:["mx","flag","nation","country","banner"],char:"\ud83c\uddf2\ud83c\uddfd",fitzpatrick_scale:!1,category:"flags"},micronesia:{keywords:["micronesia,","federated","states","flag","nation","country","banner"],char:"\ud83c\uddeb\ud83c\uddf2",fitzpatrick_scale:!1,category:"flags"},moldova:{keywords:["moldova,","republic","flag","nation","country","banner"],char:"\ud83c\uddf2\ud83c\udde9",fitzpatrick_scale:!1,category:"flags"},monaco:{keywords:["mc","flag","nation","country","banner"],char:"\ud83c\uddf2\ud83c\udde8",fitzpatrick_scale:!1,category:"flags"},mongolia:{keywords:["mn","flag","nation","country","banner"],char:"\ud83c\uddf2\ud83c\uddf3",fitzpatrick_scale:!1,category:"flags"},montenegro:{keywords:["me","flag","nation","country","banner"],char:"\ud83c\uddf2\ud83c\uddea",fitzpatrick_scale:!1,category:"flags"},montserrat:{keywords:["ms","flag","nation","country","banner"],char:"\ud83c\uddf2\ud83c\uddf8",fitzpatrick_scale:!1,category:"flags"},morocco:{keywords:["ma","flag","nation","country","banner"],char:"\ud83c\uddf2\ud83c\udde6",fitzpatrick_scale:!1,category:"flags"},mozambique:{keywords:["mz","flag","nation","country","banner"],char:"\ud83c\uddf2\ud83c\uddff",fitzpatrick_scale:!1,category:"flags"},myanmar:{keywords:["mm","flag","nation","country","banner"],char:"\ud83c\uddf2\ud83c\uddf2",fitzpatrick_scale:!1,category:"flags"},namibia:{keywords:["na","flag","nation","country","banner"],char:"\ud83c\uddf3\ud83c\udde6",fitzpatrick_scale:!1,category:"flags"},nauru:{keywords:["nr","flag","nation","country","banner"],char:"\ud83c\uddf3\ud83c\uddf7",fitzpatrick_scale:!1,category:"flags"},nepal:{keywords:["np","flag","nation","country","banner"],char:"\ud83c\uddf3\ud83c\uddf5",fitzpatrick_scale:!1,category:"flags"},netherlands:{keywords:["nl","flag","nation","country","banner"],char:"\ud83c\uddf3\ud83c\uddf1",fitzpatrick_scale:!1,category:"flags"},new_caledonia:{keywords:["new","caledonia","flag","nation","country","banner"],char:"\ud83c\uddf3\ud83c\udde8",fitzpatrick_scale:!1,category:"flags"},new_zealand:{keywords:["new","zealand","flag","nation","country","banner"],char:"\ud83c\uddf3\ud83c\uddff",fitzpatrick_scale:!1,category:"flags"},nicaragua:{keywords:["ni","flag","nation","country","banner"],char:"\ud83c\uddf3\ud83c\uddee",fitzpatrick_scale:!1,category:"flags"},niger:{keywords:["ne","flag","nation","country","banner"],char:"\ud83c\uddf3\ud83c\uddea",fitzpatrick_scale:!1,category:"flags"},nigeria:{keywords:["flag","nation","country","banner"],char:"\ud83c\uddf3\ud83c\uddec",fitzpatrick_scale:!1,category:"flags"},niue:{keywords:["nu","flag","nation","country","banner"],char:"\ud83c\uddf3\ud83c\uddfa",fitzpatrick_scale:!1,category:"flags"},norfolk_island:{keywords:["norfolk","island","flag","nation","country","banner"],char:"\ud83c\uddf3\ud83c\uddeb",fitzpatrick_scale:!1,category:"flags"},northern_mariana_islands:{keywords:["northern","mariana","islands","flag","nation","country","banner"],char:"\ud83c\uddf2\ud83c\uddf5",fitzpatrick_scale:!1,category:"flags"},north_korea:{keywords:["north","korea","nation","flag","country","banner"],char:"\ud83c\uddf0\ud83c\uddf5",fitzpatrick_scale:!1,category:"flags"},norway:{keywords:["no","flag","nation","country","banner"],char:"\ud83c\uddf3\ud83c\uddf4",fitzpatrick_scale:!1,category:"flags"},oman:{keywords:["om_symbol","flag","nation","country","banner"],char:"\ud83c\uddf4\ud83c\uddf2",fitzpatrick_scale:!1,category:"flags"},pakistan:{keywords:["pk","flag","nation","country","banner"],char:"\ud83c\uddf5\ud83c\uddf0",fitzpatrick_scale:!1,category:"flags"},palau:{keywords:["pw","flag","nation","country","banner"],char:"\ud83c\uddf5\ud83c\uddfc",fitzpatrick_scale:!1,category:"flags"},palestinian_territories:{keywords:["palestine","palestinian","territories","flag","nation","country","banner"],char:"\ud83c\uddf5\ud83c\uddf8",fitzpatrick_scale:!1,category:"flags"},panama:{keywords:["pa","flag","nation","country","banner"],char:"\ud83c\uddf5\ud83c\udde6",fitzpatrick_scale:!1,category:"flags"},papua_new_guinea:{keywords:["papua","new","guinea","flag","nation","country","banner"],char:"\ud83c\uddf5\ud83c\uddec",fitzpatrick_scale:!1,category:"flags"},paraguay:{keywords:["py","flag","nation","country","banner"],char:"\ud83c\uddf5\ud83c\uddfe",fitzpatrick_scale:!1,category:"flags"},peru:{keywords:["pe","flag","nation","country","banner"],char:"\ud83c\uddf5\ud83c\uddea",fitzpatrick_scale:!1,category:"flags"},philippines:{keywords:["ph","flag","nation","country","banner"],char:"\ud83c\uddf5\ud83c\udded",fitzpatrick_scale:!1,category:"flags"},pitcairn_islands:{keywords:["pitcairn","flag","nation","country","banner"],char:"\ud83c\uddf5\ud83c\uddf3",fitzpatrick_scale:!1,category:"flags"},poland:{keywords:["pl","flag","nation","country","banner"],char:"\ud83c\uddf5\ud83c\uddf1",fitzpatrick_scale:!1,category:"flags"},portugal:{keywords:["pt","flag","nation","country","banner"],char:"\ud83c\uddf5\ud83c\uddf9",fitzpatrick_scale:!1,category:"flags"},puerto_rico:{keywords:["puerto","rico","flag","nation","country","banner"],char:"\ud83c\uddf5\ud83c\uddf7",fitzpatrick_scale:!1,category:"flags"},qatar:{keywords:["qa","flag","nation","country","banner"],char:"\ud83c\uddf6\ud83c\udde6",fitzpatrick_scale:!1,category:"flags"},reunion:{keywords:["r\xe9union","flag","nation","country","banner"],char:"\ud83c\uddf7\ud83c\uddea",fitzpatrick_scale:!1,category:"flags"},romania:{keywords:["ro","flag","nation","country","banner"],char:"\ud83c\uddf7\ud83c\uddf4",fitzpatrick_scale:!1,category:"flags"},ru:{keywords:["russian","federation","flag","nation","country","banner"],char:"\ud83c\uddf7\ud83c\uddfa",fitzpatrick_scale:!1,category:"flags"},rwanda:{keywords:["rw","flag","nation","country","banner"],char:"\ud83c\uddf7\ud83c\uddfc",fitzpatrick_scale:!1,category:"flags"},st_barthelemy:{keywords:["saint","barth\xe9lemy","flag","nation","country","banner"],char:"\ud83c\udde7\ud83c\uddf1",fitzpatrick_scale:!1,category:"flags"},st_helena:{keywords:["saint","helena","ascension","tristan","cunha","flag","nation","country","banner"],char:"\ud83c\uddf8\ud83c\udded",fitzpatrick_scale:!1,category:"flags"},st_kitts_nevis:{keywords:["saint","kitts","nevis","flag","nation","country","banner"],char:"\ud83c\uddf0\ud83c\uddf3",fitzpatrick_scale:!1,category:"flags"},st_lucia:{keywords:["saint","lucia","flag","nation","country","banner"],char:"\ud83c\uddf1\ud83c\udde8",fitzpatrick_scale:!1,category:"flags"},st_pierre_miquelon:{keywords:["saint","pierre","miquelon","flag","nation","country","banner"],char:"\ud83c\uddf5\ud83c\uddf2",fitzpatrick_scale:!1,category:"flags"},st_vincent_grenadines:{keywords:["saint","vincent","grenadines","flag","nation","country","banner"],char:"\ud83c\uddfb\ud83c\udde8",fitzpatrick_scale:!1,category:"flags"},samoa:{keywords:["ws","flag","nation","country","banner"],char:"\ud83c\uddfc\ud83c\uddf8",fitzpatrick_scale:!1,category:"flags"},san_marino:{keywords:["san","marino","flag","nation","country","banner"],char:"\ud83c\uddf8\ud83c\uddf2",fitzpatrick_scale:!1,category:"flags"},sao_tome_principe:{keywords:["sao","tome","principe","flag","nation","country","banner"],char:"\ud83c\uddf8\ud83c\uddf9",fitzpatrick_scale:!1,category:"flags"},saudi_arabia:{keywords:["flag","nation","country","banner"],char:"\ud83c\uddf8\ud83c\udde6",fitzpatrick_scale:!1,category:"flags"},senegal:{keywords:["sn","flag","nation","country","banner"],char:"\ud83c\uddf8\ud83c\uddf3",fitzpatrick_scale:!1,category:"flags"},serbia:{keywords:["rs","flag","nation","country","banner"],char:"\ud83c\uddf7\ud83c\uddf8",fitzpatrick_scale:!1,category:"flags"},seychelles:{keywords:["sc","flag","nation","country","banner"],char:"\ud83c\uddf8\ud83c\udde8",fitzpatrick_scale:!1,category:"flags"},sierra_leone:{keywords:["sierra","leone","flag","nation","country","banner"],char:"\ud83c\uddf8\ud83c\uddf1",fitzpatrick_scale:!1,category:"flags"},singapore:{keywords:["sg","flag","nation","country","banner"],char:"\ud83c\uddf8\ud83c\uddec",fitzpatrick_scale:!1,category:"flags"},sint_maarten:{keywords:["sint","maarten","dutch","flag","nation","country","banner"],char:"\ud83c\uddf8\ud83c\uddfd",fitzpatrick_scale:!1,category:"flags"},slovakia:{keywords:["sk","flag","nation","country","banner"],char:"\ud83c\uddf8\ud83c\uddf0",fitzpatrick_scale:!1,category:"flags"},slovenia:{keywords:["si","flag","nation","country","banner"],char:"\ud83c\uddf8\ud83c\uddee",fitzpatrick_scale:!1,category:"flags"},solomon_islands:{keywords:["solomon","islands","flag","nation","country","banner"],char:"\ud83c\uddf8\ud83c\udde7",fitzpatrick_scale:!1,category:"flags"},somalia:{keywords:["so","flag","nation","country","banner"],char:"\ud83c\uddf8\ud83c\uddf4",fitzpatrick_scale:!1,category:"flags"},south_africa:{keywords:["south","africa","flag","nation","country","banner"],char:"\ud83c\uddff\ud83c\udde6",fitzpatrick_scale:!1,category:"flags"},south_georgia_south_sandwich_islands:{keywords:["south","georgia","sandwich","islands","flag","nation","country","banner"],char:"\ud83c\uddec\ud83c\uddf8",fitzpatrick_scale:!1,category:"flags"},kr:{keywords:["south","korea","nation","flag","country","banner"],char:"\ud83c\uddf0\ud83c\uddf7",fitzpatrick_scale:!1,category:"flags"},south_sudan:{keywords:["south","sd","flag","nation","country","banner"],char:"\ud83c\uddf8\ud83c\uddf8",fitzpatrick_scale:!1,category:"flags"},es:{keywords:["spain","flag","nation","country","banner"],char:"\ud83c\uddea\ud83c\uddf8",fitzpatrick_scale:!1,category:"flags"},sri_lanka:{keywords:["sri","lanka","flag","nation","country","banner"],char:"\ud83c\uddf1\ud83c\uddf0",fitzpatrick_scale:!1,category:"flags"},sudan:{keywords:["sd","flag","nation","country","banner"],char:"\ud83c\uddf8\ud83c\udde9",fitzpatrick_scale:!1,category:"flags"},suriname:{keywords:["sr","flag","nation","country","banner"],char:"\ud83c\uddf8\ud83c\uddf7",fitzpatrick_scale:!1,category:"flags"},swaziland:{keywords:["sz","flag","nation","country","banner"],char:"\ud83c\uddf8\ud83c\uddff",fitzpatrick_scale:!1,category:"flags"},sweden:{keywords:["se","flag","nation","country","banner"],char:"\ud83c\uddf8\ud83c\uddea",fitzpatrick_scale:!1,category:"flags"},switzerland:{keywords:["ch","flag","nation","country","banner"],char:"\ud83c\udde8\ud83c\udded",fitzpatrick_scale:!1,category:"flags"},syria:{keywords:["syrian","arab","republic","flag","nation","country","banner"],char:"\ud83c\uddf8\ud83c\uddfe",fitzpatrick_scale:!1,category:"flags"},taiwan:{keywords:["tw","flag","nation","country","banner"],char:"\ud83c\uddf9\ud83c\uddfc",fitzpatrick_scale:!1,category:"flags"},tajikistan:{keywords:["tj","flag","nation","country","banner"],char:"\ud83c\uddf9\ud83c\uddef",fitzpatrick_scale:!1,category:"flags"},tanzania:{keywords:["tanzania,","united","republic","flag","nation","country","banner"],char:"\ud83c\uddf9\ud83c\uddff",fitzpatrick_scale:!1,category:"flags"},thailand:{keywords:["th","flag","nation","country","banner"],char:"\ud83c\uddf9\ud83c\udded",fitzpatrick_scale:!1,category:"flags"},timor_leste:{keywords:["timor","leste","flag","nation","country","banner"],char:"\ud83c\uddf9\ud83c\uddf1",fitzpatrick_scale:!1,category:"flags"},togo:{keywords:["tg","flag","nation","country","banner"],char:"\ud83c\uddf9\ud83c\uddec",fitzpatrick_scale:!1,category:"flags"},tokelau:{keywords:["tk","flag","nation","country","banner"],char:"\ud83c\uddf9\ud83c\uddf0",fitzpatrick_scale:!1,category:"flags"},tonga:{keywords:["to","flag","nation","country","banner"],char:"\ud83c\uddf9\ud83c\uddf4",fitzpatrick_scale:!1,category:"flags"},trinidad_tobago:{keywords:["trinidad","tobago","flag","nation","country","banner"],char:"\ud83c\uddf9\ud83c\uddf9",fitzpatrick_scale:!1,category:"flags"},tunisia:{keywords:["tn","flag","nation","country","banner"],char:"\ud83c\uddf9\ud83c\uddf3",fitzpatrick_scale:!1,category:"flags"},tr:{keywords:["turkey","flag","nation","country","banner"],char:"\ud83c\uddf9\ud83c\uddf7",fitzpatrick_scale:!1,category:"flags"},turkmenistan:{keywords:["flag","nation","country","banner"],char:"\ud83c\uddf9\ud83c\uddf2",fitzpatrick_scale:!1,category:"flags"},turks_caicos_islands:{keywords:["turks","caicos","islands","flag","nation","country","banner"],char:"\ud83c\uddf9\ud83c\udde8",fitzpatrick_scale:!1,category:"flags"},tuvalu:{keywords:["flag","nation","country","banner"],char:"\ud83c\uddf9\ud83c\uddfb",fitzpatrick_scale:!1,category:"flags"},uganda:{keywords:["ug","flag","nation","country","banner"],char:"\ud83c\uddfa\ud83c\uddec",fitzpatrick_scale:!1,category:"flags"},ukraine:{keywords:["ua","flag","nation","country","banner"],char:"\ud83c\uddfa\ud83c\udde6",fitzpatrick_scale:!1,category:"flags"},united_arab_emirates:{keywords:["united","arab","emirates","flag","nation","country","banner"],char:"\ud83c\udde6\ud83c\uddea",fitzpatrick_scale:!1,category:"flags"},uk:{keywords:["united","kingdom","great","britain","northern","ireland","flag","nation","country","banner","british","UK","english","england","union jack"],char:"\ud83c\uddec\ud83c\udde7",fitzpatrick_scale:!1,category:"flags"},england:{keywords:["flag","english"],char:"\ud83c\udff4\udb40\udc67\udb40\udc62\udb40\udc65\udb40\udc6e\udb40\udc67\udb40\udc7f",fitzpatrick_scale:!1,category:"flags"},scotland:{keywords:["flag","scottish"],char:"\ud83c\udff4\udb40\udc67\udb40\udc62\udb40\udc73\udb40\udc63\udb40\udc74\udb40\udc7f",fitzpatrick_scale:!1,category:"flags"},wales:{keywords:["flag","welsh"],char:"\ud83c\udff4\udb40\udc67\udb40\udc62\udb40\udc77\udb40\udc6c\udb40\udc73\udb40\udc7f",fitzpatrick_scale:!1,category:"flags"},us:{keywords:["united","states","america","flag","nation","country","banner"],char:"\ud83c\uddfa\ud83c\uddf8",fitzpatrick_scale:!1,category:"flags"},us_virgin_islands:{keywords:["virgin","islands","us","flag","nation","country","banner"],char:"\ud83c\uddfb\ud83c\uddee",fitzpatrick_scale:!1,category:"flags"},uruguay:{keywords:["uy","flag","nation","country","banner"],char:"\ud83c\uddfa\ud83c\uddfe",fitzpatrick_scale:!1,category:"flags"},uzbekistan:{keywords:["uz","flag","nation","country","banner"],char:"\ud83c\uddfa\ud83c\uddff",fitzpatrick_scale:!1,category:"flags"},vanuatu:{keywords:["vu","flag","nation","country","banner"],char:"\ud83c\uddfb\ud83c\uddfa",fitzpatrick_scale:!1,category:"flags"},vatican_city:{keywords:["vatican","city","flag","nation","country","banner"],char:"\ud83c\uddfb\ud83c\udde6",fitzpatrick_scale:!1,category:"flags"},venezuela:{keywords:["ve","bolivarian","republic","flag","nation","country","banner"],char:"\ud83c\uddfb\ud83c\uddea",fitzpatrick_scale:!1,category:"flags"},vietnam:{keywords:["viet","nam","flag","nation","country","banner"],char:"\ud83c\uddfb\ud83c\uddf3",fitzpatrick_scale:!1,category:"flags"},wallis_futuna:{keywords:["wallis","futuna","flag","nation","country","banner"],char:"\ud83c\uddfc\ud83c\uddeb",fitzpatrick_scale:!1,category:"flags"},western_sahara:{keywords:["western","sahara","flag","nation","country","banner"],char:"\ud83c\uddea\ud83c\udded",fitzpatrick_scale:!1,category:"flags"},yemen:{keywords:["ye","flag","nation","country","banner"],char:"\ud83c\uddfe\ud83c\uddea",fitzpatrick_scale:!1,category:"flags"},zambia:{keywords:["zm","flag","nation","country","banner"],char:"\ud83c\uddff\ud83c\uddf2",fitzpatrick_scale:!1,category:"flags"},zimbabwe:{keywords:["zw","flag","nation","country","banner"],char:"\ud83c\uddff\ud83c\uddfc",fitzpatrick_scale:!1,category:"flags"},united_nations:{keywords:["un","flag","banner"],char:"\ud83c\uddfa\ud83c\uddf3",fitzpatrick_scale:!1,category:"flags"},pirate_flag:{keywords:["skull","crossbones","flag","banner"],char:"\ud83c\udff4\u200d\u2620\ufe0f",fitzpatrick_scale:!1,category:"flags"}}); \ No newline at end of file diff --git a/website/admin/tinymce/plugins/emoticons/plugin.min.js b/website/admin/tinymce/plugins/emoticons/plugin.min.js new file mode 100644 index 0000000..fa6b8d2 --- /dev/null +++ b/website/admin/tinymce/plugins/emoticons/plugin.min.js @@ -0,0 +1 @@ +!function(){"use strict";function t(){}function n(t){return function(){return t}}function e(t){return t}function o(){return u}var r,i=tinymce.util.Tools.resolve("tinymce.PluginManager"),a=n(!1),c=n(!(r=null)),u={fold:function(t,n){return t()},isSome:a,isNone:c,getOr:e,getOrThunk:l,getOrDie:function(t){throw new Error(t||"error: getOrDie called on none.")},getOrNull:n(null),getOrUndefined:n(void 0),or:e,orThunk:l,map:o,each:t,bind:o,exists:a,forall:c,filter:function(){return u},toArray:function(){return[]},toString:n("none()")};function l(t){return t()}function s(t){var n=t;return{get:function(){return n},set:function(t){n=t}}}function f(t,n){for(var e=k(t),o=0,r=e.length;o=(c="Could not load emoticons

"}]},buttons:[{type:"cancel",text:"Close",primary:!0}],initialData:{pattern:"",results:[]}}),g.focus(S),g.unblock()})))}function p(t){t.on("PreInit",(function(){t.parser.addAttributeFilter("data-emoticon",(function(t){!function(t){for(var n,e=0,o=t.length;e"),(p=y.getAll("title")[0])&&p.firstChild&&(v.title=p.firstChild.value),u.each(y.getAll("meta"),(function(e){var t,n=e.attr("name"),l=e.attr("http-equiv");n?v[n.toLowerCase()]=e.attr("content"):"Content-Type"===l&&(t=/charset\s*=\s*(.*)\s*/gi.exec(e.attr("content")))&&(v.docencoding=t[1])})),(p=y.getAll("html")[0])&&(v.langcode=_(p,"lang")||_(p,"xml:lang")),v.stylesheets=[],u.each(y.getAll("link"),(function(e){"stylesheet"===e.attr("rel")&&v.stylesheets.push(e.attr("href"))})),(p=y.getAll("body")[0])&&(v.langdir=_(p,"dir"),v.style=_(p,"style"),v.visited_color=_(p,"vlink"),v.link_color=_(p,"link"),v.active_color=_(p,"alink")),a=v,c=d(d({},{title:"",keywords:"",description:"",robots:"",author:"",docencoding:""}),a),n.windowManager.open({title:"Metadata and Document Properties",size:"normal",body:{type:"panel",items:[{name:"title",type:"input",label:"Title"},{name:"keywords",type:"input",label:"Keywords"},{name:"description",type:"input",label:"Description"},{name:"robots",type:"input",label:"Robots"},{name:"author",type:"input",label:"Author"},{name:"docencoding",type:"input",label:"Encoding"}]},buttons:[{type:"cancel",name:"cancel",text:"Cancel"},{type:"submit",name:"save",text:"Save",primary:!0}],initialData:c,onSubmit:function(e){var t=e.getData(),l=function(e,t,n){function l(e,t,n){e.attr(t,n||void 0)}function i(e){d.firstChild?d.insert(e,d.firstChild):d.append(e)}var r,a,c=e.dom,s=o(e,n),d=s.getAll("head")[0];d||(r=s.getAll("html")[0],d=new g("head",1),r.firstChild?r.insert(d,r.firstChild,!0):r.append(d)),r=s.firstChild,t.xml_pi?(a='version="1.0"',t.docencoding&&(a+=' encoding="'+t.docencoding+'"'),7!==r.type&&(r=new g("xml",7),s.insert(r,s.firstChild,!0)),r.value=a):r&&7===r.type&&r.remove(),r=s.getAll("#doctype")[0],t.doctype?(r||(r=new g("#doctype",10),t.xml_pi?s.insert(r,s.firstChild):i(r)),r.value=t.doctype.substring(9,t.doctype.length-1)):r&&r.remove(),r=null,u.each(s.getAll("meta"),(function(e){"Content-Type"===e.attr("http-equiv")&&(r=e)})),t.docencoding?(r||((r=new g("meta",1)).attr("http-equiv","Content-Type"),r.shortEnded=!0,i(r)),r.attr("content","text/html; charset="+t.docencoding)):r&&r.remove(),r=s.getAll("title")[0],t.title?(r?r.empty():i(r=new g("title",1)),r.append(new g("#text",3)).value=t.title):r&&r.remove(),u.each("keywords,description,author,copyright,robots".split(","),(function(e){for(var n,l=s.getAll("meta"),o=t[e],a=0;a"))}(n,u.extend(a,t),r.get());r.set(l),e.close()}})}))}function a(e){return e.replace(/<\/?[A-Z]+/g,(function(e){return e.toLowerCase()}))}function c(e,r,c,s){var d,m,g,f,h,y,v,_,b,x,k,C,A,w="",P=e.dom;s.selection||(f=e.getParam("protect"),h=s.content,u.each(f,(function(e){h=h.replace(e,(function(e){return"\x3c!--mce:protected "+escape(e)+"--\x3e"}))})),g=h,"raw"===s.format&&r.get()||s.source_view&&t(e)||(-1!==(d=(g=(g=0!==g.length||s.source_view?g:u.trim(r.get())+"\n"+u.trim(g)+"\n"+u.trim(c.get())).replace(/<(\/?)BODY/gi,"<$1body")).indexOf("",d),r.set(a(g.substring(0,d+1))),-1===(m=g.indexOf("\n'),C+=x.getParam("fullpage_default_doctype",""),C+="\n\n\n",(k=x.getParam("fullpage_default_title"))&&(C+=""+k+"\n"),(k=n(x))&&(C+='\n'),(k=l(x))&&(A+="font-family: "+k+";"),(k=i(x))&&(A+="font-size: "+k+";"),(k=x.getParam("fullpage_default_text_color"))&&(A+="color: "+k+";"),C+="\n\n")),c.set("\n\n")),y=o(e,r.get()),p(y.getAll("style"),(function(e){e.firstChild&&(w+=e.firstChild.value)})),(v=y.getAll("body")[0])&&P.setAttribs(e.getBody(),{style:v.attr("style")||"",dir:v.attr("dir")||"",vLink:v.attr("vlink")||"",link:v.attr("link")||"",aLink:v.attr("alink")||""}),P.remove("fullpage_styles"),_=e.getDoc().getElementsByTagName("head")[0],w&&P.add(_,"style",{id:"fullpage_styles"}).appendChild(document.createTextNode(w)),b={},u.each(_.getElementsByTagName("link"),(function(e){"stylesheet"===e.rel&&e.getAttribute("data-mce-fullpage")&&(b[e.href]=e)})),u.each(y.getAll("link"),(function(e){var t=e.attr("href");if(!t)return!0;b[t]||"stylesheet"!==e.attr("rel")||P.add(_,"link",{rel:"stylesheet",text:"text/css",href:t,"data-mce-fullpage":"1"}),delete b[t]})),u.each(b,(function(e){e.parentNode.removeChild(e)}))))}var s=tinymce.util.Tools.resolve("tinymce.PluginManager"),d=function(){return(d=Object.assign||function(e){for(var t,n=1,l=arguments.length;n/g,(function(e,t){return unescape(t)})))}))}))}(); \ No newline at end of file diff --git a/website/admin/tinymce/plugins/fullscreen/plugin.min.js b/website/admin/tinymce/plugins/fullscreen/plugin.min.js new file mode 100644 index 0000000..edd306c --- /dev/null +++ b/website/admin/tinymce/plugins/fullscreen/plugin.min.js @@ -0,0 +1 @@ +!function(){"use strict";function e(e){var n=e;return{get:function(){return n},set:function(e){n=e}}}function n(e){return function(n){return t=typeof(r=n),(null===r?"null":"object"==t&&(Array.prototype.isPrototypeOf(r)||r.constructor&&"Array"===r.constructor.name)?"array":"object"==t&&(String.prototype.isPrototypeOf(r)||r.constructor&&"String"===r.constructor.name)?"string":t)===e;var r,t}}function r(e){return function(n){return typeof n===e}}function t(e){return!(null==e)}function o(){}function i(e){return function(){return e}}function u(e){return e}var c=tinymce.util.Tools.resolve("tinymce.PluginManager"),a=n("string"),s=n("array"),l=r("boolean"),f=r("function"),m=r("number");function d(){return g}var h=i(!1),v=i(!0),g={fold:function(e,n){return e()},isSome:h,isNone:v,getOr:u,getOrThunk:p,getOrDie:function(e){throw new Error(e||"error: getOrDie called on none.")},getOrNull:i(null),getOrUndefined:i(void 0),or:u,orThunk:p,map:d,each:o,bind:d,exists:h,forall:v,filter:function(){return g},toArray:function(){return[]},toString:i("none()")};function p(e){return e()}function w(n){function r(){return t.get().each(n)}var t=e(C.none());return{clear:function(){r(),t.set(C.none())},isSet:function(){return t.get().isSome()},get:function(){return t.get()},set:function(e){r(),t.set(C.some(e))}}}function y(){return w((function(e){return e.unbind()}))}function b(e,n){for(var r=e.length,t=new Array(r),o=0;o'+e.name+""}var n,a,o,r,s,l,m,h;return{name:"plugins",title:"Plugins",items:[{type:"htmlpanel",presets:"document",html:[null==e?"":'
'+(l=c((r=b((o=a=e).plugins),void 0===(s=o.getParam("forced_plugins"))?r:u(r,(function(e){return!(-1"+(n=a,o=e,function(e,t,n){for(var a=0,o=e.length;a");var n,o})),m=l.length,h=l.join(""),"

"+A.translate(["Plugins installed ({0}):",m])+"

    "+h+"
"),(n=c(u(x,(function(e){var t=e.key,n=e.type;return"autocorrect"!==t&&"premium"===n})),(function(e){return"
  • "+A.translate(e.name)+"
  • "})).join(""),'

    '+A.translate("Premium plugins:")+"

    ")].join("")}]}}function p(e,t){return function(){var n,a,i,r,s,l,u,p,d,g,f,v=(n=e,a=t,u={name:"shortcuts",title:"Handy Shortcuts",items:[{type:"table",header:["Action","Shortcut"],cells:c(w,(function(e){var t=c(e.shortcuts,m).join(" or ");return[e.action,t]}))}]},p={name:"keyboardnav",title:"Keyboard Navigation",items:[{type:"htmlpanel",presets:"document",html:"

    Editor UI keyboard navigation

    \n\n

    Activating keyboard navigation

    \n\n

    The sections of the outer UI of the editor - the menubar, toolbar, sidebar and footer - are all keyboard navigable. As such, there are multiple ways to activate keyboard navigation:

    \n
      \n
    • Focus the menubar: Alt + F9 (Windows) or ⌥F9 (MacOS)
    • \n
    • Focus the toolbar: Alt + F10 (Windows) or ⌥F10 (MacOS)
    • \n
    • Focus the footer: Alt + F11 (Windows) or ⌥F11 (MacOS)
    • \n
    \n\n

    Focusing the menubar or toolbar will start keyboard navigation at the first item in the menubar or toolbar, which will be highlighted with a gray background. Focusing the footer will start keyboard navigation at the first item in the element path, which will be highlighted with an underline.

    \n\n

    Moving between UI sections

    \n\n

    When keyboard navigation is active, pressing tab will move the focus to the next major section of the UI, where applicable. These sections are:

    \n
      \n
    • the menubar
    • \n
    • each group of the toolbar
    • \n
    • the sidebar
    • \n
    • the element path in the footer
    • \n
    • the wordcount toggle button in the footer
    • \n
    • the branding link in the footer
    • \n
    • the editor resize handle in the footer
    • \n
    \n\n

    Pressing shift + tab will move backwards through the same sections, except when moving from the footer to the toolbar. Focusing the element path then pressing shift + tab will move focus to the first toolbar group, not the last.

    \n\n

    Moving within UI sections

    \n\n

    Keyboard navigation within UI sections can usually be achieved using the left and right arrow keys. This includes:

    \n
      \n
    • moving between menus in the menubar
    • \n
    • moving between buttons in a toolbar group
    • \n
    • moving between items in the element path
    • \n
    \n\n

    In all these UI sections, keyboard navigation will cycle within the section. For example, focusing the last button in a toolbar group then pressing right arrow will move focus to the first item in the same toolbar group.

    \n\n

    Executing buttons

    \n\n

    To execute a button, navigate the selection to the desired button and hit space or enter.

    \n\n

    Opening, navigating and closing menus

    \n\n

    When focusing a menubar button or a toolbar button with a menu, pressing space, enter or down arrow will open the menu. When the menu opens the first item will be selected. To move up or down the menu, press the up or down arrow key respectively. This is the same for submenus, which can also be opened and closed using the left and right arrow keys.

    \n\n

    To close any active menu, hit the escape key. When a menu is closed the selection will be restored to its previous selection. This also works for closing submenus.

    \n\n

    Context toolbars and menus

    \n\n

    To focus an open context toolbar such as the table context toolbar, press Ctrl + F9 (Windows) or ⌃F9 (MacOS).

    \n\n

    Context toolbar navigation is the same as toolbar navigation, and context menu navigation is the same as standard menu navigation.

    \n\n

    Dialog navigation

    \n\n

    There are two types of dialog UIs in TinyMCE: tabbed dialogs and non-tabbed dialogs.

    \n\n

    When a non-tabbed dialog is opened, the first interactive component in the dialog will be focused. Users can navigate between interactive components by pressing tab. This includes any footer buttons. Navigation will cycle back to the first dialog component if tab is pressed while focusing the last component in the dialog. Pressing shift + tab will navigate backwards.

    \n\n

    When a tabbed dialog is opened, the first button in the tab menu is focused. Pressing tab will navigate to the first interactive component in that tab, and will cycle through the tab\u2019s components, the footer buttons, then back to the tab button. To switch to another tab, focus the tab button for the current tab, then use the arrow keys to cycle through the tab buttons.

    "}]},d=h(n),r=T.majorVersion,s=T.minorVersion,l=0===r.indexOf("@")?"X.X.X":r+"."+s,g={name:"versions",title:"Version",items:[{type:"htmlpanel",html:"

    "+A.translate(["You are using {0}",'TinyMCE '+l+""])+"

    ",presets:"document"}]},f=o(((i={})[u.name]=u,i[p.name]=p,i[d.name]=d,i[g.name]=g,i),a.get()),y.from(n.getParam("help_tabs")).fold((function(){return-1!==(n=(t=b(e=f)).indexOf("versions"))&&(t.splice(n,1),t.push("versions")),{tabs:e,names:t};var e,t,n}),(function(e){return t=f,n={},a=c(e,(function(e){return"string"==typeof e?(k(t,e)&&(n[e]=t[e]),e):(n[e.name]=e).name})),{tabs:n,names:a};var t,n,a}))),x=v.tabs,C=function(e){for(var t=[],n=function(e){t.push(e)},a=0;a")})),(t=n).ui.registry.addButton("hr",{icon:"horizontal-rule",tooltip:"Horizontal line",onAction:e}),t.ui.registry.addMenuItem("hr",{icon:"horizontal-rule",text:"Horizontal line",onAction:e})}))}(); \ No newline at end of file diff --git a/website/admin/tinymce/plugins/image/plugin.min.js b/website/admin/tinymce/plugins/image/plugin.min.js new file mode 100644 index 0000000..4df5352 --- /dev/null +++ b/website/admin/tinymce/plugins/image/plugin.min.js @@ -0,0 +1 @@ +!function(){"use strict";function e(e){return function(t){return r=typeof(n=t),(null===n?"null":"object"==r&&(Array.prototype.isPrototypeOf(n)||n.constructor&&"Array"===n.constructor.name)?"array":"object"==r&&(String.prototype.isPrototypeOf(n)||n.constructor&&"String"===n.constructor.name)?"string":r)===e;var n,r}}function t(e){return function(t){return typeof t===e}}function n(e){return!(null==e)}function r(){}function i(e){return function(){return e}}function a(e){return e}function o(){return y}var l,s=tinymce.util.Tools.resolve("tinymce.PluginManager"),c=function(){return(c=Object.assign||function(e){for(var t,n=1,r=arguments.length;n');var r=function(t,e){return function(n){return t.selection.selectorChangedWithUnbind(e.join(","),n.setActive).unbind}};return t.ui.registry.addToggleButton("indent2em",{icon:"indent2em",tooltip:n,onAction:function(){o()},onSetup:r(t,['*[style*="text-indent"]','*[data-mce-style*="text-indent"]'])}),t.ui.registry.addMenuItem("indent2em",{text:n,onAction:function(){o()}}),t.addCommand("indent2em",o),{getMetadata:function(){return{name:n,url:"http://tinymce.ax-z.cn/more-plugins/indent2em.php"}}}})); \ No newline at end of file diff --git a/website/admin/tinymce/plugins/indent2em/plugin.min.js b/website/admin/tinymce/plugins/indent2em/plugin.min.js new file mode 100644 index 0000000..5860fa2 --- /dev/null +++ b/website/admin/tinymce/plugins/indent2em/plugin.min.js @@ -0,0 +1 @@ +tinymce.PluginManager.add("indent2em",(function(t,e){var n="\u9996\u884c\u7f29\u8fdb",i=tinymce.util.Tools.resolve("tinymce.util.Tools"),d=t.getParam("indent2em_val","2em"),o=function(){var e=t.dom,n=t.selection.getSelectedBlocks(),o="";i.each(n,(function(t){if(""==o&&(o=e.getStyle(t,"text-indent")==d?"remove":"add"),"add"==o)e.setStyle(t,"text-indent",d);else{var n=e.getAttrib(t,"style"),i=new RegExp("text-indent:[\\s]*"+d+";","ig");n=n.replace(i,""),e.setAttrib(t,"style",n)}}))};t.ui.registry.getAll().icons.indent2em||t.ui.registry.addIcon("indent2em",'');var r=function(t,e){return function(n){return t.selection.selectorChangedWithUnbind(e.join(","),n.setActive).unbind}};return t.ui.registry.addToggleButton("indent2em",{icon:"indent2em",tooltip:n,onAction:function(){o()},onSetup:r(t,['*[style*="text-indent"]','*[data-mce-style*="text-indent"]'])}),t.ui.registry.addMenuItem("indent2em",{text:n,onAction:function(){o()}}),t.addCommand("indent2em",o),{getMetadata:function(){return{name:n,url:"http://tinymce.ax-z.cn/more-plugins/indent2em.php"}}}})); \ No newline at end of file diff --git a/website/admin/tinymce/plugins/insertdatetime/plugin.min.js b/website/admin/tinymce/plugins/insertdatetime/plugin.min.js new file mode 100644 index 0000000..3e071f2 --- /dev/null +++ b/website/admin/tinymce/plugins/insertdatetime/plugin.min.js @@ -0,0 +1 @@ +!function(){"use strict";function e(e){return e.getParam("insertdatetime_timeformat",e.translate("%H:%M:%S"))}function t(e){return e.getParam("insertdatetime_formats",["%H:%M:%S","%Y-%m-%d","%I:%M:%S %p","%D"])}function n(e,t){if((e=""+e).length'+n+"")):e.insertContent(r(e,t))}var i=tinymce.util.Tools.resolve("tinymce.PluginManager"),o="Sun Mon Tue Wed Thu Fri Sat Sun".split(" "),u="Sunday Monday Tuesday Wednesday Thursday Friday Saturday Sunday".split(" "),c="Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec".split(" "),m="January February March April May June July August September October November December".split(" "),l=tinymce.util.Tools.resolve("tinymce.util.Tools");i.add("insertdatetime",(function(n){var i,o,u,c,m,s,d,p;function g(e){return o.execCommand("mceInsertDate",!1,e)}(i=n).addCommand("mceInsertDate",(function(e,t){a(i,null!=t?t:i.getParam("insertdatetime_dateformat",i.translate("%Y-%m-%d")))})),i.addCommand("mceInsertTime",(function(t,n){a(i,null!=n?n:e(i))})),d=t(o=n),u=0<(s=t(m=o)).length?s[0]:e(m),c=u,p={get:function(){return c},set:function(e){c=e}},o.ui.registry.addSplitButton("insertdatetime",{icon:"insert-time",tooltip:"Insert date/time",select:function(e){return e===p.get()},fetch:function(e){e(l.map(d,(function(e){return{type:"choiceitem",text:r(o,e),value:e}})))},onAction:function(e){g(p.get())},onItemAction:function(e,t){p.set(t),g(t)}}),o.ui.registry.addNestedMenuItem("insertdatetime",{icon:"insert-time",text:"Date/time",getSubmenuItems:function(){return l.map(d,(function(e){return{type:"menuitem",text:r(o,e),onAction:(t=e,function(){p.set(t),g(t)})};var t}))}})}))}(); \ No newline at end of file diff --git a/website/admin/tinymce/plugins/legacyoutput/plugin.min.js b/website/admin/tinymce/plugins/legacyoutput/plugin.min.js new file mode 100644 index 0000000..49e957a --- /dev/null +++ b/website/admin/tinymce/plugins/legacyoutput/plugin.min.js @@ -0,0 +1 @@ +!function(){"use strict";var e=tinymce.util.Tools.resolve("tinymce.PluginManager"),t=tinymce.util.Tools.resolve("tinymce.util.Tools");e.add("legacyoutput",(function(e){var i,a;(a=i=e).settings.inline_styles=!1,a.getParam("fontsize_formats")||(a.settings.fontsize_formats="8pt=1 10pt=2 12pt=3 14pt=4 18pt=5 24pt=6 36pt=7"),a.getParam("font_formats")||(a.settings.font_formats="Andale Mono=andale mono,monospace;Arial=arial,helvetica,sans-serif;Arial Black=arial black,sans-serif;Book Antiqua=book antiqua,palatino,serif;Comic Sans MS=comic sans ms,sans-serif;Courier New=courier new,courier,monospace;Georgia=georgia,palatino,serif;Helvetica=helvetica,arial,sans-serif;Impact=impact,sans-serif;Symbol=symbol;Tahoma=tahoma,arial,helvetica,sans-serif;Terminal=terminal,monaco,monospace;Times New Roman=times new roman,times,serif;Trebuchet MS=trebuchet ms,geneva,sans-serif;Verdana=verdana,geneva,sans-serif;Webdings=webdings;Wingdings=wingdings,zapf dingbats"),i.on("PreInit",(function(){var e=i,a="p,h1,h2,h3,h4,h5,h6,td,th,div,ul,ol,li,table",s=t.explode(e.getParam("font_size_style_values","xx-small,x-small,small,medium,large,x-large,xx-large")),l=e.schema;e.formatter.register({alignleft:{selector:a,attributes:{align:"left"}},aligncenter:{selector:a,attributes:{align:"center"}},alignright:{selector:a,attributes:{align:"right"}},alignjustify:{selector:a,attributes:{align:"justify"}},bold:[{inline:"b",remove:"all",preserve_attributes:["class","style"]},{inline:"strong",remove:"all",preserve_attributes:["class","style"]},{inline:"span",styles:{fontWeight:"bold"}}],italic:[{inline:"i",remove:"all",preserve_attributes:["class","style"]},{inline:"em",remove:"all",preserve_attributes:["class","style"]},{inline:"span",styles:{fontStyle:"italic"}}],underline:[{inline:"u",remove:"all",preserve_attributes:["class","style"]},{inline:"span",styles:{textDecoration:"underline"},exact:!0}],strikethrough:[{inline:"strike",remove:"all",preserve_attributes:["class","style"]},{inline:"span",styles:{textDecoration:"line-through"},exact:!0}],fontname:{inline:"font",toggle:!1,attributes:{face:"%value"}},fontsize:{inline:"font",toggle:!1,attributes:{size:function(e){return String(t.inArray(s,e.value)+1)}}},forecolor:{inline:"font",attributes:{color:"%value"},links:!0,remove_similar:!0,clear_child_styles:!0},hilitecolor:{inline:"font",styles:{backgroundColor:"%value"},links:!0,remove_similar:!0,clear_child_styles:!0}}),t.each("b,i,u,strike".split(","),(function(e){l.addValidElements(e+"[*]")})),l.getElementRule("font")||l.addValidElements("font[face|size|color|style]"),t.each(a.split(","),(function(e){var t=l.getElementRule(e);t&&(t.attributes.align||(t.attributes.align={},t.attributesOrder.push("align")))}))}))}))}(); \ No newline at end of file diff --git a/website/admin/tinymce/plugins/link/plugin.min.js b/website/admin/tinymce/plugins/link/plugin.min.js new file mode 100644 index 0000000..2cc2d2a --- /dev/null +++ b/website/admin/tinymce/plugins/link/plugin.min.js @@ -0,0 +1 @@ +!function(){"use strict";function t(t){return function(n){return r=typeof(e=n),(null===e?"null":"object"==r&&(Array.prototype.isPrototypeOf(e)||e.constructor&&"Array"===e.constructor.name)?"array":"object"==r&&(String.prototype.isPrototypeOf(e)||e.constructor&&"String"===e.constructor.name)?"string":r)===t;var e,r}}function n(t){return function(n){return typeof n===t}}function e(){}function r(t){return function(){return t}}function o(t){return t}function i(t,n){return t===n}function u(){return v}var a,l=tinymce.util.Tools.resolve("tinymce.PluginManager"),c=tinymce.util.Tools.resolve("tinymce.util.VK"),f=t("string"),s=t("array"),m=function(t){return a===t},g=n("boolean"),d=n("function"),h=r(!1),p=r(!(a=null)),v={fold:function(t,n){return t()},isSome:h,isNone:p,getOr:o,getOrThunk:y,getOrDie:function(t){throw new Error(t||"error: getOrDie called on none.")},getOrNull:r(null),getOrUndefined:r(void 0),or:o,orThunk:y,map:u,each:e,bind:u,exists:h,forall:p,filter:function(){return v},toArray:function(){return[]},toString:r("none()")};function y(t){return t()}function k(t,n,e){return function(t){for(var r,o=0,i=t.length;o=e.childNodes.length?n.data.length:0}:n.previousSibling&&Me(n.previousSibling)?{container:n.previousSibling,offset:n.previousSibling.data.length}:n.nextSibling&&Me(n.nextSibling)?{container:n.nextSibling,offset:0}:{container:e,offset:t}}function We(e){var t=e.cloneRange(),n=Ve(e.startContainer,e.startOffset);t.setStart(n.container,n.offset);var r=Ve(e.endContainer,e.endOffset);return t.setEnd(r.container,r.offset),t}function Qe(e,t){var n=t||e.selection.getStart(!0);return e.dom.getParent(n,"OL,UL,DL",qt(e,n))}function Xe(e){var t,n,r=e.selection.getSelectedBlocks();return b((t=e,n=Mt.map(r,(function(e){return t.dom.getParent(e,"li,dd,dt",qt(t,e))||e})),Xt.unique(n)),Ft)}function qe(e,t){return w(e.dom.getParents(t,"ol,ul",qt(e,t)))}function ze(e,t,n){return void 0===n&&(n=i),e.exists((function(e){return n(e,t)}))}function Ye(e,t,n){return e.isSome()&&t.isSome()?E.some(n(e.getOrDie(),t.getOrDie())):E.none()}function Ze(e,t,n){return e.fire("ListMutation",{action:t,element:n})}function Ge(e,t){we(e.item,t.list)}function Je(e,t){for(var n=0;ne.length?tt:et)(r,e,t)}),[])).map((function(e){return e.list})).toArray()}function ft(e,t){C(b(e,it),(function(e){return function(e){switch(t){case"Indent":e.depth++;break;case"Outdent":e.depth--;break;case"Flatten":e.depth=0}e.dirty=!0}(e),0}))}function dt(e,t){var n,r,o,i,s,u,c,f,d,l,m,p,g,v=S((i=qe(o=r=e,o.selection.getStart()),s=b(o.selection.getSelectedBlocks(),_t),u=i.toArray().concat(s),zt(r,u)),me.fromDom),h=S(b(Xe(e),Ht),me.fromDom),y=!1;return(v.length||h.length)&&(n=e.selection.getBookmark(),f=t,C((d=v,g=S(Xe(c=e),me.fromDom),l=Ye(L(g,a(rt)),L(D(g),a(rt)),(function(e,t){return{start:e,end:t}})),m=!1,p={get:function(){return m},set:function(e){m=e}},S(d,(function(e){return{sourceList:e,entries:Yt(0,l,p,e)}}))),(function(e){ft(e.entries,f);var t,n,r=(t=c,T(function(e,t){if(0===e.length)return[];for(var n=t(e[0]),r=[],o=[],i=0,a=e.length;i"):"application/x-shockwave-flash"===r.sourcemime?(u='',r.poster&&(u+=''),u+""):-1!==r.sourcemime.indexOf("audio")?(s=r,m?m(s):'"):"script"===r.type?'