Compare commits

..

402 Commits

Author SHA1 Message Date
Pierre Goiffon
180da03f08 N°2980 Fix backup not executed anymore
Regression introduced by #89
2020-05-05 09:00:40 +02:00
Eric
f92a980b4d N°2974 - Fix Global Search doesn't search in external field.
For External Field, allow the search also for FriendlyNames.
2020-05-04 18:13:18 +02:00
Eric
843798505a N°2974 - Fix Global Search doesn't search in external field
The IsSearchable() check was wrong for some attributes
2020-05-04 11:40:02 +02:00
Pierre Goiffon
96d888fcf3 N°2968 fix email-reply notification not updated
- add a specific container for attachments list, upload button and #attachment_plugin hidden input is outside of it
- refactor code between abstract class and implementation, add some comments
- now refreshes only the attachment list instead of the whole content
2020-04-28 17:47:20 +02:00
Pierre Goiffon
1904bfdba6 css-variables : update to 2.7.0-2 2020-04-21 16:35:41 +02:00
Eric
1b2d3d1e84 N°2952 - Provisioning for hybrid auth fails
Changed Origin for change to an allowed value
2020-04-21 11:59:48 +02:00
Eric Espié
1f750bb12d N°2902 Fix alias renaming when already exists in one OQL of an UNION
The legacy impl is not modified
2020-04-20 14:59:56 +02:00
Eric
5b60ec9edf N°2919 - Dashboard - Fix dashboard not saved
the sanitization was too strong. Some names can contain ':'
2020-04-10 18:11:36 +02:00
Eric
c1a7a36896 Compatibility with MySQL 5.6 2020-04-06 09:02:06 +02:00
Eric
15e5e21a89 Compatibility with MySQL 5.6 2020-04-01 17:37:55 +02:00
Molkobain
30034d381b Update version number to 2.7.0-1 2020-03-31 09:47:37 +02:00
Molkobain
986eb90546 N°2893 - Fix DataModel Viewer not supporting special chars in class name (eg. ") 2020-03-31 09:40:31 +02:00
Pierre Goiffon
84968ff550 Merge remote-tracking branch 'origin/release/2.7.0' 2020-03-26 08:50:14 +01:00
bruno DA SILVA
46151c87c0 N°2888 Check password policy only if field set with a string
Some callers are setting the field using an ormPassword object containing hashed password + salt

examples:
 - csv import
 - data synchro
 - ...
2020-03-25 12:43:41 +01:00
Pierre Goiffon
75a900c6f8 🚀 Tool to batch update XML datamodel version 2020-03-24 16:46:48 +01:00
Molkobain
e8c9d99783 Increase XML version to v1.7 2020-03-24 14:06:41 +01:00
Eric
1600302ad9 N°2869 - Removed Check for bad finalclass in root classes (already done) 2020-03-19 15:40:52 +01:00
Eric
a9c3a1b782 N°2869 - Check for bad finalclass in root classes (Allow all non-abstract child classes) 2020-03-19 10:01:16 +01:00
Eric
74848254a4 N°2869 - Check for bad finalclass in root classes 2020-03-18 14:10:35 +01:00
Eric
d7d9bfe0fd N°2869 - Check for bad finalclass in intermediate classes 2020-03-18 10:09:05 +01:00
odain
dd96dec100 Fix license file generation; exclude itop-portal-base 2020-03-18 08:42:55 +01:00
Pierre Goiffon
16ff51f3b7 📄 Update licenses after generation tool upgrade
See 76d26e8e
2020-03-18 08:15:09 +01:00
Pierre Goiffon
27c651b33c 📄 Remove itop-portal-base from license file 2020-03-17 18:08:49 +01:00
Pierre Goiffon
32375265cb 📄 Remove 2.x/authent-cas from license file 2020-03-17 17:47:25 +01:00
Pierre Goiffon
0cba163dc9 🔖 Update version to final in iTop files 2020-03-17 16:50:45 +01:00
Pierre Goiffon
fd1e17cc32 🚀 Release tool to update versions 2020-03-17 16:49:05 +01:00
Eric
d85e1906b7 N°2746 - New Attribute Enum Set
XML migration from 1.7 to 1.6
2020-03-17 12:03:10 +01:00
Pierre Goiffon
f8df84aa7b Update dict for 2.7.0-RC 2020-03-17 10:55:53 +01:00
Eric
c26b9459bb N°2869 - Fix 2.7 Migration
Run UPDATE requests just after the corresponding ALTER TABLE requests
2020-03-16 18:49:12 +01:00
Molkobain
4f7676c42d N°2735 - Rollback previous "fixes" to keep the simple ID policy in the Designer and a unique ID generation at runtime 2020-03-16 12:17:09 +01:00
Molkobain
ceddafaebe N°2735 - Rename parameter for better consistency 2020-03-16 12:17:09 +01:00
Stephen Abello
950640babe N°1986 - Revert feature 2020-03-13 10:24:25 +01:00
jbostoen
11e6be1037 🌐 Added NL translations (#124)
Co-authored-by: jbostoen <->
2020-03-13 09:42:37 +01:00
Molkobain
29d963317f N°2735 - Fix dashlet ID generation to have the "CUSTOM" prefix only at runtime 2020-03-12 16:46:15 +01:00
Molkobain
dd300e075c N°2735 - Fix dashlet edition in the Designer (property form ID was not matching dashlet's) 2020-03-12 16:46:03 +01:00
Molkobain
774ace2302 Fix icon select widget to be compatible with iTop 2.7 2020-03-12 14:16:03 +01:00
Molkobain
bbfddea93d Open new_dashlet_id operation for Designer 2020-03-12 14:16:02 +01:00
Stephen Abello
c5c7fd5c85 N°2855 - Security hardening 2020-03-12 14:13:17 +01:00
jbostoen
5d4b9f4a89 🌐 Fix typos in English translation (#123) 2020-03-12 08:51:40 +01:00
Stephen Abello
d01caaf4e4 N°2853 - Security hardening 2020-03-10 10:23:38 +01:00
Pierre Goiffon
f895821db9 ⚗️ CONTRIBUTING : added some emoji O:) 2020-03-06 20:52:33 +01:00
bruno DA SILVA
19f34d1a72 composer reflexion: list outdated packages 2020-03-05 11:33:36 +01:00
Pierre Goiffon
7ff1a03a3c N°2820 monthly log rotation : restore default config 2020-03-04 16:04:19 +01:00
Pierre Goiffon
eadc3b72c2 📝 N°2793 log rotation add PHPDoc about timezones 2020-03-04 14:23:34 +01:00
odain
c06f8e9a98 N°2793 log rotation test : fix timezone issues 2020-03-04 12:05:42 +01:00
Pierre Goiffon
6675d7d42a N°2793 Test log rotation 2020-03-04 09:21:05 +01:00
Eric
afc118e9c2 🐛 fix GetAsPlainText() on EnumSet 2020-03-03 17:34:15 +01:00
Pierre Goiffon
f36fcb2a2d N°2820 Log rotation : change default from weekly to monthly 2020-03-03 15:31:11 +01:00
Eric
f062af367d N°2826 - Bad SQL request for group by with data-localizer
Unit tests to check the fix in data-localizer
2020-03-03 15:25:12 +01:00
Pierre Goiffon
29d24faf52 N°2793 Log rotation : fix no rotation :/
Was caused by erroneous file exists test
2020-03-03 10:18:09 +01:00
Pierre Goiffon
33f3f2810e N°2793 Log rotation : add file exists check in the lock 2020-03-02 18:33:00 +01:00
Pierre Goiffon
fad00200b6 🔧 PHPStorm remove is_null() rewrite inspection 2020-03-02 15:56:26 +01:00
Pierre Goiffon
56ef6feadf N°2820 Log rotation : new MonthlyRotatingLogFileNameBuilder class 2020-03-02 15:52:59 +01:00
Pierre Goiffon
2be16f9078 N°2793 Log rotation (#117)
Now log file name is unchanged : current log is still /log/error.log \o/

Rotation check (using file last modification time) is done :
* on each file write : we don't want to miss calls if session last from 23:59:59 to 00:01 for example ! Though the filemtime() call is done once per session to lower performance impacts
* using a new background process (LogFileRotationProcess)

File renaming on setup is therefore removed.
Also the interface is renamed (from ILogFileNameBuilder to iLogFileNameBuilder) to conform to iTop convention.
2020-03-02 15:01:12 +01:00
Eric
6874aed4a2 N°1627 - Ticket ref sometimes duplicate
add MakeInsertQuery() to legacy
2020-03-02 12:04:12 +01:00
Pierre Goiffon
07b8830436 N°2814 Fix cannot authenticate in some HTTP calls
basic mode was forced in 0dd1f26b
scripts concerned :
* synchro/synchro_import.php
* webservices/cron.php
* webservices/import.php
2020-03-02 11:56:00 +01:00
Molkobain
39d3e00ba1 N°2822 - Fix timeout message through AJAX calls in the Portal 2020-02-28 16:53:16 +01:00
Stephen Abello
ffa43160bf N°1164 #1491 - Add padding and border to code blocks 2020-02-28 16:42:46 +01:00
Pierre Goiffon
a45d1336f4 🎨 Change \ormStopWatch::ComputeGoal for IDE convencience, add phpdoc 2020-02-28 12:02:20 +01:00
Federico Lazcano
5a287fabba 🌐 Typo in ES_CR User Requests 2020-02-28 08:23:34 +01:00
Federico Lazcano
da86ee4114 🌐 Typo in ES_CR Incidents 2020-02-28 08:22:59 +01:00
Federico Lazcano
5157788afe 🌐 Typo in ES_CR User Requests 2020-02-28 08:22:14 +01:00
Molkobain
386e25efd6 N°2314 - Remove basque-red, ocean-blue and test-blue from default themes 2020-02-27 15:41:54 +01:00
Molkobain
649e2f8e6a Internal: Remove unused import 2020-02-27 15:10:41 +01:00
Molkobain
3c3d744747 N°2314 - Refactor part of the compilation in dedicated helpers 2020-02-27 15:09:57 +01:00
Molkobain
1371eee826 N°2735 - Continue rework of the dashlet id generation: Dashlet could not be added in the Designer 2020-02-27 11:54:20 +01:00
Molkobain
6645a5053f N°2806 - Fix errors on legacy portal "portal" tag during migration to iTop 2.7 2020-02-26 17:17:56 +01:00
Molkobain
e2a3e0e74f N°2735 - Continue rework of the dashlet id generation:
- Move generation from DashboardLayout to Dashboard
- Migrate dashlet user preference in RuntimeDashboard only (and not in DesignTimeDashboard)
2020-02-26 16:29:32 +01:00
Molkobain
401f82062a N°2735 - Make sure to always have the dashboard (sanitized) id for dashlets rendering 2020-02-26 12:10:18 +01:00
Molkobain
5a01a76f80 N°2735 - Add new sanitize filter ('element_identifier') for dashboard identifier 2020-02-26 12:10:18 +01:00
Pierre Goiffon
3e5520d079 N°2735 Fix new dashlet id didn't contain dashboard id 2020-02-26 09:13:19 +01:00
Pierre Goiffon
beef2a89a3 N°2684 Remove upgrade from another repository
This upgrade procedure was :
* dangerous : running two iTop of different versions on the same database should not be done
* insufficient : just /extensions/* was copied, not any Hub or Designer data, no log, no instance.txt, ...
2020-02-25 18:01:59 +01:00
Molkobain
2f920cbb46 Internal: PHPDoc and warnings suppression 2020-02-25 17:45:18 +01:00
Pierre Goiffon
feae36e5b8 N°2735 Fix dashlet id duplicates when moving dashlet from one cell to another 2020-02-25 15:43:20 +01:00
Stephen Abello
92ae0e72e1 N°2314 - Markup extensibility: Add a variable for hovered table lines background color 2020-02-25 15:14:12 +01:00
Stephen Abello
ed030403aa N°2112 - Remove unused legacy portal conf variable and its usage 2020-02-25 14:00:58 +01:00
Pierre Goiffon
dfc894f6fd N°2735 Fix cannot edit new dashlet properties regression
Was introduced by cf83bc73
2020-02-25 11:17:52 +01:00
Stephen Abello
368b49ef8f N°2314 - Markup extensibility: Fix table sorter icons in html export pages 2020-02-25 10:36:56 +01:00
Stephen Abello
ccfd3848fb N°1164 #1491 - Fix syntax code highlighting display in CaseLog/HTML fields 2020-02-25 09:54:18 +01:00
Molkobain
ea59f7bc23 N°2314 - Markup extensibility: Add metadata to caselogs in the admin. console 2020-02-24 18:22:01 +01:00
Molkobain
9d6ed7f489 N°2806 - Fix errors on legacy portal constants during migration to iTop 2.7 2020-02-24 17:03:13 +01:00
Molkobain
0aa006f7c4 Internal: Fix typo in PHPDoc 2020-02-24 16:47:10 +01:00
Molkobain
c669d6951b PHPDoc and warnings suppression 2020-02-24 16:36:31 +01:00
Molkobain
9412f260ae PHPDoc 2020-02-24 11:01:24 +01:00
Molkobain
9781a11988 N°2803 - Regression: Fix "forgot_password" parameter not working anymore 2020-02-24 10:58:24 +01:00
Molkobain
1ed0210fe2 N°2799 - Fix double encoding in "top-list" display mode of the ManageBrick 2020-02-24 09:47:22 +01:00
Molkobain
1ce5ec73ea N°2798 - Fix unable to submit portal forms (Regression from dba6e8ce) 2020-02-24 09:24:23 +01:00
Eric
98304e2bda N°2596 - Allow '1' as true value for boolean in XML files 2020-02-21 18:14:03 +01:00
Pierre Goiffon
04fc58b55c 📝 Some @since annotations were missing complete version (ex 2.5 instead of 2.5.0) 2020-02-21 18:05:30 +01:00
Eric
096c3a3f13 N°2772 - Revert the loading of JS Dict in setup pages 2020-02-21 17:15:12 +01:00
Eric
87e22163d7 N°2037 - Add Twig template rendering to the WebPage 2020-02-21 14:35:25 +01:00
acognet
4cc8b89f4e N°2037 - New dashlet Gantt - add method to insert twig in an existing page 2020-02-21 12:09:15 +01:00
Pierre Goiffon
19809249a2 📝 Update PHPDoc for StopWatches interfaces 2020-02-20 18:01:09 +01:00
Molkobain
7347eed3ac PHPDoc 2020-02-20 17:43:14 +01:00
Molkobain
69d816e345 N°2275 - Add XML delta cleanup on datamodel BC breaking changes introduced in 2.7.0 2020-02-20 17:43:14 +01:00
Vincent Dumas
4008cb7688 Add blocks to enable customization 2020-02-20 17:18:39 +01:00
Lars Hippler
41a1bede70 🌐 Update DE-dictionary for iTop 2.7.0 (#113)
Many thanks @r0ert !
2020-02-20 16:04:24 +01:00
odain
e12845e412 N°2651 - Remove test directories from lib 2020-02-20 15:03:36 +01:00
odain
b30ad45792 N°2651 - Fix missing autoload 2020-02-20 14:58:39 +01:00
odain
84a11fb3c1 added namespace + mv iTopComposer + optimize FileIterator 2020-02-20 14:56:08 +01:00
Pierre Goiffon
ee39a387db N°2651 Remove tests from lib : browse dirs using SPL classes instead of GLOB 2020-02-20 14:56:08 +01:00
bruno DA SILVA
e3c6ac814e N°2651 - Removal of "Test" dirs within dependencies handled using composer 2020-02-20 14:56:08 +01:00
Eric
d668d65c70 N°2772 - Fix errors during upgrade. Prevent JS Dict load for setup pages. 2020-02-20 14:45:39 +01:00
Pierre Goiffon
e21e7c9cf0 🌐 N°2795 Fix dict typos 2020-02-20 09:36:33 +01:00
bruno DA SILVA
27a0de1da1 N°2154 - fix server crash in rare cases
Under undetermined circumstances, `exec('php -v')` called the current script triggering an infinite loop crashing the server
problem reported by @molkobain
see: https://stackoverflow.com/questions/43728378/running-php-files-through-shell-exec
2020-02-19 15:43:33 +01:00
Molkobain
d76e54996c PHPDoc 2020-02-19 11:54:50 +01:00
Pierre Goiffon
a4710f7542 N°2760 Abstract classes for extension API interfaces : remove return; for @return void methods 2020-02-18 18:15:45 +01:00
Eric
98a9c680c5 🐛 Updated rest example 2020-02-18 17:02:13 +01:00
Pierre Goiffon
a92157f763 N°2790 fix collapsibleLabel
* change icon when label closed
* fix switch in about dialog for licenses details
2020-02-18 16:34:51 +01:00
bruno DA SILVA
412f1a394f N°2574 - 💚 fix unit test
The behaviours has changed since the "password_renewed_date" is not changed only after the inter/update and no more just aftyer the $oUserLocal->Set('password')
2020-02-18 14:49:53 +01:00
Molkobain
dba6e8ce1a Fix images being too wide in HTML fields and caselogs in the end-users portal
Regression introduced in a previous version of iTop.
2020-02-17 16:29:21 +01:00
Molkobain
a127ca9ca0 N°2313 - Fix regression: No more validation message on password update in the end-users portal 2020-02-17 15:51:38 +01:00
Molkobain
0b5ee1e05c Internal: Fix typo in PHPDoc 2020-02-17 11:24:20 +01:00
Eric
f94e86ecea 🐛 Add missing function 2020-02-14 17:18:00 +01:00
Pierre Goiffon
fe770f36c5 N°2634 / N°2735 Migrate dashlet user prefs to new dashlet ID format 2020-02-14 15:59:09 +01:00
Pierre Goiffon
cf83bc7364 N°2634 / N°2735 Fix dashlets identifiers : was causing prb on widget init, prefs save
Dashlet id now includes :
* "CUSTOM-" if dashlet is contained in a custom dashboard, nothing elsewhere
* the ID of the dashboard
  - for menus : menu id escaped for HTML
  - for AttributeDashboard : <class>__<field>
* the row / cell / dashlet idx

Examples :
CUSTOM-UserRequestOverview_IDrow1-col0-0
Organization__overview_IDrow1-col0-12
2020-02-14 15:59:09 +01:00
Eric
76982a2846 Revert Last change. The values are already protected at this stage. 2020-02-14 15:42:05 +01:00
bruno DA SILVA
4cedd30625 N°2574 - bugfix and UI
- 🐛 fix regression preventing automatic update of password_renewed_date
 - 💄 add a "general information" fieldset
2020-02-13 15:23:56 +01:00
bruno DA SILVA
a86079c477 N°2154 - 🐛 fix an awful typo producing a nonsense
I'm sorry!
2020-02-13 15:21:01 +01:00
Eric
128a237392 N°2746 - Fix Tags configuration screen (removed EnumSet from tag editable list) 2020-02-13 12:31:22 +01:00
Eric
0ecfffe413 N°2746 - Fix export separator 2020-02-13 12:12:35 +01:00
Eric
ef3bdd63a4 N°2746 - Fix search from shortcut 2020-02-13 11:56:19 +01:00
Eric
585135c6c7 N°2758 - Keep AddCondition to avoid BC break 2020-02-13 11:56:01 +01:00
Eric
b3faa96a45 🌐 Add Trigger context label 2020-02-13 09:53:55 +01:00
Eric
6f04525cdf 🎨 cleanup code 2020-02-13 09:49:58 +01:00
Pierre Goiffon
03834fedb8 N°2369 deprecate MySQL views 2020-02-12 18:11:12 +01:00
Vincent Dumas
6bde8e867f Move menu "Universal Search" under "Query" 2020-02-12 18:01:38 +01:00
Molkobain
0e3d195250 N°2275 - Fix XML delta computation putting flags on wrong XML levels 2020-02-12 17:40:53 +01:00
Pierre Goiffon
fae8c9edbd N°2780 Add ContextTag::TAG_CONSOLE for ajax operations 2020-02-12 17:20:10 +01:00
Pierre Goiffon
133d267aca N°2329 Update TCPDF to version fixing unlink bug
Was updated to 6.3.2 fot PHP 7.4 compat, but this version had a regression (issue 159 in the original repo)
This commit integrates 6.3.4 that includes a fix for issue 159
2020-02-12 15:23:57 +01:00
Stephen Abello
166986f336 N°2314 - Markup extensibility: Replace some hardcoded values by overloadable variables 2020-02-12 14:53:19 +01:00
Stephen Abello
f76d649d1a Wee cleanup 2020-02-12 14:53:19 +01:00
Stephen Abello
30747b92c7 N°2755 - Security hardening 2020-02-12 14:53:19 +01:00
Stephen Abello
12ce718662 Internal: Add HtmlEntityDecode() to utils, a counterpart to HtmlEntities() 2020-02-12 14:53:19 +01:00
Molkobain
a1cdb46663 Internal: Refactor newsroom SCSS rules to real SCSS 2020-02-12 14:20:27 +01:00
Pierre Goiffon
824d8398a3 N°2634 / N°2735 Allow saving list prefs for all DashletObjectList
The id generated for the dashlets in the markup is the one used in the saved appUserPreferences. As no control is done during compilation nor in the Designer editor, we could have duplicates.
The first fix (081ba68a) was adding a generated suffix, but for default dashlet this was generated each time so the id was different on every page load ! For custom dashlets as their definition was saved in a XML file it was ok.
This new fix adds a prefix containing row and col id, so every time the id is the same. No duplicates should be found in the same cell.
2020-02-12 14:07:57 +01:00
Eric
406774aa15 N°2746 - Fix Import/Export using labels or code 2020-02-12 12:08:40 +01:00
Pierre Goiffon
dd8712e2e8 📝 Add more doc for \DBObject::GetAsHTML 2020-02-12 11:44:00 +01:00
Eric
767bcdf117 N°2746 - Fix unit tests (typo) 2020-02-11 17:00:55 +01:00
Eric
5e060737df N°2746 - Fix unit tests 2020-02-11 16:46:24 +01:00
Eric
d9bf0fe012 N°2746 - Fix breadcrumb for search of enumSet 2020-02-11 16:02:55 +01:00
Eric
93c9783b1a N°2746 - Fix empty search for TagSet 2020-02-11 14:51:22 +01:00
Eric
e9c1467026 N°2746 - Fix "Modify All" fatal error 2020-02-11 14:35:38 +01:00
Eric
863cb4cad6 N°2758 - Allow only one condition on ValueSetDef and restore cache 2020-02-11 11:54:00 +01:00
Pierre Goiffon
94b70fc473 N°2776 ObjectFormManager : change transaction scope
* move ApplyStimulus & triggers out of the transaction
* move \utils::RemoveTransaction to a finally block
2020-02-11 11:36:59 +01:00
Pierre Goiffon
4dc383cba8 N°2684 Fix setup broke when upgrading with a config file from another directory
In the moduleschoice screens we were using a wrong approot_url !
2020-02-11 09:41:48 +01:00
Pierre Goiffon
55d8a2316a 📝 GetAttributeFlags PHPDoc revised 2020-02-11 08:34:57 +01:00
Stephen Abello
fe8f274c14 N°2314 - Markup extensibility: Replace a hardcoded value by an overloadable variable 2020-02-10 15:33:47 +01:00
Stephen Abello
72fad49c4e N°2314 - Markup extensibility: Add default color to body node 2020-02-10 15:33:47 +01:00
Eric
888d0775e6 N°2758 - Removed ValueSetDef cache 2020-02-10 14:29:28 +01:00
Molkobain
db19f71758 N°2771 - Fix "Unknown form type" when changing user language in portal 2020-02-10 14:20:11 +01:00
Molkobain
a259443735 N°2314 - Markup extensibility: Add attribute flags as metadata to object forms 2020-02-10 13:27:36 +01:00
Pierre Goiffon
58e8ca1f50 📝 GetAttributeFlags PHPDoc 2020-02-10 09:56:31 +01:00
Pierre Goiffon
ab79426508 N°2293 some PHPDoc update 2020-02-07 18:21:02 +01:00
bruno DA SILVA
7e61917521 N°524 - password validity message can be superseded with conf 2020-02-07 17:25:17 +01:00
Molkobain
e42aab30a5 Internal: Fix regression introduced in 3d2a844f ("Close" button always displayed in object forms in IE) 2020-02-07 17:22:41 +01:00
Molkobain
a79ef0bd51 Update (massively) translations before iTop 2.7 release 2020-02-07 16:51:21 +01:00
Eric
5d88391109 N°2758 - Reset ValueSetDef cache when modifying some parameters 2020-02-07 14:27:22 +01:00
Molkobain
c56c04d84d N°2760 - Ease API interfaces implementation through abstract classes 2020-02-06 18:09:59 +01:00
Molkobain
f2b8f50a94 Internal: Add Anne to the sample data to welcome her! 👋 2020-02-06 18:07:51 +01:00
Molkobain
9de11a29fb PHPDoc 2020-02-06 16:25:25 +01:00
Molkobain
6537e00453 Internal: Add Matthieu to the sample data to welcome him! 👋 2020-02-06 15:53:26 +01:00
Eric
dd5f4909da Fix warning 2020-02-06 15:01:02 +01:00
Stephen Abello
ed67df734f N°2755 - Security hardening 2020-02-06 14:50:27 +01:00
Stephen Abello
44894526f1 N°2742 - HTML files preview are now raw text only 2020-02-06 14:27:13 +01:00
xtophe38
de78963b30 Fix DataAdministration translation to be aligned with other menus 2020-02-06 14:25:52 +01:00
bruno DA SILVA
948fd6f0ce N°2154 - improve robustness of submitted config validator
thanks to @molkobain 's awful provider's using PHP 4.4 within CLI
2020-02-06 14:07:39 +01:00
bruno DA SILVA
214dbeef5b N°2154 - var into string patterns can now also be enabled using server vars
- usage: $_SERVER['ITOP_CONFIG_PLACEHOLDERS']
 - plus removal of useless log Trace since this code is too early in iTop's init process for this feature
2020-02-06 14:05:08 +01:00
bruno DA SILVA
f2fbd8457d N°2498 - Authorize map extension
so as `.js.map` is not forbidden by apache
2020-02-06 14:05:08 +01:00
Molkobain
6a432c6a25 N°2757 - Fix count in group by dashlets 2020-02-06 12:12:27 +01:00
Molkobain
e96a8387a0 N°2750 - Regression: Fix default user profile image not shown in portal due to N°2060 2020-02-06 10:06:18 +01:00
Pierre Goiffon
f3576cffb0 📝 README : remove 2.4.* version as this branch isn't supported anymore by Combodo 2020-02-05 14:51:46 +01:00
Molkobain
c5625e6a8d Internal: Fix setup headers style due to 71708cf 2020-02-05 14:49:33 +01:00
Molkobain
3d2a844fef N°2313 - Markup extensibility: Improve success message display during the workflow 2020-02-05 12:10:15 +01:00
Molkobain
110a030902 PHPDoc 2020-02-05 12:10:15 +01:00
Stephen Abello
5ccd885607 Remove DB Tools from excluded modules 2020-02-05 12:04:26 +01:00
Stephen Abello
e5c6efbe69 Merge branch 'master' into develop
# Conflicts:
#	README.md
2020-02-05 11:24:44 +01:00
Stephen Abello
bd083d632f Update readme for 2.6.3 release 2020-02-05 11:22:39 +01:00
Stephen Abello
65b8132914 N°2314 - Markup extensibility: Fix collapsible icons in "About iTop" modal 2020-02-05 09:47:27 +01:00
Eric
3c2130aa72 N°2321 - Fix SQL request generation for inherited magic attributes 2020-02-04 15:54:03 +01:00
Stephen Abello
e70a2f75d3 N°2748 - Fix regression introduced by 71f5d29c, CKEditor's paragraph spacing wasn't coherent with how it's displayed in iTop 2020-02-04 11:41:10 +01:00
Molkobain
fe8e6ba4b0 N°2314 - Markup extensibility: Fix UI elements not using main colors variables 2020-02-04 10:32:57 +01:00
Eric
008614fde6 N°2321 - Fix SQL request generation for inherited magic attributes 2020-02-04 10:28:35 +01:00
Molkobain
ac6e60f5a1 N°2595 - Reorganize admin. console menus: Change new menu groups IDs to avoid collision with existing extensions 2020-02-04 09:50:11 +01:00
Stephen Abello
bf18d623d6 N°2314 - Markup extensibility: Add 2 additional themes for the backoffice
Adds a colored top bar to easily identify different environments (tests, production, ...)
2020-02-03 16:17:46 +01:00
Stephen Abello
10d04756ee N°2314 - Markup extensibility: Fall back on iTop's default theme when a non existing theme is selected 2020-02-03 15:12:59 +01:00
bruno DA SILVA
6e927114e0 N°2154 - 💚 fix tests
- the correct file is now versioned
2020-02-03 12:04:51 +01:00
Pierre Goiffon
682c24a873 N°2293 DBUpdate : save changed fields and corresponding previous values (#111)
* N°2293 DBUpdate : save changed fields and corresponding previous values for callbacks
* update PHPDoc
* remove m_aChanges and ListChangesUpdated() that were introduced in 2.7.0-beta
* add m_aPreviousValuesForUpdatedAttributes and ListPreviousValuesForUpdatedAttributes()

* :memo Woops forgot to change one PHPDoc

* 📝 Some more PHPDoc O:)

* 📝 Add more info in .doc README

* 📝 Well, again some PHPDoc O:)

* 📝 Replace inline @link by @see
@link are for URI, see https://docs.phpdoc.org/latest/references/phpdoc/inline-tags/link.html
2020-01-31 18:01:26 +01:00
bruno DA SILVA
d4b4ced649 🌐 update dictionaries
- set the translation as requested by Q&A
2020-01-31 17:29:38 +01:00
bruno DA SILVA
c2589492d9 📝 documentation generator dependencies handling improvement
- ignore /.doc/vendor
 - uses a lock file (at /.doc/composer.lock)
2020-01-31 17:29:38 +01:00
bruno DA SILVA
15c9cf926e 2154 - preserve "var" in conf
- add possibility to inject var using string patterns (ie: `'%env(DB_HOST)?:localhost%`)
 - on WriteToFile, preserve the non interpreted value when the interpreted value is kept the same
 - added unit tests for both behaviours
 - minor bugfix (default value in comment was wrong) and code readability improvements
2020-01-31 17:29:37 +01:00
Molkobain
78d4c8c7c7 Internal: Fix typo 2020-01-31 17:22:57 +01:00
Eric
d9e8eed084 💚 Fix CI on TagSet search (request have changed) 2020-01-31 16:13:59 +01:00
Eric
ebe86d09ee N°985 - Add applicable contexts on Trigger (logs) 2020-01-30 16:18:49 +01:00
Eric
5e5d368299 N°2657 - MTP : Progress Bar has disappeared (Search exact match) 2020-01-30 16:02:16 +01:00
Molkobain
f990a83453 N°2060 - Migrate error page to the Symfony framework 2020-01-30 13:56:32 +01:00
Molkobain
c6325dce8e Internal: Fix autoloader path for Symfony bin/console utility 2020-01-30 13:56:32 +01:00
Eric
bbca1625fb N°2657 - MTP : Progress Bar has disappeared (Search exact match) 2020-01-30 12:31:22 +01:00
Pierre Goiffon
53975d1d8f 📝 Replace inline @link by @see
@link are for URI, see https://docs.phpdoc.org/latest/references/phpdoc/inline-tags/link.html
2020-01-30 09:35:25 +01:00
Pierre Goiffon
1358bf9b7f 📝 Well, again some PHPDoc O:) 2020-01-30 09:25:53 +01:00
Pierre Goiffon
7c17be4db6 📝 Add more info in .doc README 2020-01-30 09:22:38 +01:00
Pierre Goiffon
367a92b711 📝 Some more PHPDoc O:) 2020-01-30 08:39:18 +01:00
Pierre Goiffon
0a3201dd41 :memo Woops forgot to change one PHPDoc 2020-01-29 18:43:46 +01:00
Pierre Goiffon
d82690dd84 N°2293 DBUpdate : save changed fields and corresponding previous values for callbacks
* update PHPDoc
* remove m_aChanges and ListChangesUpdated() that were introduced in 2.7.0-beta
* add m_aPreviousValuesForUpdatedAttributes and ListPreviousValuesForUpdatedAttributes()
2020-01-29 18:36:46 +01:00
Eric
7f9e4385ac N°2657 - MTP : Progress Bar has disappeared (support any code length) 2020-01-29 18:01:17 +01:00
Stephen Abello
aa3e284af3 Update README for 2.7.0-beta2 2020-01-29 16:59:16 +01:00
Stephen Abello
a941e5f752 Merge branch 'develop' of https://github.com/Combodo/iTop into develop 2020-01-29 11:49:38 +01:00
Stephen Abello
b1878f7265 Update version number for 2.7.0-beta2 2020-01-29 11:49:20 +01:00
Molkobain
b106a54c50 N°2314 - Markup extensibility: Add 2 additional themes for the backoffice
Basic color changes to identify different environments (tests, production, ...)
2020-01-29 11:04:20 +01:00
Molkobain
002da0b387 N°2314 - Markup extensibility: Rework some SCSS variables 2020-01-29 11:04:20 +01:00
acognet
6b9e723a45 Merge remote-tracking branch 'origin/develop' into develop 2020-01-29 09:55:44 +01:00
acognet
b54e457cbb N°2038 - New dashlet Kanban 2020-01-29 09:54:56 +01:00
jbostoen
e750dd53d8 NL translations for iTop 2.7.0 (#94)
Made by @jbostoen & @Hipska in PR #94 . Many thanks to them !
2020-01-29 09:51:11 +01:00
Eric
da6a55504e N°985 - AttributeEnumSet (portal support) 2020-01-28 17:37:17 +01:00
Eric
b58356c42e N°985 - Add applicable contexts on Trigger (search) 2020-01-28 17:37:17 +01:00
Molkobain
524e43b8c4 N°2313 - Markup extensibility: Add metadata on session messages in the end-users portal 2020-01-28 17:27:32 +01:00
Eric
a80bd6f2b9 N°985 - Add applicable contexts on Trigger (display read-only) 2020-01-28 15:29:12 +01:00
Eric
08eb9ee630 🌐 update dictionaries for 2.7.0-beta2 2020-01-28 15:29:12 +01:00
Eric
05485b838e N°985 - Add applicable contexts on Trigger (display read-only) 2020-01-28 15:29:12 +01:00
Eric
029fe6882d N°985 - Add applicable contexts on Trigger (Fix regression) 2020-01-28 15:29:12 +01:00
Eric
b31eb6aab9 Comment 2020-01-28 15:29:12 +01:00
Molkobain
a96c194676 N°2313 - Markup extensibility: Add CSS classes on object details and lists in the end-users portal 2020-01-28 15:25:12 +01:00
bruno DA SILVA
0d85331bca 1627 - Ticket ref sometimes duplicate
🐛 INSERT/UPDATE do not require to free the results
2020-01-28 11:59:04 +01:00
Pierre Goiffon
e9dec8ae05 N°330 Attachments as table : fix table sorting on size and date
* portal : use data-order attribute for the DataTable plugin (https://datatables.net/manual/data/orthogonal-data)
* console : add textExtraction override for the attachments table (https://mottie.github.io/tablesorter/docs/example-option-text-extraction.html)
2020-01-28 10:11:29 +01:00
bruno DA SILVA
6a6a0ffa24 1627 - Ticket ref sometimes duplicate
🐛 fix ref. generation when inside a transaction (by opening a new connection).
note: the portal make uses of such a transaction.
2020-01-27 17:58:30 +01:00
Molkobain
87623fba3d PHPDoc 2020-01-27 16:58:55 +01:00
Molkobain
a7619f2820 N°2313 - Markup extensibility: Add metadata on admin. console object lists 2020-01-27 16:58:55 +01:00
bruno DA SILVA
cff53d71ba N°2154 & N°2720 & N°2684 - config integrity during setup 2020-01-27 15:21:50 +01:00
Molkobain
71708cfbc7 Internal: Fix setup headers size 2020-01-27 14:54:53 +01:00
acognet
e05b3a5fb9 N°2618 - Fix missing scroll bar in DataModel Viewer for class with large number of attributs 2020-01-27 10:47:19 +01:00
acognet
bfcb1fdb30 N°2618 - Fix missing scroll bar in DataModel Viewer for class with large number of attributs 2020-01-27 10:47:19 +01:00
Eric
cc4e1ea104 N°985 - Add applicable contexts on Trigger (Add portal contexts) 2020-01-24 17:43:59 +01:00
Molkobain
5485897bbb N°2313 - Markup extensibility: Fix raw value and attribute label not always being escaped 2020-01-24 17:38:18 +01:00
Molkobain
27f343e543 N°330 - Attachments: Align table rendering to linkset tables rendering 2020-01-24 17:02:02 +01:00
Molkobain
cca79735fc N°330 - Attachments: Fix empty "Delete" column displayed all the time 2020-01-24 17:02:02 +01:00
Molkobain
c48bbfd32a N°2313 - Markup extensibility: Add metadata on attachments 2020-01-24 17:02:02 +01:00
Molkobain
3ae2058f6f N°2314 - Markup extensibility: Refactor utils::GetCSSFromSASS() to enable SCSS compilation out of a file 2020-01-24 17:02:02 +01:00
Molkobain
0a63568715 PHPDoc 2020-01-24 17:02:02 +01:00
Molkobain
f878eea68d N°330 - Attachments: Update MS Office and OpenOffice file icons with more modern versions 2020-01-24 17:02:02 +01:00
Eric
8ad2b8091c N°2657 - MTP : Progress Bar has disappeared 2020-01-23 11:28:52 +01:00
bruno DA SILVA
d6ca08efb8 N°2730 - Cannot log callstack with callback into EventIssue 2020-01-22 17:37:44 +01:00
Molkobain
ba8a2c1b15 N°2710 - Fix setup crash due to PHP notices (regression introduced in 59678955) 2020-01-22 13:32:31 +01:00
Molkobain
bd9da07734 Merge branch 'support/2.5' 2020-01-22 09:55:50 +01:00
Molkobain
3dbbf296b8 Exclude combodo-db-tools module from packages by default 2020-01-22 09:10:54 +01:00
bruno DA SILVA
0ae0336e04 N°1627 - Ticket ref sometimes duplicate
🐛 Ticket creation no more crash if the current user have limited read access
2020-01-21 18:31:09 +01:00
Molkobain
8df0ef6af9 N°2723 - Fix double scrollbar in search criterion 2020-01-21 17:40:11 +01:00
Molkobain
d77c77c03b PHPDoc 2020-01-21 17:20:12 +01:00
Molkobain
5967895561 N°2710 - Fix extremely slow page load for first user after setup (regression introduced in N°2314) 2020-01-21 17:19:16 +01:00
Molkobain
6e754d4fa5 Setup: Fix graphiz detection feedback message on Windows systems 2020-01-21 15:50:33 +01:00
Molkobain
165fd0e700 N°2314 - Setup: Improve UI of user message when CRON is running 2020-01-21 15:35:09 +01:00
Molkobain
d100ce8005 PHPDoc and code formatting 2020-01-21 15:35:09 +01:00
Eric
770f5a7b67 N°985 - Add applicable contexts on Trigger (order values in DB) 2020-01-21 14:55:03 +01:00
Molkobain
a993f6a80b PHPDoc 2020-01-21 14:19:45 +01:00
Molkobain
c8bb710d21 N°2314 - Markup extensibility: Fix regression introduced in the previous commit (used a PHP 7.x function) 2020-01-21 14:17:44 +01:00
Molkobain
d963fbd8cf N°2314 - Markup extensibility: Fix crash when no <theme> defined in datamodel 2020-01-21 12:20:59 +01:00
Eric
beda8e2810 N°985 - Add applicable contexts on Trigger (fix MTP warnings) 2020-01-21 12:01:42 +01:00
Pierre Goiffon
083f8d69c2 Revert "N°2618 DataModel viewer : fix no vertical scrollbar in MSIE"
Was introducing a regression in Chrome & Fx (cannot change tab anymore)
This reverts commit 8a666b09d6.
2020-01-21 10:51:16 +01:00
Eric
1c16eeb5e4 N°2240 - Supportability - Maintenance mode (setup reset maintenance mode) 2020-01-21 10:27:47 +01:00
Stephen Abello
ecc0b57b31 Merge branch 'master' into develop
# Conflicts:
#	css/css-variables.scss
#	css/light-grey.css
#	datamodels/2.x/authent-external/module.authent-external.php
#	datamodels/2.x/authent-ldap/module.authent-ldap.php
#	datamodels/2.x/authent-local/module.authent-local.php
#	datamodels/2.x/itop-attachments/module.attachments.php
#	datamodels/2.x/itop-backup/module.itop-backup.php
#	datamodels/2.x/itop-bridge-virtualization-storage/module.itop-bridge-virtualization-storage.php
#	datamodels/2.x/itop-change-mgmt-itil/module.itop-change-mgmt-itil.php
#	datamodels/2.x/itop-change-mgmt/module.itop-change-mgmt.php
#	datamodels/2.x/itop-config-mgmt/module.itop-config-mgmt.php
#	datamodels/2.x/itop-config/module.itop-config.php
#	datamodels/2.x/itop-datacenter-mgmt/module.itop-datacenter-mgmt.php
#	datamodels/2.x/itop-endusers-devices/module.itop-endusers-devices.php
#	datamodels/2.x/itop-full-itil/module.itop-full-itil.php
#	datamodels/2.x/itop-hub-connector/module.itop-hub-connector.php
#	datamodels/2.x/itop-incident-mgmt-itil/module.itop-incident-mgmt-itil.php
#	datamodels/2.x/itop-knownerror-mgmt/module.itop-knownerror-mgmt.php
#	datamodels/2.x/itop-portal-base/module.itop-portal-base.php
#	datamodels/2.x/itop-portal/module.itop-portal.php
#	datamodels/2.x/itop-problem-mgmt/module.itop-problem-mgmt.php
#	datamodels/2.x/itop-profiles-itil/module.itop-profiles-itil.php
#	datamodels/2.x/itop-request-mgmt-itil/module.itop-request-mgmt-itil.php
#	datamodels/2.x/itop-request-mgmt/module.itop-request-mgmt.php
#	datamodels/2.x/itop-service-mgmt-provider/module.itop-service-mgmt-provider.php
#	datamodels/2.x/itop-service-mgmt/module.itop-service-mgmt.php
#	datamodels/2.x/itop-sla-computation/module.itop-sla-computation.php
#	datamodels/2.x/itop-storage-mgmt/module.itop-storage-mgmt.php
#	datamodels/2.x/itop-tickets/module.itop-tickets.php
#	datamodels/2.x/itop-virtualization-mgmt/module.itop-virtualization-mgmt.php
#	datamodels/2.x/itop-welcome-itil/module.itop-welcome-itil.php
#	datamodels/2.x/version.xml
2020-01-20 16:42:42 +01:00
Stephen Abello
be9f6eff29 Merge branch 'develop' of https://github.com/Combodo/iTop into develop 2020-01-20 16:41:44 +01:00
Stephen Abello
50a8af4082 Update version number for 2.6.3 2020-01-20 16:30:51 +01:00
Stephen Abello
6a1125875b Merge branch 'support/2.5'
# Conflicts:
#	css/css-variables.scss
#	css/light-grey.css
#	datamodels/2.x/authent-external/module.authent-external.php
#	datamodels/2.x/authent-ldap/module.authent-ldap.php
#	datamodels/2.x/authent-local/module.authent-local.php
#	datamodels/2.x/itop-attachments/module.attachments.php
#	datamodels/2.x/itop-backup/module.itop-backup.php
#	datamodels/2.x/itop-bridge-virtualization-storage/module.itop-bridge-virtualization-storage.php
#	datamodels/2.x/itop-change-mgmt-itil/module.itop-change-mgmt-itil.php
#	datamodels/2.x/itop-change-mgmt/module.itop-change-mgmt.php
#	datamodels/2.x/itop-config-mgmt/module.itop-config-mgmt.php
#	datamodels/2.x/itop-config/module.itop-config.php
#	datamodels/2.x/itop-datacenter-mgmt/module.itop-datacenter-mgmt.php
#	datamodels/2.x/itop-endusers-devices/module.itop-endusers-devices.php
#	datamodels/2.x/itop-full-itil/module.itop-full-itil.php
#	datamodels/2.x/itop-hub-connector/module.itop-hub-connector.php
#	datamodels/2.x/itop-incident-mgmt-itil/module.itop-incident-mgmt-itil.php
#	datamodels/2.x/itop-knownerror-mgmt/module.itop-knownerror-mgmt.php
#	datamodels/2.x/itop-portal-base/module.itop-portal-base.php
#	datamodels/2.x/itop-portal/module.itop-portal.php
#	datamodels/2.x/itop-problem-mgmt/module.itop-problem-mgmt.php
#	datamodels/2.x/itop-profiles-itil/module.itop-profiles-itil.php
#	datamodels/2.x/itop-request-mgmt-itil/module.itop-request-mgmt-itil.php
#	datamodels/2.x/itop-request-mgmt/module.itop-request-mgmt.php
#	datamodels/2.x/itop-service-mgmt-provider/module.itop-service-mgmt-provider.php
#	datamodels/2.x/itop-service-mgmt/module.itop-service-mgmt.php
#	datamodels/2.x/itop-sla-computation/module.itop-sla-computation.php
#	datamodels/2.x/itop-storage-mgmt/module.itop-storage-mgmt.php
#	datamodels/2.x/itop-tickets/module.itop-tickets.php
#	datamodels/2.x/itop-virtualization-mgmt/module.itop-virtualization-mgmt.php
#	datamodels/2.x/itop-welcome-itil/module.itop-welcome-itil.php
#	datamodels/2.x/version.xml
2020-01-20 16:10:21 +01:00
Stephen Abello
878c23892d Update version number for 2.5.4 2020-01-20 15:59:08 +01:00
Eric
900e8ac6d7 N°985 - Add applicable contexts on Trigger 2020-01-20 15:50:08 +01:00
Stephen Abello
248dab9289 N°2633 - Security hardening 2020-01-20 15:46:04 +01:00
Molkobain
2fcea4d02e N°2313 - Markup extensibility: Add field label in its metadata 2020-01-20 14:43:40 +01:00
Stephen Abello
1927fc743a N°2314 - Fix left padding for menu entries 2020-01-20 11:20:56 +01:00
Molkobain
6aff09eaf7 N°2708 - Internal: Fix regression introduced with N°2313 "Undefined index 'prefix'" 2020-01-20 11:16:07 +01:00
Molkobain
54e9830a3b PHPDoc 2020-01-20 09:53:22 +01:00
Molkobain
a45819dbf0 N°2682 - Portal: Fix transaction ID not being removed 2020-01-17 17:40:37 +01:00
Molkobain
e8aaec5789 N°2060 - Regression: Fix missing PORTAL_ID constant 2020-01-17 17:33:52 +01:00
Molkobain
d16c0ffef9 N°2313 - Markup extensibility: Add metadata on admin. console object creation forms 2020-01-17 14:16:31 +01:00
Molkobain
24ad593dc8 N°2313 - Markup extensibility: Add password attributes to exclude list in metadata 2020-01-17 09:03:14 +01:00
Molkobain
0b67828ab9 Add comments in standard end-users portal XML 2020-01-17 09:03:14 +01:00
Eric
8a1a78444d N°2249 - Supportability - Updater module (unified version name) 2020-01-16 18:13:58 +01:00
Eric
4552bc0778 N°2249 - Supportability - Updater module (changed version name in the priv_module_install table) 2020-01-16 17:42:02 +01:00
Eric
3a113e31fb N°2249 - Supportability - Updater module (run setup when error occurs) 2020-01-16 17:25:28 +01:00
Pierre Goiffon
8a666b09d6 N°2618 DataModel viewer : fix no vertical scrollbar in MSIE
The scrollbar is present on the right side but after viewport limit so not visible !
Can't change div.ui-layout-pane.ui-layout-center width as it is calculated dynamically by JS Layout...
So added another container with a margin. The CSS rules are added to MSIE only using the media query tip :/
2020-01-16 16:40:36 +01:00
Pierre Goiffon
0d9dc34a08 Schema.php : replace <br/> to <br> (might break on MSIE) 2020-01-16 15:06:04 +01:00
Pierre Goiffon
c7ca1eeab5 🎨 Code formatting on pages/schema.php 2020-01-16 15:06:04 +01:00
Eric
02265135e3 N°2249 - Supportability - Updater module (run setup when error occurs) 2020-01-16 11:43:17 +01:00
Eric
2c1bf665c3 N°2249 - Supportability - Updater module (Add read-only warning) 2020-01-16 11:34:50 +01:00
Molkobain
60b6fcc783 N°2313 - Markup extensibility: Better display of success messages on form validation 2020-01-16 11:34:08 +01:00
Molkobain
53adb37f43 N°2060 - Fix session messages and SCSS compilation services being cached 2020-01-16 11:34:08 +01:00
Molkobain
a6fe564a95 Add comments in standard end-users portal XML 2020-01-16 11:34:08 +01:00
Pierre Goiffon
4945f25d49 N°2602 Portal : fix no more border around new caselog editor
With the new version of CKE N°2271, container is span.cke on MSIE instead of div.cke
2020-01-16 11:27:24 +01:00
Eric
e5f3daf88a N°2249 - Supportability - Updater module (Add read-only warning) 2020-01-16 11:19:30 +01:00
Eric
cc3e6d64e1 N°2249 - Supportability - Updater module (Allow to run setup in case of failure) 2020-01-16 10:49:49 +01:00
Eric
8024aad43d N°2249 - Supportability - Updater module (Add read-only warning) 2020-01-16 10:47:37 +01:00
Pierre Goiffon
757dbb8b25 N°2311 login page : add autofocus attribute to the id field
https://caniuse.com/#feat=autofocus
2020-01-16 10:38:08 +01:00
Eric
b370deaac9 N°2313 - Markup extensibility: Add support for both code AND title in admin. console tabs 2020-01-16 09:56:22 +01:00
Eric
026b7e1836 N°2249 - Supportability - Updater module (split ajax calls) 2020-01-15 17:09:31 +01:00
Eric
d03b924240 N°2249 - Supportability - Updater module (split ajax calls) 2020-01-15 16:58:36 +01:00
Eric
97a047e38f N°2249 - Supportability - Updater module (split ajax calls) 2020-01-15 16:42:47 +01:00
Eric
5be800cfce N°2249 - Supportability - Updater module (split ajax calls) 2020-01-15 15:48:54 +01:00
Molkobain
956b597e50 Fix how user data is retrieved for "Form Prefill" in the end-users portal 2020-01-15 15:16:50 +01:00
Molkobain
57100dee9f N°2060 - WIP: Fix cached part of the portal (sync. commit) 2020-01-15 12:53:40 +01:00
Eric
c3cc1afec1 🙈 remove unnecessary info 2020-01-15 11:37:10 +01:00
Pierre Goiffon
7fe24f58f3 N°330 Display attachments as table : portal remove author column 2020-01-15 10:26:25 +01:00
Molkobain
e4160c7cf2 N°2702 - Portal: Fix origin modal not closing when switching to editing of an object 2020-01-15 10:15:36 +01:00
Molkobain
7d87768ec4 PHPDoc and warnings suppression 2020-01-15 10:15:36 +01:00
Molkobain
9946e6c41a Fix typo 2020-01-15 10:15:36 +01:00
Stephen Abello
02b483e33e Setup's cursor style on label wasn't present in .scss file and was lost since 7b6481e 2020-01-15 10:14:59 +01:00
Stephen Abello
7b6481efbd N°2112: Setup alert message introduced by 83ba909 stopped working since 797893d🐒 🐒 2020-01-15 10:09:46 +01:00
Molkobain
efef582119 N°2306 - Security hardening (Fix regression introduced in f3b66a44, thanks to @bruno-ds !) 2020-01-15 08:42:35 +01:00
Molkobain
5056e561fe PHPDoc 2020-01-15 08:42:35 +01:00
Molkobain
4400cfde62 N°2313 - Markup extensibility: Update usages of admin. console tabs to have codes and titles 2020-01-15 08:42:35 +01:00
Molkobain
5a39581c60 N°2313 - Markup extensibility: Add support for both code AND title in admin. console tabs 2020-01-15 08:42:35 +01:00
Pierre Goiffon
4eab0e6450 N°330 Display attachments as table : portal improvements
* display attachments count in section title, updated on each add/delete
* remove "no attchments message" on adding new attachment
2020-01-14 11:56:20 +01:00
Molkobain
f3b66a44ee N°2306 - Security hardening 2020-01-14 11:50:50 +01:00
Molkobain
558f108520 N°2314 - Change breadcrumb icons color to black instead of Combodo's orange 2020-01-14 11:09:01 +01:00
Molkobain
07a93d12e2 Cleanup: Remove old/unused images/CSS files (Exhaustive list in migration notes) 2020-01-14 11:09:01 +01:00
Eric
ce127278bb N°2434 - Track field Comment in core/delete - API REST 2020-01-14 10:46:21 +01:00
Molkobain
887946144c N°2696 - Upgrade ArchiveTar to v1.4.9 (PHP 7.4 compatibility) 2020-01-14 10:35:53 +01:00
Molkobain
cc887c29fd N°2696 - Upgrade SCSSPHP to v1.0.6 (PHP 7.4 compatibility) 2020-01-14 10:35:53 +01:00
Molkobain
460836852e N°2696 - Upgrade SwiftMailer to v5.4.12 (Allow explicit tls1.0, tls1.1, tls1.2 for startTLS) 2020-01-14 10:35:53 +01:00
Eric
208d7ee7ba N°2093 - ApplyStimulus return true when stimuli is not applicable 2020-01-14 10:27:55 +01:00
Eric
3d92b73ae5 :globe-with-meridian: changed filesystem into files for itop-core-update 2020-01-14 10:14:03 +01:00
Stephen Abello
deddb0824b N°2315: Forgot password sent page needed stylization 2020-01-14 09:26:58 +01:00
Vladimir Kunin
3718899663 🌐 Update Russian translations for 2.7.0-beta 2020-01-13 17:52:15 +01:00
Pierre Goiffon
7f30d74f30 N°2269 Update Font Awesome to 5.12.0 2020-01-13 10:47:57 +01:00
Eric
21199fce34 N°2240 - Supportability - Maintenance mode exit on MTP or core update error 2020-01-10 15:32:29 +01:00
Pierre Goiffon
ad821e7d9c N°2651 rollback gitignore for lib tests dirs
Too dangerous ! We'll work properly on this but for 2.8
2020-01-10 15:23:15 +01:00
Eric
881fc2a1de N°2240 - Supportability - Maintenance mode exit on MTP or core update error 2020-01-10 14:14:20 +01:00
Vincent Dumas
44ee6baddb N°2675: Fix AdminTools DataSynchro creation
User with a profile enabling write access on the group id="AdminTools" was not able to create a DataSynchro also it should have been.
2020-01-09 16:07:47 +01:00
Federico Lazcano
42d782740e Paste error! 2020-01-09 10:05:22 +01:00
Federico Lazcano
cf16229948 🌐 Typos and new translations in ES CR 2020-01-09 10:05:22 +01:00
Federico Lazcano
a25427f4c6 Change from alias to real name
Sorry @Molkobain i changed my mind :-|
2020-01-09 10:01:03 +01:00
Federico Lazcano
04b2f7c836 🌐 Added ES CR translations 2020-01-09 09:28:36 +01:00
Molkobain
0f917af55a 👥 Add @lazki to our contributors list. Thanks! 👏 2020-01-09 09:12:27 +01:00
Federico Lazcano
daaed4696e 🌐 Typo in ES CR Translation 2020-01-09 09:08:34 +01:00
Pierre Goiffon
5f52c273d9 N°2329 PHP 7.4 compat : update setup requirements
This PHP version should be ok : we will give it a try during the beta program
2020-01-09 09:05:24 +01:00
Molkobain
b8d35e4783 👥 Add Guy Couronné (@GurneyHallack) to our contributors list! 2020-01-08 19:53:12 +01:00
Molkobain
149dff4b4d N°2313 - Markup extensibility: Add markup hooks on BrowseBrick and ManageBrick tables 2020-01-08 19:48:45 +01:00
Molkobain
f235e0cd66 Update copyright 2020-01-08 19:48:45 +01:00
Pierre Goiffon
e47e02932a N°2329 PHP 7.4 compat : fix warnings in TCPDF
Integrate last TCPDF fork version (6.3.2)
2020-01-08 17:50:51 +01:00
Eric
4544bba652 N°2240 - Supportability - Maintenance mode (setup CRON message) 2020-01-08 17:29:53 +01:00
Eric
9445e12254 MSIE 11 minimum 2020-01-08 17:23:36 +01:00
Eric
951945a607 N°2240 - Supportability - Maintenance mode (Better REST/Export message) 2020-01-08 17:17:34 +01:00
Eric
34f8fff01c Fetch() ignore row when sub-class does not exist 2020-01-08 16:38:11 +01:00
Stephen Abello
8d45e48ce1 🥅 N°1192 Portal: Increase navigation rules checks robustness 2020-01-08 15:31:19 +01:00
Eric
ed26f1cecc Fix menu creation flags 2020-01-08 15:10:10 +01:00
Molkobain
bc298afda3 Merge remote-tracking branch 'origin/master' into develop
# Conflicts:
#	datamodels/2.x/combodo-db-tools/cs.dict.combodo-db-tools.php
#	datamodels/2.x/combodo-db-tools/da.dict.combodo-db-tools.php
#	datamodels/2.x/combodo-db-tools/datamodel.combodo-db-tools.xml
#	datamodels/2.x/combodo-db-tools/db_analyzer.class.inc.php
#	datamodels/2.x/combodo-db-tools/dbtools.php
#	datamodels/2.x/combodo-db-tools/de.dict.combodo-db-tools.php
#	datamodels/2.x/combodo-db-tools/default.css
#	datamodels/2.x/combodo-db-tools/default.scss
#	datamodels/2.x/combodo-db-tools/en.dict.combodo-db-tools.php
#	datamodels/2.x/combodo-db-tools/es_cr.dict.combodo-db-tools.php
#	datamodels/2.x/combodo-db-tools/fr.dict.combodo-db-tools.php
#	datamodels/2.x/combodo-db-tools/hu.dict.combodo-db-tools.php
#	datamodels/2.x/combodo-db-tools/it.dict.combodo-db-tools.php
#	datamodels/2.x/combodo-db-tools/ja.dict.combodo-db-tools.php
#	datamodels/2.x/combodo-db-tools/module.combodo-db-tools.php
#	datamodels/2.x/combodo-db-tools/nl.dict.combodo-db-tools.php
#	datamodels/2.x/combodo-db-tools/pt_br.dict.combodo-db-tools.php
#	datamodels/2.x/combodo-db-tools/ru.dict.combodo-db-tools.php
#	datamodels/2.x/combodo-db-tools/tr.dict.combodo-db-tools.php
#	datamodels/2.x/combodo-db-tools/zh_cn.dict.combodo-db-tools.php
2020-01-08 12:03:55 +01:00
Molkobain
4f0e3430c0 Merge remote-tracking branch 'origin/support/2.5' 2020-01-08 11:58:15 +01:00
Molkobain
3347f400b8 Internal: Revert files deleted by mistake 🙈 2020-01-08 11:57:29 +01:00
Molkobain
6082308e20 Add combodo-db-tools/1.0.7 module as a default module 2020-01-08 11:40:35 +01:00
odain
1fc290587c N°2154: Fix security breach (scratch install usecase) 2020-01-08 10:10:49 +01:00
Molkobain
77fa02fcf9 PHPDoc and warnings suppression 2020-01-08 10:06:03 +01:00
Molkobain
d445551031 N°1986 - Fix regression introduced in b91183e9, creation form should never be read-only 2020-01-08 10:05:33 +01:00
Molkobain
ebfe9da464 N°2306 - Security hardening 2020-01-07 20:59:09 +01:00
odain
fdd79e91f0 N°2154: Fix security breach (scratch install usecase) 2020-01-07 17:44:39 +01:00
Molkobain
94a09493b0 N°2306 - Security hardening (BC break for some portal extensions, see migration notes) 2020-01-07 17:40:03 +01:00
Molkobain
56dbbb09dc Fix dependencies between modules 2020-01-07 17:00:19 +01:00
Pierre Goiffon
f019e05af5 N°2042 deprecated chrono extensivity 2020-01-07 16:07:25 +01:00
bruno DA SILVA
838c4f123c 👌 peer review
mostly coding convention,

thanks @molkobain
2020-01-07 15:34:27 +01:00
bruno DA SILVA
2043010aad N°2293 - API OnDBUpdate and AfterUpdate need modified fields and previous data
- add a getter for the protected property DBObject::$m_aChanges
2020-01-07 15:05:29 +01:00
bruno DA SILVA
cda18b950e N°524 - Password policy
- removal of a forgotten console.debug
2020-01-07 14:28:20 +01:00
Molkobain
acf28ca4aa N°2306 - Security hardening 2020-01-07 13:54:16 +01:00
Eric
864ded2102 Refactor Core Update (+8 squashed commit)
Squashed commit:

[b907bb759] Refactor Core Update

[5da2473aa] Refactor Core Update

[3fce45615] Refactor Core Update

[5f050a828] Refactor Core Update

[4b9b85174] Refactor Core Update

[f637ed358] Refactor Core Update

[56543edce] Refactor Core Update

[7f06900ef] Refactor Core Update
2020-01-07 10:00:14 +01:00
Eric
5cdc58846b Allow browsing developed OQL class tree 2020-01-07 10:00:14 +01:00
Eric
45cd96eb0d More informative message when class does not exist 2020-01-07 10:00:14 +01:00
Eric
c8335499fd Allow browsing developed OQL class tree 2020-01-07 10:00:14 +01:00
Eric
7f3efe59ab Refactor Core Update (+3 squashed commit)
Squashed commit:

[e1cbfe93f] Refactor Core Update

[41ec2adf7] Refactor Core Update

[ca6cefca3] Refactor Core Update
2020-01-07 10:00:13 +01:00
bruno DA SILVA
69551378c2 n°524 - password policy
- ajax message is now translated in the user's language
 - prevent the form submission if the password policy is not respected
2020-01-06 18:33:47 +01:00
odain
f3fd4bde87 💚 2020-01-06 16:09:41 +01:00
bruno DA SILVA
c115f64cb5 N°2154 - Security breach 2020-01-06 15:31:31 +01:00
Stephen Abello
ee61c1e8fb N°524: Fix style for inputs' feedback on "change password" page 2020-01-06 13:51:40 +01:00
bruno DA SILVA
e716fb118b N°2574 - enable Password expiry 2020-01-06 12:14:34 +01:00
bruno DA SILVA
b0c76346a5 N° 524 - password policy
better colors for : "change pwd" page: add feedback during the password typing
2020-01-06 11:45:48 +01:00
Pierre Goiffon
56807fd941 Person sample file : fix Descartes email
Fix typo introduced in 906e309791
2020-01-06 11:17:57 +01:00
Molkobain
b56f248b79 👥 Add Pimkie to our contributors list (BR / IT translations) 2020-01-06 09:50:15 +01:00
bruno DA SILVA
7a85201a07 524 - password policy
"change pwd" page: add feedback during the password typing
2020-01-06 09:31:28 +01:00
Purple Grape
97ebffd5fb improved chinese translations
1 improved chinese translations
2 fix some missing enries
3 correct line number against english language
2020-01-06 08:43:25 +01:00
Eric
46c239c211 typo 2020-01-03 16:40:49 +01:00
Vincent Dumas
906e309791 Replace Erri De Luca by René Descartes 2020-01-03 11:10:44 +01:00
bruno DA SILVA
4ad1ca0fc6 add option classmap-authoritative to composer.json 2020-01-02 14:19:00 +01:00
bruno DA SILVA
015955f396 N°2306 - Security hardening 2019-12-30 17:31:50 +01:00
Pierre Goiffon
9bee1905c8 N°2329 PHP 7.4 compat : remove get_magic_quotes_gpc/get_magic_quotes_runtime calls
Methods are now deprecated and since PHP 5.4 were always returning false
2019-12-24 17:30:12 +01:00
Pierre Goiffon
8ab157eae4 N°2329 PHP 7.4 compat, AttributeDefinition : fix visibilities of members called by AttributeDefinition::__construct
Not enough to get rid of child classes constructors though :/
2019-12-24 15:28:36 +01:00
Molkobain
17978b829b Internal: Simplify classes FQN 2019-12-24 15:08:45 +01:00
Molkobain
4ddb23cd7c N°2654 - Portal: Fix filter on external key when coming from filter brick 2019-12-24 15:08:45 +01:00
Pierre Goiffon
e27eb7419e N°2329 PHP 7.4 compat, AttributeDefinition : add __construct() to child classes
Shouldn't be necessary but if not present PHP 7.4.0/7.4.1 is crashing when executing new Attribute...(...)
2019-12-24 12:22:49 +01:00
Pierre Goiffon
64ef572429 🎨 AttributeDefinition : some little inspections fixes, and fix misordered function modifiers
According to PSR, we should use public static and not static public
See https://www.itophub.io/wiki/page?id=latest%3Acustomization%3Acoding_standards
2019-12-24 12:22:49 +01:00
Pierre Goiffon
2f81e0fd6f N°2329 PHP 7.4 compat : remove deprecated array with curly braces 2019-12-23 18:44:52 +01:00
odain
987f1f7dbf N°2568 - Log_KPI viewer in the console - Fix broken links 2019-12-23 17:17:10 +01:00
Pierre Goiffon
b53c91f7f3 Merge remote-tracking branch 'origin/master' into develop
# Conflicts:
#	Jenkinsfile
#	setup/setuputils.class.inc.php
2019-12-23 11:34:55 +01:00
Pierre Goiffon
5fce2a2c1c Setup : fix MySQL TLS wiki URL 2019-12-23 11:27:56 +01:00
Pierre Goiffon
13d31ac211 utils::GetDefaultUrlAppRoot : make comparison case insentitive, add a test 2019-12-23 11:06:29 +01:00
Pierre Goiffon
57ae29cf2f \SetupPage::error : remove "error" title as existing calls already add it 2019-12-23 09:54:07 +01:00
Pierre Goiffon
0b3895e39e Core update : fix CanUpdateCore result never displayed on server with warning enabled
Was caused by a call to :
\Combodo\iTop\FilesInformation\Service\FilesInformationUtils::Scan
With path set to ''. Made from :
\Combodo\iTop\FilesInformation\Service\FilesInformation::CanUpdateCore
2019-12-20 18:37:51 +01:00
Pierre Goiffon
0d231d9b94 N°2651 Remove lib test files from index 2019-12-20 17:07:20 +01:00
Molkobain
27a6abeeb3 Internal: Add Benjamin to the sample data to welcome him! 2019-12-20 12:21:02 +01:00
Pierre Goiffon
c75e6960a7 N°2651 Remove lib test files from index 2019-12-20 11:57:18 +01:00
Pierre Goiffon
4766ca3fd0 N°2650 fix run_query error handling incompatible with PHP < 7.3.0 2019-12-20 09:21:00 +01:00
odain
523dd97eca N°2570 Update iTop license list 2019-12-19 16:40:17 +01:00
bruno DA SILVA
c09bd2bfc6 2626 - log modularity: filterable logs using minimal log level per channel
🔊 Adding log level Trace, which is not logged by default (as for Debug)
2019-12-19 11:17:18 +01:00
Molkobain
bd662eaf19 Update README to add 2.7.0-beta section 2019-12-18 16:47:11 +01:00
Pierre Goiffon
ff75ecfe27 💄 Setup : add styling on prerequisites summary title 2019-12-18 11:12:21 +01:00
Pierre Goiffon
54f8b74383 📝 restore WizardStep documentation
Do not add documentation in a doc block containing @copyright O:)
2019-12-18 11:05:41 +01:00
Pierre Goiffon
18a506673f 💄 Setup : restore label{ cursor:pointer;} 2019-12-18 10:44:28 +01:00
Pierre Goiffon
03b8ed5ce4 Merge branch 'support/2.6.2' 2019-10-07 09:41:08 +02:00
Pierre Goiffon
a625733885 👷 Jenkins : fix jenkinsfile filename case 2019-09-10 14:23:36 +02:00
2692 changed files with 45736 additions and 144176 deletions

View File

@@ -23,7 +23,7 @@ Some iTop specific tags were added :
### known limitations:
#### `@see` tags must be very specific:
* always prefix class members with `ClassName::`
* always prefix class members (attributes or methods) with `ClassName::` (do not use self)
* for methods always suffix them with `()`,
* do not reference variables since they are not documented. If you have to, always prefix them with `$`

3015
.doc/composer.lock generated Normal file

File diff suppressed because it is too large Load Diff

4
.gitignore vendored
View File

@@ -41,6 +41,10 @@ test/vendor/*
!/.idea/inspectionProfiles
!/.idea/inspectionProfiles/*
# doc. generation
/.doc/vendor
#phpdocumentor temp file
ast.dump

View File

@@ -71,6 +71,7 @@
<inspection_tool class="HtmlRequiredAltAttribute" enabled="true" level="WEAK WARNING" enabled_by_default="true" />
<inspection_tool class="HtmlRequiredLangAttribute" enabled="true" level="WEAK WARNING" enabled_by_default="true" />
<inspection_tool class="InconsistentLineSeparators" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="IsNullFunctionUsageInspection" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="MysqlParsingInspection" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="PhpComposerExtensionStubsInspection" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="PhpIncludeInspection" enabled="true" level="WEAK WARNING" enabled_by_default="true" />

6
.make/README.md Normal file
View File

@@ -0,0 +1,6 @@
= Make Doc =
.make folder is meant to gather tools for releasing process. Maybe other new purposes will come as well....
== license ==
- updateLicenses.php: used to update community-licenses.xml easily based on composer.json files
- sortLicenceXml.php: used to sort licenses based on scope + product name

View File

@@ -0,0 +1,98 @@
<?php
/**
* Copyright (C) 2010-2020 Combodo SARL
*
* This file is part of iTop.
*
* iTop is free software; you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* iTop 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with iTop. If not, see <http: *www.gnu.org/licenses/>
*
*/
$iTopFolder = __DIR__ . "/../../" ;
require_once ("$iTopFolder/approot.inc.php");
$sApproot = APPROOT;
$aTrace = array();
$aParamsConfig = array(
'composer-path' => array(
'default' => 'composer.phar',
)
);
$aParamsConfigNotFound = array_flip(array_keys($aParamsConfig));
$aGivenArgs = $argv;
unset($aGivenArgs[0]);
$aParams = array();
foreach ($aParamsConfig as $sParam => $aConfig)
{
$bParamsFound = false;
foreach ($aGivenArgs as $sGivenArg)
{
if (preg_match("/--$sParam(?:=(?<value>.*))?$/", $sGivenArg, $aMatches))
{
$aParams[$sParam] =
isset($aMatches['value'])
? $aMatches['value']
: true
;
$bParamsFound = true;
unset($aGivenArgs[$sGivenArg]);
}
}
if ($bParamsFound)
{
unset($aParamsConfigNotFound[$sParam]);
}
}
foreach ($aParamsConfigNotFound as $sParamsConfigNotFound => $void)
{
if (isset($aParamsConfig[$sParamsConfigNotFound]['default']))
{
$aParams[$sParamsConfigNotFound] = $aParamsConfig[$sParamsConfigNotFound]['default'];
$aTrace[] = "\e[1;30mUsing default value '{$aParams[$sParamsConfigNotFound]}' for '$sParamsConfigNotFound'\e[0m\n";
continue;
}
die("Missing '$sParamsConfigNotFound'");
}
echo "This command aims at helping you find upgradable dependencies\n";
echo "\e[0;33mBeware of the version colored in orange, they probably introduce BC breaks!\e[0m\n";
$sCommand = "{$aParams['composer-path']} show -loD --working-dir=$sApproot --ansi";
$execCode = exec($sCommand, $output);
$sOutput = implode("\n", $output)."\n";
if (!$execCode)
{
echo "\e[41mFailed to execute '$sCommand'\e[0m\n";
echo "Trace: \n".implode("\n", $aTrace);
}
else
{
$iCountDepdendenciesFound = count($output);
$iCountBc = substr_count($sOutput, '[33m');
echo sprintf("Found \033[44m%d\033[0m upgradable dependencies, including \e[41m%s BC break\e[0m 😱 :\n\n", $iCountDepdendenciesFound, $iCountBc);
}
echo $sOutput;

View File

@@ -0,0 +1,57 @@
<?php
/**
* Copyright (C) 2010-2020 Combodo SARL
*
* This file is part of iTop.
*
* iTop is free software; you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* iTop 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with iTop. If not, see <http: *www.gnu.org/licenses/>
*
*/
use Combodo\iTop\Composer\iTopComposer;
$iTopFolder = __DIR__ . "/../../" ;
require_once ("$iTopFolder/approot.inc.php");
require_once (APPROOT."/setup/setuputils.class.inc.php");
if (php_sapi_name() !== 'cli')
{
throw new \Exception('This script can only run from CLI');
}
clearstatcache();
$oiTopComposer = new iTopComposer();
$aDeniedButStillPresent = $oiTopComposer->ListDeniedButStillPresent();
foreach ($aDeniedButStillPresent as $sDir)
{
if (! preg_match('#[tT]ests?/?$#', $sDir))
{
echo "\nfound INVALID denied test dir: '$sDir'\n";
throw new \Exception("$sDir must end with /Test/ or /test/");
}
try
{
SetupUtils::rrmdir($sDir);
echo "Remove denied test dir: '$sDir'\n";
}
catch (\Exception $e)
{
echo "\nFAILED to remove denied test dir: '$sDir'\n";
}
}

View File

@@ -0,0 +1,90 @@
#/bin/bash
#git diff --name-status 2.6.2..HEAD js |grep 'A\sjs/' |awk -F/ '{printf("lib/%s/%s\n",$2,$3)}'|sort |uniq >/tmp/toto
#git diff --name-status 2.6.2..HEAD lib |grep 'A\slib/' |awk -F/ '{printf("lib/%s/%s\n",$2,$3)}'|sort |uniq >/tmp/toto
function HELP(){
echo " Syntax: bash $0 /var/www/html/iTop"
}
if [ $# -eq 0 ]
then
echo "no iTop path provided"
HELP
exit 1
fi
iTopPath=$1
if [ ! -d $iTopPath ]
then
echo "$iTopPath is not an iTop path."
HELP
exit 1
fi
echo "<?xml version=\"1.0\"?>
<licenses>"
for subfolder in lib datamodels
do
for l in $(find $iTopPath/$subfolder/ -name composer.json|sed 's|/composer.json||')
do
if [ ! -d $l ]
then
continue
fi
if [ "$subfolder" == "datamodels" ]
then
if [ $(find $l -name module*.php|wc -l) -ne 0 -o $(echo "$l"|grep -c "itop-portal-base") -ne 0 ]
then
continue
fi
fi
dir=$(dirname $(dirname $l))
prod=$(echo $l| sed "s|$dir/||1")
echo $l $subfolder
lictype=$(cd $l && composer licenses --format json |jq .license[] |sed 's|\"||g')
authors=""
if [ -f $l/composer.json ]
then
author_nb=$(grep -c authors $l/composer.json|sed 's| ||g')
if [ "x$author_nb" != "x0" ]
then
OLDIFS=$IFS
IFS=$'\n'
for a in $(cat $l/composer.json |jq .authors[].name|sed 's|\"||g')
do
authors="$authors$a - "
done
authors="$authors#"
authors=$(echo $authors |sed 's| - #||')
IFS=$OLDIFS
fi
fi
lic=""
for licf in $(find $l -name LICEN*)
do
lic=$(cat $licf)
break
done
#if [ "x$lic" == "x" ]
#then
# echo "============== no license found $l"
#fi
echo " <license>
<product scope=\"$subfolder\">$prod</product>
<author>$authors</author>
<license_type>$lictype</license_type>
<text><![CDATA[
$lic
]]></text>
</license>"
done
done
echo "</licenses>"

View File

@@ -0,0 +1,64 @@
<?php
/**
* script used to sort license file (usefull for autogeneration)
* Example:
*/
$iTopFolder = __DIR__ . "/../../" ;
$xmlFilePath = $iTopFolder . "setup/licenses/community-licenses.xml";
$dom = new DOMDocument();
$dom->load($xmlFilePath);
$xp = new DOMXPath($dom);
$licenseList = $xp->query('/licenses/license');
$licenses = iterator_to_array($licenseList);
function get_scope($product_node)
{
$scope = $product_node->getAttribute("scope");
if ($scope === "")
{ //put iTop first
return "aaaaaaaaa";
}
return $scope;
}
function get_product_node($license_node)
{
foreach ($license_node->childNodes as $child)
{
if (is_a($child, 'DomElement') && $child->tagName === "product")
{
return $child;
}
}
return null;
}
function sort_by_product($a, $b)
{
$aProductNode = get_product_node($a);
$bProductNode = get_product_node($b);
$res = strcmp(get_scope($aProductNode), get_scope($bProductNode));
if ($res !== 0)
{
return $res;
}
//sort on node product name
return strcmp($aProductNode->nodeValue, $bProductNode->nodeValue);
}
usort($licenses, 'sort_by_product');
$newdom = new DOMDocument("1.0");
$newdom->formatOutput = true;
$root = $newdom->createElement("licenses");
$newdom->appendChild($root);
foreach ($licenses as $b) {
$node = $newdom->importNode($b,true);
$root->appendChild($newdom->importNode($b,true));
}
$newdom->save($xmlFilePath);

View File

@@ -0,0 +1,89 @@
<?php
/**
* script used to sort license file (usefull for autogeneration)
* Example: php
*/
$iTopFolder = __DIR__ . "/../../" ;
$xmlFilePath = $iTopFolder . "setup/licenses/community-licenses.xml";
function get_scope($product_node)
{
$scope = $product_node->getAttribute("scope");
if ($scope === "")
{ //put iTop first
return "aaaaaaaaa";
}
return $scope;
}
function get_product_node($license_node)
{
foreach ($license_node->childNodes as $child)
{
if (is_a($child, 'DomElement') && $child->tagName === "product")
{
return $child;
}
}
return null;
}
function sort_by_product($a, $b)
{
$aProductNode = get_product_node($a);
$bProductNode = get_product_node($b);
$res = strcmp(get_scope($aProductNode), get_scope($bProductNode));
if ($res !== 0)
{
return $res;
}
//sort on node product name
return strcmp($aProductNode->nodeValue, $bProductNode->nodeValue);
}
function get_license_nodes($file_path)
{
$dom = new DOMDocument();
$dom->load($file_path);
$xp = new DOMXPath($dom);
$licenseList = $xp->query('/licenses/license');
$licenses = iterator_to_array($licenseList);
usort($licenses, 'sort_by_product');
return $licenses;
}
$old_licenses = get_license_nodes($xmlFilePath);
//generate file with updated licenses
$generated_license_file_path = __DIR__."/provfile.xml";
exec("bash " . __DIR__ . "/gen-community-license.sh $iTopFolder > ". $generated_license_file_path);
$new_licenses = get_license_nodes($generated_license_file_path);
exec("rm -f ". $generated_license_file_path);
foreach ($old_licenses as $b) {
$aProductNode = get_product_node($b);
if (get_scope($aProductNode) !== "lib" && get_scope($aProductNode) !== "datamodels" )
{
$new_licenses[] = $b;
}
}
usort($new_licenses, 'sort_by_product');
$new_dom = new DOMDocument("1.0");
$new_dom->formatOutput = true;
$root = $new_dom->createElement("licenses");
$new_dom->appendChild($root);
foreach ($new_licenses as $b) {
$node = $new_dom->importNode($b,true);
$root->appendChild($new_dom->importNode($b,true));
}
$new_dom->save($xmlFilePath);

View File

@@ -0,0 +1,47 @@
<?php
/*******************************************************************************
* Tool to automate version update before release
*
* Will update version in the following files :
*
* * datamodels/2.x/.../module.*.php
* * datamodels/2.x/version.xml
* * css/css-variables.scss $version
*
* Usage :
* `php .make\release\update-versions.php "2.7.0-rc"`
*
* @since 2.7.0
******************************************************************************/
require_once (__DIR__.'/../../approot.inc.php');
require_once (__DIR__.DIRECTORY_SEPARATOR.'update.classes.inc.php');
/** @var \FileVersionUpdater[] $aFilesUpdaters */
$aFilesUpdaters = array(
new iTopVersionFileUpdater(),
new CssVariablesFileUpdater(),
new DatamodelsModulesFiles(),
);
if (count($argv) === 1)
{
echo '/!\ You must pass the new version as parameter';
exit(1);
}
$sVersionLabel = $argv[1];
if (empty($sVersionLabel))
{
echo 'Version passed as parameter is empty !';
exit(2);
}
foreach ($aFilesUpdaters as $oFileVersionUpdater)
{
$oFileVersionUpdater->UpdateAllFiles($sVersionLabel);
}

View File

@@ -0,0 +1,36 @@
<?php
/*******************************************************************************
* Tool to automate datamodel version update in XML
*
* Will update version in the following files :
*
* datamodels/2.x/.../datamodel.*.xml
*
* Usage :
* `php .make\release\update-xml.php "1.7"`
*
* @since 2.7.0
******************************************************************************/
require_once (__DIR__.'/../../approot.inc.php');
require_once (__DIR__.DIRECTORY_SEPARATOR.'update.classes.inc.php');
if (count($argv) === 1)
{
echo '/!\ You must pass the new version as parameter';
exit(1);
}
$sVersionLabel = $argv[1];
if (empty($sVersionLabel))
{
echo 'Version passed as parameter is empty !';
exit(2);
}
$oFileVersionUpdater = new DatamodelsXmlFiles();
$oFileVersionUpdater->UpdateAllFiles($sVersionLabel);

View File

@@ -0,0 +1,169 @@
<?php
/*******************************************************************************
* Classes for updater tools
*
* @see update-versions.php
* @see update-xml.php
******************************************************************************/
require_once (__DIR__.'/../../approot.inc.php');
abstract class FileVersionUpdater
{
/**
* @return string[] full path of files to modify
*/
abstract public function GetFiles();
/**
* Warnign : will consume lots of memory on larger files !
*
* @param string $sVersionLabel
* @param string $sFileContent
* @param string $sFileFullPath
*
* @return string file content with replaced values
*/
abstract public function UpdateFileContent($sVersionLabel, $sFileContent, $sFileFullPath);
public function UpdateAllFiles($sVersionLabel)
{
$aFilesToUpdate = $this->GetFiles();
$sFileUpdaterName = get_class($this);
echo "# Updater : $sFileUpdaterName\n";
foreach ($aFilesToUpdate as $sFileToUpdateFullPath)
{
try
{
$sCurrentFileContent = file_get_contents($sFileToUpdateFullPath);
$sNewFileContent = $this->UpdateFileContent($sVersionLabel, $sCurrentFileContent, $sFileToUpdateFullPath);
file_put_contents($sFileToUpdateFullPath, $sNewFileContent);
echo " - $sFileToUpdateFullPath : OK !\n";
}
catch (Exception $e)
{
echo " - $sFileToUpdateFullPath : Error :(\n";
}
}
}
}
abstract class AbstractSingleFileVersionUpdater extends FileVersionUpdater
{
private $sFileToUpdate;
public function __construct($sFileToUpdate)
{
$this->sFileToUpdate = $sFileToUpdate;
}
public function GetFiles()
{
return array(APPROOT.$this->sFileToUpdate);
}
}
class iTopVersionFileUpdater extends AbstractSingleFileVersionUpdater
{
public function __construct()
{
parent::__construct('datamodels/2.x/version.xml');
}
/**
* @inheritDoc
*/
public function UpdateFileContent($sVersionLabel, $sFileContent, $sFileFullPath)
{
return preg_replace(
'/(<version>)[^<]*(<\/version>)/',
'${1}'.$sVersionLabel.'${2}',
$sFileContent
);
}
}
class CssVariablesFileUpdater extends AbstractSingleFileVersionUpdater
{
public function __construct()
{
parent::__construct('css/css-variables.scss');
}
/**
* @inheritDoc
*/
public function UpdateFileContent($sVersionLabel, $sFileContent, $sFileFullPath)
{
return preg_replace(
'/(\$version: "v)[^"]*(";)/',
'${1}'.$sVersionLabel.'${2}',
$sFileContent
);
}
}
abstract class AbstractGlobFileVersionUpdater extends FileVersionUpdater
{
protected $sGlobPattern;
public function __construct($sGlobPattern)
{
$this->sGlobPattern = $sGlobPattern;
}
public function GetFiles()
{
return glob($this->sGlobPattern);
}
}
class DatamodelsModulesFiles extends AbstractGlobFileVersionUpdater
{
public function __construct()
{
parent::__construct(APPROOT.'datamodels/2.x/*/module.*.php');
}
/**
* @inheritDoc
*/
public function UpdateFileContent($sVersionLabel, $sFileContent, $sFileFullPath)
{
$sModulePath = realpath($sFileFullPath);
$sModuleFileName = basename($sModulePath, 1);
$sModuleName = preg_replace('/[^.]+\.([^.]+)\.php/', '$1', $sModuleFileName);
return preg_replace(
"/('$sModuleName\/)[^']+(')/",
'${1}'.$sVersionLabel.'${2}',
$sFileContent
);
}
}
class DatamodelsXmlFiles extends AbstractGlobFileVersionUpdater
{
public function __construct()
{
parent::__construct(APPROOT.'datamodels/2.x/*/datamodel.*.xml');
}
/**
* @inheritDoc
*/
public function UpdateFileContent($sVersionLabel, $sFileContent, $sFileFullPath)
{
return preg_replace(
'/(<itop_design .* version=")[^"]+(">)/',
'${1}'.$sVersionLabel.'${2}',
$sFileContent
);
}
}

View File

@@ -10,8 +10,8 @@ Here are some guidelines that will help us integrate your work!
### Subjects
You are welcome to create pull requests on any of those subjects:
* 🐛 `:bug:` bug fix
* 🌐 `:globe_with_meridians:` translation / i18n / l10n
* 🐛 bug fix
* 🌐 translation / i18n / l10n
If you want to implement a **new feature**, please [create a corresponding ticket](https://sourceforge.net/p/itop/tickets/new/) for review.
If you ever want to begin implementation, do so in a fork, and add a link to the corresponding commits in the ticket.
@@ -27,7 +27,7 @@ If you have an idea you're sure would benefit to all of iTop users, you may
[create a corresponding ticket](https://sourceforge.net/p/itop/tickets/new/) to submit it, but be warned that there are lots of good
reasons to refuse such changes.
### License
### 📄 License
iTop is distributed under the AGPL-3.0 license (see the [license.txt] file),
your code must comply with this license.
@@ -37,7 +37,7 @@ If you want to use another license, you may [create an extension][wiki new ext].
[wiki new ext]: https://www.itophub.io/wiki/page?id=latest%3Acustomization%3Astart#by_writing_your_own_extension
## Branch model
## 🔀 Branch model
TL;DR:
> **create a fork from iTop main repository,
@@ -80,7 +80,7 @@ That may be different if you want to fix a bug, please use develop anyway and as
## Coding
### PHP styleguide
### 🎨 PHP styleguide
Please follow [our guidelines](https://www.itophub.io/wiki/page?id=latest%3Acustomization%3Acoding_standards).
@@ -88,7 +88,7 @@ Please follow [our guidelines](https://www.itophub.io/wiki/page?id=latest%3Acust
A [dedicated page](https://www.itophub.io/wiki/page?id=latest%3Acustomization%3Atranslation) is available in the official wiki.
### Tests
### Tests
Please create tests that covers as much as possible the code you're submitting.
@@ -117,7 +117,7 @@ Our tests are located in the `test/` directory, containing a PHPUnit config file
* 💄 `:lipstick:` Updating the UI and style files.
## Pull request
## 👥 Pull request
When your code is working, please:

View File

@@ -51,17 +51,30 @@ iTop also offers mass import tools and web services to integrate with your IT
## Last releases
### Versions 2.7.*
- 2.7.0-beta2 published on January 29, 2020
- [Changes since the previous version][62]
- [New features][63]
- [Migration notes][64]
- [Download iTop 2.7.0-beta2][65]
[62]: https://www.itophub.io/wiki/page?id=2_7_0:release:change_log
[63]: https://www.itophub.io/wiki/page?id=2_7_0:release:2_7_whats_new
[64]: https://www.itophub.io/wiki/page?id=2_7_0:install:260_to_270_migration_notes
[65]: https://sourceforge.net/projects/itop/files/itop/2.7.0-beta2
### Versions 2.6.*
- 2.6.0 published on January 9, 2019
- [Changes since the previous version][58]
- [New features][59]
- [Migration notes][60]
- [Download iTop 2.6.1][61]
- [Download iTop 2.6.3][61]
[58]: https://www.itophub.io/wiki/page?id=2_6_0:release:change_log
[59]: https://www.itophub.io/wiki/page?id=2_6_0:release:2_6_whats_new
[60]: https://www.itophub.io/wiki/page?id=2_6_0:install:250_to_260_migration_notes
[61]: https://sourceforge.net/projects/itop/files/itop/2.6.1
[61]: https://sourceforge.net/projects/itop/files/itop/2.6.3
### Versions 2.5.*
@@ -75,20 +88,6 @@ iTop also offers mass import tools and web services to integrate with your IT
[55]: https://www.itophub.io/wiki/page?id=2_5_0:release:2_5_whats_new
[56]: https://www.itophub.io/wiki/page?id=2_5_0:install:240_to_250_migration_notes
[57]: https://sourceforge.net/projects/itop/files/itop/2.5.1
### Versions 2.4.*
- 2.4.0 published on November 16, 2017
- [Changes since the previous version][50]
- [New features][51]
- [Migration notes][52]
- [Download iTop 2.4.1][53]
[50]: https://www.itophub.io/wiki/page?id=2_4_0:release:change_log
[51]: https://www.itophub.io/wiki/page?id=2_4_0:release:2_4_whats_new
[52]: https://www.itophub.io/wiki/page?id=2_4_0:install:230_to_240_migration_notes
[53]: https://sourceforge.net/projects/itop/files/itop/2.4.1
## About Us
@@ -112,6 +111,7 @@ We would like to give a special thank you to the people from the community who c
- Casteleyn, Thomas
- Castro, Randall Badilla
- Colantoni, Maria Laura
- Couronné, Guy
- Dvořák, Lukáš
- Goethals, Stefan
- Gumble, David
@@ -121,6 +121,7 @@ We would like to give a special thank you to the people from the community who c
- Konečný, Kamil
- Kunin, Vladimir
- Lassiter, Dennis
- Lazcano, Federico
- Lucas, Jonathan
- Malik, Remie
- Rosenke, Stephan
@@ -143,4 +144,5 @@ We would like to give a special thank you to the people from the community who c
### Companies
- Hardis
- ITOMIG
- Pimkie

View File

@@ -1,27 +1,20 @@
<?php
// Copyright (C) 2010-2013 Combodo SARL
//
// This file is part of iTop.
//
// iTop is free software; you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// iTop 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 Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with iTop. If not, see <http://www.gnu.org/licenses/>
/**
* UserRightsProfile
* User management Module, basing the right on profiles and a matrix (similar to UserRightsMatrix, but profiles and other decorations have been added)
* Copyright (C) 2013-2020 Combodo SARL
*
* @copyright Copyright (C) 2010-2012 Combodo SARL
* @license http://opensource.org/licenses/AGPL-3.0
* This file is part of iTop.
*
* iTop is free software; you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* iTop 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
*/
define('ADMIN_PROFILE_NAME', 'Administrator');
@@ -179,7 +172,7 @@ class URP_Profiles extends UserRightsBaseClassGUI
parent::DisplayBareRelations($oPage, $bEditMode);
if (!$bEditMode)
{
$oPage->SetCurrentTab(Dict::S('UI:UserManagement:GrantMatrix'));
$oPage->SetCurrentTab('UI:UserManagement:GrantMatrix');
$this->DoShowGrantSumary($oPage);
}
}

View File

@@ -1,27 +1,20 @@
<?php
// Copyright (C) 2010-2013 Combodo SARL
//
// This file is part of iTop.
//
// iTop is free software; you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// iTop 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 Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with iTop. If not, see <http://www.gnu.org/licenses/>
/**
* UserRightsProfile
* User management Module, basing the right on profiles and a matrix (similar to UserRightsMatrix, but profiles and other decorations have been added)
* Copyright (C) 2013-2020 Combodo SARL
*
* @copyright Copyright (C) 2010-2012 Combodo SARL
* @license http://opensource.org/licenses/AGPL-3.0
* This file is part of iTop.
*
* iTop is free software; you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* iTop 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
*/
define('ADMIN_PROFILE_NAME', 'Administrator');
@@ -321,7 +314,7 @@ class URP_Profiles extends UserRightsBaseClassGUI
parent::DisplayBareRelations($oPage, $bEditMode);
if (!$bEditMode)
{
$oPage->SetCurrentTab(Dict::S('UI:UserManagement:GrantMatrix'));
$oPage->SetCurrentTab('UI:UserManagement:GrantMatrix');
$this->DoShowGrantSumary($oPage);
}
}

View File

@@ -1,27 +1,20 @@
<?php
// Copyright (C) 2010-2012 Combodo SARL
//
// This file is part of iTop.
//
// iTop is free software; you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// iTop 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 Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with iTop. If not, see <http://www.gnu.org/licenses/>
/**
* UserRightsProjection
* User management Module, basing the right on profiles and a matrix (similar to UserRightsProfile, but enhanced with dimensions and projection of classes and profile over the dimensions)
* Copyright (C) 2013-2020 Combodo SARL
*
* @copyright Copyright (C) 2010-2012 Combodo SARL
* @license http://opensource.org/licenses/AGPL-3.0
* This file is part of iTop.
*
* iTop is free software; you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* iTop 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
*/
define('ADMIN_PROFILE_ID', 1);
@@ -153,7 +146,7 @@ class URP_Profiles extends UserRightsBaseClass
parent::DisplayBareRelations($oPage, $bEditMode);
if (!$bEditMode)
{
$oPage->SetCurrentTab(Dict::S('UI:UserManagement:GrantMatrix'));
$oPage->SetCurrentTab('UI:UserManagement:GrantMatrix');
$this->DoShowGrantSumary($oPage);
}
}

View File

@@ -1,27 +1,20 @@
<?php
// Copyright (C) 2010-2018 Combodo SARL
//
// This file is part of iTop.
//
// iTop is free software; you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// iTop 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 Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with iTop. If not, see <http://www.gnu.org/licenses/>
/**
* Simple web page with no includes, header or fancy formatting, useful to
* generate HTML fragments when called by an AJAX method
* Copyright (C) 2013-2020 Combodo SARL
*
* @copyright Copyright (C) 2010-2017 Combodo SARL
* @license http://opensource.org/licenses/AGPL-3.0
* This file is part of iTop.
*
* iTop is free software; you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* iTop 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
*/
require_once(APPROOT."/application/webpage.class.inc.php");
@@ -57,56 +50,67 @@ class ajax_page extends WebPage implements iTabbedPage
utils::InitArchiveMode();
}
/**
* @inheritDoc
* @throws \Exception
*/
public function AddTabContainer($sTabContainer, $sPrefix = '')
{
$this->add($this->m_oTabs->AddTabContainer($sTabContainer, $sPrefix));
}
public function AddToTab($sTabContainer, $sTabLabel, $sHtml)
/**
* @inheritDoc
* @throws \Exception
*/
public function AddToTab($sTabContainer, $sTabCode, $sHtml)
{
$this->add($this->m_oTabs->AddToTab($sTabContainer, $sTabLabel, $sHtml));
$this->add($this->m_oTabs->AddToTab($sTabContainer, $sTabCode, $sHtml));
}
/**
* @inheritDoc
*/
public function SetCurrentTabContainer($sTabContainer = '')
{
return $this->m_oTabs->SetCurrentTabContainer($sTabContainer);
}
public function SetCurrentTab($sTabLabel = '')
{
return $this->m_oTabs->SetCurrentTab($sTabLabel);
}
/**
* Add a tab which content will be loaded asynchronously via the supplied URL
*
* Limitations:
* Cross site scripting is not not allowed for security reasons. Use a normal tab with an IFRAME if you want to pull content from another server.
* Static content cannot be added inside such tabs.
*
* @param string $sTabLabel The (localised) label of the tab
* @param string $sUrl The URL to load (on the same server)
* @param boolean $bCache Whether or not to cache the content of the tab once it has been loaded. flase will cause the tab to be reloaded upon each activation.
* @since 2.0.3
* @inheritDoc
*/
public function AddAjaxTab($sTabLabel, $sUrl, $bCache = true)
public function SetCurrentTab($sTabCode = '', $sTabTitle = null)
{
$this->add($this->m_oTabs->AddAjaxTab($sTabLabel, $sUrl, $bCache));
return $this->m_oTabs->SetCurrentTab($sTabCode, $sTabTitle);
}
/**
* @inheritDoc
* @throws \Exception
*/
public function AddAjaxTab($sTabCode, $sUrl, $bCache = true, $sTabTitle = null)
{
$this->add($this->m_oTabs->AddAjaxTab($sTabCode, $sUrl, $bCache, $sTabTitle));
}
/**
* @inheritDoc
*/
public function GetCurrentTab()
{
return $this->m_oTabs->GetCurrentTab();
}
public function RemoveTab($sTabLabel, $sTabContainer = null)
/**
* @inheritDoc
*/
public function RemoveTab($sTabCode, $sTabContainer = null)
{
$this->m_oTabs->RemoveTab($sTabLabel, $sTabContainer);
$this->m_oTabs->RemoveTab($sTabCode, $sTabContainer);
}
/**
* Finds the tab whose title matches a given pattern
* @return mixed The name of the tab as a string or false if not found
* @inheritDoc
*/
public function FindTab($sPattern, $sTabContainer = null)
{
@@ -119,21 +123,23 @@ class ajax_page extends WebPage implements iTabbedPage
* that we are using this is not supported... TO DO upgrade
* the whole jquery bundle...
*/
public function SelectTab($sTabContainer, $sTabLabel)
public function SelectTab($sTabContainer, $sTabCode)
{
$this->add_ready_script($this->m_oTabs->SelectTab($sTabContainer, $sTabLabel));
$this->add_ready_script($this->m_oTabs->SelectTab($sTabContainer, $sTabCode));
}
/**
* @param string $sHtml
*/
public function AddToMenu($sHtml)
{
$this->m_sMenu .= $sHtml;
}
/**
* Echoes the content of the whole page
* @return void
*/
public function output()
/**
* @inheritDoc
*/
public function output()
{
if (!empty($this->sContentType))
{
@@ -310,7 +316,11 @@ EOF
{
}
public function add($sHtml)
/**
* @inheritDoc
* @throws \Exception
*/
public function add($sHtml)
{
if (($this->m_oTabs->GetCurrentTabContainer() != '') && ($this->m_oTabs->GetCurrentTab() != ''))
{
@@ -323,10 +333,9 @@ EOF
}
/**
* Records the current state of the 'html' part of the page output
* @return mixed The current state of the 'html' output
*/
public function start_capture()
* @inheritDoc
*/
public function start_capture()
{
$sCurrentTabContainer = $this->m_oTabs->GetCurrentTabContainer();
$sCurrentTab = $this->m_oTabs->GetCurrentTab();
@@ -342,13 +351,10 @@ EOF
}
}
/**
* Returns the part of the html output that occurred since the call to start_capture
* and removes this part from the current html output
* @param $offset mixed The value returned by start_capture
* @return string The part of the html output that was added since the call to start_capture
*/
public function end_capture($offset)
/**
* @inheritDoc
*/
public function end_capture($offset)
{
if (is_array($offset))
{
@@ -369,11 +375,9 @@ EOF
}
/**
* Add any text or HTML fragment (identified by an ID) at the end of the body of the page
* This is useful to add hidden content, DIVs or FORMs that should not
* be embedded into each other.
* @inheritDoc
*/
public function add_at_the_end($s_html, $sId = '')
public function add_at_the_end($s_html, $sId = '')
{
if ($sId != '')
{
@@ -381,27 +385,27 @@ EOF
}
$this->s_deferred_content .= $s_html;
}
/**
* Adds a script to be executed when the DOM is ready (typical JQuery use)
* NOT implemented in this version of the class.
* @return void
*/
* @inheritDoc
*/
public function add_ready_script($sScript)
{
$this->m_sReadyScript .= $sScript."\n";
}
/**
* Cannot be called in this context, since Ajax pages do not share
* any context with the calling page !!
* @inheritDoc
*/
public function GetUniqueId()
{
assert(false);
return 0;
}
/**
* @inheritDoc
*/
public static function FilterXSS($sHTML)
{
return str_ireplace(array('<script', '</script>'), array('<!-- <removed-script', '</removed-script> -->'), $sHTML);

View File

@@ -1,20 +1,22 @@
<?php
// Copyright (C) 2010-2015 Combodo SARL
//
// This file is part of iTop.
//
// iTop is free software; you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// iTop 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 Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with iTop. If not, see <http://www.gnu.org/licenses/>
/**
* Copyright (C) 2013-2020 Combodo SARL
*
* This file is part of iTop.
*
* iTop is free software; you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* iTop 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
*/
use Symfony\Component\DependencyInjection\Container;
@@ -30,6 +32,7 @@ require_once(APPROOT.'application/newsroomprovider.class.inc.php');
* @copyright Copyright (C) 2010-2012 Combodo SARL
* @license http://opensource.org/licenses/AGPL-3.0
* @package Extensibility
* @since 2.7.0
*/
interface iLoginExtension
{
@@ -41,6 +44,9 @@ interface iLoginExtension
public function ListSupportedLoginModes();
}
/**
* @since 2.7.0
*/
interface iLoginFSMExtension extends iLoginExtension
{
/**
@@ -58,8 +64,14 @@ interface iLoginFSMExtension extends iLoginExtension
public function LoginAction($sLoginState, &$iErrorCode);
}
/**
* @since 2.7.0
*/
abstract class AbstractLoginFSMExtension implements iLoginFSMExtension
{
/**
* @inheritDoc
*/
public abstract function ListSupportedLoginModes();
/**
@@ -151,27 +163,50 @@ abstract class AbstractLoginFSMExtension implements iLoginFSMExtension
return LoginWebPage::LOGIN_FSM_CONTINUE;
}
/**
* @param int $iErrorCode (see LoginWebPage::EXIT_CODE_...)
*
* @return int LoginWebPage::LOGIN_FSM_RETURN_ERROR, LoginWebPage::LOGIN_FSM_RETURN_OK or LoginWebPage::LOGIN_FSM_RETURN_IGNORE
*/
protected function OnCredentialsOK(&$iErrorCode)
{
return LoginWebPage::LOGIN_FSM_CONTINUE;
}
/**
* @param int $iErrorCode (see LoginWebPage::EXIT_CODE_...)
*
* @return int LoginWebPage::LOGIN_FSM_RETURN_ERROR, LoginWebPage::LOGIN_FSM_RETURN_OK or LoginWebPage::LOGIN_FSM_RETURN_IGNORE
*/
protected function OnUsersOK(&$iErrorCode)
{
return LoginWebPage::LOGIN_FSM_CONTINUE;
}
/**
* @param int $iErrorCode (see LoginWebPage::EXIT_CODE_...)
*
* @return int LoginWebPage::LOGIN_FSM_RETURN_ERROR, LoginWebPage::LOGIN_FSM_RETURN_OK or LoginWebPage::LOGIN_FSM_RETURN_IGNORE
*/
protected function OnConnected(&$iErrorCode)
{
return LoginWebPage::LOGIN_FSM_CONTINUE;
}
/**
* @param int $iErrorCode (see LoginWebPage::EXIT_CODE_...)
*
* @return int LoginWebPage::LOGIN_FSM_RETURN_ERROR, LoginWebPage::LOGIN_FSM_RETURN_OK or LoginWebPage::LOGIN_FSM_RETURN_IGNORE
*/
protected function OnError(&$iErrorCode)
{
return LoginWebPage::LOGIN_FSM_CONTINUE;
}
}
/**
* @since 2.7.0
*/
interface iLogoutExtension extends iLoginExtension
{
/**
@@ -180,6 +215,9 @@ interface iLogoutExtension extends iLoginExtension
public function LogoutAction();
}
/**
* @since 2.7.0
*/
interface iLoginUIExtension extends iLoginExtension
{
/**
@@ -188,7 +226,11 @@ interface iLoginUIExtension extends iLoginExtension
public function GetTwigContext();
}
/**
* @api
* @package Extensibility
* @since 2.7.0
*/
interface iPreferencesExtension
{
/**
@@ -206,6 +248,33 @@ interface iPreferencesExtension
public function ApplyPreferences(WebPage $oPage, $sOperation);
}
/**
* Extend this class instead of implementing iPreferencesExtension if you don't need to overload all methods
*
* @api
* @package Extensibility
* @since 2.7.0
*/
abstract class AbstractPreferencesExtension implements iPreferencesExtension
{
/**
* @inheritDoc
*/
public function DisplayPreferences(WebPage $oPage)
{
// Do nothing
}
/**
* @inheritDoc
*/
public function ApplyPreferences(WebPage $oPage, $sOperation)
{
// Do nothing
}
}
/**
* Implement this interface to change the behavior of the GUI for some objects.
*
@@ -366,6 +435,77 @@ interface iApplicationUIExtension
public function EnumAllowedActions(DBObjectSet $oSet);
}
/**
* Extend this class instead of implementing iApplicationUIExtension if you don't need to overload
*
* @api
* @package Extensibility
* @since 2.7.0
*/
abstract class AbstractApplicationUIExtension implements iApplicationUIExtension
{
/**
* @inheritDoc
*/
public function OnDisplayProperties($oObject, WebPage $oPage, $bEditMode = false)
{
}
/**
* @inheritDoc
*/
public function OnDisplayRelations($oObject, WebPage $oPage, $bEditMode = false)
{
}
/**
* @inheritDoc
*/
public function OnFormSubmit($oObject, $sFormPrefix = '')
{
}
/**
* @inheritDoc
*/
public function OnFormCancel($sTempId)
{
}
/**
* @inheritDoc
*/
public function EnumUsedAttributes($oObject)
{
return array();
}
/**
* @inheritDoc
*/
public function GetIcon($oObject)
{
return '';
}
/**
* @inheritDoc
*/
public function GetHilightClass($oObject)
{
return HILIGHT_CLASS_NONE;
}
/**
* @inheritDoc
*/
public function EnumAllowedActions(DBObjectSet $oSet)
{
return array();
}
}
/**
* Implement this interface to perform specific things when objects are manipulated
*
@@ -393,7 +533,7 @@ interface iApplicationObjectExtension
public function OnIsModified($oObject);
/**
* Invoked to determine wether an object can be written to the database
* Invoked to determine whether an object can be written to the database
*
* The GUI calls this verb and reports any issue.
* Anyhow, this API can be called in other contexts such as the CSV import tool.
@@ -421,7 +561,10 @@ interface iApplicationObjectExtension
* Invoked when an object is updated into the database. The method is called right <b>after</b> the object has been written to the
* database.
*
* Changes made to the object can be get using {@link $oObject::$m_aChanges}. Do not call {@link \DBObject::ListChanges} for this purpose !
* Useful methods you can call on $oObject :
*
* * {@see DBObject::ListPreviousValuesForUpdatedAttributes()} : list of changed attributes and their values before the change
* * {@see DBObject::Get()} : for a given attribute the new value that was persisted
*
* @param \cmdbAbstractObject $oObject The target object
* @param CMDBChange|null $oChange A change context. Since 2.0 it is fine to ignore it, as the framework does maintain this information
@@ -429,7 +572,7 @@ interface iApplicationObjectExtension
*
* @return void
*
* @since 2.7.0 N°2293 can access object changes by calling {@link $oObject::$m_aChanges}
* @since 2.7.0 N°2293 can access object changes by calling {@see DBObject::ListPreviousValuesForUpdatedAttributes()} on $oObject
*/
public function OnDBUpdate($oObject, $oChange = null);
@@ -460,6 +603,62 @@ interface iApplicationObjectExtension
public function OnDBDelete($oObject, $oChange = null);
}
/**
* Extend this class instead of iApplicationObjectExtension if you don't need to overload all methods
*
* @api
* @package Extensibility
* @since 2.7.0
*/
abstract class AbstractApplicationObjectExtension implements iApplicationObjectExtension
{
/**
* @inheritDoc
*/
public function OnIsModified($oObject)
{
return false;
}
/**
* @inheritDoc
*/
public function OnCheckToWrite($oObject)
{
return array();
}
/**
* @inheritDoc
*/
public function OnCheckToDelete($oObject)
{
return array();
}
/**
* @inheritDoc
*/
public function OnDBUpdate($oObject, $oChange = null)
{
}
/**
* @inheritDoc
*/
public function OnDBInsert($oObject, $oChange = null)
{
}
/**
* @inheritDoc
*/
public function OnDBDelete($oObject, $oChange = null)
{
}
}
/**
* New extension to add menu items in the "popup" menus inside iTop. Provides a greater flexibility than
* iApplicationUIExtension::EnumAllowedActions.
@@ -586,7 +785,6 @@ abstract class ApplicationPopupMenuItem
*
* @param string $sUID The unique identifier of this menu in iTop... make sure you pass something unique enough
* @param string $sLabel The display label of the menu (must be localized)
* @param array $aCssClasses The CSS classes to add to the menu
*/
public function __construct($sUID, $sLabel)
{
@@ -848,6 +1046,41 @@ interface iPageUIExtension
public function GetBannerHtml(iTopWebPage $oPage);
}
/**
* Extend this class instead of iPageUIExtension if you don't need to overload all methods
*
* @api
* @package Extensibility
* @since 2.7.0
*/
abstract class AbstractPageUIExtension implements iPageUIExtension
{
/**
* @inheritDoc
*/
public function GetNorthPaneHtml(iTopWebPage $oPage)
{
return '';
}
/**
* @inheritDoc
*/
public function GetSouthPaneHtml(iTopWebPage $oPage)
{
return '';
}
/**
* @inheritDoc
*/
public function GetBannerHtml(iTopWebPage $oPage)
{
return '';
}
}
/**
* Implement this interface to add content to any enhanced portal page
*
@@ -855,7 +1088,7 @@ interface iPageUIExtension
*
* @api
* @package Extensibility
* @since 2.4
* @since 2.4.0
*/
interface iPortalUIExtension
{
@@ -1079,11 +1312,6 @@ class RestResult
/**
* Default constructor - ok!
*
* @param DBObject $oObject The object being reported
* @param string $sAttCode The attribute code (must be valid)
*
* @return string A scalar representation of the value
*/
public function __construct()
{

View File

@@ -1,6 +1,6 @@
<?php
/**
* Copyright (C) 2013-2019 Combodo SARL
* Copyright (C) 2013-2020 Combodo SARL
*
* This file is part of iTop.
*
@@ -150,7 +150,7 @@ EOF
* @param bool $bMustNotExist
*
* @see SetSessionMessage()
* @since 2.6
* @since 2.6.0
*/
protected function SetSessionMessageFromInstance($sMessageId, $sMessage, $sSeverity, $fRank, $bMustNotExist = false)
{
@@ -204,6 +204,7 @@ EOF
* @throws \DictExceptionMissingString
* @throws \MySQLException
* @throws \OQLException
* @throws \Exception
*/
public function DisplayBareHeader(WebPage $oPage, $bEditMode = false)
{
@@ -494,7 +495,10 @@ EOF
$bCanEdit = UserRights::IsAdministrator() || $oAttDef->IsUserEditable();
$sDivId = $oDashboard->GetId();
$oPage->add('<div class="dashboard_contents" id="'.$sDivId.'">');
$aExtraParams = array('query_params' => $this->ToArgsForQuery());
$aExtraParams = array(
'query_params' => $this->ToArgsForQuery(),
'dashboard_div_id' => $sDivId,
);
$oDashboard->Render($oPage, false, $aExtraParams, $bCanEdit);
$oPage->add('</div>');
}
@@ -534,7 +538,7 @@ EOF
{
continue;
}
$oPage->AddAjaxTab($oAttDef->GetLabel(), utils::GetAbsoluteUrlAppRoot().'pages/ajax.render.php?operation=dashboard&class='.get_class($this).'&id='.$this->GetKey().'&attcode='.$oAttDef->GetCode());
$oPage->AddAjaxTab($oAttDef->GetLabel(), utils::GetAbsoluteUrlAppRoot().'pages/ajax.render.php?operation=dashboard&class='.get_class($this).'&id='.$this->GetKey().'&attcode='.$oAttDef->GetCode(), true, 'Class:'.$sClass.'/Attribute:'.$sAttCode);
continue;
}
@@ -556,7 +560,7 @@ EOF
{
$sCount = " ($iCount)";
}
$oPage->SetCurrentTab($oAttDef->GetLabel().$sCount);
$oPage->SetCurrentTab('Class:'.$sClass.'/Attribute:'.$sAttCode, $oAttDef->GetLabel().$sCount);
if ($this->IsNew())
{
$iFlags = $this->GetInitialStateAttributeFlags($sAttCode);
@@ -735,9 +739,9 @@ EOF
$oNotifSet = new DBObjectSet($aNotifSearches[$sNotifClass], array());
$iNotifsCount += $oNotifSet->Count();
}
// Display notifications regarding the object: on block per subclass to have the intersting columns
// Display notifications regarding the object: on block per subclass to have the interesting columns
$sCount = ($iNotifsCount > 0) ? ' ('.$iNotifsCount.')' : '';
$oPage->SetCurrentTab(Dict::S('UI:NotificationsTab').$sCount);
$oPage->SetCurrentTab('UI:NotificationsTab', Dict::S('UI:NotificationsTab').$sCount);
foreach($aNotificationClasses as $sNotifClass)
{
@@ -801,7 +805,7 @@ EOF
$aTableClasses[] = 'one-col-details';
}
$oPage->SetCurrentTab(Dict::S($sTab));
$oPage->SetCurrentTab($sTab);
$oPage->add('<table style="'.implode('; ', $aTableStyles).'" class="'.implode(' ',
$aTableClasses).'" data-mode="'.$sEditMode.'"><tr>');
foreach($aCols as $sColIndex => $aFieldsets)
@@ -838,6 +842,7 @@ EOF
{
$oAttDef = MetaModel::GetAttributeDef($sClass, $sAttCode);
$sAttDefClass = get_class($oAttDef);
$sAttLabel = MetaModel::GetLabel($sClass, $sAttCode);
if ($bEditMode)
{
@@ -940,6 +945,8 @@ EOF
// - Attribute code and AttributeDef. class
$val['attcode'] = $sAttCode;
$val['atttype'] = $sAttDefClass;
$val['attlabel'] = $sAttLabel;
$val['attflags'] = ($bEditMode) ? $this->GetFormAttributeFlags($sAttCode) : OPT_ATT_READONLY;
// - How the field should be rendered
$val['layout'] = (in_array($oAttDef->GetEditClass(), static::GetAttEditClassesToRenderAsLargeField())) ? 'large' : 'small';
@@ -1027,12 +1034,12 @@ HTML
/** @var \iTopWebPage $oPage */
$oPage->AddTabContainer(OBJECT_PROPERTIES_TAB);
$oPage->SetCurrentTabContainer(OBJECT_PROPERTIES_TAB);
$oPage->SetCurrentTab(Dict::S('UI:PropertiesTab'));
$oPage->SetCurrentTab('UI:PropertiesTab');
$this->DisplayBareProperties($oPage, $bEditMode);
$this->DisplayBareRelations($oPage, $bEditMode);
//$oPage->SetCurrentTab(Dict::S('UI:HistoryTab'));
//$oPage->SetCurrentTab('UI:HistoryTab');
//$this->DisplayBareHistory($oPage, $bEditMode);
$oPage->AddAjaxTab(Dict::S('UI:HistoryTab'),
$oPage->AddAjaxTab('UI:HistoryTab',
utils::GetAbsoluteUrlAppRoot().'pages/ajax.render.php?operation=history&class='.$sClass.'&id='.$iKey);
$oPage->add(<<<HTML
</div><!-- End of object-details -->
@@ -1047,6 +1054,7 @@ HTML
* @throws \ArchivedObjectException
* @throws \CoreException
* @throws \DictExceptionMissingString
* @throws \Exception
*/
public function DisplayPreview(WebPage $oPage)
{
@@ -2659,7 +2667,7 @@ EOF
$oPage->AddTabContainer(OBJECT_PROPERTIES_TAB, $sPrefix);
$oPage->SetCurrentTabContainer(OBJECT_PROPERTIES_TAB);
$oPage->SetCurrentTab(Dict::S('UI:PropertiesTab'));
$oPage->SetCurrentTab('UI:PropertiesTab');
$aFieldsMap = $this->DisplayBareProperties($oPage, true, $sPrefix, $aExtraParams);
if (!is_array($aFieldsMap))
@@ -2857,7 +2865,7 @@ EOF
* @throws \MySQLException
* @throws \MySQLHasGoneAwayException
*/
public function DisplayStimulusForm(WebPage $oPage, $sStimulus, $aPrefillFormParam = null)
public function DisplayStimulusForm(WebPage $oPage, $sStimulus, $aPrefillFormParam = null, $bDisplayBareProperties = true)
{
$sClass = get_class($this);
$iKey = $this->GetKey();
@@ -2918,7 +2926,7 @@ HTML
$aExpectedAttributes = $aPrefillFormParam['expected_attributes'];
}
$sButtonsPosition = MetaModel::GetConfig()->Get('buttons_position');
if ($sButtonsPosition == 'bottom')
if ($sButtonsPosition == 'bottom' && $bDisplayBareProperties)
{
// bottom: Displays the ticket details BEFORE the actions
$oPage->add('<div class="ui-widget-content">');
@@ -3029,7 +3037,7 @@ HTML
</div><!-- End of object-details -->
HTML
);
if ($sButtonsPosition != 'top')
if ($sButtonsPosition != 'top' && $bDisplayBareProperties)
{
// bottom or both: Displays the ticket details AFTER the actions
$oPage->add('<div class="ui-widget-content">');
@@ -3213,7 +3221,6 @@ EOF
$data = $oDoc->GetData();
switch ($oDoc->GetMimeType())
{
case 'text/html':
case 'text/xml':
$oPage->add("<iframe id='preview_$sAttCode' src=\"".utils::GetAbsoluteUrlAppRoot()."pages/ajax.render.php?operation=display_document&class=$sClass&id=$Id&field=$sAttCode\" width=\"100%\" height=\"400\">Loading...</iframe>\n");
break;
@@ -4018,7 +4025,7 @@ EOF
/**
* @param string $sMessageIdPrefix
*
* @since 2.6
* @since 2.6.0
*/
protected function SetWarningsAsSessionMessages($sMessageIdPrefix)
{
@@ -4197,8 +4204,9 @@ EOF
*/
public function DisplayCaseLog(WebPage $oPage, $sAttCode, $sComment = '', $sPrefix = '', $bEditMode = false)
{
$oPage->SetCurrentTab(Dict::S('UI:PropertiesTab'));
$oPage->SetCurrentTab('UI:PropertiesTab');
$sClass = get_class($this);
if ($this->IsNew())
{
$iFlags = $this->GetInitialStateAttributeFlags($sAttCode);
@@ -4207,6 +4215,7 @@ EOF
{
$iFlags = $this->GetAttributeFlags($sAttCode);
}
if ($iFlags & OPT_ATT_HIDDEN)
{
// The case log is hidden do nothing
@@ -4214,6 +4223,16 @@ EOF
else
{
$oAttDef = MetaModel::GetAttributeDef(get_class($this), $sAttCode);
$sAttDefClass = get_class($oAttDef);
$sAttLabel = $oAttDef->GetLabel();
$sAttMetaDataLabel = utils::HtmlEntities($sAttLabel);
$sAttMetaDataFlagHidden = (($iFlags & OPT_ATT_HIDDEN) === OPT_ATT_HIDDEN) ? 'true' : 'false';
$sAttMetaDataFlagReadOnly = (($iFlags & OPT_ATT_READONLY) === OPT_ATT_READONLY) ? 'true' : 'false';
$sAttMetaDataFlagMandatory = (($iFlags & OPT_ATT_MANDATORY) === OPT_ATT_MANDATORY) ? 'true' : 'false';
$sAttMetaDataFlagMustChange = (($iFlags & OPT_ATT_MUSTCHANGE) === OPT_ATT_MUSTCHANGE) ? 'true' : 'false';
$sAttMetaDataFlagMustPrompt = (($iFlags & OPT_ATT_MUSTPROMPT) === OPT_ATT_MUSTPROMPT) ? 'true' : 'false';
$sAttMetaDataFlagSlave = (($iFlags & OPT_ATT_SLAVE) === OPT_ATT_SLAVE) ? 'true' : 'false';
$sInputId = $this->m_iFormId.'_'.$sAttCode;
if ((!$bEditMode) || ($iFlags & (OPT_ATT_READONLY | OPT_ATT_SLAVE)))
@@ -4250,19 +4269,32 @@ EOF
$sValue = $this->Get($sAttCode);
$sDisplayValue = $this->GetEditValue($sAttCode);
$aArgs = array('this' => $this, 'formPrefix' => $sPrefix);
$sHTMLValue = '';
if ($sComment != '')
{
$sHTMLValue = '<span>'.$sComment.'</span><br/>';
}
$sHTMLValue .= "<span style=\"font-family:Tahoma,Verdana,Arial,Helvetica;font-size:12px;\" id=\"field_{$sInputId}\">".self::GetFormElementForField($oPage,
$sClass, $sAttCode, $oAttDef, $sValue, $sDisplayValue, $sInputId, '', $iFlags,
$aArgs).'</span>';
$sCommentAsHtml = ($sComment != '') ? '<span>'.$sComment.'</span><br/>' : '';
$sFieldAsHtml = self::GetFormElementForField($oPage, $sClass, $sAttCode, $oAttDef, $sValue, $sDisplayValue, $sInputId, '', $iFlags, $aArgs);
$sHTMLValue = <<<HTML
<div class="field_data">
<div class="field_value">
$sCommentAsHtml
$sFieldAsHtml
</div>
</div>
HTML;
$aFieldsMap[$sAttCode] = $sInputId;
}
$oPage->add('<fieldset><legend>'.$oAttDef->GetLabel().'</legend>');
$oPage->add($sHTMLValue);
$oPage->add('</fieldset>');
$oPage->add(<<<HTML
<fieldset>
<legend>{$sAttLabel}</legend>
<div class="field_container field_large" data-attribute-code="{$sAttCode}" data-attribute-type="{$sAttDefClass}" data-attribute-label="{$sAttMetaDataLabel}"
data-attribute-flag-hidden="{$sAttMetaDataFlagHidden}" data-attribute-flag-read-only="{$sAttMetaDataFlagReadOnly}" data-attribute-flag-mandatory="{$sAttMetaDataFlagMandatory}"
data-attribute-flag-must-change="{$sAttMetaDataFlagMustChange}" data-attribute-flag-must-prompt="{$sAttMetaDataFlagMustPrompt}" data-attribute-flag-slave="{$sAttMetaDataFlagSlave}">
{$sHTMLValue}
</div>
</fieldset>
HTML
);
}
}
@@ -5122,8 +5154,10 @@ EOF
*
* @return array
* @since 2.7.0
*
* @internal Do NOT use, this is experimental and most likely to be moved elsewhere when we find its rightful place.
*/
protected static function GetAttDefClassesToExcludeFromMarkupMetadataRawValue(){
public static function GetAttDefClassesToExcludeFromMarkupMetadataRawValue(){
return array(
'AttributeBlob',
'AttributeCustomFields',
@@ -5132,7 +5166,9 @@ EOF
'AttributeStopWatch',
'AttributeSubItem',
'AttributeTable',
'AttributeText'
'AttributeText',
'AttributePassword',
'AttributeOneWayPassword',
);
}
}

View File

@@ -176,12 +176,6 @@ abstract class Dashboard
protected function InitDashletFromDOMNode($oDomNode)
{
$sId = $oDomNode->getAttribute('id');
// To avoid collision with other dashlets with the same ID we suffix it. Collisions typically happen with extensions.
// Note: The check is done so we don't append it at each save of the dashboard.
if(strpos($sId, 'uniqid_') === false)
{
$sId .= '_uniqid_' . uniqid();
}
$sDashletType = $oDomNode->getAttribute('xsi:type');
@@ -341,6 +335,25 @@ abstract class Dashboard
}
/**
* @return mixed
*/
public function GetId()
{
return $this->sId;
}
/**
* Return a sanitize ID for usages in XML/HTML attributes
*
* @return string
* @since 2.7.0
*/
public function GetSanitizedId()
{
return utils::Sanitize($this->GetId(), '', 'element_identifier');
}
/**
* @return string
*/
@@ -516,10 +529,25 @@ EOF
*/
public function Render($oPage, $bEditMode = false, $aExtraParams = array(), $bCanEdit = true)
{
if (!array_key_exists('dashboard_div_id', $aExtraParams))
{
$aExtraParams['dashboard_div_id'] = utils::Sanitize($this->GetId(), '', 'element_identifier');
}
$oPage->add('<div class="dashboard-title-line"><div class="dashboard-title">'.htmlentities(Dict::S($this->sTitle), ENT_QUOTES, 'UTF-8', false).'</div></div>');
$oLayout = new $this->sLayoutClass;
/** @var \DashboardLayoutMultiCol $oLayout */
$oLayout = new $this->sLayoutClass();
foreach($this->aCells as $iCellIdx => $aDashlets)
{
foreach($aDashlets as $oDashlet)
{
$aDashletCoordinates = $oLayout->GetDashletCoordinates($iCellIdx);
$this->PrepareDashletForRendering($oDashlet, $aDashletCoordinates, $aExtraParams);
}
}
$oLayout->Render($oPage, $this->aCells, $bEditMode, $aExtraParams);
if (!$bEditMode)
{
@@ -561,19 +589,21 @@ EOF
// Toolbox/palette to edit the properties of each dashlet
$oPage->add('<div class="ui-widget-content ui-corner-all"><div class="ui-widget-header ui-corner-all" style="text-align:center; padding: 2px;">'.Dict::S('UI:DashboardEdit:DashletProperties').'</div>');
/** @var \DashboardLayoutMultiCol $oLayout */
$oLayout = new $this->sLayoutClass();
$oPage->add('<div id="dashlet_properties" style="text-align:center">');
foreach($this->aCells as $aCell)
foreach($this->aCells as $iCellIdx => $aCell)
{
/** @var \Dashlet $oDashlet */
foreach($aCell as $oDashlet)
{
$sId = $oDashlet->GetID();
if ($oDashlet->IsVisible())
{
$oPage->add('<div class="dashlet_properties" id="dashlet_properties_'.$sId.'" style="display:none">');
$oPage->add('<div class="dashlet_properties" id="dashlet_properties_'.$oDashlet->GetID().'" style="display:none">');
$oForm = $oDashlet->GetForm();
$this->SetFormParams($oForm, $aExtraParams);
$oForm->RenderAsPropertySheet($oPage, false, '.itop-dashboard');
$oForm->RenderAsPropertySheet($oPage, false, '.itop-dashboard');
$oPage->add('</div>');
}
}
@@ -633,6 +663,18 @@ EOF
return $iNewId + 1;
}
/**
* Prepare dashlet for rendering (eg. change its ID or another processing).
* Meant to be overloaded.
*
* @param \Dashlet $oDashlet
* @param array $aCoordinates
* @param array $aExtraParams
*
* @return void
*/
abstract protected function PrepareDashletForRendering(Dashlet $oDashlet, $aCoordinates, $aExtraParams = array());
/**
* @param \DesignerForm $oForm
* @param array $aExtraParams
@@ -657,11 +699,34 @@ EOF
}
/**
* @return mixed
* N°2634: we must have a unique id per dashlet!
* To avoid collision with other dashlets with the same ID we prefix it with row/cell id
* Collisions typically happen with extensions.
*
* @param boolean $bIsCustomized
* @param string $sDashboardDivId
* @param int $iRow
* @param int $iCol
* @param string $sDashletOrigId
*
* @return string
*
* @since 2.7.0 N°2735
*/
public function GetId()
public static function GetDashletUniqueId($bIsCustomized, $sDashboardDivId, $iRow, $iCol, $sDashletOrigId)
{
return $this->sId;
if(strpos($sDashletOrigId, '_ID_row') !== false)
{
return $sDashletOrigId;
}
$sDashletId = $sDashboardDivId."_ID_row".$iRow."_col".$iCol."_".$sDashletOrigId;
if ($bIsCustomized)
{
$sDashletId = 'CUSTOM_'.$sDashletId;
}
return $sDashletId;
}
}
@@ -670,12 +735,12 @@ EOF
*/
class RuntimeDashboard extends Dashboard
{
/** @var bool $bCustomized */
protected $bCustomized;
/** @var string $sDefinitionFile */
private $sDefinitionFile = '';
/** @var null $sReloadURL */
private $sReloadURL = null;
/** @var bool $bCustomized */
protected $bCustomized;
/**
* @inheritDoc
@@ -683,12 +748,22 @@ class RuntimeDashboard extends Dashboard
public function __construct($sId)
{
parent::__construct($sId);
$this->bCustomized = false;
$this->oMetaModel = new ModelReflectionRuntime();
$this->bCustomized = false;
}
/**
* @return bool
* @since 2.7.0
*/
public function GetCustomFlag()
{
return $this->bCustomized;
}
/**
* @param bool $bCustomized
* @since 2.7.0
*/
public function SetCustomFlag($bCustomized)
{
@@ -846,7 +921,7 @@ class RuntimeDashboard extends Dashboard
if (!$bEditMode && !$oPage->IsPrintableVersion())
{
$sId = $this->GetId();
$sDivId = preg_replace('/[^a-zA-Z0-9_]/', '', $sId);
$sDivId = utils::Sanitize($sId, '', 'element_identifier');
if ($this->GetAutoReload())
{
$sFile = addslashes($this->GetDefinitionFile());
@@ -909,7 +984,7 @@ EOF
protected function RenderSelector($oPage, $aAjaxParams = array())
{
$sId = $this->GetId();
$sDivId = preg_replace('/[^a-zA-Z0-9_]/', '', $sId);
$sDivId = utils::Sanitize($sId, '', 'element_identifier');
$sExtraParams = json_encode($aAjaxParams);
$sSelectorHtml = '<div class="dashboard-selector">';
@@ -1098,9 +1173,11 @@ EOF
{
$aRenderParams = $aExtraParams;
}
$aRenderParams['dashboard_div_id'] = $aExtraParams['dashboard_div_id'];
$sJSExtraParams = json_encode($aExtraParams);
$oPage->add('<div id="dashboard_editor">');
$oPage->add('<div class="ui-layout-center">');
$this->SetCustomFlag(true);
$this->Render($oPage, true, $aRenderParams);
$oPage->add('</div>');
$oPage->add('<div class="ui-layout-east">');
@@ -1129,7 +1206,7 @@ EOF
$sAutoApplyConfirmationMessage = addslashes(Dict::S('UI:AutoApplyConfirmationMessage'));
$oPage->add_ready_script(
<<<EOF
<<<JS
window.bLeavingOnUserAction = false;
$('#dashboard_editor').dialog({
@@ -1172,10 +1249,15 @@ $('#dashboard_editor').dialog({
});
$('#dashboard_editor .ui-layout-center').runtimedashboard({
dashboard_id: '$sId', layout_class: '$sLayoutClass', title: '$sTitle',
auto_reload: $sAutoReload, auto_reload_sec: $sAutoReloadSec,
submit_to: '$sUrl', submit_parameters: {operation: 'save_dashboard', file: '$sFile', extra_params: $sJSExtraParams, reload_url: '$sReloadURL'},
render_to: '$sUrl', render_parameters: {operation: 'render_dashboard', file: '$sFile', extra_params: $sJSExtraParams, reload_url: '$sReloadURL'},
dashboard_id: '$sId',
layout_class: '$sLayoutClass',
title: '$sTitle',
auto_reload: $sAutoReload,
auto_reload_sec: $sAutoReloadSec,
submit_to: '$sUrl',
submit_parameters: {operation: 'save_dashboard', file: '$sFile', extra_params: $sJSExtraParams, reload_url: '$sReloadURL'},
render_to: '$sUrl',
render_parameters: {operation: 'render_dashboard', file: '$sFile', extra_params: $sJSExtraParams, reload_url: '$sReloadURL'},
new_dashlet_parameters: {operation: 'new_dashlet'}
});
@@ -1214,7 +1296,7 @@ window.onbeforeunload = function() {
}
// return nothing ! safer for IE
};
EOF
JS
);
$oPage->add_ready_script("");
}
@@ -1354,7 +1436,7 @@ EOF
$sCancelButtonLabel = Dict::S('UI:Button:Cancel');
$oPage->add_ready_script(
<<<EOF
<<<JS
$('#dashlet_creation_dlg').dialog({
width: 600,
modal: true,
@@ -1383,7 +1465,7 @@ $('#dashlet_creation_dlg').dialog({
],
close: function() { $(this).remove(); }
});
EOF
JS
);
}
@@ -1418,4 +1500,83 @@ EOF
{
$this->sReloadURL = $sReloadURL;
}
/**
* @inheritDoc
*/
protected function PrepareDashletForRendering(Dashlet $oDashlet, $aCoordinates, $aExtraParams = array())
{
$sDashletIdOrig = $oDashlet->GetID();
$sDashboardSanitizedId = $this->GetSanitizedId();
$sDashletIdNew = static::GetDashletUniqueId($this->GetCustomFlag(), $sDashboardSanitizedId, $aCoordinates[1], $aCoordinates[0], $sDashletIdOrig);
$oDashlet->SetID($sDashletIdNew);
$this->UpdateDashletUserPrefs($oDashlet, $sDashletIdOrig, $aExtraParams);
}
/**
* Migrate dashlet specific prefs to new format
* Before 2.7.0 we were using the same for dashboard menu or dashboard attributes, standard or custom :
* <alias>-<class>|Dashlet<idx_dashlet>
* Since 2.7.0 it is the following, with a "CUSTOM_" prefix if necessary :
* * dashboard menu : <dashboard_id>_IDrow<row_idx>-col<col_idx>-<dashlet_idx>
* * dashboard attribute : <class>__<attcode>_IDrow<row_idx>-col<col_idx>-<dashlet_idx>
*
* @param \Dashlet $oDashlet
* @param string $sDashletIdOrig
*
* @param array $aExtraParams
*
* @since 2.7.0 N°2735
*/
private function UpdateDashletUserPrefs(Dashlet $oDashlet, $sDashletIdOrig, array $aExtraParams)
{
$bIsDashletWithListPref = ($oDashlet instanceof DashletObjectList);
if (!$bIsDashletWithListPref)
{
return;
}
/** @var \DashletObjectList $oDashlet */
$bDashletIdInNewFormat = ($sDashletIdOrig === $oDashlet->GetID());
if ($bDashletIdInNewFormat)
{
return;
}
$sNewPrefKey = $this->GetDashletObjectListAppUserPreferencesPrefix($oDashlet, $aExtraParams, $oDashlet->GetID());
$sPrefValueForNewKey = appUserPreferences::GetPref($sNewPrefKey, null);
$bHasPrefInNewFormat = ($sPrefValueForNewKey !== null);
if ($bHasPrefInNewFormat)
{
return;
}
$sOldPrefKey = $this->GetDashletObjectListAppUserPreferencesPrefix($oDashlet, $aExtraParams, $sDashletIdOrig);
$sPrefValueForOldKey = appUserPreferences::GetPref($sOldPrefKey, null);
$bHasPrefInOldFormat = ($sPrefValueForOldKey !== null);
if (!$bHasPrefInOldFormat)
{
return;
}
appUserPreferences::SetPref($sNewPrefKey, $sPrefValueForOldKey);
appUserPreferences::UnsetPref($sOldPrefKey);
}
/**
* @param \DashletObjectList $oDashlet
* @param array $aExtraParams
* @param string $sDashletId
*
* @return string
* @since 2.7.0
*/
private function GetDashletObjectListAppUserPreferencesPrefix(DashletObjectList $oDashlet, $aExtraParams, $sDashletId)
{
$sDataTableId = Dashlet::APPUSERPREFERENCES_PREFIX.$sDashletId;
$oFilter = $oDashlet->GetDBSearch($aExtraParams);
$aClassAliases = $oFilter->GetSelectedClasses();
return DataTableSettings::GetAppUserPreferenceKey($aClassAliases, $sDataTableId);
}
}

View File

@@ -26,14 +26,17 @@
abstract class DashboardLayout
{
public function __construct()
{
}
abstract public function Render($oPage, $aDashlets, $bEditMode = false);
/**
* @param int $iCellIdx
*
* @return array Containing 2 scalars: Col number and row number (starting from 0)
* @since 2.7.0
*/
abstract public function GetDashletCoordinates($iCellIdx);
static public function GetInfo()
public static function GetInfo()
{
return array(
'label' => '',
@@ -51,7 +54,7 @@ abstract class DashboardLayoutMultiCol extends DashboardLayout
{
$this->iNbCols = 1;
}
protected function TrimCell($aDashlets)
{
$aKeys = array_reverse(array_keys($aDashlets));
@@ -61,7 +64,7 @@ abstract class DashboardLayoutMultiCol extends DashboardLayout
{
/** @var \Dashlet $oDashlet */
$oDashlet = $aDashlets[$aKeys[$idx]];
if ($oDashlet->IsVisible())
if ($oDashlet::IsVisible())
{
$bNoVisibleFound = false;
}
@@ -110,20 +113,21 @@ abstract class DashboardLayoutMultiCol extends DashboardLayout
{
// Trim the list of cells to remove the invisible/empty ones at the end of the array
$aCells = $this->TrimCellsArray($aCells);
$oPage->add('<table style="width:100%;table-layout:fixed;"><tbody>');
$iCellIdx = 0;
$fColSize = 100 / $this->iNbCols;
$sStyle = $bEditMode ? 'border: 1px #ccc dashed; width:'.$fColSize.'%;' : 'width: '.$fColSize.'%;';
$sClass = $bEditMode ? 'layout_cell edit_mode' : 'dashboard';
$iNbRows = ceil(count($aCells) / $this->iNbCols);
for($iRows = 0; $iRows < $iNbRows; $iRows++)
{
$oPage->add('<tr>');
$oPage->add("<tr data-dashboard-row-index=\"$iRows\">");
for($iCols = 0; $iCols < $this->iNbCols; $iCols++)
{
$sCellClass = ($iRows == $iNbRows-1) ? $sClass.' layout_last_used_rank' : $sClass;
$oPage->add("<td style=\"$sStyle\" class=\"$sCellClass\" data-dashboard-cell-index=\"$iCellIdx\">");
$oPage->add("<td style=\"$sStyle\" class=\"$sCellClass\" data-dashboard-column-index=\"$iCols\" data-dashboard-cell-index=\"$iCellIdx\">");
if (array_key_exists($iCellIdx, $aCells))
{
$aDashlets = $aCells[$iCellIdx];
@@ -132,7 +136,7 @@ abstract class DashboardLayoutMultiCol extends DashboardLayout
/** @var \Dashlet $oDashlet */
foreach($aDashlets as $oDashlet)
{
if ($oDashlet->IsVisible())
if ($oDashlet::IsVisible())
{
$oDashlet->DoRender($oPage, $bEditMode, true /* bEnclosingDiv */, $aExtraParams);
}
@@ -155,10 +159,10 @@ abstract class DashboardLayoutMultiCol extends DashboardLayout
if ($bEditMode) // Add one row for extensibility
{
$sStyle = 'style="border: 1px #ccc dashed; width:'.$fColSize.'%;" class="layout_cell edit_mode layout_extension" data-dashboard-cell-index="'.$iCellIdx.'"';
$oPage->add('<tr>');
$oPage->add("<tr data-dashboard-row-index=\"$iRows\">");
for($iCols = 0; $iCols < $this->iNbCols; $iCols++)
{
$oPage->add("<td $sStyle>");
$oPage->add("<td $sStyle data-dashboard-column-index=\"$iCols\">");
$oPage->add('&nbsp;');
$oPage->add('</td>');
}
@@ -166,6 +170,17 @@ abstract class DashboardLayoutMultiCol extends DashboardLayout
}
$oPage->add('</tbody></table>');
}
/**
* @inheritDoc
*/
public function GetDashletCoordinates($iCellIdx)
{
$iColNumber = (int) $iCellIdx % $this->iNbCols;
$iRowNumber = (int) floor($iCellIdx / $this->iNbCols);
return array($iColNumber, $iRowNumber);
}
}
class DashboardLayoutOneCol extends DashboardLayoutMultiCol

View File

@@ -26,6 +26,9 @@ require_once(APPROOT.'application/forms.class.inc.php');
*/
abstract class Dashlet
{
/** @var string */
const APPUSERPREFERENCES_PREFIX = 'Dashlet';
protected $oModelReflection;
protected $sId;
protected $bRedrawNeeded;
@@ -514,7 +517,7 @@ EOF
*
* Used as a fallback in iTop for unknown dashlet classes.
*
* @since 2.5
* @since 2.5.0
*/
class DashletUnknown extends Dashlet
{
@@ -613,12 +616,12 @@ class DashletUnknown extends Dashlet
{
$aInfos = static::GetInfo();
$sIconUrl = utils::GetAbsoluteUrlAppRoot().$aInfos['icon'];
$sIconUrl = utils::HtmlEntities(utils::GetAbsoluteUrlAppRoot().$aInfos['icon']);
$sExplainText = ($bEditMode) ? Dict::Format('UI:DashletUnknown:RenderText:Edit', $this->GetDashletType()) : Dict::S('UI:DashletUnknown:RenderText:View');
$oPage->add('<div class="dashlet-content">');
$oPage->add('<div class="dashlet-ukn-image"><img src="'.utils::HtmlEntities($sIconUrl).'" /></div>');
$oPage->add('<div class="dashlet-ukn-image"><img src="'.$sIconUrl.'" /></div>');
$oPage->add('<div class="dashlet-ukn-text">'.$sExplainText.'</div>');
$oPage->add('</div>');
@@ -633,12 +636,12 @@ class DashletUnknown extends Dashlet
{
$aInfos = static::GetInfo();
$sIconUrl = utils::GetAbsoluteUrlAppRoot().$aInfos['icon'];
$sIconUrl = utils::HtmlEntities(utils::GetAbsoluteUrlAppRoot().$aInfos['icon']);
$sExplainText = Dict::Format('UI:DashletUnknown:RenderNoDataText:Edit', $this->GetDashletType());
$oPage->add('<div class="dashlet-content">');
$oPage->add('<div class="dashlet-ukn-image"><img src="'.utils::HtmlEntities($sIconUrl).'" /></div>');
$oPage->add('<div class="dashlet-ukn-image"><img src="'.$sIconUrl.'" /></div>');
$oPage->add('<div class="dashlet-ukn-text">'.$sExplainText.'</div>');
$oPage->add('</div>');
@@ -774,12 +777,12 @@ class DashletProxy extends DashletUnknown
{
$aInfos = static::GetInfo();
$sIconUrl = utils::GetAbsoluteUrlAppRoot().$aInfos['icon'];
$sIconUrl = utils::HtmlEntities(utils::GetAbsoluteUrlAppRoot().$aInfos['icon']);
$sExplainText = Dict::Format('UI:DashletProxy:RenderNoDataText:Edit', $this->GetDashletType());
$oPage->add('<div class="dashlet-content">');
$oPage->add('<div class="dashlet-pxy-image"><img src="'.utils::HtmlEntities($sIconUrl).'" /></div>');
$oPage->add('<div class="dashlet-pxy-image"><img src="'.$sIconUrl.'" /></div>');
$oPage->add('<div class="dashlet-pxy-text">'.$sExplainText.'</div>');
$oPage->add('</div>');
@@ -860,7 +863,7 @@ class DashletPlainText extends Dashlet
*/
public function Render($oPage, $bEditMode = false, $aExtraParams = array())
{
$sText = htmlentities($this->aProperties['text'], ENT_QUOTES, 'UTF-8');
$sText = utils::HtmlEntities($this->aProperties['text']);
$sText = str_replace(array("\r\n", "\n", "\r"), "<br/>", $sText);
$sId = 'plaintext_'.($bEditMode? 'edit_' : '').$this->sId;
@@ -913,15 +916,28 @@ class DashletObjectList extends Dashlet
public function Render($oPage, $bEditMode = false, $aExtraParams = array())
{
$sTitle = $this->aProperties['title'];
$sQuery = $this->aProperties['query'];
$sShowMenu = $this->aProperties['menu'] ? '1' : '0';
$oPage->add('<div class="dashlet-content">');
$sHtmlTitle = htmlentities(Dict::S($sTitle), ENT_QUOTES, 'UTF-8'); // done in the itop block
$sHtmlTitle = utils::HtmlEntities(Dict::S($sTitle)); // done in the itop block
if ($sHtmlTitle != '')
{
$oPage->add('<h1>'.$sHtmlTitle.'</h1>');
}
$oFilter = $this->GetDBSearch($aExtraParams);
$oBlock = new DisplayBlock($oFilter, 'list');
$aParams = array(
'menu' => $sShowMenu,
'table_id' => self::APPUSERPREFERENCES_PREFIX.$this->sId,
);
$sBlockId = 'block_'.$this->sId.($bEditMode ? '_edit' : ''); // make a unique id (edition occurring in the same DOM)
$oBlock->Display($oPage, $sBlockId, array_merge($aExtraParams, $aParams));
$oPage->add('</div>');
}
public function GetDBSearch($aExtraParams = array())
{
$sQuery = $this->aProperties['query'];
if (isset($aExtraParams['query_params']))
{
$aQueryParams = $aExtraParams['query_params'];
@@ -935,15 +951,8 @@ class DashletObjectList extends Dashlet
{
$aQueryParams = array();
}
$oFilter = DBObjectSearch::FromOQL($sQuery, $aQueryParams);
$oBlock = new DisplayBlock($oFilter, 'list');
$aParams = array(
'menu' => $sShowMenu,
'table_id' => 'Dashlet'.$this->sId,
);
$sBlockId = 'block_'.$this->sId.($bEditMode ? '_edit' : ''); // make a unique id (edition occurring in the same DOM)
$oBlock->Display($oPage, $sBlockId, array_merge($aExtraParams, $aParams));
$oPage->add('</div>');
return DBObjectSearch::FromOQL($sQuery, $aQueryParams);
}
/**
@@ -956,7 +965,7 @@ class DashletObjectList extends Dashlet
$bShowMenu = $this->aProperties['menu'];
$oPage->add('<div class="dashlet-content">');
$sHtmlTitle = htmlentities($this->oModelReflection->DictString($sTitle), ENT_QUOTES, 'UTF-8'); // done in the itop block
$sHtmlTitle = utils::HtmlEntities($this->oModelReflection->DictString($sTitle)); // done in the itop block
if ($sHtmlTitle != '')
{
$oPage->add('<h1>'.$sHtmlTitle.'</h1>');
@@ -1249,7 +1258,7 @@ abstract class DashletGroupBy extends Dashlet
case 'table':
default:
$sHtmlTitle = htmlentities(Dict::S($sTitle), ENT_QUOTES, 'UTF-8'); // done in the itop block
$sHtmlTitle = utils::HtmlEntities(Dict::S($sTitle)); // done in the itop block
$sType = 'count';
$aParams = array(
'group_by' => $this->sGroupByExpr,
@@ -1686,7 +1695,7 @@ class DashletGroupByPie extends DashletGroupBy
$sBlockId = 'block_fake_'.$this->sId.($bEditMode ? '_edit' : ''); // make a unique id (edition occuring in the same DOM)
$HTMLsTitle = ($sTitle != '') ? '<h1 style="text-align:center">'.htmlentities($sTitle, ENT_QUOTES, 'UTF-8').'</h1>' : '';
$HTMLsTitle = ($sTitle != '') ? '<h1 style="text-align:center">'.utils::HtmlEntities($sTitle).'</h1>' : '';
$oPage->add("<div style=\"background-color:#fff;padding:0.25em;\">$HTMLsTitle<div id=\"$sBlockId\" style=\"background-color:#fff;\"></div></div>");
$aDisplayValues = $this->MakeSimulatedData();
@@ -1758,7 +1767,7 @@ class DashletGroupByBars extends DashletGroupBy
$sBlockId = 'block_fake_'.$this->sId.($bEditMode ? '_edit' : ''); // make a unique id (edition occuring in the same DOM)
$HTMLsTitle = ($sTitle != '') ? '<h1 style="text-align:center">'.htmlentities($sTitle, ENT_QUOTES, 'UTF-8').'</h1>' : '';
$HTMLsTitle = ($sTitle != '') ? '<h1 style="text-align:center">'.utils::HtmlEntities($sTitle).'</h1>' : '';
$oPage->add("<div style=\"background-color:#fff;padding:0.25em;\">$HTMLsTitle<div id=\"$sBlockId\" style=\"background-color:#fff;\"></div></div>");
$aDisplayValues = $this->MakeSimulatedData();
@@ -1907,16 +1916,16 @@ class DashletHeaderStatic extends Dashlet
*/
public function Render($oPage, $bEditMode = false, $aExtraParams = array())
{
$sTitle = $this->aProperties['title'];
$sTitle = utils::HtmlEntities($this->aProperties['title']);
$sIcon = $this->aProperties['icon'];
$oIconSelect = $this->oModelReflection->GetIconSelectionField('icon');
$sIconPath = $oIconSelect->MakeFileUrl($sIcon);
$sIconPath = utils::HtmlEntities($oIconSelect->MakeFileUrl($sIcon));
$oPage->add('<div class="dashlet-content">');
$oPage->add('<div class="main_header">');
$oPage->add('<img src="'.utils::HtmlEntities($sIconPath).'">');
$oPage->add('<img src="'.$sIconPath.'">');
$oPage->add('<h1>'.$this->oModelReflection->DictString($sTitle).'</h1>');
$oPage->add('</div>');
@@ -2037,14 +2046,14 @@ class DashletHeaderDynamic extends Dashlet
*/
public function Render($oPage, $bEditMode = false, $aExtraParams = array())
{
$sTitle = $this->aProperties['title'];
$sTitle = utils::HtmlEntities($this->aProperties['title']);
$sIcon = $this->aProperties['icon'];
$sSubtitle = $this->aProperties['subtitle'];
$sSubtitle = utils::HtmlEntities($this->aProperties['subtitle']);
$sQuery = $this->aProperties['query'];
$sGroupBy = $this->aProperties['group_by'];
$oIconSelect = $this->oModelReflection->GetIconSelectionField('icon');
$sIconPath = $oIconSelect->MakeFileUrl($sIcon);
$sIconPath = utils::HtmlEntities($oIconSelect->MakeFileUrl($sIcon));
$aValues = $this->GetValues();
if (count($aValues) > 0)
@@ -2072,7 +2081,7 @@ class DashletHeaderDynamic extends Dashlet
$oPage->add('<div class="dashlet-content">');
$oPage->add('<div class="main_header">');
$oPage->add('<img src="'.utils::HtmlEntities($sIconPath).'">');
$oPage->add('<img src="'.$sIconPath.'">');
if (isset($aExtraParams['query_params']))
{
@@ -2101,9 +2110,9 @@ class DashletHeaderDynamic extends Dashlet
*/
public function RenderNoData($oPage, $bEditMode = false, $aExtraParams = array())
{
$sTitle = $this->aProperties['title'];
$sTitle = utils::HtmlEntities($this->aProperties['title']);
$sIcon = $this->aProperties['icon'];
$sSubtitle = $this->aProperties['subtitle'];
$sSubtitle = utils::HtmlEntities($this->aProperties['subtitle']);
$sQuery = $this->aProperties['query'];
$sGroupBy = $this->aProperties['group_by'];
@@ -2111,12 +2120,12 @@ class DashletHeaderDynamic extends Dashlet
$sClass = $oQuery->GetClass();
$oIconSelect = $this->oModelReflection->GetIconSelectionField('icon');
$sIconPath = $oIconSelect->MakeFileUrl($sIcon);
$sIconPath = utils::HtmlEntities($oIconSelect->MakeFileUrl($sIcon));
$oPage->add('<div class="dashlet-content">');
$oPage->add('<div class="main_header">');
$oPage->add('<img src="'.utils::HtmlEntities($sIconPath).'">');
$oPage->add('<img src="'.$sIconPath.'">');
$sBlockId = 'block_fake_'.$this->sId.($bEditMode ? '_edit' : ''); // make a unique id (edition occuring in the same DOM)
@@ -2147,8 +2156,8 @@ class DashletHeaderDynamic extends Dashlet
$sTitle = $this->oModelReflection->DictString($sTitle);
$sSubtitle = $this->oModelReflection->DictFormat($sSubtitle, $iTotal);
$oPage->add('<h1>'.$sTitle.'</h1>');
$oPage->add('<a class="summary">'.$sSubtitle.'</a>');
$oPage->add('<h1>'.utils::HtmlEntities($sTitle).'</h1>');
$oPage->add('<a class="summary">'.utils::HtmlEntities($sSubtitle).'</a>');
$oPage->add('</div>');
$oPage->add('</div>');

View File

@@ -15,7 +15,7 @@
<menu id="AdminTools" xsi:type="MenuGroup" _delta="define">
<rank>80</rank>
</menu>
<menu id="System" xsi:type="MenuGroup" _delta="define">
<menu id="SystemTools" xsi:type="MenuGroup" _delta="define">
<rank>100</rank>
<enable_class>ResourceSystemMenu</enable_class>
<enable_action>UR_ACTION_MODIFY</enable_action>

View File

@@ -1,6 +1,6 @@
<?php
/**
* Copyright (C) 2013-2019 Combodo SARL
* Copyright (C) 2013-2020 Combodo SARL
*
* This file is part of iTop.
*
@@ -443,24 +443,29 @@ EOF;
}
/**
* @param $aColumns
* @param $sSelectMode
* @param $bViewLink
* @param array $aColumns
* @param string $sSelectMode
* @param bool $bViewLink
*
* @return array
* @throws \CoreException
* @throws \DictExceptionMissingString
* @throws \Exception
*/
protected function GetHTMLTableConfig($aColumns, $sSelectMode, $bViewLink)
{
$aAttribs = array();
if ($sSelectMode == 'multiple')
{
$aAttribs['form::select'] = array('label' => "<input type=\"checkbox\" onClick=\"CheckAll('.selectList{$this->iListId}:not(:disabled)', this.checked);\" class=\"checkAll\"></input>", 'description' => Dict::S('UI:SelectAllToggle+'));
$aAttribs['form::select'] = array(
'label' => "<input type=\"checkbox\" onClick=\"CheckAll('.selectList{$this->iListId}:not(:disabled)', this.checked);\" class=\"checkAll\"></input>",
'description' => Dict::S('UI:SelectAllToggle+'),
'metadata' => array(),
);
}
else if ($sSelectMode == 'single')
{
$aAttribs['form::select'] = array('label' => "", 'description' => '');
$aAttribs['form::select'] = array('label' => '', 'description' => '', 'metadata' => array());
}
foreach($this->aClassAliases as $sAlias => $sClassName)
@@ -471,12 +476,33 @@ EOF;
{
if ($sAttCode == '_key_')
{
$aAttribs['key_'.$sAlias] = array('label' => MetaModel::GetName($sClassName), 'description' => '');
$sAttLabel = MetaModel::GetName($sClassName);
$aAttribs['key_'.$sAlias] = array(
'label' => $sAttLabel,
'description' => '',
'metadata' => array(
'object_class' => $sClassName,
'attribute_label' => $sAttLabel,
),
);
}
else
{
$oAttDef = MetaModel::GetAttributeDef($sClassName, $sAttCode);
$aAttribs[$sAttCode.'_'.$sAlias] = array('label' => MetaModel::GetLabel($sClassName, $sAttCode), 'description' => $oAttDef->GetOrderByHint());
$sAttDefClass = get_class($oAttDef);
$sAttLabel = MetaModel::GetLabel($sClassName, $sAttCode);
$aAttribs[$sAttCode.'_'.$sAlias] = array(
'label' => $sAttLabel,
'description' => $oAttDef->GetOrderByHint(),
'metadata' => array(
'object_class' => $sClassName,
'attribute_code' => $sAttCode,
'attribute_type' => $sAttDefClass,
'attribute_label' => $sAttLabel,
),
);
}
}
}
@@ -497,6 +523,7 @@ EOF;
* @throws \MissingQueryArgument
* @throws \MySQLException
* @throws \MySQLHasGoneAwayException
* @throws \Exception
*/
protected function GetHTMLTableValues($aColumns, $sSelectMode, $iPageSize, $bViewLink, $aExtraParams)
{
@@ -507,6 +534,7 @@ EOF;
}
$aValues = array();
$aAttDefsCache = array();
$this->oSet->Seek(0);
$iMaxObjects = $iPageSize;
while (($aObjects = $this->oSet->FetchAssoc()) && ($iMaxObjects != 0))
@@ -547,11 +575,41 @@ EOF;
{
if ($sAttCode == '_key_')
{
$aRow['key_'.$sAlias] = $aObjects[$sAlias]->GetHyperLink();
$aRow['key_'.$sAlias] = array(
'value_raw' => $aObjects[$sAlias]->GetKey(),
'value_html' => $aObjects[$sAlias]->GetHyperLink(),
);
}
else
{
$aRow[$sAttCode.'_'.$sAlias] = $aObjects[$sAlias]->GetAsHTML($sAttCode, $bLocalize);
// Prepare att. def. classes cache to avoid retrieving AttDef for each row
if(!isset($aAttDefsCache[$sClassName][$sAttCode]))
{
$aAttDefClassesCache[$sClassName][$sAttCode] = get_class(MetaModel::GetAttributeDef($sClassName, $sAttCode));
}
// Only retrieve raw (stored) value for simple fields
$bExcludeRawValue = false;
foreach (cmdbAbstractObject::GetAttDefClassesToExcludeFromMarkupMetadataRawValue() as $sAttDefClassToExclude)
{
if (is_a($aAttDefClassesCache[$sClassName][$sAttCode], $sAttDefClassToExclude, true))
{
$bExcludeRawValue = true;
break;
}
}
if($bExcludeRawValue)
{
$aRow[$sAttCode.'_'.$sAlias] = $aObjects[$sAlias]->GetAsHTML($sAttCode, $bLocalize);
}
else
{
$aRow[$sAttCode.'_'.$sAlias] = array(
'value_raw' => $aObjects[$sAlias]->Get($sAttCode),
'value_html' => $aObjects[$sAlias]->GetAsHTML($sAttCode, $bLocalize),
);
}
}
}
}
@@ -597,6 +655,7 @@ EOF;
* @throws \MissingQueryArgument
* @throws \MySQLException
* @throws \MySQLHasGoneAwayException
* @throws \Exception
*/
public function GetHTMLTable(WebPage $oPage, $aColumns, $sSelectMode, $iPageSize, $bViewLink, $aExtraParams)
{
@@ -609,7 +668,7 @@ EOF;
$aValues = $this->GetHTMLTableValues($aColumns, $sSelectMode, $iPageSize, $bViewLink, $aExtraParams);
$sHtml = '<table class="listContainer">';
$sHtml = '<table class="listContainer object-list">';
foreach($this->oSet->GetFilter()->GetInternalParams() as $sName => $sValue)
{
@@ -1099,9 +1158,18 @@ class DataTableSettings implements Serializable
*/
protected function GetPrefsKey($sTableId = null)
{
if ($sTableId == null) $sTableId = '*';
return static::GetAppUserPreferenceKey($this->aClassAliases, $sTableId);
}
public static function GetAppUserPreferenceKey($aClassAliases, $sTableId)
{
if ($sTableId === null)
{
$sTableId = '*';
}
$aKeys = array();
foreach($this->aClassAliases as $sAlias => $sClass)
foreach($aClassAliases as $sAlias => $sClass)
{
$aKeys[] = $sAlias.'-'.$sClass;
}

View File

@@ -1,6 +1,6 @@
<?php
/**
* Copyright (C) 2013-2019 Combodo SARL
* Copyright (C) 2013-2020 Combodo SARL
*
* This file is part of iTop.
*
@@ -51,7 +51,7 @@ class iTopWebPage extends NiceWebPage implements iTabbedPage
{
parent::__construct($sTitle, $bPrintable);
$this->m_oTabs = new TabManager();
$this->oCtx = new ContextTag('GUI:Console');
$this->oCtx = new ContextTag(ContextTag::TAG_CONSOLE);
ApplicationContext::SetUrlMakerClass('iTopStandardURLMaker');
@@ -80,6 +80,7 @@ class iTopWebPage extends NiceWebPage implements iTabbedPage
$this->add_linked_stylesheet("../css/c3.min.css");
$this->add_linked_stylesheet("../css/font-awesome/css/all.min.css");
$this->add_linked_stylesheet("../css/font-awesome/css/v4-shims.min.css");
$this->add_linked_stylesheet("../js/ckeditor/plugins/codesnippet/lib/highlight/styles/obsidian.css");
$this->add_linked_script('../js/jquery.layout.min.js');
$this->add_linked_script('../js/jquery.ba-bbq.min.js');
@@ -93,6 +94,7 @@ class iTopWebPage extends NiceWebPage implements iTabbedPage
$this->add_linked_script("../js/swfobject.js");
$this->add_linked_script("../js/ckeditor/ckeditor.js");
$this->add_linked_script("../js/ckeditor/adapters/jquery.js");
$this->add_linked_script("../js/ckeditor/plugins/codesnippet/lib/highlight/highlight.pack.js");
$this->add_linked_script("../js/jquery.qtip-1.0.min.js");
$this->add_linked_script('../js/property_field.js');
$this->add_linked_script('../js/icon_select.js');
@@ -350,6 +352,20 @@ JS
.magnificPopup({type: 'image', closeOnContentClick: true });
JS
);
// Highlight code content created with CKEditor
$this->add_ready_script(
<<<JS
// Highlight code content for HTML AttributeText
$("[data-attribute-type='AttributeText'] .HTML pre").each(function(i, block) {
hljs.highlightBlock(block);
});
// Highlight code content for CaseLogs
$("[data-attribute-type='AttributeCaseLog'] .caselog_entry_html pre").each(function(i, block) {
hljs.highlightBlock(block);
});
JS
);
$this->add_init_script(
<<< JS
@@ -894,8 +910,7 @@ EOF
/**
* Outputs (via some echo) the complete HTML page by assembling all its elements
*
* @inheritDoc
* @throws \Exception
*/
public function output()
@@ -1167,7 +1182,7 @@ EOF;
}
// Render the revision number
if (ITOP_REVISION == '$WCREV$')
if (ITOP_REVISION == 'svn')
{
// This is NOT a version built using the buil system, just display the main version
$sVersionString = Dict::Format('UI:iTopVersion:Short', ITOP_APPLICATION, ITOP_VERSION);
@@ -1467,10 +1482,7 @@ EOF;
}
/**
* @param string $sTabContainer
* @param string $sPrefix
*
* @return mixed|void
* @inheritDoc
* @throws \Exception
*/
public function AddTabContainer($sTabContainer, $sPrefix = '')
@@ -1479,22 +1491,16 @@ EOF;
}
/**
* @param string $sTabContainer
* @param string $sTabLabel
* @param string $sHtml
*
* @return mixed|void
* @inheritDoc
* @throws \Exception
*/
public function AddToTab($sTabContainer, $sTabLabel, $sHtml)
public function AddToTab($sTabContainer, $sTabCode, $sHtml)
{
$this->add($this->m_oTabs->AddToTab($sTabContainer, $sTabLabel, $sHtml));
$this->add($this->m_oTabs->AddToTab($sTabContainer, $sTabCode, $sHtml));
}
/**
* @param string $sTabContainer
*
* @return mixed|string
* @inheritDoc
*/
public function SetCurrentTabContainer($sTabContainer = '')
{
@@ -1502,36 +1508,25 @@ EOF;
}
/**
* @param string $sTabLabel
*
* @return mixed|string
* @inheritDoc
*/
public function SetCurrentTab($sTabLabel = '')
public function SetCurrentTab($sTabCode = '', $sTabTitle = null)
{
return $this->m_oTabs->SetCurrentTab($sTabLabel);
return $this->m_oTabs->SetCurrentTab($sTabCode, $sTabTitle);
}
/**
* Add a tab which content will be loaded asynchronously via the supplied URL
*
* Limitations:
* Cross site scripting is not not allowed for security reasons. Use a normal tab with an IFRAME if you want to pull content from
* another server. Static content cannot be added inside such tabs.
*
* @param string $sTabLabel The (localised) label of the tab
* @param string $sUrl The URL to load (on the same server)
* @param boolean $bCache Whether or not to cache the content of the tab once it has been loaded. flase will cause the tab to be
* reloaded upon each activation.
*
* @inheritDoc
* @throws \Exception
* @since 2.0.3
*/
public function AddAjaxTab($sTabLabel, $sUrl, $bCache = true)
public function AddAjaxTab($sTabCode, $sUrl, $bCache = true, $sTabTitle = null)
{
$this->add($this->m_oTabs->AddAjaxTab($sTabLabel, $sUrl, $bCache));
$this->add($this->m_oTabs->AddAjaxTab($sTabCode, $sUrl, $bCache, $sTabTitle));
}
/**
* @return string
* @inheritDoc
*/
public function GetCurrentTab()
{
@@ -1539,23 +1534,15 @@ EOF;
}
/**
* @param string $sTabLabel
* @param string|null $sTabContainer
*
* @return mixed|void
* @inheritDoc
*/
public function RemoveTab($sTabLabel, $sTabContainer = null)
public function RemoveTab($sTabCode, $sTabContainer = null)
{
$this->m_oTabs->RemoveTab($sTabLabel, $sTabContainer);
$this->m_oTabs->RemoveTab($sTabCode, $sTabContainer);
}
/**
* Finds the tab whose title matches a given pattern
*
* @param string $sPattern
* @param string|null $sTabContainer
*
* @return mixed The name of the tab as a string or false if not found
* @inheritDoc
*/
public function FindTab($sPattern, $sTabContainer = null)
{
@@ -1569,17 +1556,15 @@ EOF;
* the whole jquery bundle...
*
* @param string $sTabContainer
* @param string $sTabLabel
* @param string $sTabCode
*/
public function SelectTab($sTabContainer, $sTabLabel)
public function SelectTab($sTabContainer, $sTabCode)
{
$this->add_ready_script($this->m_oTabs->SelectTab($sTabContainer, $sTabLabel));
$this->add_ready_script($this->m_oTabs->SelectTab($sTabContainer, $sTabCode));
}
/**
* @param string $sHtml
*
* @return mixed|void
* @inheritDoc
* @throws \Exception
*/
public function add($sHtml)
@@ -1595,9 +1580,7 @@ EOF;
}
/**
* Records the current state of the 'html' part of the page output
*
* @return mixed The current state of the 'html' output
* @inheritDoc
*/
public function start_capture()
{
@@ -1617,12 +1600,7 @@ EOF;
}
/**
* Returns the part of the html output that occurred since the call to start_capture
* and removes this part from the current html output
*
* @param $offset mixed The value returned by start_capture
*
* @return string The part of the html output that was added since the call to start_capture
* @inheritDoc
*/
public function end_capture($offset)
{
@@ -1683,7 +1661,7 @@ EOF;
* @param string $sCssClasses CSS classes to add to the container
*
* @throws \Exception
* @since 2.6
* @since 2.6.0
*/
public function AddHeaderMessage($sContent, $sCssClasses = 'message_info')
{

View File

@@ -1,12 +1,15 @@
<?php
/**
* Class LoginForm
*
* @copyright Copyright (C) 2010-2019 Combodo SARL
* @license http://opensource.org/licenses/AGPL-3.0
*/
/**
* Class LoginForm
*
* @since 2.7.0
*/
class LoginForm extends AbstractLoginFSMExtension implements iLoginUIExtension
{
private $bForceFormOnError = false;
@@ -21,6 +24,9 @@ class LoginForm extends AbstractLoginFSMExtension implements iLoginUIExtension
return array('form');
}
/**
* @inheritDoc
*/
protected function OnReadCredentials(&$iErrorCode)
{
if (!isset($_SESSION['login_mode']) || ($_SESSION['login_mode'] == 'form'))
@@ -51,6 +57,9 @@ class LoginForm extends AbstractLoginFSMExtension implements iLoginUIExtension
return LoginWebPage::LOGIN_FSM_CONTINUE;
}
/**
* @inheritDoc
*/
protected function OnCheckCredentials(&$iErrorCode)
{
if ($_SESSION['login_mode'] == 'form')
@@ -66,6 +75,9 @@ class LoginForm extends AbstractLoginFSMExtension implements iLoginUIExtension
return LoginWebPage::LOGIN_FSM_CONTINUE;
}
/**
* @inheritDoc
*/
protected function OnCredentialsOK(&$iErrorCode)
{
if ($_SESSION['login_mode'] == 'form')
@@ -85,6 +97,9 @@ class LoginForm extends AbstractLoginFSMExtension implements iLoginUIExtension
return LoginWebPage::LOGIN_FSM_CONTINUE;
}
/**
* @inheritDoc
*/
protected function OnError(&$iErrorCode)
{
if ($_SESSION['login_mode'] == 'form')
@@ -94,6 +109,9 @@ class LoginForm extends AbstractLoginFSMExtension implements iLoginUIExtension
return LoginWebPage::LOGIN_FSM_CONTINUE;
}
/**
* @inheritDoc
*/
protected function OnConnected(&$iErrorCode)
{
if ($_SESSION['login_mode'] == 'form')
@@ -105,7 +123,7 @@ class LoginForm extends AbstractLoginFSMExtension implements iLoginUIExtension
}
/**
* @return LoginTwigContext
* @inheritDoc
* @throws \Exception
*/
public function GetTwigContext()
@@ -125,7 +143,7 @@ class LoginForm extends AbstractLoginFSMExtension implements iLoginUIExtension
$oLoginContext->AddBlockExtension('login_submit', new LoginBlockExtension('extensionblock/loginformsubmit.html.twig'));
$oLoginContext->AddBlockExtension('login_form_footer', new LoginBlockExtension('extensionblock/loginformfooter.html.twig'));
$bEnableResetPassword = empty(MetaModel::GetConfig()->Get('forgot_password')) ? true : MetaModel::GetConfig()->Get('forgot_password');
$bEnableResetPassword = MetaModel::GetConfig()->Get('forgot_password');
$sResetPasswordUrl = utils::GetAbsoluteUrlAppRoot() . 'pages/UI.php?loginop=forgot_pwd';
$aData = array(
'bEnableResetPassword' => $bEnableResetPassword,

View File

@@ -189,51 +189,52 @@ class LoginWebPage extends NiceWebPage
UserRights::Login($sAuthUser); // Set the user's language (if possible!)
/** @var UserInternal $oUser */
$oUser = UserRights::GetUserObject();
if ($oUser == null)
if ($oUser != null)
{
throw new Exception(Dict::Format('UI:ResetPwd-Error-WrongLogin', $sAuthUser));
}
if (!MetaModel::IsValidAttCode(get_class($oUser), 'reset_pwd_token'))
{
throw new Exception(Dict::S('UI:ResetPwd-Error-NotPossible'));
}
if (!$oUser->CanChangePassword())
{
throw new Exception(Dict::S('UI:ResetPwd-Error-FixedPwd'));
}
$sTo = $oUser->GetResetPasswordEmail(); // throws Exceptions if not allowed
if ($sTo == '')
{
throw new Exception(Dict::S('UI:ResetPwd-Error-NoEmail'));
if (!MetaModel::IsValidAttCode(get_class($oUser), 'reset_pwd_token'))
{
throw new Exception(Dict::S('UI:ResetPwd-Error-NotPossible'));
}
if (!$oUser->CanChangePassword())
{
throw new Exception(Dict::S('UI:ResetPwd-Error-FixedPwd'));
}
$sTo = $oUser->GetResetPasswordEmail(); // throws Exceptions if not allowed
if ($sTo == '')
{
throw new Exception(Dict::S('UI:ResetPwd-Error-NoEmail'));
}
// This token allows the user to change the password without knowing the previous one
$sToken = substr(md5(APPROOT.uniqid()), 0, 16);
$oUser->Set('reset_pwd_token', $sToken);
CMDBObject::SetTrackInfo('Reset password');
$oUser->AllowWrite(true);
$oUser->DBUpdate();
$oEmail = new Email();
$oEmail->SetRecipientTO($sTo);
$sFrom = MetaModel::GetConfig()->Get('forgot_password_from');
$oEmail->SetRecipientFrom($sFrom);
$oEmail->SetSubject(Dict::S('UI:ResetPwd-EmailSubject', $oUser->Get('login')));
$sResetUrl = utils::GetAbsoluteUrlAppRoot().'pages/UI.php?loginop=reset_pwd&auth_user='.urlencode($oUser->Get('login')).'&token='.urlencode($sToken);
$oEmail->SetBody(Dict::Format('UI:ResetPwd-EmailBody', $sResetUrl, $oUser->Get('login')));
$iRes = $oEmail->Send($aIssues, true /* force synchronous exec */);
switch ($iRes)
{
//case EMAIL_SEND_PENDING:
case EMAIL_SEND_OK:
break;
case EMAIL_SEND_ERROR:
default:
IssueLog::Error('Failed to send the email with the NEW password for '.$oUser->Get('friendlyname').': '.implode(', ', $aIssues));
throw new Exception(Dict::S('UI:ResetPwd-Error-Send'));
}
}
// This token allows the user to change the password without knowing the previous one
$sToken = substr(md5(APPROOT.uniqid()), 0, 16);
$oUser->Set('reset_pwd_token', $sToken);
CMDBObject::SetTrackInfo('Reset password');
$oUser->AllowWrite(true);
$oUser->DBUpdate();
$oEmail = new Email();
$oEmail->SetRecipientTO($sTo);
$sFrom = MetaModel::GetConfig()->Get('forgot_password_from');
$oEmail->SetRecipientFrom($sFrom);
$oEmail->SetSubject(Dict::S('UI:ResetPwd-EmailSubject', $oUser->Get('login')));
$sResetUrl = utils::GetAbsoluteUrlAppRoot().'pages/UI.php?loginop=reset_pwd&auth_user='.urlencode($oUser->Get('login')).'&token='.urlencode($sToken);
$oEmail->SetBody(Dict::Format('UI:ResetPwd-EmailBody', $sResetUrl, $oUser->Get('login')));
$iRes = $oEmail->Send($aIssues, true /* force synchronous exec */);
switch ($iRes)
{
//case EMAIL_SEND_PENDING:
case EMAIL_SEND_OK:
break;
case EMAIL_SEND_ERROR:
default:
IssueLog::Error('Failed to send the email with the NEW password for '.$oUser->Get('friendlyname').': '.implode(', ', $aIssues));
throw new Exception(Dict::S('UI:ResetPwd-Error-Send'));
}
$oTwigContext = new LoginTwigRenderer();
$aVars = $oTwigContext->GetDefaultVars();
@@ -315,7 +316,7 @@ class LoginWebPage extends NiceWebPage
{
$aVars['bBadToken'] = false;
// Trash the token and change the password
$oUser->Set('reset_pwd_token', '');
$oUser->Set('reset_pwd_token', new ormPassword());
$oUser->AllowWrite(true);
$oUser->SetPassword($sNewPwd); // Does record the change into the DB
$aVars['sUrl'] = utils::GetAbsoluteUrlAppRoot();
@@ -789,12 +790,13 @@ class LoginWebPage extends NiceWebPage
$oPerson = null;
try
{
$sOrigin = 'External User provisioning';
CMDBObject::SetTrackOrigin('custom-extension');
$sInfo = 'External User provisioning';
if (isset($_SESSION['login_mode']))
{
$sOrigin .= " ({$_SESSION['login_mode']})";
$sInfo .= " ({$_SESSION['login_mode']})";
}
CMDBObject::SetTrackOrigin($sOrigin);
CMDBObject::SetTrackInfo($sInfo);
$oPerson = MetaModel::NewObject('Person');
$oPerson->Set('first_name', $sFirstName);
@@ -842,6 +844,14 @@ class LoginWebPage extends NiceWebPage
$oUser = null;
try
{
CMDBObject::SetTrackOrigin('custom-extension');
$sInfo = 'External User provisioning';
if (isset($_SESSION['login_mode']))
{
$sInfo .= " ({$_SESSION['login_mode']})";
}
CMDBObject::SetTrackInfo($sInfo);
$oUser = MetaModel::GetObjectByName('UserExternal', $sAuthUser, false);
if (is_null($oUser))
{
@@ -929,6 +939,7 @@ class LoginWebPage extends NiceWebPage
{
// No rights to be here, redirect to the portal
header('Location: '.$ret);
die();
}
}
return self::EXIT_CODE_OK;
@@ -1061,6 +1072,24 @@ class LoginWebPage extends NiceWebPage
exit;
}
}
else if ($operation == 'check_pwd_policy')
{
$sAuthUser = $_SESSION['auth_user'];
UserRights::Login($sAuthUser); // Set the user's language
$aPwdMap = array();
foreach (array('new_pwd', 'retype_new_pwd') as $postedPwd)
{
$oUser = new UserLocal();
$oUser->ValidatePassword($_POST[$postedPwd]);
$aPwdMap[$postedPwd]['isValid'] = $oUser->IsPasswordValid();
$aPwdMap[$postedPwd]['message'] = $oUser->getPasswordValidityMessage();
}
echo json_encode($aPwdMap);
die();
}
if ($operation == 'do_change_pwd')
{
if (isset($_SESSION['auth_user']))

View File

@@ -263,12 +263,15 @@ EOF
/**
* Handles the display of the sub-menus (called recursively if necessary)
*
* @param \WebPage $oPage
* @param array $aMenus
* @param array $aExtraParams
* @param int $iActiveMenu
*
* @return true if the currently selected menu is one of the submenus
* @throws DictExceptionMissingString
* @throws \Exception
*/
static protected function DisplaySubMenu($oPage, $aMenus, $aExtraParams, $iActiveMenu = -1)
{
@@ -301,7 +304,7 @@ EOF
$sLinkTarget .= ' target="_blank"';
}
$sURL = '"'.$oMenu->GetHyperlink($aExtraParams).'"'.$sLinkTarget;
$sTitle = $oMenu->GetTitle();
$sTitle = utils::HtmlEntities($oMenu->GetTitle());
$sItemHtml .= "<a href={$sURL}>{$sTitle}</a>";
}
else
@@ -692,8 +695,8 @@ abstract class MenuNode
public abstract function RenderContent(WebPage $oPage, $aExtraParams = array());
/**
* @param $sHyperlink
* @param $aExtraParams
* @param string $sHyperlink
* @param array $aExtraParams
* @return string
*/
protected function AddParams($sHyperlink, $aExtraParams)
@@ -737,8 +740,7 @@ class MenuGroup extends MenuNode
}
/**
* @param WebPage $oPage
* @param array $aExtraParams
* @inheritDoc
*/
public function RenderContent(WebPage $oPage, $aExtraParams = array())
{
@@ -776,8 +778,7 @@ class TemplateMenuNode extends MenuNode
}
/**
* @param $aExtraParams
* @return string
* @inheritDoc
*/
public function GetHyperlink($aExtraParams)
{
@@ -786,10 +787,8 @@ class TemplateMenuNode extends MenuNode
}
/**
* @param WebPage $oPage
* @param array $aExtraParams
* @return mixed|void
* @throws DictExceptionMissingString
* @inheritDoc
* @throws \Exception
*/
public function RenderContent(WebPage $oPage, $aExtraParams = array())
{
@@ -878,12 +877,8 @@ class OQLMenuNode extends MenuNode
}
/**
* @param WebPage $oPage
* @param array $aExtraParams
* @return mixed|void
* @throws CoreException
* @throws DictExceptionMissingString
* @throws OQLException
* @inheritDoc
* @throws \Exception
*/
public function RenderContent(WebPage $oPage, $aExtraParams = array())
{
@@ -902,11 +897,11 @@ class OQLMenuNode extends MenuNode
}
/**
* @param $sOql
* @param $sTitle
* @param $sUsageId
* @param $bSearchPane
* @param $bSearchOpen
* @param string $sOql
* @param string $sTitle
* @param string $sUsageId
* @param bool $bSearchPane
* @param bool $bSearchOpen
* @param WebPage $oPage
* @param array $aExtraParams
* @param bool $bEnableBreadcrumb
@@ -927,7 +922,7 @@ class OQLMenuNode extends MenuNode
$oBlock->Display($oPage, 0);
}
$oPage->add("<p class=\"page-header\">$sIcon ".Dict::S($sTitle)."</p>");
$oPage->add("<p class=\"page-header\">$sIcon ".utils::HtmlEntities(Dict::S($sTitle))."</p>");
$aParams = array_merge(array('table_id' => $sUsageId), $aExtraParams);
$oBlock = new DisplayBlock($oSearch, 'list', false /* Asynchronous */, $aParams);
@@ -979,11 +974,9 @@ class SearchMenuNode extends MenuNode
}
/**
* @param \iTopWebPage $oPage
* @param array $aExtraParams
* @return mixed|void
* @throws DictExceptionMissingString
* @throws Exception
* @inheritDoc
* @throws \DictExceptionMissingString
* @throws \Exception
*/
public function RenderContent(WebPage $oPage, $aExtraParams = array())
{
@@ -1039,8 +1032,7 @@ class WebPageMenuNode extends MenuNode
}
/**
* @param array $aExtraParams
* @return string
* @inheritDoc
*/
public function GetHyperlink($aExtraParams)
{
@@ -1048,14 +1040,16 @@ class WebPageMenuNode extends MenuNode
return $this->AddParams( $this->sHyperlink, $aExtraParams);
}
/**
* @inheritDoc
*/
public function IsHyperLinkInNewWindow()
{
return $this->bIsLinkInNewWindow;
}
/**
* @param WebPage $oPage
* @param array $aExtraParams
* @inheritDoc
*/
public function RenderContent(WebPage $oPage, $aExtraParams = array())
{
@@ -1096,10 +1090,7 @@ class NewObjectMenuNode extends MenuNode
}
/**
* @param string[] $aExtraParams
*
* @return string
* @throws \Exception
* @inheritDoc
*/
public function GetHyperlink($aExtraParams)
{
@@ -1133,8 +1124,7 @@ class NewObjectMenuNode extends MenuNode
}
/**
* @param WebPage $oPage
* @param string[] $aExtraParams
* @inheritDoc
*/
public function RenderContent(WebPage $oPage, $aExtraParams = array())
{
@@ -1172,8 +1162,7 @@ class DashboardMenuNode extends MenuNode
}
/**
* @param string[] $aExtraParams
* @return string
* @inheritDoc
*/
public function GetHyperlink($aExtraParams)
{
@@ -1192,10 +1181,8 @@ class DashboardMenuNode extends MenuNode
}
/**
* @param \iTopWebPage $oPage
* @param string[] $aExtraParams
* @throws CoreException
* @throws Exception
* @inheritDoc
* @throws \Exception
*/
public function RenderContent(WebPage $oPage, $aExtraParams = array())
{
@@ -1203,8 +1190,9 @@ class DashboardMenuNode extends MenuNode
$oDashboard = $this->GetDashboard();
if ($oDashboard != null)
{
$sDivId = preg_replace('/[^a-zA-Z0-9_]/', '', $this->sMenuId);
$sDivId = utils::Sanitize($this->sMenuId, '', 'element_identifier');
$oPage->add('<div class="dashboard_contents" id="'.$sDivId.'">');
$aExtraParams['dashboard_div_id'] = $sDivId;
$oDashboard->SetReloadURL($this->GetHyperlink($aExtraParams));
$oDashboard->Render($oPage, false, $aExtraParams);
$oPage->add('</div>');
@@ -1289,8 +1277,7 @@ class DashboardMenuNode extends MenuNode
class ShortcutContainerMenuNode extends MenuNode
{
/**
* @param string[] $aExtraParams
* @return string
* @inheritDoc
*/
public function GetHyperlink($aExtraParams)
{
@@ -1298,15 +1285,14 @@ class ShortcutContainerMenuNode extends MenuNode
}
/**
* @param WebPage $oPage
* @param string[] $aExtraParams
* @return mixed|void
* @inheritDoc
*/
public function RenderContent(WebPage $oPage, $aExtraParams = array())
{
}
/**
* @inheritDoc
* @throws CoreException
* @throws Exception
*/
@@ -1361,9 +1347,7 @@ class ShortcutMenuNode extends MenuNode
}
/**
* @param string[] $aExtraParams
* @return string
* @throws CoreException
* @inheritDoc
*/
public function GetHyperlink($aExtraParams)
{
@@ -1381,10 +1365,8 @@ class ShortcutMenuNode extends MenuNode
}
/**
* @param WebPage $oPage
* @param string[] $aExtraParams
* @return mixed|void
* @throws DictExceptionMissingString
* @inheritDoc
* @throws \Exception
*/
public function RenderContent(WebPage $oPage, $aExtraParams = array())
{
@@ -1393,8 +1375,9 @@ class ShortcutMenuNode extends MenuNode
}
/**
* @return string
* @throws CoreException
* @inheritDoc
*
* @throws \Exception
*/
public function GetTitle()
{
@@ -1402,8 +1385,9 @@ class ShortcutMenuNode extends MenuNode
}
/**
* @return string
* @throws CoreException
* @inheritDoc
*
* @throws \Exception
*/
public function GetLabel()
{

View File

@@ -1,27 +1,20 @@
<?php
// Copyright (C) 2010-2016 Combodo SARL
//
// This file is part of iTop.
//
// iTop is free software; you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// iTop 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 Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with iTop. If not, see <http://www.gnu.org/licenses/>
/**
* Class NiceWebPage
* Copyright (C) 2013-2020 Combodo SARL
*
* @copyright Copyright (C) 2010-2016 Combodo SARL
* @license http://opensource.org/licenses/AGPL-3.0
* This file is part of iTop.
*
* iTop is free software; you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* iTop 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
*/
require_once(APPROOT."/application/webpage.class.inc.php");
@@ -257,9 +250,13 @@ EOF
parent::output();
}
/**
* @throws \Exception
* @since 2.7.0
*/
protected function LoadTheme()
{
$sCssThemeUrl = ThemeHandler::GetTheme();
$sCssThemeUrl = ThemeHandler::GetCurrentThemeUrl();
$this->add_linked_stylesheet($sCssThemeUrl);
}
}

View File

@@ -40,7 +40,7 @@ class iTopPDF extends TCPDF
*
* @uses \TCPDF::SetFont()
* @uses \iTopPDF::GetPdfFont()
* @since 2.7
* @since 2.7.0
*/
public function SetFontParams($style, $size, $fontfile='', $subset='default', $out=true)
{

View File

@@ -1,27 +1,20 @@
<?php
// Copyright (C) 2010-2017 Combodo SARL
//
// This file is part of iTop.
//
// iTop is free software; you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// iTop 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 Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with iTop. If not, see <http://www.gnu.org/licenses/>
/**
* Class DisplayTemplate
* Copyright (C) 2013-2020 Combodo SARL
*
* @copyright Copyright (C) 2010-2017 Combodo SARL
* @license http://opensource.org/licenses/AGPL-3.0
* This file is part of iTop.
*
* iTop is free software; you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* iTop 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
*/
require_once(APPROOT.'/application/displayblock.class.inc.php');
@@ -191,7 +184,7 @@ class DisplayTemplate
break;
case 'itoptab':
$oPage->SetCurrentTab(Dict::S(str_replace('_', ' ', $aAttributes['name'])));
$oPage->SetCurrentTab($aAttributes['name'], str_replace('_', ' ', $aAttributes['name']));
$oTemplate = new DisplayTemplate($sContent);
$oTemplate->Render($oPage, array()); // no params to apply, they have already been applied
//$oPage->p('iTop Tab Content:<pre>'.htmlentities($sContent, ENT_QUOTES, 'UTF-8').'</pre>');

View File

@@ -1,74 +1,190 @@
<?php
/**
* Copyright (C) 2013-2020 Combodo SARL
*
* * Copyright (C) 2013-2019 Combodo SARL
* *
* * This file is part of iTop.
* *
* * iTop is free software; you can redistribute it and/or modify
* * it under the terms of the GNU Affero General Public License as published by
* * the Free Software Foundation, either version 3 of the License, or
* * (at your option) any later version.
* *
* * iTop 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 Affero General Public License for more details.
* *
* * You should have received a copy of the GNU Affero General Public License
*
* This file is part of iTop.
*
* iTop is free software; you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* iTop 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
*/
use ScssPhp\ScssPhp\Compiler;
class ThemeHandler{
public static function GetTheme()
/**
* Class ThemeHandler
*
* @author Stephen Abello <stephen.abello@combodo.com>
* @since 2.7.0
*/
class ThemeHandler
{
/**
* Return default theme name and parameters
*
* @return array
* @since 2.7.0
*/
public static function GetDefaultThemeInformation()
{
$sThemeId = MetaModel::GetConfig()->Get('backoffice_default_theme');
$sEnvPath = APPROOT.'env-' . utils::GetCurrentEnvironment() .'/';
$sThemePath = $sEnvPath.'/branding/themes/'.$sThemeId.'/';
$aThemeParameters = json_decode(file_get_contents($sThemePath.'theme-parameters.json'), true);
$sThemeCssPath = $sThemePath.'main.css';
$sTheme = '';
return array(
'name' => 'light-grey',
'parameters' => array(
'variables' => array(),
'imports' => array(
'css-variables' => '../css/css-variables.scss',
),
'stylesheets' => array(
'jqueryui' => '../css/ui-lightness/jqueryui.scss',
'main' => '../css/light-grey.scss',
),
),
);
}
/**
* Return the ID of the theme currently defined in the config. file
*
* @return string
*/
public static function GetCurrentThemeId()
{
try
{
$sThemeId = MetaModel::GetConfig()->Get('backoffice_default_theme');
}
catch(CoreException $oCompileException)
{
// Fallback on our default theme in case the config. is not available yet
$aDefaultTheme = ThemeHandler::GetDefaultThemeInformation();
$sThemeId = $aDefaultTheme['name'];
}
return $sThemeId;
}
/**
* Return the absolute path of the compiled theme folder.
*
* @param string $sThemeId
*
* @return string
*/
public static function GetCompiledThemeFolderAbsolutePath($sThemeId)
{
return APPROOT.'env-'.utils::GetCurrentEnvironment().'/branding/themes/'.$sThemeId.'/';
}
/**
* Return the absolute URL for the current theme CSS file
*
* @return string
* @throws \Exception
*/
public static function GetCurrentThemeUrl()
{
try
{
// Try to compile theme defined in the configuration
$sThemeId = static::GetCurrentThemeId();
static::CompileTheme($sThemeId);
}
catch(CoreException $oCompileException)
{
// Fallback on our default theme (should always be compilable) in case the previous theme doesn't exists
$aDefaultTheme = ThemeHandler::GetDefaultThemeInformation();
$sThemeId = $aDefaultTheme['name'];
$sDefaultThemeDirPath = static::GetCompiledThemeFolderAbsolutePath($sThemeId);
// Create our theme dir if it doesn't exist (XML theme node removed, renamed etc..)
if(!is_dir($sDefaultThemeDirPath))
{
SetupUtils::builddir($sDefaultThemeDirPath);
}
static::CompileTheme($sThemeId, $aDefaultTheme['parameters']);
}
// Return absolute url to theme compiled css
return utils::GetAbsoluteUrlModulesRoot().'/branding/themes/'.$sThemeId.'/main.css';
}
/**
* Compile the $sThemeId theme
*
* @param string $sThemeId
* @param array|null $aThemeParameters Parameters (variables, imports, stylesheets) for the theme, if not passed, will be retrieved from compiled DM
* @param array|null $aImportsPaths Paths where imports can be found. Must end with '/'
* @param string|null $sWorkingPath Path of the folder used during compilation. Must end with a '/'
*
* @throws \CoreException
*/
public static function CompileTheme($sThemeId, $aThemeParameters = null, $aImportsPaths = null, $sWorkingPath = null)
{
// Default working path
if($sWorkingPath === null)
{
$sWorkingPath = APPROOT.'env-'.utils::GetCurrentEnvironment().'/';
}
// Default import paths (env-*)
if($aImportsPaths === null)
{
$aImportsPaths = array(
APPROOT.'env-'.utils::GetCurrentEnvironment().'/',
);
}
// Note: We do NOT check that the folder exists!
$sThemeFolderPath = $sWorkingPath.'/branding/themes/'.$sThemeId.'/';
$sThemeCssPath = $sThemeFolderPath.'main.css';
// Save parameters if passed... (typically during DM compilation)
if(is_array($aThemeParameters))
{
file_put_contents($sThemeFolderPath.'/theme-parameters.json', json_encode($aThemeParameters));
}
// ... Otherwise, retrieve them from compiled DM (typically when switching current theme in the config. file)
else
{
$aThemeParameters = json_decode(@file_get_contents($sThemeFolderPath.'theme-parameters.json'), true);
if ($aThemeParameters === null)
{
throw new CoreException('Could not load "'.$sThemeId.'" theme parameters from file, check that it has been compiled correctly');
}
}
$sTmpThemeScssContent = '';
$iStyleLastModified = 0;
clearstatcache();
// Loading files to import and stylesheet to compile, also getting most recent modification time on overall files
foreach ($aThemeParameters['imports'] as $sImport)
{
$sTheme.= '@import "' . $sImport . '";' . "\n";
$iImportLastModified = filemtime($sEnvPath.$sImport);
$sTmpThemeScssContent .= '@import "'.$sImport.'";'."\n";
$iImportLastModified = @filemtime($sWorkingPath.$sImport);
$iStyleLastModified = $iStyleLastModified < $iImportLastModified ? $iImportLastModified : $iStyleLastModified;
}
foreach ($aThemeParameters['stylesheets'] as $sStylesheet)
{
$sTheme.= '@import "' . $sStylesheet . '";'."\n";
$iStylesheetLastModified = filemtime($sEnvPath.$sStylesheet);
$sTmpThemeScssContent .= '@import "'.$sStylesheet.'";'."\n";
$iStylesheetLastModified = @filemtime($sWorkingPath.$sStylesheet);
$iStyleLastModified = $iStyleLastModified < $iStylesheetLastModified ? $iStylesheetLastModified : $iStyleLastModified;
}
// Checking if our compiled css is outdated
if (!file_exists($sThemeCssPath) || (is_writable($sThemePath) && (filemtime($sThemeCssPath) < $iStyleLastModified)))
if (!file_exists($sThemeCssPath) || (is_writable($sThemeFolderPath) && (@filemtime($sThemeCssPath) < $iStyleLastModified)))
{
$oScss = new Compiler();
$oScss->setFormatter('ScssPhp\\ScssPhp\\Formatter\\Expanded');
// Setting our xml variables
$oScss->setVariables($aThemeParameters['variables']);
// Setting our import path to env-*
$oScss->setImportPaths($sEnvPath);
// Temporary disabling max exec time while compiling
$iCurrentMaxExecTime = (int) ini_get('max_execution_time');
set_time_limit(0);
// Compiling our theme
$sThemeCss = $oScss->compile($sTheme);
set_time_limit($iCurrentMaxExecTime);
file_put_contents($sThemePath.'main.css', $sThemeCss);
$sTmpThemeCssContent = utils::CompileCSSFromSASS($sTmpThemeScssContent, $aImportsPaths, $aThemeParameters['variables']);
file_put_contents($sThemeCssPath, $sTmpThemeCssContent);
}
// Return absolute url to theme compiled css
return utils::GetAbsoluteUrlModulesRoot().'/branding/themes/'.$sThemeId.'/main.css';
}
}

View File

@@ -1,23 +1,28 @@
<?php
// Copyright (C) 2010-2017 Combodo SARL
//
// This file is part of iTop.
//
// iTop is free software; you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// iTop 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 Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with iTop. If not, see <http://www.gnu.org/licenses/>
/**
* Copyright (C) 2013-2020 Combodo SARL
*
* This file is part of iTop.
*
* iTop is free software; you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* iTop 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
*/
require_once(APPROOT.'/application/webpage.class.inc.php');
require_once(APPROOT.'/application/displayblock.class.inc.php');
/**
* Class UIExtKeyWidget
* UI wdiget for displaying and editing external keys when
* UI widget for displaying and editing external keys when
* A simple drop-down list is not enough...
*
* The layout is the following
@@ -54,13 +59,7 @@
* | | +--------+ +-----+ | |
* | +--------------------------------------------+ |
* +------------------------------------------------+
* @copyright Copyright (C) 2010-2017 Combodo SARL
* @license http://opensource.org/licenses/AGPL-3.0
*/
require_once(APPROOT.'/application/webpage.class.inc.php');
require_once(APPROOT.'/application/displayblock.class.inc.php');
class UIExtKeyWidget
{
const ENUM_OUTPUT_FORMAT_CSV = 'csv';
@@ -578,8 +577,21 @@ EOF
$oNewObj->UpdateObjectFromArg('default');
$sDialogTitle = '';
$oPage->add('<div id="ac_create_'.$this->iId.'"><div class="wizContainer" style="vertical-align:top;"><div id="dcr_'.$this->iId.'">');
$oPage->add("<h1>".MetaModel::GetClassIcon($this->sTargetClass)."&nbsp;".Dict::Format('UI:CreationTitle_Class', MetaModel::GetName($this->sTargetClass))."</h1>\n");
$sClassLabel = MetaModel::GetName($this->sTargetClass);
$sClassIcon = MetaModel::GetClassIcon($this->sTargetClass);
$sObjClass = get_class($oNewObj);
$sObjKey = $oNewObj->GetKey();
$sHeaderTitle = Dict::Format('UI:CreationTitle_Class', $sClassLabel);
$oPage->add(<<<HTML
<div id="ac_create_{$this->iId}">
<!-- Beginning of object-details -->
<div class="object-details" data-object-class="$sObjClass" data-object-id="$sObjKey" data-object-mode="create">
<!-- Beginning of wizContainer -->
<div class="wizContainer" style="vertical-align:top;">
<div id="dcr_{$this->iId}">
<h1>$sClassIcon&nbsp;$sHeaderTitle</h1>
HTML
);
$aFieldsFlags = array();
$aFieldsComments = array();
foreach(MetaModel::ListAttributeDefs($this->sTargetClass) as $sAttCode => $oAttDef)
@@ -591,7 +603,13 @@ EOF
}
}
cmdbAbstractObject::DisplayCreationForm($oPage, $this->sTargetClass, $oNewObj, array(), array('formPrefix' => $this->iId, 'noRelations' => true, 'fieldsFlags' => $aFieldsFlags, 'fieldsComments' => $aFieldsComments));
$oPage->add('</div></div></div>');
$oPage->add(<<<HTML
</div>
</div><!-- End of wizContainer -->
</div><!-- End of object-details -->
</div>
HTML
);
// $oPage->add_ready_script("\$('#ac_create_$this->iId').dialog({ width: $(window).width()*0.8, height: 'auto', autoOpen: false, modal: true, title: '$sDialogTitle'});\n");
$oPage->add_ready_script("\$('#ac_create_$this->iId').dialog({ width: 'auto', height: 'auto', maxHeight: $(window).height() - 50, autoOpen: false, modal: true, title: '$sDialogTitle'});\n");
$oPage->add_ready_script("$('#dcr_{$this->iId} form').removeAttr('onsubmit');");

View File

@@ -34,7 +34,7 @@ require_once(APPROOT.'/core/userrights.class.inc.php');
*/
class appUserPreferences extends DBObject
{
static $oUserPrefs = null; // Local cache
private static $oUserPrefs = null; // Local cache
/**
* Get the value of the given property/preference
@@ -43,7 +43,7 @@ class appUserPreferences extends DBObject
* @param string $sDefaultValue The default value
* @return string The value of the property for the current user
*/
static function GetPref($sCode, $sDefaultValue)
public static function GetPref($sCode, $sDefaultValue)
{
if (self::$oUserPrefs == null)
{
@@ -65,7 +65,7 @@ class appUserPreferences extends DBObject
* @param string $sCode Code/Name of the property/preference to set
* @param string $sValue Value to set
*/
static function SetPref($sCode, $sValue)
public static function SetPref($sCode, $sValue)
{
if (self::$oUserPrefs == null)
{
@@ -83,13 +83,13 @@ class appUserPreferences extends DBObject
self::Save();
}
}
/**
* Clears the value for a given preference (or list of preferences that matches a pattern), and updates the database
* @param string $sPattern Code/Pattern of the properties/preferences to reset
* @param string $sCodeOrPattern Code/Pattern of the properties/preferences to reset
* @param boolean $bPattern Whether or not the supplied code is a PCRE pattern
*/
static function UnsetPref($sCodeOrPattern, $bPattern = false)
public static function UnsetPref($sCodeOrPattern, $bPattern = false)
{
if (self::$oUserPrefs == null)
{
@@ -124,7 +124,7 @@ class appUserPreferences extends DBObject
* Call this function to get all the preferences for the user, packed as a JSON object
* @return string JSON representation of the preferences
*/
static function GetAsJSON()
public static function GetAsJSON()
{
if (self::$oUserPrefs == null)
{
@@ -137,19 +137,19 @@ class appUserPreferences extends DBObject
/**
* Call this function if the user has changed (like when doing a logoff...)
*/
static public function ResetPreferences()
public static function ResetPreferences()
{
self::$oUserPrefs = null;
}
/**
* Call this function to ERASE all the preferences from the current user
*/
static public function ClearPreferences()
public static function ClearPreferences()
{
self::$oUserPrefs = null;
}
static protected function Save()
protected static function Save()
{
if (self::$oUserPrefs != null)
{
@@ -166,7 +166,7 @@ class appUserPreferences extends DBObject
* Loads the preferences for the current user, creating the record in the database
* if needed
*/
static protected function Load()
protected static function Load()
{
if (self::$oUserPrefs != null) return;
$oSearch = new DBObjectSearch('appUserPreferences');

View File

@@ -1,6 +1,6 @@
<?php
/**
* Copyright (C) 2013-2019 Combodo SARL
* Copyright (C) 2013-2020 Combodo SARL
*
* This file is part of iTop.
*
@@ -275,13 +275,14 @@ class utils
/**
* @param string|string[] $value
* @param string $sSanitizationFilter one of : integer, class, string, context_param, parameter, field_name,
* transaction_id, parameter, raw_data
* element_identifier, transaction_id, parameter, raw_data
*
* @return string|string[]|bool boolean for :
* * the 'class' filter (true if valid, false otherwise)
* * if the filter fails (@see \filter_var())
*
* @since 2.5.2 2.6.0 new 'transaction_id' filter
* @since 2.7.0 new 'element_identifier' filter
*/
protected static function Sanitize_Internal($value, $sSanitizationFilter)
{
@@ -351,6 +352,11 @@ class utils
}
break;
// For XML / HTML node identifiers
case 'element_identifier':
$retValue = preg_replace('/[^a-zA-Z0-9_]/', '', $value);
break;
default:
case 'raw_data':
$retValue = $value;
@@ -846,10 +852,25 @@ class utils
$sAbsoluteUrl = "$sProtocol://{$sServerName}{$sPort}{$sPath}";
$sCurrentScript = realpath($_SERVER['SCRIPT_FILENAME']);
$sAppRoot = realpath(APPROOT);
return self::GetAppRootUrl($sCurrentScript, $sAppRoot, $sAbsoluteUrl);
}
/**
* @param $sCurrentScript
* @param $sAppRoot
* @param $sAbsoluteUrl
*
* @return false|string
* @throws \Exception
*/
public static function GetAppRootUrl($sCurrentScript, $sAppRoot, $sAbsoluteUrl)
{
$sCurrentScript = str_replace('\\', '/', $sCurrentScript); // canonical path
$sAppRoot = str_replace('\\', '/', realpath(APPROOT)).'/'; // canonical path with the trailing '/' appended
$sCurrentRelativePath = str_replace($sAppRoot, '', $sCurrentScript);
$sAppRoot = str_replace('\\', '/', $sAppRoot).'/'; // canonical path with the trailing '/' appended
$sCurrentRelativePath = str_ireplace($sAppRoot, '', $sCurrentScript);
$sAppRootPos = strpos($sAbsoluteUrl, $sCurrentRelativePath);
if ($sAppRootPos !== false)
{
@@ -858,7 +879,7 @@ class utils
else
{
// Second attempt without index.php at the end...
$sCurrentRelativePath = str_replace('index.php', '', $sCurrentRelativePath);
$sCurrentRelativePath = str_ireplace('index.php', '', $sCurrentRelativePath);
$sAppRootPos = strpos($sAbsoluteUrl, $sCurrentRelativePath);
if ($sAppRootPos !== false)
{
@@ -868,8 +889,9 @@ class utils
{
// No luck...
throw new Exception("Failed to determine application root path $sAbsoluteUrl ($sCurrentRelativePath) APPROOT:'$sAppRoot'");
}
}
}
return $sAppRootUrl;
}
@@ -1489,6 +1511,17 @@ class utils
public static function HtmlEntities($sValue)
{
return htmlentities($sValue, ENT_QUOTES, 'UTF-8');
}
/**
* Helper to encapsulation iTop's html_entity_decode
* @param string $sValue
* @return string
* @since 2.7.0
*/
public static function HtmlEntityDecode($sValue)
{
return html_entity_decode($sValue, ENT_QUOTES, 'UTF-8');
}
/**
@@ -1550,18 +1583,40 @@ class utils
clearstatcache();
if (!file_exists($sCssPath) || (is_writable($sCssPath) && (filemtime($sCssPath) < filemtime($sSassPath))))
{
$oScss = new Compiler();
$oScss->setImportPaths($aImportPaths);
$oScss->setFormatter('ScssPhp\\ScssPhp\\Formatter\\Expanded');
// Temporary disabling max exec time while compiling
$iCurrentMaxExecTime = (int) ini_get('max_execution_time');
set_time_limit(0);
$sCss = $oScss->compile(file_get_contents($sSassPath));
set_time_limit($iCurrentMaxExecTime);
$sCss = static::CompileCSSFromSASS(file_get_contents($sSassPath), $aImportPaths);
file_put_contents($sCssPath, $sCss);
}
return $sCssRelPath;
}
/**
* Return a string of CSS compiled from the $sSassContent
*
* @param string $sSassContent
* @param array $aImportPaths
* @param array $aVariables
*
* @return string
*
* @since 2.7.0
*/
public static function CompileCSSFromSASS($sSassContent, $aImportPaths = array(), $aVariables = array())
{
$oSass = new Compiler();
$oSass->setFormatter('ScssPhp\\ScssPhp\\Formatter\\Expanded');
// Setting our variables
$oSass->setVariables($aVariables);
// Setting our imports paths
$oSass->setImportPaths($aImportPaths);
// Temporary disabling max exec time while compiling
$iCurrentMaxExecTime = (int) ini_get('max_execution_time');
set_time_limit(0);
// Compiling SASS
$sCss = $oSass->compile($sSassContent);
set_time_limit($iCurrentMaxExecTime);
return $sCss;
}
public static function GetImageSize($sImageData)
{

View File

@@ -1,6 +1,6 @@
<?php
/**
* Copyright (C) 2013-2019 Combodo SARL
* Copyright (C) 2013-2020 Combodo SARL
*
* This file is part of iTop.
*
@@ -17,6 +17,8 @@
* You should have received a copy of the GNU Affero General Public License
*/
use Combodo\iTop\Application\TwigBase\Twig\TwigHelper;
/**
* Generic interface common to CLI and Web pages
*/
@@ -120,6 +122,7 @@ class WebPage implements Page
protected $a_OutputOptions;
protected $bPrintable;
protected $bHasCollapsibleSection;
protected $bAddJSDict;
/**
* WebPage constructor.
@@ -150,6 +153,7 @@ class WebPage implements Page
$this->a_OutputOptions = array();
$this->bHasCollapsibleSection = false;
$this->bPrintable = $bPrintable;
$this->bAddJSDict = true;
ob_start(); // Start capturing the output
}
@@ -183,6 +187,21 @@ class WebPage implements Page
$this->s_content .= $s_html;
}
/**
* Add any rendered text or HTML fragment to the body of the page using a twig template
*
* @param string $sViewPath Absolute path of the templates folder
* @param string $sTemplateName Name of the twig template, ie MyTemplate for MyTemplate.html.twig
* @param array $aParams Params used by the twig template
* @param string $sDefaultType default type of the template ('html', 'xml', ...)
*
* @throws \Exception
*/
public function add_twig_template($sViewPath, $sTemplateName, $aParams = array(), $sDefaultType = 'html')
{
TwigHelper::RenderIntoPage($this, $sViewPath, $sTemplateName, $aParams, $sDefaultType);
}
/**
* Add any text or HTML fragment (identified by an ID) at the end of the body of the page
* This is useful to add hidden content, DIVs or FORMs that should not
@@ -296,8 +315,32 @@ class WebPage implements Page
foreach ($aConfig as $sName => $aAttribs)
{
$sClass = isset($aAttribs['class']) ? 'class="'.$aAttribs['class'].'"' : '';
$sValue = ($aRow[$sName] === '') ? '&nbsp;' : $aRow[$sName];
$sHtml .= "<td $sClass>$sValue</td>";
// Prepare metadata
// - From table config.
$sMetadata = '';
if(isset($aAttribs['metadata']))
{
foreach($aAttribs['metadata'] as $sMetadataProp => $sMetadataValue)
{
$sMetadataPropSanitized = str_replace('_', '-', $sMetadataProp);
$sMetadataValueSanitized = utils::HtmlEntities($sMetadataValue);
$sMetadata .= 'data-'.$sMetadataPropSanitized.'="'.$sMetadataValueSanitized.'" ';
}
}
// Prepare value
if(is_array($aRow[$sName]))
{
$sValueHtml = ($aRow[$sName]['value_html'] === '') ? '&nbsp;' : $aRow[$sName]['value_html'];
$sMetadata .= 'data-value-raw="'.utils::HtmlEntities($aRow[$sName]['value_raw']).'" ';
}
else
{
$sValueHtml = ($aRow[$sName] === '') ? '&nbsp;' : $aRow[$sName];
}
$sHtml .= "<td $sClass $sMetadata>$sValueHtml</td>";
}
$sHtml .= "</tr>";
@@ -504,15 +547,37 @@ class WebPage implements Page
*/
public function GetDetails($aFields)
{
$aPossibleAttFlags = MetaModel::EnumPossibleAttributeFlags();
$sHtml = "<div class=\"details\">\n";
foreach ($aFields as $aAttrib)
{
$sLayout = isset($aAttrib['layout']) ? $aAttrib['layout'] : 'small';
// Prepare metadata attributes
$sDataAttributeCode = isset($aAttrib['attcode']) ? 'data-attribute-code="'.$aAttrib['attcode'].'"' : '';
$sDataAttributeType = isset($aAttrib['atttype']) ? 'data-attribute-type="'.$aAttrib['atttype'].'"' : '';
$sDataValueRaw = isset($aAttrib['value_raw']) ? 'data-value-raw="'.$aAttrib['value_raw'].'"' : '';
$sDataAttributeLabel = isset($aAttrib['attlabel']) ? 'data-attribute-label="'.utils::HtmlEntities($aAttrib['attlabel']).'"' : '';
// - Attribute flags
$sDataAttributeFlags = '';
if(isset($aAttrib['attflags']))
{
foreach($aPossibleAttFlags as $sFlagCode => $iFlagValue)
{
// Note: Skip normal flag as we don't need it.
if($sFlagCode === 'normal')
{
continue;
}
$sFormattedFlagCode = str_ireplace('_', '-', $sFlagCode);
$sFormattedFlagValue = (($aAttrib['attflags'] & $iFlagValue) === $iFlagValue) ? 'true' : 'false';
$sDataAttributeFlags .= 'data-attribute-flag-'.$sFormattedFlagCode.'="'.$sFormattedFlagValue.'" ';
}
}
// - Value raw
$sDataValueRaw = isset($aAttrib['value_raw']) ? 'data-value-raw="'.utils::HtmlEntities($aAttrib['value_raw']).'"' : '';
$sHtml .= "<div class=\"field_container field_{$sLayout}\" $sDataAttributeCode $sDataAttributeType $sDataValueRaw>\n";
$sHtml .= "<div class=\"field_container field_{$sLayout}\" $sDataAttributeCode $sDataAttributeType $sDataAttributeLabel $sDataAttributeFlags $sDataValueRaw>\n";
$sHtml .= "<div class=\"field_label label\">{$aAttrib['label']}</div>\n";
$sHtml .= "<div class=\"field_data\">\n";
@@ -711,7 +776,10 @@ class WebPage implements Page
}
// Dict entries for JS
$this->output_dict_entries();
if ($this->bAddJSDict)
{
$this->output_dict_entries();
}
// JS files
foreach ($this->a_linked_scripts as $s_script)
@@ -1114,12 +1182,12 @@ interface iTabbedPage
/**
* @param string $sTabContainer
* @param string $sTabLabel
* @param string $sTabCode
* @param string $sHtml
*
* @return mixed
*/
public function AddToTab($sTabContainer, $sTabLabel, $sHtml);
public function AddToTab($sTabContainer, $sTabCode, $sHtml);
/**
* @param string $sTabContainer
@@ -1129,11 +1197,11 @@ interface iTabbedPage
public function SetCurrentTabContainer($sTabContainer = '');
/**
* @param string $sTabLabel
* @param string $sTabCode
*
* @return mixed
*/
public function SetCurrentTab($sTabLabel = '');
public function SetCurrentTab($sTabCode = '');
/**
* Add a tab which content will be loaded asynchronously via the supplied URL
@@ -1142,24 +1210,25 @@ interface iTabbedPage
* Cross site scripting is not not allowed for security reasons. Use a normal tab with an IFRAME if you want to
* pull content from another server. Static content cannot be added inside such tabs.
*
* @param string $sTabLabel The (localised) label of the tab
* @param string $sTabCode The (localised) label of the tab
* @param string $sUrl The URL to load (on the same server)
* @param boolean $bCache Whether or not to cache the content of the tab once it has been loaded. flase will cause
* the tab to be reloaded upon each activation.
* @param string|null $sTabTitle
*
* @since 2.0.3
*/
public function AddAjaxTab($sTabLabel, $sUrl, $bCache = true);
public function AddAjaxTab($sTabCode, $sUrl, $bCache = true, $sTabTitle = null);
public function GetCurrentTab();
/**
* @param string$sTabLabel
* @param string $sTabCode
* @param string|null $sTabContainer
*
* @return mixed
*/
public function RemoveTab($sTabLabel, $sTabContainer = null);
public function RemoveTab($sTabCode, $sTabContainer = null);
/**
* Finds the tab whose title matches a given pattern
@@ -1177,6 +1246,11 @@ interface iTabbedPage
*/
class TabManager
{
const ENUM_TAB_TYPE_HTML = 'html';
const ENUM_TAB_TYPE_AJAX = 'ajax';
const DEFAULT_TAB_TYPE = self::ENUM_TAB_TYPE_HTML;
protected $m_aTabs;
protected $m_sCurrentTabContainer;
protected $m_sCurrentTab;
@@ -1261,32 +1335,29 @@ class TabManager
/**
* @param string $sTabContainer
* @param string $sTabLabel
* @param string $sTabCode
* @param string $sHtml
* @param string|null $sTabTitle
*
* @return string
* @throws \Exception
*/
public function AddToTab($sTabContainer, $sTabLabel, $sHtml)
public function AddToTab($sTabContainer, $sTabCode, $sHtml, $sTabTitle = null)
{
if (!isset($this->m_aTabs[$sTabContainer]['tabs'][$sTabLabel]))
if (!$this->TabExists($sTabContainer, $sTabCode))
{
// Set the content of the tab
$this->m_aTabs[$sTabContainer]['tabs'][$sTabLabel] = array(
'type' => 'html',
'html' => $sHtml,
);
$this->InitTab($sTabContainer, $sTabCode, static::ENUM_TAB_TYPE_HTML, $sTabTitle);
}
else
// If target tab is not of type 'html', throw an exception
if ($this->m_aTabs[$sTabContainer]['tabs'][$sTabCode]['type'] != static::ENUM_TAB_TYPE_HTML)
{
if ($this->m_aTabs[$sTabContainer]['tabs'][$sTabLabel]['type'] != 'html')
{
throw new Exception("Cannot add HTML content to the tab '$sTabLabel' of type '{$this->m_aTabs[$sTabContainer]['tabs'][$sTabLabel]['type']}'");
}
// Append to the content of the tab
$this->m_aTabs[$sTabContainer]['tabs'][$sTabLabel]['html'] .= $sHtml;
throw new Exception("Cannot add HTML content to the tab '$sTabCode' of type '{$this->m_aTabs[$sTabContainer]['tabs'][$sTabCode]['type']}'");
}
// Append to the content of the tab
$this->m_aTabs[$sTabContainer]['tabs'][$sTabCode]['html'] .= $sHtml;
return ''; // Nothing to add to the page for now
}
@@ -1304,16 +1375,22 @@ class TabManager
}
/**
* @param string $sTabLabel
* @param string $sTabCode
*
* @return string
*/
public function SetCurrentTab($sTabLabel = '')
public function SetCurrentTab($sTabCode = '', $sTabTitle = null)
{
$sPreviousTab = $this->m_sCurrentTab;
$this->m_sCurrentTab = $sTabLabel;
$sPreviousTabCode = $this->m_sCurrentTab;
$this->m_sCurrentTab = $sTabCode;
return $sPreviousTab;
// Init tab to HTML tab if not existing
if (!$this->TabExists($this->GetCurrentTabContainer(), $sTabCode))
{
$this->InitTab($this->GetCurrentTabContainer(), $sTabCode, static::ENUM_TAB_TYPE_HTML, $sTabTitle);
}
return $sPreviousTabCode;
}
/**
@@ -1323,7 +1400,7 @@ class TabManager
* Cross site scripting is not not allowed for security reasons. Use a normal tab with an IFRAME if you want to
* pull content from another server. Static content cannot be added inside such tabs.
*
* @param string $sTabLabel The (localised) label of the tab
* @param string $sTabCode The (localised) label of the tab
* @param string $sUrl The URL to load (on the same server)
* @param boolean $bCache Whether or not to cache the content of the tab once it has been loaded. false will cause
* the tab to be reloaded upon each activation.
@@ -1332,14 +1409,12 @@ class TabManager
*
* @since 2.0.3
*/
public function AddAjaxTab($sTabLabel, $sUrl, $bCache = true)
public function AddAjaxTab($sTabCode, $sUrl, $bCache = true, $sTabTitle = null)
{
// Set the content of the tab
$this->m_aTabs[$this->m_sCurrentTabContainer]['tabs'][$sTabLabel] = array(
'type' => 'ajax',
'url' => $sUrl,
'cache' => $bCache,
);
$this->InitTab($this->m_sCurrentTabContainer, $sTabCode, static::ENUM_TAB_TYPE_AJAX, $sTabTitle);
$this->m_aTabs[$this->m_sCurrentTabContainer]['tabs'][$sTabCode]['url'] = $sUrl;
$this->m_aTabs[$this->m_sCurrentTabContainer]['tabs'][$sTabCode]['cache'] = $bCache;
return ''; // Nothing to add to the page for now
}
@@ -1361,22 +1436,22 @@ class TabManager
}
/**
* @param string $sTabLabel
* @param string $sTabCode
* @param string|null $sTabContainer
*/
public function RemoveTab($sTabLabel, $sTabContainer = null)
public function RemoveTab($sTabCode, $sTabContainer = null)
{
if ($sTabContainer == null)
{
$sTabContainer = $this->m_sCurrentTabContainer;
}
if (isset($this->m_aTabs[$sTabContainer]['tabs'][$sTabLabel]))
if (isset($this->m_aTabs[$sTabContainer]['tabs'][$sTabCode]))
{
// Delete the content of the tab
unset($this->m_aTabs[$sTabContainer]['tabs'][$sTabLabel]);
unset($this->m_aTabs[$sTabContainer]['tabs'][$sTabCode]);
// If we just removed the active tab, let's reset the active tab
if (($this->m_sCurrentTabContainer == $sTabContainer) && ($this->m_sCurrentTab == $sTabLabel))
if (($this->m_sCurrentTabContainer == $sTabContainer) && ($this->m_sCurrentTab == $sTabCode))
{
$this->m_sCurrentTab = '';
}
@@ -1398,11 +1473,11 @@ class TabManager
{
$sTabContainer = $this->m_sCurrentTabContainer;
}
foreach ($this->m_aTabs[$sTabContainer]['tabs'] as $sTabLabel => $void)
foreach ($this->m_aTabs[$sTabContainer]['tabs'] as $sTabCode => $void)
{
if (preg_match($sPattern, $sTabLabel))
if (preg_match($sPattern, $sTabCode))
{
$result = $sTabLabel;
$result = $sTabCode;
break;
}
}
@@ -1417,11 +1492,11 @@ class TabManager
* the whole jquery bundle...
*
* @param string $sTabContainer
* @param string $sTabLabel
* @param string $sTabCode
*
* @return string
*/
public function SelectTab($sTabContainer, $sTabLabel)
public function SelectTab($sTabContainer, $sTabCode)
{
$container_index = 0;
$tab_index = 0;
@@ -1431,7 +1506,7 @@ class TabManager
{
foreach ($aTabs['tabs'] as $sCurrentTabLabel => $void)
{
if ($sCurrentTabLabel == $sTabLabel)
if ($sCurrentTabLabel == $sTabCode)
{
break;
}
@@ -1462,6 +1537,18 @@ class TabManager
$container_index = 0;
if (count($aTabs['tabs']) > 0)
{
// Clean tabs
foreach ($aTabs['tabs'] as $sTabCode => $aTabData)
{
// Sometimes people set an empty tab to force content NOT to be rendered in the previous one. We need to remove them.
// Note: Look for "->SetCurrentTab('');" for examples.
if ($sTabCode === '')
{
unset($aTabs['tabs'][$sTabCode]);
}
}
// Render tabs
if ($oPage->IsPrintableVersion())
{
$oPage->add_ready_script(
@@ -1471,13 +1558,14 @@ EOF
);
$sTabs = "<!-- tabs -->\n<div id=\"tabbedContent_{$sPrefix}{$container_index}\" class=\"light\">\n";
$i = 0;
foreach ($aTabs['tabs'] as $sTabName => $aTabData)
foreach ($aTabs['tabs'] as $sTabCode => $aTabData)
{
$sTabNameEsc = addslashes($sTabName);
$sTabCodeForJs = addslashes($sTabCode);
$sTabTitleForHtml = utils::HtmlEntities($aTabData['title']);
$sTabId = "tab_{$sPrefix}{$container_index}$i";
switch ($aTabData['type'])
{
case 'ajax':
case static::ENUM_TAB_TYPE_AJAX:
$sTabHtml = '';
$sUrl = $aTabData['url'];
$oPage->add_ready_script(
@@ -1489,16 +1577,14 @@ EOF
);
break;
case 'html':
case static::ENUM_TAB_TYPE_HTML:
default:
$sTabHtml = $aTabData['html'];
}
$sTabs .= "<div class=\"printable-tab\" id=\"$sTabId\"><h2 class=\"printable-tab-title\">".htmlentities($sTabName,
ENT_QUOTES,
'UTF-8')."</h2><div class=\"printable-tab-content\">".$sTabHtml."</div></div>\n";
$sTabs .= "<div class=\"printable-tab\" id=\"$sTabId\"><h2 class=\"printable-tab-title\">$sTabTitleForHtml</h2><div class=\"printable-tab-content\">".$sTabHtml."</div></div>\n";
$oPage->add_ready_script(
<<< EOF
oHiddeableChapters['$sTabId'] = '$sTabNameEsc';
oHiddeableChapters['$sTabId'] = '$sTabCodeForJs';
EOF
);
$i++;
@@ -1511,34 +1597,34 @@ EOF
$sTabs .= "<ul>\n";
// Display the unordered list that will be rendered as the tabs
$i = 0;
foreach ($aTabs['tabs'] as $sTabName => $aTabData)
foreach ($aTabs['tabs'] as $sTabCode => $aTabData)
{
$sTabCodeForHtml = utils::HtmlEntities($sTabCode);
$sTabTitleForHtml = utils::HtmlEntities($aTabData['title']);
switch ($aTabData['type'])
{
case 'ajax':
$sTabs .= "<li data-cache=\"".($aTabData['cache'] ? 'true' : 'false')."\"><a href=\"{$aTabData['url']}\" class=\"tab\"><span>".htmlentities($sTabName,
ENT_QUOTES, 'UTF-8')."</span></a></li>\n";
case static::ENUM_TAB_TYPE_AJAX:
$sTabs .= "<li data-cache=\"".($aTabData['cache'] ? 'true' : 'false')."\"><a href=\"{$aTabData['url']}\" class=\"tab\" data-tab-id=\"$sTabCodeForHtml\"><span>$sTabTitleForHtml</span></a></li>\n";
break;
case 'html':
case static::ENUM_TAB_TYPE_HTML:
default:
$sTabs .= "<li><a href=\"#tab_{$sPrefix}{$container_index}$i\" class=\"tab\"><span>".htmlentities($sTabName,
ENT_QUOTES, 'UTF-8')."</span></a></li>\n";
$sTabs .= "<li><a href=\"#tab_{$sPrefix}{$container_index}$i\" class=\"tab\" data-tab-id=\"$sTabCodeForHtml\"><span>$sTabTitleForHtml</span></a></li>\n";
}
$i++;
}
$sTabs .= "</ul>\n";
// Now add the content of the tabs themselves
$i = 0;
foreach ($aTabs['tabs'] as $sTabName => $aTabData)
foreach ($aTabs['tabs'] as $sTabCode => $aTabData)
{
switch ($aTabData['type'])
{
case 'ajax':
case static::ENUM_TAB_TYPE_AJAX:
// Nothing to add
break;
case 'html':
case static::ENUM_TAB_TYPE_HTML:
default:
$sTabs .= "<div id=\"tab_{$sPrefix}{$container_index}$i\">".$aTabData['html']."</div>\n";
}
@@ -1553,4 +1639,46 @@ EOF
return $sContent;
}
}
/**
* @param string $sTabContainer
* @param string $sTabCode
* @param string $sTabType
* @param string|null $sTabTitle
* @since 2.7.0
*/
protected function InitTab($sTabContainer, $sTabCode, $sTabType = self::DEFAULT_TAB_TYPE, $sTabTitle = null)
{
if (!$this->TabExists($sTabContainer, $sTabCode))
{
// Container
if (!array_key_exists($sTabContainer, $this->m_aTabs))
{
$this->m_aTabs[$sTabContainer] = array(
'prefix' => '',
'tabs' => array(),
);
}
// Common properties
$this->m_aTabs[$sTabContainer]['tabs'][$sTabCode] = array(
'type' => $sTabType,
'title' => ($sTabTitle !== null) ? Dict::S($sTabTitle) : Dict::S($sTabCode),
);
// Specific properties
switch($sTabType)
{
case static::ENUM_TAB_TYPE_AJAX:
$this->m_aTabs[$sTabContainer]['tabs'][$sTabCode]['url'] = null;
$this->m_aTabs[$sTabContainer]['tabs'][$sTabCode]['cache'] = null;
break;
case static::ENUM_TAB_TYPE_HTML:
default:
$this->m_aTabs[$sTabContainer]['tabs'][$sTabCode]['html'] = null;
break;
}
}
}
}

View File

@@ -273,10 +273,6 @@ class WizardHelper
static public function FromJSON($sJSON)
{
$oWizHelper = new WizardHelper();
if (get_magic_quotes_gpc())
{
$sJSON = stripslashes($sJSON);
}
$aData = json_decode($sJSON, true); // true means hash array instead of object
$oWizHelper->m_aData = $aData;
return $oWizHelper;

View File

@@ -174,7 +174,7 @@ Class XLSXWriter
fwrite($fd,'<c r="'.$cell.'" s="'.$s.'" t="n"><v>'.self::convert_date_time($value).'</v></c>');
} else if ($value==''){
fwrite($fd,'<c r="'.$cell.'" s="'.$s.'"/>');
} else if ($value{0}=='='){
} else if ($value[0]=='='){
fwrite($fd,'<c r="'.$cell.'" s="'.$s.'" t="s"><f>'.self::xmlspecialchars($value).'</f></c>');
} else if ($value!==''){
fwrite($fd,'<c r="'.$cell.'" s="'.$s.'" t="s"><v>'.self::xmlspecialchars($this->setSharedString($value)).'</v></c>');

View File

@@ -64,11 +64,12 @@ if (file_exists(MAINTENANCE_MODE_FILE) && !$bBypassMaintenance)
case $sSAPIName == 'CLI':
case array_key_exists('HTTP_X_COMBODO_AJAX', $_SERVER):
case isset($_SERVER['REQUEST_URI']) && EndsWith($_SERVER['REQUEST_URI'], '/webservices/soapserver.php'):
case isset($_SERVER['REQUEST_URI']) && EndsWith($_SERVER['REQUEST_URI'], '/webservices/rest.php'):
case isset($_SERVER['REQUEST_URI']) && (strpos($_SERVER['REQUEST_URI'], '/webservices/soapserver.php') !== false):
case isset($_SERVER['REQUEST_URI']) && (strpos($_SERVER['REQUEST_URI'], '/webservices/export-v2.php') !== false):
_MaintenanceTextMessage($sMessage);
break;
case isset($_SERVER['REQUEST_URI']) && (strpos($_SERVER['REQUEST_URI'], '/webservices/rest.php') !== false):
case isset($_SERVER['CONTENT_TYPE']) && ($_SERVER['CONTENT_TYPE'] == 'application/json'):
_MaintenanceJsonMessage($sTitle, $sMessage);
break;

View File

@@ -3,26 +3,25 @@
"license": "AGPLv3",
"require": {
"php": ">=5.6.0",
"ext-soap": "*",
"ext-ctype": "*",
"ext-dom": "*",
"ext-gd": "*",
"ext-iconv": "*",
"ext-json": "*",
"ext-mysqli": "*",
"ext-dom": "*",
"ext-iconv": "*",
"ext-gd": "*",
"ext-ctype": "*",
"scssphp/scssphp": "1.0.0",
"swiftmailer/swiftmailer": "5.4.9",
"ext-soap": "*",
"combodo/tcpdf": "6.3.4",
"nikic/php-parser": "^3.1",
"pear/archive_tar": "1.4.9",
"pelago/emogrifier": "2.1.0",
"combodo/tcpdf": "6.3.0",
"pear/archive_tar": "1.4.7",
"scssphp/scssphp": "1.0.6",
"swiftmailer/swiftmailer": "5.4.12",
"symfony/console": "3.4.*",
"symfony/dotenv": "3.4.*",
"symfony/framework-bundle": "3.4.*",
"symfony/polyfill-php70": "1.*",
"symfony/twig-bundle": "3.4.*",
"symfony/yaml": "3.4.*",
"symfony/polyfill-php70": "1.*"
"symfony/yaml": "3.4.*"
},
"require-dev": {
"symfony/stopwatch": "3.4.*",
@@ -44,12 +43,15 @@
"preferred-install": {
"*": "dist"
},
"sort-packages": true
"sort-packages": true,
"classmap-authoritative": true
},
"autoload": {
"classmap": [
"core",
"application"
"application",
"sources/application",
"sources/Composer"
],
"exclude-from-classmap": [
"core/dbobjectsearch.class.php",
@@ -73,5 +75,10 @@
"allow-contrib": false,
"require": "3.4.*"
}
},
"scripts": {
"post-install-cmd": ["@rmDeniedTestDir"],
"post-update-cmd": ["@rmDeniedTestDir"],
"rmDeniedTestDir": "@php .make/composer/rmDeniedTestDir.php"
}
}
}

116
composer.lock generated
View File

@@ -4,20 +4,20 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "554231903f26fc1944cd123d64adb410",
"content-hash": "b29eb2767d269b9ec2cf4d148dc083bc",
"packages": [
{
"name": "combodo/tcpdf",
"version": "6.3.0",
"version": "6.3.4",
"source": {
"type": "git",
"url": "https://github.com/combodo-itop-libs/TCPDF.git",
"reference": "d645f9438b757499ac4cb39c10c41ded0f9f0326"
"reference": "fe1c625d33e8f7d872d6fb69fb0255fd0e5cee2d"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/combodo-itop-libs/TCPDF/zipball/d645f9438b757499ac4cb39c10c41ded0f9f0326",
"reference": "d645f9438b757499ac4cb39c10c41ded0f9f0326",
"url": "https://api.github.com/repos/combodo-itop-libs/TCPDF/zipball/fe1c625d33e8f7d872d6fb69fb0255fd0e5cee2d",
"reference": "fe1c625d33e8f7d872d6fb69fb0255fd0e5cee2d",
"shasum": ""
},
"require": {
@@ -49,9 +49,14 @@
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"LGPL-3.0"
"LGPL-3.0-only"
],
"authors": [
{
"name": "Nicola Asuni",
"email": "info@tecnick.com",
"role": "lead"
},
{
"name": "Combodo",
"email": "contact@combodo.com"
@@ -59,7 +64,58 @@
],
"description": "TCPDF fork adding requirements for iTop: Specific fonts.",
"homepage": "https://github.com/combodo-itop-libs/TCPDF",
"time": "2019-08-16T08:14:13+00:00"
"time": "2020-02-12T14:16:56+00:00"
},
{
"name": "nikic/php-parser",
"version": "v3.1.5",
"source": {
"type": "git",
"url": "https://github.com/nikic/PHP-Parser.git",
"reference": "bb87e28e7d7b8d9a7fda231d37457c9210faf6ce"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/bb87e28e7d7b8d9a7fda231d37457c9210faf6ce",
"reference": "bb87e28e7d7b8d9a7fda231d37457c9210faf6ce",
"shasum": ""
},
"require": {
"ext-tokenizer": "*",
"php": ">=5.5"
},
"require-dev": {
"phpunit/phpunit": "~4.0|~5.0"
},
"bin": [
"bin/php-parse"
],
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "3.0-dev"
}
},
"autoload": {
"psr-4": {
"PhpParser\\": "lib/PhpParser"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"BSD-3-Clause"
],
"authors": [
{
"name": "Nikita Popov"
}
],
"description": "A PHP parser written in PHP",
"keywords": [
"parser",
"php"
],
"time": "2018-02-28T20:30:58+00:00"
},
{
"name": "paragonie/random_compat",
@@ -112,16 +168,16 @@
},
{
"name": "pear/archive_tar",
"version": "1.4.7",
"version": "1.4.9",
"source": {
"type": "git",
"url": "https://github.com/pear/Archive_Tar.git",
"reference": "7e48add6f8edc3027dd98ad15964b1a28fd0c845"
"reference": "c5b00053770e1d72128252c62c2c1a12c26639f0"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/pear/Archive_Tar/zipball/7e48add6f8edc3027dd98ad15964b1a28fd0c845",
"reference": "7e48add6f8edc3027dd98ad15964b1a28fd0c845",
"url": "https://api.github.com/repos/pear/Archive_Tar/zipball/c5b00053770e1d72128252c62c2c1a12c26639f0",
"reference": "c5b00053770e1d72128252c62c2c1a12c26639f0",
"shasum": ""
},
"require": {
@@ -174,7 +230,7 @@
"archive",
"tar"
],
"time": "2019-04-08T13:15:55+00:00"
"time": "2019-12-04T10:17:28+00:00"
},
{
"name": "pear/console_getopt",
@@ -588,23 +644,25 @@
},
{
"name": "scssphp/scssphp",
"version": "1.0.0",
"version": "1.0.6",
"source": {
"type": "git",
"url": "https://github.com/scssphp/scssphp.git",
"reference": "6c8734b6edcf6c2fa785ad874b998fa854a7d030"
"reference": "5b3c9d704950d8f9637f5110c36c281ec47dc13c"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/scssphp/scssphp/zipball/6c8734b6edcf6c2fa785ad874b998fa854a7d030",
"reference": "6c8734b6edcf6c2fa785ad874b998fa854a7d030",
"url": "https://api.github.com/repos/scssphp/scssphp/zipball/5b3c9d704950d8f9637f5110c36c281ec47dc13c",
"reference": "5b3c9d704950d8f9637f5110c36c281ec47dc13c",
"shasum": ""
},
"require": {
"php": "^5.6.0 || ^7"
"ext-ctype": "*",
"ext-json": "*",
"php": ">=5.6.0"
},
"require-dev": {
"phpunit/phpunit": "~4.6",
"phpunit/phpunit": "^5.7 || ^6.5 || ^7.5 || ^8.3",
"squizlabs/php_codesniffer": "~2.5",
"twbs/bootstrap": "~4.3",
"zurb/foundation": "~6.5"
@@ -643,20 +701,20 @@
"scss",
"stylesheet"
],
"time": "2019-06-05T01:22:01+00:00"
"time": "2019-12-12T05:00:52+00:00"
},
{
"name": "swiftmailer/swiftmailer",
"version": "v5.4.9",
"version": "v5.4.12",
"source": {
"type": "git",
"url": "https://github.com/swiftmailer/swiftmailer.git",
"reference": "7ffc1ea296ed14bf8260b6ef11b80208dbadba91"
"reference": "181b89f18a90f8925ef805f950d47a7190e9b950"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/swiftmailer/swiftmailer/zipball/7ffc1ea296ed14bf8260b6ef11b80208dbadba91",
"reference": "7ffc1ea296ed14bf8260b6ef11b80208dbadba91",
"url": "https://api.github.com/repos/swiftmailer/swiftmailer/zipball/181b89f18a90f8925ef805f950d47a7190e9b950",
"reference": "181b89f18a90f8925ef805f950d47a7190e9b950",
"shasum": ""
},
"require": {
@@ -697,7 +755,7 @@
"mail",
"mailer"
],
"time": "2018-01-23T07:37:21+00:00"
"time": "2018-07-31T09:26:32+00:00"
},
{
"name": "symfony/cache",
@@ -2521,13 +2579,13 @@
"prefer-lowest": false,
"platform": {
"php": ">=5.6.0",
"ext-soap": "*",
"ext-ctype": "*",
"ext-dom": "*",
"ext-gd": "*",
"ext-iconv": "*",
"ext-json": "*",
"ext-mysqli": "*",
"ext-dom": "*",
"ext-iconv": "*",
"ext-gd": "*",
"ext-ctype": "*"
"ext-soap": "*"
},
"platform-dev": [],
"platform-overrides": {

View File

@@ -457,7 +457,7 @@ class Str
public static function gpc2pure($gpc)
{
if (ini_get('magic_quotes_sybase')) $pure = str_replace("''", "'", $gpc);
else $pure = get_magic_quotes_gpc() ? stripslashes($gpc) : $gpc;
else $pure = $gpc;
return $pure;
}
public static function html2pure($html)

File diff suppressed because it is too large Load Diff

View File

@@ -82,7 +82,8 @@ interface iScheduledProcess extends iProcess
*
* Other info (module name and time default value) should be provided using a method that needs to be implemented.
*
* @since 2.7.0
* @since 2.7.0 PR #89
* @since 2.7.0-2 N°2580 Fix {@link GetNextOccurrence} returning wrong value
*/
abstract class AbstractWeeklyScheduledProcess implements iScheduledProcess
{
@@ -191,7 +192,8 @@ abstract class AbstractWeeklyScheduledProcess implements iScheduledProcess
}
$oNow = new DateTime();
$iNextPos = false;
for ($iDay = $oNow->format('N'); $iDay <= 7; $iDay++)
$sDay = $oNow->format('N');
for ($iDay = (int) $sDay; $iDay <= 7; $iDay++)
{
$iNextPos = array_search($iDay, $aDays, true);
if ($iNextPos !== false)

View File

@@ -64,7 +64,7 @@ class MySQLException extends CoreException
/**
* Class MySQLQueryHasNoResultException
*
* @since 2.5
* @since 2.5.0
*/
class MySQLQueryHasNoResultException extends MySQLException
{
@@ -74,7 +74,7 @@ class MySQLQueryHasNoResultException extends MySQLException
/**
* Class MySQLHasGoneAwayException
*
* @since 2.5
* @since 2.5.0
* @see itop bug 1195
* @see https://dev.mysql.com/doc/refman/5.7/en/gone-away.html
*/
@@ -126,12 +126,12 @@ class CMDBSource
protected static $m_sDBName;
/**
* @var boolean
* @since 2.5 N°1260 MySQL TLS first implementation
* @since 2.5.0 N°1260 MySQL TLS first implementation
*/
protected static $m_bDBTlsEnabled;
/**
* @var string
* @since 2.5 N°1260 MySQL TLS first implementation
* @since 2.5.0 N°1260 MySQL TLS first implementation
*/
protected static $m_sDBTlsCA;
@@ -1390,7 +1390,7 @@ class CMDBSource
* @return string query to upgrade table charset and collation if needed, null if not
* @throws \MySQLException
*
* @since 2.5 N°1001 switch to utf8mb4
* @since 2.5.0 N°1001 switch to utf8mb4
* @see https://dev.mysql.com/doc/refman/5.7/en/charset-table.html
*/
public static function DBCheckTableCharsetAndCollation($sTableName)
@@ -1540,7 +1540,7 @@ class CMDBSource
* @return string query to upgrade database charset and collation if needed, null if not
* @throws \MySQLException
*
* @since 2.5 N°1001 switch to utf8mb4
* @since 2.5.0 N°1001 switch to utf8mb4
* @see https://dev.mysql.com/doc/refman/5.7/en/charset-database.html
*/
public static function DBCheckCharsetAndCollation()

View File

@@ -1,35 +1,44 @@
<?php
// Copyright (C) 2010-2014 Combodo SARL
//
// This file is part of iTop.
//
// iTop is free software; you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// iTop 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 Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with iTop. If not, see <http://www.gnu.org/licenses/>
/**
* Copyright (C) 2010-2020 Combodo SARL
*
* This file is part of iTop.
*
* iTop is free software; you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* iTop 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with iTop. If not, see <http://www.gnu.org/licenses/>
*/
/**
* Any extension to compute things like a stop watch deadline or working hours
* Any extension to compute things like a stop watch deadline or working hours
*
* @copyright Copyright (C) 2010-2012 Combodo SARL
* @license http://opensource.org/licenses/AGPL-3.0
*/
/**
* Metric computing for stop watches
* Metric computing for stop watches.
* Can be used for AttributeStopWatch goal (iTop XML node xpath: /itop_design/classes/class/fields/field/goal)
*/
interface iMetricComputer
{
public static function GetDescription();
/**
* @param \DBObject $oObject
*
* @return float number of seconds for the time limit
*/
public function ComputeMetric($oObject);
}
@@ -41,21 +50,21 @@ interface iWorkingTimeComputer
public static function GetDescription();
/**
* Get the date/time corresponding to a given delay in the future from the present
* considering only the valid (open) hours for a specified object
* @param $oObject DBObject The object for which to compute the deadline
* @param $iDuration integer The duration (in seconds) in the future
* @param $oStartDate DateTime The starting point for the computation
* @return DateTime The date/time for the deadline
* @param DBObject $oObject The object for which to compute the deadline
* @param integer $iDuration The duration (in seconds) in the future
* @param DateTime $oStartDate The starting point for the computation
*
* @return DateTime The date/time corresponding to a given delay in the future from the present
* considering only the valid (open) hours for a specified object
*/
public function GetDeadline($oObject, $iDuration, DateTime $oStartDate);
/**
* Get duration (considering only open hours) elapsed bewteen two given DateTimes
* @param $oObject DBObject The object for which to compute the duration
* @param $oStartDate DateTime The starting point for the computation (default = now)
* @param $oEndDate DateTime The ending point for the computation (default = now)
* @return integer The duration (number of seconds) of open hours elapsed between the two dates
* @param DBObject $oObject The object for which to compute the duration
* @param DateTime $oStartDate The starting point for the computation (default = now)
* @param DateTime $oEndDate The ending point for the computation (default = now)
*
* @return integer The duration (number of seconds) elapsed between two given dates, considering only open hours
*/
public function GetOpenDuration($oObject, DateTime $oStartDate, DateTime $oEndDate);
}
@@ -87,12 +96,7 @@ class DefaultWorkingTimeComputer implements iWorkingTimeComputer
}
/**
* Get the date/time corresponding to a given delay in the future from the present
* considering only the valid (open) hours for a specified object
* @param $oObject DBObject The object for which to compute the deadline
* @param $iDuration integer The duration (in seconds) in the future
* @param $oStartDate DateTime The starting point for the computation
* @return DateTime The date/time for the deadline
* @inheritDoc
*/
public function GetDeadline($oObject, $iDuration, DateTime $oStartDate)
{
@@ -113,11 +117,7 @@ class DefaultWorkingTimeComputer implements iWorkingTimeComputer
}
/**
* Get duration (considering only open hours) elapsed bewteen two given DateTimes
* @param $oObject DBObject The object for which to compute the duration
* @param $oStartDate DateTime The starting point for the computation (default = now)
* @param $oEndDate DateTime The ending point for the computation (default = now)
* @return integer The duration (number of seconds) of open hours elapsed between the two dates
* @inheritDoc
*/
public function GetOpenDuration($oObject, DateTime $oStartDate, DateTime $oEndDate)
{
@@ -134,6 +134,3 @@ class DefaultWorkingTimeComputer implements iWorkingTimeComputer
return $iDuration;
}
}
?>

View File

@@ -25,6 +25,7 @@ define('ITOP_APPLICATION_SHORT', 'iTop');
define('ITOP_VERSION', '2.7.0-dev');
define('ITOP_REVISION', 'svn');
define('ITOP_BUILD_DATE', '$WCNOW$');
define('ITOP_VERSION_FULL', ITOP_VERSION.'-'.ITOP_REVISION);
define('ACCESS_USER_WRITE', 1);
define('ACCESS_ADMIN_WRITE', 2);
@@ -89,7 +90,16 @@ class Config
protected $m_aWebServiceCategories;
protected $m_aAddons;
/** @var ConfigPlaceholdersResolver */
private $oConfigPlaceholdersResolver;
protected $m_aModuleSettings;
/**
* @var \iTopConfigParser|null
*/
private $oItopConfigParser;
//for each conf entry, whether the non interpreted value can be kept in case is is written back to the disk.
private $m_aCanOverrideSettings;
/**
* New way to store the settings !
@@ -351,7 +361,7 @@ class Config
'source_of_value' => '',
'show_in_conf_sample' => true,
),
'export_pdf_font' => array( // @since 2.7 PR #49
'export_pdf_font' => array( // @since 2.7.0 PR #49 / N°1947
'type' => 'string',
'description' => 'Font used when generating a PDF file',
'default' => 'DejaVuSans', // DejaVuSans is a UTF-8 Unicode font, embedded in the TCPPDF lib we're using
@@ -395,8 +405,8 @@ class Config
),
'log_filename_builder_impl' => array(
'type' => 'string',
'description' => 'Name of the ILogFileNameBuilder to use',
'default' => 'WeeklyRotatingLogFileNameBuilder',
'description' => 'Name of the iLogFileNameBuilder to use',
'default' => 'MonthlyRotatingLogFileNameBuilder',
'value' => '',
'source_of_value' => '',
'show_in_conf_sample' => false,
@@ -930,15 +940,6 @@ class Config
'source_of_value' => '',
'show_in_conf_sample' => false,
),
'portal_tickets' => array(
'type' => 'string',
'description' => 'CSV list of classes supported in the portal',
// examples... not used
'default' => 'UserRequest',
'value' => 'UserRequest',
'source_of_value' => '',
'show_in_conf_sample' => true,
),
'portal_dispatch_urls' => array(
'type' => 'array',
'description' => 'Associative array of sPortalId => Home page URL (relatively to the application root)',
@@ -1250,6 +1251,8 @@ class Config
),
);
public function IsProperty($sPropCode)
{
return (array_key_exists($sPropCode, $this->m_aSettings));
@@ -1278,12 +1281,16 @@ class Config
* @param string $sPropCode
* @param mixed $value
* @param string $sSourceDesc mandatory for variables with show_in_conf_sample=false
* @param bool $bCanOverride whether the written to file value can still be the non evaluated version on must be the literal
*
* @throws \CoreException
*/
public function Set($sPropCode, $value, $sSourceDesc = 'unknown')
public function Set($sPropCode, $value, $sSourceDesc = 'unknown', $bCanOverride = false)
{
$sType = $this->m_aSettings[$sPropCode]['type'];
$value = $this->oConfigPlaceholdersResolver->Resolve($value);
switch ($sType)
{
case 'bool':
@@ -1303,8 +1310,16 @@ class Config
default:
throw new CoreException('Unknown type for setting', array('property' => $sPropCode, 'type' => $sType));
}
if ($this->m_aSettings[$sPropCode]['value'] == $value)
{
//when you set the exact same value than the previous one, then, you still can preserve the non evaluated version and so on preserve vars/jokers.
$bCanOverride = true;
}
$this->m_aSettings[$sPropCode]['value'] = $value;
$this->m_aSettings[$sPropCode]['source_of_value'] = $sSourceDesc;
$this->m_aCanOverrideSettings[$sPropCode] = $bCanOverride;
}
/**
@@ -1398,6 +1413,8 @@ class Config
*/
public function __construct($sConfigFile = null, $bLoadConfig = true)
{
$this->oConfigPlaceholdersResolver = new ConfigPlaceholdersResolver();
$this->m_sFile = $sConfigFile;
if (is_null($sConfigFile))
{
@@ -1558,7 +1575,7 @@ class Config
{
$value = $rawvalue;
}
$this->Set($sPropCode, $value, $sConfigFile);
$this->Set($sPropCode, $value, $sConfigFile, true);
}
}
@@ -1889,6 +1906,30 @@ class Config
{
$sFileName = $this->m_sFile;
}
$oHandle = null;
$sConfig = null;
if (is_file($this->m_sFile))
{
$oHandle = fopen($this->m_sFile, 'r');
$index = 0;
while (!flock($oHandle, LOCK_SH))
{
if ($index > 50)
{
throw new ConfigException("Could not read to configuration file", array('file' => $this->m_sFile));
}
usleep(100000);
$index++;
}
$sConfig = file_get_contents($this->m_sFile);
}
$this->oItopConfigParser = new iTopConfigParser($sConfig);
if ($oHandle !==null)
{
flock($oHandle, LOCK_UN);
}
$hFile = @fopen($sFileName, 'w');
if ($hFile !== false)
{
@@ -1962,30 +2003,28 @@ class Config
// Write all values that are either always visible or present in the cloned config file
if ($aSettingInfo['show_in_conf_sample'] || (!empty($aSettingInfo['source_of_value']) && ($aSettingInfo['source_of_value'] != 'unknown')))
{
$sType = $aSettingInfo['type'];
switch ($sType)
{
case 'bool':
$sSeenAs = $aSettingInfo['value'] ? 'true' : 'false';
break;
default:
$sSeenAs = self::PrettyVarExport($aSettingInfo['value'], "\t");
}
fwrite($hFile, "\n");
if (isset($aSettingInfo['description']))
{
fwrite($hFile, "\t// $sPropCode: {$aSettingInfo['description']}\n");
}
if (isset($aSettingInfo['default']))
{
$default = $aSettingInfo['default'];
if ($aSettingInfo['type'] == 'bool')
{
$default = $default ? 'true' : 'false';
}
fwrite($hFile,
"\t//\tdefault: ".self::PrettyVarExport($aSettingInfo['default'], "\t//\t\t", true)."\n");
$sComment = self::PrettyVarExport(null,$aSettingInfo['default'], "\t//\t\t", true);
fwrite($hFile,"\t//\tdefault: {$sComment}\n");
}
if (isset($this->m_aCanOverrideSettings[$sPropCode]) && $this->m_aCanOverrideSettings[$sPropCode])
{
$aParserValue = $this->oItopConfigParser->GetVarValue('MySettings', $sPropCode);
}
else
{
$aParserValue = null;
}
$sSeenAs = self::PrettyVarExport($aParserValue,$aSettingInfo['value'], "\t");
fwrite($hFile, "\t'$sPropCode' => $sSeenAs,\n");
}
}
@@ -1999,7 +2038,7 @@ class Config
fwrite($hFile, "\t'$sModule' => array (\n");
foreach ($aProperties as $sProperty => $value)
{
$sNiceExport = self::PrettyVarExport($value, "\t\t");
$sNiceExport = self::PrettyVarExport($this->oItopConfigParser->GetVarValue('MyModuleSettings', $sProperty), $value, "\t\t");
fwrite($hFile, "\t\t'$sProperty' => $sNiceExport,\n");
}
fwrite($hFile, "\t),\n");
@@ -2012,19 +2051,26 @@ class Config
fwrite($hFile, " *\n");
fwrite($hFile, " */\n");
fwrite($hFile, "\$MyModules = array(\n");
fwrite($hFile, "\t'addons' => array (\n");
foreach ($this->m_aAddons as $sKey => $sFile)
$aParserValue = $this->oItopConfigParser->GetVarValue('MyModules', 'addons');
if ($aParserValue['found'])
{
fwrite($hFile, "\t\t'$sKey' => '$sFile',\n");
fwrite($hFile, "\t'addons' => {$aParserValue['value']},\n");
}
else
{
fwrite($hFile, "\t'addons' => array (\n");
foreach ($this->m_aAddons as $sKey => $sFile)
{
fwrite($hFile, "\t\t'$sKey' => '$sFile',\n");
}
fwrite($hFile, "\t),\n");
}
fwrite($hFile, "\t),\n");
fwrite($hFile, ");\n");
fwrite($hFile, '?'.'>'); // Avoid perturbing the syntax highlighting !
$bReturn = fclose($hFile);
utils::SetConfig($this);
FileLog::RenameLegacyLogFiles();
return $bReturn;
}
@@ -2211,6 +2257,7 @@ class Config
/**
* Pretty format a var_export'ed value so that (if possible) the identation is preserved on every line
*
* @param array $aParserValue
* @param mixed $value The value to export
* @param string $sIndentation The string to use to indent the text
* @param bool $bForceIndentation Forces the identation (enven if it breaks/changes an eval, for example to ouput a
@@ -2218,8 +2265,13 @@ class Config
*
* @return string The indented export string
*/
protected static function PrettyVarExport($value, $sIndentation, $bForceIndentation = false)
protected static function PrettyVarExport($aParserValue, $value, $sIndentation, $bForceIndentation = false)
{
if (is_array($aParserValue) && $aParserValue['found'])
{
return $aParserValue['value'];
}
$sExport = var_export($value, true);
$sNiceExport = str_replace(array("\r\n", "\n", "\r"), "\n".$sIndentation, trim($sExport));
if (!$bForceIndentation)
@@ -2239,3 +2291,99 @@ class Config
}
}
class ConfigPlaceholdersResolver
{
/**
* @var null|array
*/
private $aEnv;
/**
* @var null|array
*/
private $aServer;
public function __construct($aEnv = null, $aServer = null)
{
$this->aEnv = $aEnv ?: $_ENV;
$this->aServer = $aServer ?: $_SERVER;
}
public function Resolve($rawValue)
{
if (empty($this->aEnv['ITOP_CONFIG_PLACEHOLDERS']) && empty($this->aServer['ITOP_CONFIG_PLACEHOLDERS']))
{
return $rawValue;
}
if (is_array($rawValue))
{
$aResolvedRawValue = array();
foreach ($rawValue as $key => $value)
{
$aResolvedRawValue[$key] = $this->Resolve($value);
}
return $aResolvedRawValue;
}
if (!is_string($rawValue))
{
return $rawValue;
}
$sPattern = '/\%(env|server)\((\w+)\)(?:\?:(\w*))?\%/'; //3 capturing groups, ie `%env(HTTP_PORT)?:8080%` produce: `env` `HTTP_PORT` and `8080`.
if (! preg_match_all($sPattern, $rawValue, $aMatchesCollection, PREG_SET_ORDER))
{
return $rawValue;
}
$sValue = $rawValue;
foreach ($aMatchesCollection as $aMatches)
{
$sWholeMask = $aMatches[0];
$sSource = $aMatches[1];
$sKey = $aMatches[2];
$sDefault = isset($aMatches[3]) ? $aMatches[3] : null;
$sReplacement = $this->Get($sSource, $sKey, $sDefault, $sWholeMask);
$sValue = str_replace($sWholeMask, $sReplacement, $sValue);
}
return $sValue;
}
private function Get($sSourceName, $sKey, $sDefault, $sWholeMask)
{
if ('env' == $sSourceName)
{
$aSource = $this->aEnv;
}
else if ('server' == $sSourceName)
{
$aSource = $this->aServer;
}
else
{
$sErrorMessage = sprintf('unsupported source name "%s" into "%s"', $sSourceName, $sWholeMask);
IssueLog::Error($sErrorMessage, self::class, array($sSourceName, $sKey, $sDefault, $sWholeMask));
throw new ConfigException($sErrorMessage);
}
if (array_key_exists($sKey, $aSource))
{
return $aSource[$sKey];
}
if (null !== $sDefault)
{
return $sDefault;
}
$sErrorMessage = sprintf('key "%s" not found into "%s" while expanding', $sSourceName, $sWholeMask);
IssueLog::Error($sErrorMessage, self::class, array($sSourceName, $sKey, $sDefault, $sWholeMask));
throw new ConfigException($sErrorMessage);
}
}

View File

@@ -19,14 +19,14 @@
/**
* Simple helper class for keeping track of the context inside the call stack
*
*
* To check (anywhere in the code) if a particular context tag is present
* in the call stack simply do:
*
*
* if (ContextTag::Check(<the_tag>)) ...
*
*
* For example to know if the code is being executed in the context of a portal do:
*
*
* if (ContextTag::Check('GUI:Portal'))
*
* @copyright Copyright (C) 2016-2017 Combodo SARL
@@ -35,8 +35,15 @@
class ContextTag
{
const TAG_PORTAL = 'GUI:Portal';
const TAG_CRON = 'CRON';
const TAG_CONSOLE = 'GUI:Console';
const TAG_SETUP = 'Setup';
const TAG_SYNCHRO = 'Synchro';
const TAG_REST = 'REST/JSON';
protected static $aStack = array();
/**
* Store a context tag on the stack
* @param string $sTag
@@ -46,6 +53,11 @@ class ContextTag
static::$aStack[] = $sTag;
}
public static function AddContext($sTag)
{
static::$aStack[] = $sTag;
}
/**
* Cleanup the context stack
*/
@@ -53,7 +65,7 @@ class ContextTag
{
array_pop(static::$aStack);
}
/**
* Check if a given tag is present in the stack
* @param string $sTag
@@ -63,13 +75,53 @@ class ContextTag
{
return in_array($sTag, static::$aStack);
}
/**
* Get the whole stack as an array
* @return hash
* @return array
*/
public static function GetStack()
{
return static::$aStack;
}
}
/**
* Get all the predefined context tags
* @return array
*/
public static function GetTags()
{
$aRawTags = array(
ContextTag::TAG_REST,
ContextTag::TAG_SYNCHRO,
ContextTag::TAG_SETUP,
ContextTag::TAG_CONSOLE,
ContextTag::TAG_CRON,
ContextTag::TAG_PORTAL);
$aTags = array();
foreach ($aRawTags as $sRawTag)
{
$aTags[$sRawTag] = Dict::S("Core:Context={$sRawTag}");
}
$aPortalsConf = PortalDispatcherData::GetData();
$aDispatchers = array();
foreach ($aPortalsConf as $sPortalId => $aConf)
{
$sHandlerClass = $aConf['handler'];
$aDispatchers[$sPortalId] = new $sHandlerClass($sPortalId);
}
foreach ($aDispatchers as $sPortalId => $oDispatcher)
{
if ($sPortalId != 'backoffice')
{
$aTags['Portal:'.$sPortalId] = $oDispatcher->GetLabel();
}
}
return $aTags;
}
}

View File

@@ -115,7 +115,7 @@ class CoreException extends Exception
* @see \DBObject::DBInsertNoReload()
* @see \DBObject::DBUpdate()
*
* @since 2.6 N°659 uniqueness constraint
* @since 2.6.0 N°659 uniqueness constraint
*/
class CoreCannotSaveObjectException extends CoreException
{

View File

@@ -24,6 +24,7 @@
*/
final class ItopCounter
{
/**
* Key based counter.
* The counter is protected against concurrency script.
@@ -35,13 +36,9 @@ final class ItopCounter
* * `0` when no $oNewObjectValueProvider is given (or null)
* * `$oNewObjectValueProvider() + 1` otherwise
*
* @throws \ArchivedObjectException
* @throws \CoreCannotSaveObjectException
* @throws \CoreException
* @throws \CoreOqlMultipleResultsForbiddenException
* @throws \CoreUnexpectedValue
* @throws \MySQLException
* @throws \OQLException
* @throws \Exception
*/
public static function Inc($sCounterName, $oNewObjectValueProvider = null)
{
@@ -50,35 +47,91 @@ final class ItopCounter
$oiTopMutex = new iTopMutex($sMutexKeyName);
$oiTopMutex->Lock();
$oFilter = DBObjectSearch::FromOQL('SELECT KeyValueStore WHERE key_name=:key_name AND namespace=:namespace', array(
'key_name' => $sCounterName,
'namespace' => $sSelfClassName,
));
$oCounter = $oFilter->GetFirstResult();
if (is_null($oCounter))
$bIsInsideTransaction = CMDBSource::IsInsideTransaction();
if ($bIsInsideTransaction)
{
if (null != $oNewObjectValueProvider)
// # Transaction isolation hack:
// When inside a transaction, we need to open a new connection for the counter.
// So it is visible immediately to the connections outside of the transaction.
// Either way, the lock is not long enought, and there would be duplicate ref.
//
// SELECT ... FOR UPDATE would have also worked but with the cost of extra long lock (until the commit),
// we did not wanted this! As opening a short connection is less prone to starving than a long running one.
// Plus it would trigger way more deadlocks!
$hDBLink = self::InitMySQLSession();
}
else
{
$hDBLink = CMDBSource::GetMysqli();
}
try
{
$oFilter = DBObjectSearch::FromOQL('SELECT KeyValueStore WHERE key_name=:key_name AND namespace=:namespace', array(
'key_name' => $sCounterName,
'namespace' => $sSelfClassName,
));
$oAttDef = MetaModel::GetAttributeDef('KeyValueStore', 'value');
$aAttToLoad = array('KeyValueStore' => array('value' => $oAttDef));
$sSql = $oFilter->MakeSelectQuery(array(), array(), $aAttToLoad);
$hResult = mysqli_query($hDBLink, $sSql);
$aCounter = mysqli_fetch_array($hResult, MYSQLI_NUM);
mysqli_free_result($hResult);
//Rebuild the filter, as the MakeSelectQuery polluted the orignal and it cannot be reused
$oFilter = DBObjectSearch::FromOQL('SELECT KeyValueStore WHERE key_name=:key_name AND namespace=:namespace', array(
'key_name' => $sCounterName,
'namespace' => $sSelfClassName,
));
if (is_null($aCounter))
{
$iComputedValue = $oNewObjectValueProvider();
if (null != $oNewObjectValueProvider)
{
$iComputedValue = $oNewObjectValueProvider();
}
else
{
$iComputedValue = 0;
}
$iCurrentValue = $iComputedValue + 1;
$aQueryParams = array(
'key_name' => $sCounterName,
'value' => "$iCurrentValue",
'namespace' => $sSelfClassName,
);
$sSql = $oFilter->MakeInsertQuery($aQueryParams);
}
else
{
$iComputedValue = 0;
$iCurrentValue = (int) $aCounter[1];
$iCurrentValue++;
$aQueryParams = array(
'value' => "$iCurrentValue",
);
$sSql = $oFilter->MakeUpdateQuery($aQueryParams);
}
$oCounter = MetaModel::NewObject('KeyValueStore', array(
'key_name' => $sCounterName,
'value' => $iComputedValue,
'namespace' => $sSelfClassName,
));
$hResult = mysqli_query($hDBLink, $sSql);
}
catch(Exception $e)
{
IssueLog::Error($e->getMessage());
throw $e;
}
finally
{
if ($bIsInsideTransaction)
{
mysqli_close($hDBLink);
}
$oiTopMutex->Unlock();
}
$iCurrentValue = (int) $oCounter->Get('value');
$iCurrentValue++;
$oCounter->Set('value', $iCurrentValue);
$oCounter->DBWrite();
$oiTopMutex->Unlock();
return $iCurrentValue;
}
@@ -114,6 +167,32 @@ final class ItopCounter
return self::Inc($sRootClass, $oNewObjectCallback);
}
/**
* @return \mysqli
* @throws \ConfigException
* @throws \CoreException
* @throws \MySQLException
*/
private static function InitMySQLSession()
{
$oConfig = utils::GetConfig();
$sDBHost = $oConfig->Get('db_host');
$sDBUser = $oConfig->Get('db_user');
$sDBPwd = $oConfig->Get('db_pwd');
$sDBName = $oConfig->Get('db_name');
$bDBTlsEnabled = $oConfig->Get('db_tls.enabled');
$sDBTlsCA = $oConfig->Get('db_tls.ca');
$hDBLink = CMDBSource::GetMysqliInstance($sDBHost, $sDBUser, $sDBPwd, $sDBName, $bDBTlsEnabled, $sDBTlsCA, false);
if (!$hDBLink)
{
throw new Exception("Could not connect to the DB server (host=$sDBHost, user=$sDBUser): ".mysqli_connect_error().' (mysql errno: '.mysqli_connect_errno().')');
}
return $hDBLink;
}
}
@@ -130,7 +209,7 @@ class KeyValueStore extends DBObject
public static function Init()
{
$aParams = array(
'category' => 'bizmodel',
'category' => '',
'key_type' => 'autoincrement',
'name_attcode' => array('key_name'),
'state_attcode' => '',

View File

@@ -83,8 +83,9 @@ abstract class DBObject implements iDisplay
/** @var bool true IF the object is mapped to a DB record */
protected $m_bIsInDB = false;
protected $m_iKey = null;
/** @var array key: attcode, value: corresponding current value (in memory, before persisting object) */
/** @var array attcode => value : corresponding current value (the new value passed to {@see DBObject::Set()}). Reset during {@see DBObject::DBUpdate()} */
private $m_aCurrValues = array();
/** @var array attcode => value : previous values before the {@see DBObject::Set()} call. Array is reset at the end of {@see DBObject::DBUpdate()} */
protected $m_aOrigValues = array();
protected $m_aExtendedData = null;
@@ -97,7 +98,8 @@ abstract class DBObject implements iDisplay
private $m_bDirty = false;
/**
* @var boolean|null true if the object has been verified and is consistent with integrity rules. If null, then the check has to be performed again to know the status
* @var boolean|null true if the object has been verified and is consistent with integrity rules.
* If null, then the check has to be performed again to know the status
* @see CheckToWrite()
*/
private $m_bCheckStatus = null;
@@ -114,7 +116,7 @@ abstract class DBObject implements iDisplay
/**
* @var null|string[] list of warnings thrown during DB write
* @see CheckToWrite()
* @since 2.6 N°659 uniqueness constraints
* @since 2.6.0 N°659 uniqueness constraints
*/
protected $m_aCheckWarnings = null;
protected $m_aDeleteIssues = null;
@@ -134,10 +136,11 @@ abstract class DBObject implements iDisplay
*/
protected $m_aModifiedAtt = array();
/**
* @var array attname => currentvalue Persists changes for {@link DBUpdate}
* @var array attname => value : value before the last {@see DBObject::Set()} call. Set at the beginning of {@see DBObject::DBUpdate()}.
* @see DBObject::ListPreviousValuesForUpdatedAttributes() getter for this attribute
* @since 2.7.0 N°2293
*/
protected $m_aChanges;
protected $m_aPreviousValuesForUpdatedAttributes;
/**
* @var array Set of Synch data related to this object
* <ul>
@@ -642,7 +645,7 @@ abstract class DBObject implements iDisplay
* @throws \CoreException
* @throws \CoreUnexpectedValue
* @throws \Exception
* @since 2.6
* @since 2.6.0
*/
public function SetIfNull($sAttCode, $value)
{
@@ -698,21 +701,22 @@ abstract class DBObject implements iDisplay
return $oAttDef->GetLabel();
}
/**
* Getter : get a value from the current object of from a related object
*
* Get the value of the attribute $sAttCode
* This call may involve an object reload if the object was not completely loaded (lazy loading)
*
* @api
*
* @param string $sAttCode Could be an extended attribute code in the form extkey_id->anotherkey_id->remote_attr
*
* @return mixed|string
*
* @throws ArchivedObjectException
* @throws CoreException
*/
/**
* Getter : get a value from the current object of from a related object
*
* Get the value of the attribute $sAttCode
* This call may involve an object reload if the object was not completely loaded (lazy loading)
*
* @api
*
* @param string $sAttCode Could be an extended attribute code in the form extkey_id->anotherkey_id->remote_attr
*
* @return mixed|string
*
* @throws \ArchivedObjectException
* @throws \CoreException
* @throws \Exception
*/
public function Get($sAttCode)
{
if (($iPos = strpos($sAttCode, '->')) === false)
@@ -852,17 +856,13 @@ abstract class DBObject implements iDisplay
}
/**
* Get the value as it was before change with Set
*
* The original value vary according to the persisted state
* - not persisted: NULL
* - persisted: the "in DB" value
*
* @param string $sAttCode
*
* @return mixed|null the original value
* @return mixed|null the value as it was before changed with {@see DBObject::Set()}.
* Returns null if the attribute wasn't changed.
*
* @throws CoreException
* @see DBObject::$m_aOrigValues
* @throws CoreException if the attribute is unknown for the current object
*/
public function GetOriginal($sAttCode)
{
@@ -1072,21 +1072,20 @@ abstract class DBObject implements iDisplay
}
/**
* Get $sAttCode formatted as HTML
*
* The returned string is already escaped, and as such is protected against XSS
* The markup relies on a few assumptions (CSS) that could change without notice
*
* @api
*
* @param string $sAttCode
* @param bool $bLocalize
*
* @return string
* @return string $sAttCode formatted as HTML for the console details forms (when viewing, not when editing !)
* The returned string is already escaped, and as such is protected against XSS
* The markup relies on a few assumptions (CSS) that could change without notice
*
* @throws ArchivedObjectException
* @throws CoreException
* @throws DictExceptionMissingString
*
* @see \Combodo\iTop\Form\Field\Field for rendering in portal forms
*/
public function GetAsHTML($sAttCode, $bLocalize = true)
{
@@ -1671,6 +1670,7 @@ abstract class DBObject implements iDisplay
*
* @return integer the binary combination of flags for the given attribute in the given state of the object.
* Values can be one of the OPT_ATT_HIDDEN, OPT_ATT_READONLY, OPT_ATT_MANDATORY, ... (see define in metamodel.class.php)
* Combine multiple values using the "|" operator, for example `OPT_ATT_READONLY | OPT_ATT_HIDDEN`.
*
* @throws \CoreException
*
@@ -1912,7 +1912,7 @@ abstract class DBObject implements iDisplay
return "Bad type";
}
elseif ($oAtt instanceof AttributeClassAttCodeSet)
elseif (($oAtt instanceof AttributeClassAttCodeSet) || ($oAtt instanceof AttributeEnumSet))
{
if (is_string($toCheck))
{
@@ -1988,7 +1988,7 @@ abstract class DBObject implements iDisplay
* @throws \CoreException
* @throws \OQLException
*
* @since 2.6 N°659 uniqueness constraint
* @since 2.6.0 N°659 uniqueness constraint
* @api
*/
protected function DoCheckUniqueness()
@@ -2036,7 +2036,7 @@ abstract class DBObject implements iDisplay
* @return string dict key : Class:$sClassName/UniquenessRule:$sUniquenessRuleId if none then will use Core:UniquenessDefaultError
* Dictionary keys can contain "$this" placeholders
*
* @since 2.6 N°659 uniqueness constraint
* @since 2.6.0 N°659 uniqueness constraint
*/
protected function GetUniquenessRuleMessage($sUniquenessRuleId)
{
@@ -2088,7 +2088,7 @@ abstract class DBObject implements iDisplay
* @return \DBSearch
* @throws \CoreException
* @throws \OQLException
* @since 2.6 N°659 uniqueness constraint
* @since 2.6.0 N°659 uniqueness constraint
* @api
*/
protected function GetSearchForUniquenessRule($sUniquenessRuleId, $aUniquenessRuleProperties)
@@ -2237,7 +2237,7 @@ abstract class DBObject implements iDisplay
/**
* Check if it is allowed to delete the existing object from the database
*
* an array of displayable error is added in {@link $m_aDeleteIssues}
* an array of displayable error is added in {@see DBObject::$m_aDeleteIssues}
*
* @internal
*
@@ -2376,12 +2376,12 @@ abstract class DBObject implements iDisplay
}
/**
* List the attributes that have been changed since the object has been loaded from the DB
*
* @api
* @api-advanced
*
* @return array attname => currentvalue
* @return array attname => currentvalue List the attributes that have been changed using {@see DBObject::Set()}. Reset during {@see DBObject::DBUpdate()}
* @uses m_aCurrValues
* @see \DBObject::ListPreviousValuesForUpdatedAttributes()
* @throws Exception
*/
public function ListChanges()
@@ -2390,12 +2390,35 @@ abstract class DBObject implements iDisplay
{
return $this->ListChangedValues($this->m_aCurrValues);
}
else
{
return $this->m_aCurrValues;
}
return $this->m_aCurrValues;
}
/**
* @api
* @api-advanced
*
* To be used during the {@link \DBObject::DBUpdate()} call stack.
*
* To get values that were set to the changed fields, simply use {@link \DBObject::Get()}
*
* @return array attname => value : value that was present before the last {@see DBObject::Set()} call.
* This array is set at the beginning of {@see DBObject::DBpdate()} using {@see DBObject::InitPreviousValuesForUpdatedAttributes()}.
* @uses m_aPreviousValuesForUpdatedAttributes
* @see \DBObject::ListChanges()
* @since 2.7.0 N°2293
*/
public function ListPreviousValuesForUpdatedAttributes()
{
if (empty($this->m_aPreviousValuesForUpdatedAttributes))
{
return array();
}
return $this->m_aPreviousValuesForUpdatedAttributes;
}
/**
* Whether or not an object was modified since last read from the DB
* (ie: does it differ from the DB ?)
@@ -2642,7 +2665,7 @@ abstract class DBObject implements iDisplay
*
* @return int key of the newly created object
* @throws \ArchivedObjectException
* @throws \CoreCannotSaveObjectException if {@link CheckToWrite()} returns issues
* @throws \CoreCannotSaveObjectException if {@see DBObject::CheckToWrite()} returns issues
* @throws \CoreException
* @throws \CoreUnexpectedValue
* @throws \CoreWarning
@@ -2927,8 +2950,8 @@ abstract class DBObject implements iDisplay
/**
* @internal
*
* @deprecated 2.7.0 N°2361 simply use {@link DBInsert} instead, that will automatically create and persist a CMDBChange object.
* If you need to persist your own, call {@link CMDBObject::SetCurrentChange} before.
* @deprecated 2.7.0 N°2361 simply use {@see DBObject::DBInsert()} instead, that will automatically create and persist a CMDBChange object.
* If you need to persist your own, call {@see CMDBObject::SetCurrentChange()} before.
*
* @param CMDBChange $oChange
*
@@ -2944,8 +2967,8 @@ abstract class DBObject implements iDisplay
/**
* @internal
*
* @deprecated 2.7.0 N°2361 simply use {@link DBInsertNoReload} instead, that will automatically create and persist a CMDBChange object.
* If you need to persist your own, call {@link CMDBObject::SetCurrentChange} before.
* @deprecated 2.7.0 N°2361 simply use {@see DBObject::DBInsertNoReload()} instead, that will automatically create and persist a CMDBChange object.
* If you need to persist your own, call {@see CMDBObject::SetCurrentChange()} before.
*
* @param CMDBChange $oChange
*
@@ -3007,13 +3030,14 @@ abstract class DBObject implements iDisplay
/**
* Update an object in DB
*
* @api
* @see DBWrite
*
* @api
* @see DBObject::DBWrite()
*
* @return int object key
*
*
* @throws \CoreException
* @throws \CoreCannotSaveObjectException if CheckToWrite() returns issues
* @throws \Exception
*/
public function DBUpdate()
{
@@ -3030,7 +3054,8 @@ abstract class DBObject implements iDisplay
}
$aUpdateReentrance[$sKey] = true;
$this->m_aChanges = array(); // reset attribute to avoid stack collisions
$this->InitPreviousValuesForUpdatedAttributes();
try
{
$this->DoComputeValues();
@@ -3183,7 +3208,9 @@ abstract class DBObject implements iDisplay
$this->DBWriteLinks();
$this->WriteExternalAttributes();
$this->m_aChanges = $this->ListChanges(); // N°2293 save changes for use in user callbacks
// following lines are resetting changes (so after this {@see DBObject::ListChanges()} won't return changes anymore)
// new values are already in the object (call {@see DBObject::Get()} to get them)
// call {@see DBObject::ListPreviousValuesForUpdatedAttributes()} to get changed fields and previous values
$this->m_bDirty = false;
$this->m_aTouchedAtt = array();
$this->m_aModifiedAtt = array();
@@ -3287,12 +3314,36 @@ abstract class DBObject implements iDisplay
return $this->m_iKey;
}
/**
* @internal
* Save updated fields previous values for {@see DBObject::DBUpdate()} callbacks
* @see DBObject::ListPreviousValuesForUpdatedAttributes() to get the data in the callbacks
* @uses ListChanges
* @uses m_aOrigValues
* @uses m_aPreviousValuesForUpdatedAttributes
* @since 2.7.0 N°2293
* @throws \Exception
*/
private function InitPreviousValuesForUpdatedAttributes()
{
$aChanges= $this->ListChanges();
if (empty($aChanges))
{
$this->m_aPreviousValuesForUpdatedAttributes = array();
return;
}
$aPreviousValuesForUpdatedAttributes = array_intersect_key($this->m_aOrigValues, $aChanges);
$this->m_aPreviousValuesForUpdatedAttributes = $aPreviousValuesForUpdatedAttributes;
}
/**
*
* @internal
*
* @deprecated 2.7.0 N°2361 simply use {@link DBUpdate} instead, that will automatically create and persist a CMDBChange object.
* If you need to persist your own, call {@link CMDBObject::SetCurrentChange} before.
* @deprecated 2.7.0 N°2361 simply use {@see DBObject::DBUpdate()} instead, that will automatically create and persist a CMDBChange object.
* If you need to persist your own, call {@see CMDBObject::SetCurrentChange()} before.
*
* @param CMDBChange $oChange
*
@@ -3563,8 +3614,8 @@ abstract class DBObject implements iDisplay
/**
* @internal
*
* @deprecated 2.7.0 N°2361 simply use {@link DBDelete} instead.
* If you need to persist your own, call {@link CMDBObject::SetCurrentChange} before.
* @deprecated 2.7.0 N°2361 simply use {@see DBObject::DBDelete()} instead.
* If you need to persist your own, call {@see CMDBObject::SetCurrentChange()} before.
*
* @param CMDBChange $oChange
* @param boolean $bSkipStrongSecurity
@@ -3656,7 +3707,8 @@ abstract class DBObject implements iDisplay
if (!array_key_exists($sStimulusCode, $aStateTransitions))
{
// This simulus has no effect in the current state... do nothing
return true;
IssueLog::Error(get_class($this).": Transition $sStimulusCode is not allowed in ".$this->Get($sStateAttCode));
return false;
}
$aTransitionDef = $aStateTransitions[$sStimulusCode];
@@ -4116,13 +4168,15 @@ abstract class DBObject implements iDisplay
}
/**
* This method is called after the object is updated into DB. You can get changes using @link m_aChanges}.
*
* Warning : do not use {@link ListChanges} as it will return an empty array.
*
* @overwritable-hook You can extend this method in order to provide your own logic.
*
* @since 2.7.0 N°2293 can access object changes using {@link m_aChanges}
* This method is called after the object is updated into DB, and just before the {@see DBObject::Reload()} call.
*
* Warning : do not use {@see DBObject::ListChanges()} as it will return an empty array !
* Use instead {@see DBObject::ListPreviousValuesForUpdatedAttributes()} to get modified fields and their previous values,
* and {@see DBObject::Get()} to get the persisted value for a given attribute.
*
* @since 2.7.0 N°2293 can access object changes by calling {@see DBObject::ListPreviousValuesForUpdatedAttributes()}
*/
protected function AfterUpdate()
{

View File

@@ -223,9 +223,9 @@ class DBObjectSearch extends DBSearch
public function RenameAlias($sOldName, $sNewName)
{
$bFound = false;
if (array_key_exists($sOldName, $this->m_aClasses))
if (!array_key_exists($sOldName, $this->m_aClasses))
{
$bFound = true;
return false;
}
if (array_key_exists($sNewName, $this->m_aClasses))
{
@@ -528,7 +528,7 @@ class DBObjectSearch extends DBSearch
*
* @throws \CoreException
*
* @since 2.5 N°1418
* @since 2.5.0 N°1418
*/
public function AddConditionForInOperatorUsingParam($sFilterCode, $aValues, $bPositiveMatch = true)
{
@@ -1798,6 +1798,24 @@ class DBObjectSearch extends DBSearch
return $sRet;
}
/**
* Generate an INSERT statement.
* Note : unlike `RenderUpdate` and `RenderSelect`, it is limited to one and only one table.
*
* @param array $aValues is an array of $sAttCode => $value
* @param array $aArgs
*
* @return string
* @throws \CoreException
*/
public function MakeInsertQuery($aValues, $aArgs = array())
{
$oSQLObjectQueryBuilder = new SQLObjectQueryBuilder($this);
$oSQLQuery = $oSQLObjectQueryBuilder->MakeSQLObjectUpdateQuery($aValues);
$aScalarArgs = MetaModel::PrepareQueryArguments($aArgs, $this->GetInternalParams());
$sRet = $oSQLQuery->RenderInsert($aScalarArgs);
return $sRet;
}
/**
* Get an SQLObjectQuery from the search. This SQLObjectQuery can be rendered as a select, select group by, update or delete

View File

@@ -980,7 +980,15 @@ class DBObjectSet implements iDBObjectSetIterator
}
else
{
$oRetObj = MetaModel::GetObjectByRow($sClass, $aRow, $sClassAlias, $this->m_aAttToLoad, $this->m_aExtendedDataSpec);
try
{
$oRetObj = MetaModel::GetObjectByRow($sClass, $aRow, $sClassAlias, $this->m_aAttToLoad, $this->m_aExtendedDataSpec);
}
catch (CoreException $e)
{
$this->m_iCurrRow++;
$oRetObj = $this->Fetch($sRequestedClassAlias);
}
}
break;
}

View File

@@ -238,6 +238,12 @@ abstract class DBSearch
*/
abstract public function GetClassAlias();
/**
* @return string
* @internal
*/
abstract public function GetFirstJoinedClass();
/**
* Change the class
*
@@ -1136,21 +1142,22 @@ abstract class DBSearch
*/
protected abstract function SetDataFiltered();
/**
* @internal
*
* @param $aOrderBy
* @param $aArgs
* @param $aAttToLoad
* @param $aExtendedDataSpec
* @param $iLimitCount
* @param $iLimitStart
* @param $bGetCount
* @param null $aGroupByExpr
* @param null $aSelectExpr
*
* @return mixed
*/
/**
* @param $aOrderBy
* @param $aArgs
* @param $aAttToLoad
* @param $aExtendedDataSpec
* @param $iLimitCount
* @param $iLimitStart
* @param $bGetCount
* @param null $aGroupByExpr
* @param null $aSelectExpr
*
* @return SQLObjectQuery
* @throws \CoreException
* @internal
*
*/
protected function GetSQLQuery($aOrderBy, $aArgs, $aAttToLoad, $aExtendedDataSpec, $iLimitCount, $iLimitStart, $bGetCount, $aGroupByExpr = null, $aSelectExpr = null)
{
$oSearch = $this;

View File

@@ -161,6 +161,11 @@ class DBUnionSearch extends DBSearch
return $this->aSearches;
}
public function GetFirstJoinedClass()
{
return $this->GetClass();
}
/**
* Limited to the selected classes
*/

View File

@@ -1,29 +1,20 @@
<?php
// Copyright (C) 2010-2017 Combodo SARL
//
// This file is part of iTop.
//
// iTop is free software; you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// iTop 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 Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with iTop. If not, see <http://www.gnu.org/licenses/>
/**
* Persistent class Event and derived
* Application internal events
* There is also a file log
* Copyright (C) 2013-2020 Combodo SARL
*
* @copyright Copyright (C) 2010-2012 Combodo SARL
* @license http://opensource.org/licenses/AGPL-3.0
* This file is part of iTop.
*
* iTop is free software; you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* iTop 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
*/
class Event extends DBObject implements iDisplay
@@ -101,7 +92,7 @@ class Event extends DBObject implements iDisplay
//$this->DisplayBareHeader($oPage, $bEditMode);
$oPage->AddTabContainer(OBJECT_PROPERTIES_TAB);
$oPage->SetCurrentTabContainer(OBJECT_PROPERTIES_TAB);
$oPage->SetCurrentTab(Dict::S('UI:PropertiesTab'));
$oPage->SetCurrentTab('UI:PropertiesTab');
$this->DisplayBareProperties($oPage, $bEditMode);
}

View File

@@ -193,7 +193,7 @@ EOF
$oAttDef = MetaModel::GetAttributeDef(get_class($oObj), $sAttCode);
$sRet = $oAttDef->GetAsCSV($value, '', '', $oObj);
}
else if ($value instanceOf ormTagSet)
else if ($value instanceOf ormSet)
{
$oAttDef = MetaModel::GetAttributeDef(get_class($oObj), $sAttCode);
$sRet = $oAttDef->GetAsCSV($value, '', '', $oObj);
@@ -386,4 +386,4 @@ EOF
{
return array('xlsx' => Dict::S('Core:BulkExport:XLSXFormat'));
}
}
}

View File

@@ -183,7 +183,7 @@ class HTMLDOMSanitizer extends HTMLSanitizer
'h4' => array('style'),
'nav' => array('style'),
'section' => array('style'),
'code' => array('style'),
'code' => array('style', 'class'),
'table' => array('style', 'width', 'summary', 'align', 'border', 'cellpadding', 'cellspacing'),
'thead' => array('style'),
'tbody' => array('style'),

120
core/iTopConfigParser.php Normal file
View File

@@ -0,0 +1,120 @@
<?php
/**
* Created by Bruno DA SILVA, working for Combodo
* Date: 31/12/2019
* Time: 12:29
*/
use PhpParser\Node\Expr\Assign;
use PhpParser\ParserFactory;
use PhpParser\PrettyPrinter\Standard;
class iTopConfigParser
{
/** @var \PhpParser\Node[] */
private $aInitialNodes;
/** @var \PhpParser\Node[] */
private $aVisitedNodes;
/** @var string|null */
private $oException = null;
/**
* @var array
*/
private $aVarsMap;
/**
* iTopConfigValidator constructor.
*
* @param $sConfig
* @param \PhpParser\Parser|null $oParser
*
* @throws \Exception
*/
public function __construct($sConfig)
{
$oParser = (new ParserFactory())->create(ParserFactory::PREFER_PHP7);
$this->aVarsMap = array(
'MySettings' => array(),
'MyModuleSettings' => array(),
'MyModules' => array(),
);
if ($sConfig !== null)
{
$this->BrowseFile($oParser, $sConfig);
}
}
/**
* @return array
*/
public function GetVarsMap()
{
return $this->aVarsMap;
}
/**
* @param $arrayName
* @param $key
*
* @return array
*/
public function GetVarValue($arrayName, $key)
{
if (!array_key_exists($arrayName, $this->aVarsMap)){
return array('found' => false);
}
$arrayValue = $this->aVarsMap[$arrayName];
if (!array_key_exists($key, $arrayValue)){
return array('found' => false);
}
return array('found' => true,
'value' => $arrayValue[$key]);
}
/**
* @param \PhpParser\Parser $oParser
* @param $sConfig
*
* @return \Combodo\iTop\Config\Validator\ConfigNodesVisitor
*/
private function BrowseFile(\PhpParser\Parser $oParser, $sConfig)
{
$prettyPrinter = new Standard();
try
{
$aNodes = $oParser->parse($sConfig);
}
catch (\Error $e)
{
$sMessage = Dict::Format('config-parse-error', $e->getMessage(), $e->getLine());
$this->oException = new \Exception($sMessage, 0, $e);
}
foreach ($aNodes as $oAssignation)
{
if (! $oAssignation instanceof Assign)
{
continue;
}
$sCurrentRootVar = $oAssignation->var->name;
if (!array_key_exists($sCurrentRootVar, $this->aVarsMap))
{
continue;
}
$aCurrentRootVarMap =& $this->aVarsMap[$sCurrentRootVar];
foreach ($oAssignation->expr->items as $oItem)
{
$sValue = $prettyPrinter->prettyPrintExpr($oItem->value);
$aCurrentRootVarMap[$oItem->key->value] = $sValue;
}
}
}
}

View File

@@ -198,7 +198,7 @@ class ExecutionKPI
self::Report("</div>");
self::Report("<p><a class=\"kpi-next-page-button\" href=\"#end-".md5($sExecId)."\">Next page stats</a></p>");
self::Report("<p><a href=\"#end-".md5($sExecId)."\">Next page stats</a></p>");
$fSlowQueries = MetaModel::GetConfig()->Get('log_kpi_slow_queries');

View File

@@ -546,7 +546,7 @@ class DBObjectSearch extends DBSearch
*
* @throws \CoreException
*
* @since 2.5 N°1418
* @since 2.5.0 N°1418
*/
public function AddConditionForInOperatorUsingParam($sFilterCode, $aValues, $bPositiveMatch = true)
{
@@ -1678,6 +1678,25 @@ class DBObjectSearch extends DBSearch
return $sRet;
}
/**
* Generate an INSERT statement.
* Note : unlike `RenderUpdate` and `RenderSelect`, it is limited to one and only one table.
*
* @param array $aValues is an array of $sAttCode => $value
* @param array $aArgs
*
* @return string
* @throws \CoreException
*/
public function MakeInsertQuery($aValues, $aArgs = array())
{
$oSQLObjectQueryBuilder = new SQLObjectQueryBuilder($this);
$oSQLQuery = $oSQLObjectQueryBuilder->MakeSQLObjectUpdateQuery($aValues);
$aScalarArgs = MetaModel::PrepareQueryArguments($aArgs, $this->GetInternalParams());
$sRet = $oSQLQuery->RenderInsert($aScalarArgs);
return $sRet;
}
public function GetSQLQueryStructure($aAttToLoad, $bGetCount, $aGroupByExpr = null, $aSelectedClasses = null, $aSelectExpr = null)
{
// Hide objects that are not visible to the current user

View File

@@ -18,24 +18,36 @@
/**
* @since 2.7.0 N°2518
* @since 2.7.0 N°2518 N°2793
*/
interface ILogFileNameBuilder
interface iLogFileNameBuilder
{
public function __construct($sFileFullPath);
/**
* @param string $sLogFileFullPath full path name for the log file
*/
public function __construct($sLogFileFullPath = null);
/**
* @return string log file path we will write new log entry to
*/
public function GetLogFilePath();
}
class DefaultLogFileNameBuilder implements ILogFileNameBuilder
class DefaultLogFileNameBuilder implements iLogFileNameBuilder
{
private $sLogFileFullPath;
public function __construct($sFileFullPath)
/**
* @inheritDoc
*/
public function __construct($sLogFileFullPath = null)
{
$this->sLogFileFullPath = $sFileFullPath;
$this->sLogFileFullPath = $sLogFileFullPath;
}
/**
* @inheritDoc
*/
public function GetLogFilePath()
{
return $this->sLogFileFullPath;
@@ -45,60 +57,365 @@ class DefaultLogFileNameBuilder implements ILogFileNameBuilder
/**
* Adds a suffix to the filename
*
* @since 2.7.0 N°2518
* @since 2.7.0 N°2518 N°2793
*/
abstract class RotatingLogFileNameBuilder implements ILogFileNameBuilder
abstract class RotatingLogFileNameBuilder implements iLogFileNameBuilder
{
/**
* Test is done each time to cover edge case like session beginning at 23:59 and ending at 00:01
* We are caching the file mtime though
* @var array with full file path as key and DateTime (file last modification time) as value
*/
protected static $aLogFileLastModified = array();
/** @var string */
protected $sLogFileFullPath;
/** @var string */
protected $sFilePath;
/** @var string */
protected $sFileBaseName;
/** @var string */
protected $sFileExtension;
public function __construct($sFileFullPath)
/**
* @inheritDoc
*/
public function __construct($sLogFileFullPath = null)
{
$aPathParts = pathinfo($sFileFullPath);
$this->sLogFileFullPath = $sLogFileFullPath;
}
protected function GetLastModifiedDateForFile()
{
if (isset(static::$aLogFileLastModified[$this->sLogFileFullPath]))
{
return static::$aLogFileLastModified[$this->sLogFileFullPath];
}
return null;
}
protected function SetLastModifiedDateForFile($oDateTime)
{
static::$aLogFileLastModified[$this->sLogFileFullPath] = $oDateTime;
}
/**
* Need to be called when the file is rotated : actually the next call will need to check on the real date modified instead of using
* the previously cached value !
*/
public function ResetLastModifiedDateForFile()
{
static::$aLogFileLastModified[$this->sLogFileFullPath] = null;
}
/**
* @inheritDoc
*
* Doing the check before opening and writing the log file. There is also a iProcess but cron can be disabled...
*
* @see \LogFileRotationProcess the iProcess impl
*/
public function GetLogFilePath()
{
$this->CheckAndRotateLogFile();
return $this->sLogFileFullPath;
}
/**
* Check log last date modified. If too old then rotate the log file (move it to a new name with a suffix)
*
* @uses filemtime() to get log file date last modified
*/
public function CheckAndRotateLogFile()
{
$oConfig = utils::GetConfig();
$sItopTimeZone = $oConfig->Get('timezone');
$timezone = new DateTimeZone($sItopTimeZone);
if ($this->GetLastModifiedDateForFile() === null)
{
if (!$this->IsLogFileExists())
{
return;
}
$iLogDateLastModifiedTimeStamp = filemtime($this->sLogFileFullPath);
if ($iLogDateLastModifiedTimeStamp === false)
{
return;
}
$oDateTime = DateTime::createFromFormat('U', $iLogDateLastModifiedTimeStamp);
$oDateTime->setTimezone($timezone);
$this->SetLastModifiedDateForFile($oDateTime);
}
$oNow = new DateTime('now', $timezone);
$bShouldRotate = $this->ShouldRotate($this->GetLastModifiedDateForFile(), $oNow);
if (!$bShouldRotate)
{
return;
}
$this->RotateLogFile($this->GetLastModifiedDateForFile());
}
/**
* Rotate current log file
*
* @param DateTime $oLogFileLastModified date when the log file was last modified
*
* @uses \iTopMutex instead of flock as doing a rename on a file with a flock cause an error on PHP 5.6.40 Windows (ok on 7.3.15 though)
* @uses GetRotatedFileName to get rotated file name
*/
protected function RotateLogFile($oLogFileLastModified)
{
if (!$this->IsLogFileExists()) // extra check, but useful for cron also !
{
return;
}
$oLock = null;
try
{
$oLock = new iTopMutex('log_rotation_'.$this->sLogFileFullPath);
$oLock->Lock();
if (!$this->IsLogFileExists()) // extra extra check if we were blocked and another process moved the file in the meantime
{
$oLock->Unlock();
return;
}
$this->ResetLastModifiedDateForFile();
$sNewLogFileName = $this->GetRotatedFileName($oLogFileLastModified);
rename($this->sLogFileFullPath, $sNewLogFileName);
}
catch (Exception $e)
{
// nothing to do, cannot log... file will be renamed on the next call O:)
return;
}
finally
{
if (!is_null($oLock)) { $oLock->Unlock();}
}
}
/**
* @param DateTime $oLogFileLastModified date when the log file was last modified
*
* @return string the full path of the rotated log file
* @uses static::$oLogFileLastModified
* @uses GetFileSuffix
*/
public function GetRotatedFileName($oLogFileLastModified)
{
$aPathParts = pathinfo($this->sLogFileFullPath);
$this->sFilePath = $aPathParts['dirname'];
$this->sFileBaseName = $aPathParts['filename'];
$this->sFileExtension = $aPathParts['extension'];
}
public function GetLogFilePath()
{
$sFileSuffix = $this->GetFileSuffix();
$sFileSuffix = $this->GetFileSuffix($oLogFileLastModified);
return $this->sFilePath
.'/'
return $this->sFilePath.DIRECTORY_SEPARATOR
.$this->sFileBaseName
.'.'.$sFileSuffix
.'.'.$this->sFileExtension;
}
abstract protected function GetFileSuffix();
/**
* @return bool true if file exists and is readable
*/
public function IsLogFileExists()
{
if (!file_exists($this->sLogFileFullPath))
{
return false;
}
if (!is_readable($this->sLogFileFullPath))
{
return false;
}
return true;
}
/**
* **Warning :** both DateTime params must have the same timezone set ! Should use the iTop timezone ('timezone' config parameter)
*
* @param DateTime $oLogFileLastModified date when the log file was last modified
* @param DateTime $oNow date/time of the log we want to write
*
* @return bool true if the file has older informations and we need to move it to an archive (rotate), false if we don't have to
*/
abstract public function ShouldRotate($oLogFileLastModified, $oNow);
/**
* @param DateTime $oDate log file last modification date
*
* @return string suffix for the rotated log file
*/
abstract protected function GetFileSuffix($oDate);
/**
* @see \LogFileRotationProcess
*
* @param \DateTime $oNow current date
*
* @return DateTime time when the cron process should run
*/
abstract public function GetCronProcessNextOccurrence(DateTime $oNow);
}
/**
* @since 2.7.0 N°2518
* @since 2.7.0 N°2518 N°2793
*/
class DailyRotatingLogFileNameBuilder extends RotatingLogFileNameBuilder
{
protected function GetFileSuffix()
/**
* @inheritDoc
*/
protected function GetFileSuffix($oDate)
{
return date('Y-m-d');
return $oDate->format('Y-m-d');
}
/**
* @inheritDoc
*/
public function ShouldRotate($oLogFileLastModified, $oNow)
{
$iLogYear = $oLogFileLastModified->format('Y');
$iLogDay = $oLogFileLastModified->format('z');
$iNowYear = $oNow->format('Y');
$iNowDay = $oNow->format('z');
if ($iLogYear !== $iNowYear)
{
return true;
}
if ($iLogDay !== $iNowDay)
{
return true;
}
return false;
}
/**
* @inheritDoc
*/
public function GetCronProcessNextOccurrence(DateTime $oNow)
{
$oOccurrence = clone $oNow;
$oOccurrence->modify('tomorrow');
return $oOccurrence;
}
}
/**
* @since 2.7.0 N°2518
* @since 2.7.0 N°2518 N°2793
*/
class WeeklyRotatingLogFileNameBuilder extends RotatingLogFileNameBuilder
{
protected function GetFileSuffix()
/**
* @inheritDoc
*/
protected function GetFileSuffix($oDate)
{
$sWeekYear = date('o');
$sWeekNumber = date('W');
$sWeekYear = $oDate->format('o');
$sWeekNumber = $oDate->format('W');
return $sWeekYear.'-week'.$sWeekNumber;
}
/**
* @inheritDoc
*/
public function ShouldRotate($oLogFileLastModified, $oNow)
{
$iLogYear = $oLogFileLastModified->format('Y');
$iLogWeek = $oLogFileLastModified->format('W');
$iNowYear = $oNow->format('Y');
$iNowWeek = $oNow->format('W');
if ($iLogYear !== $iNowYear)
{
return true;
}
if ($iLogWeek !== $iNowWeek)
{
return true;
}
return false;
}
/**
* @inheritDoc
*/
public function GetCronProcessNextOccurrence(DateTime $oNow)
{
$oOccurrence = clone $oNow;
$oOccurrence->modify('Monday next week');
$oOccurrence->setTime(0, 0, 0);
return $oOccurrence;
}
}
/**
* @since 2.7.0 N°2820
*/
class MonthlyRotatingLogFileNameBuilder extends RotatingLogFileNameBuilder
{
/**
* @inheritDoc
*/
public function ShouldRotate($oLogFileLastModified, $oNow)
{
$iLogYear = $oLogFileLastModified->format('Y');
$iLogMonth = $oLogFileLastModified->format('n');
$iNowYear = $oNow->format('Y');
$iNowMonth = $oNow->format('n');
if ($iLogYear !== $iNowYear)
{
return true;
}
if ($iLogMonth !== $iNowMonth)
{
return true;
}
return false;
}
/**
* @inheritDoc
*/
protected function GetFileSuffix($oDate)
{
$sWeekYear = $oDate->format('o');
$sWeekNumber = $oDate->format('m');
return $sWeekYear.'-month'.$sWeekNumber;
}
/**
* @inheritDoc
*/
public function GetCronProcessNextOccurrence(DateTime $oNow)
{
$oOccurrence = clone $oNow;
$oOccurrence->modify('first day of next month');
$oOccurrence->setTime(0, 0, 0);
return $oOccurrence;
}
}
/**
@@ -111,7 +428,7 @@ class LogFileNameBuilderFactory
*
* @param string $sFileFullPath
*
* @return \ILogFileNameBuilder
* @return \iLogFileNameBuilder
* @throws \ConfigException
* @throws \CoreException
*/
@@ -119,7 +436,7 @@ class LogFileNameBuilderFactory
{
$oConfig = utils::GetConfig();
$sFileNameBuilderImpl = $oConfig->Get('log_filename_builder_impl');
if (empty($sFileNameBuilderImpl) || !class_exists($sFileNameBuilderImpl))
if (!is_a($sFileNameBuilderImpl, iLogFileNameBuilder::class, true))
{
$sFileNameBuilderImpl = 'DefaultLogFileNameBuilder';
}
@@ -134,7 +451,7 @@ class LogFileNameBuilderFactory
*
* @copyright Copyright (C) 2010-2017 Combodo SARL
* @license http://opensource.org/licenses/AGPL-3.0
* @since 2.7.0 allow to rotate file (N°2518)
* @since 2.7.0 N°2518 N°2793 file log rotation
*/
class FileLog
{
@@ -153,52 +470,6 @@ class FileLog
$this->oFileNameBuilder = LogFileNameBuilderFactory::GetInstance($sFileName);
}
/**
* Since 2.7.0 with the 'log_filename_builder_impl' param the logs will output to different files name
* As now by default iTop will use {@link WeeklyRotatingLogFileNameBuilder} (rotation each week), to avoid confusion, we're renaming
* the legacy error.log / setup.log.
*
* @since 2.7.0 N°2518
* @uses utils::GetConfig() the config must be persisted !
*/
public static function RenameLegacyLogFiles()
{
$oConfig = utils::GetConfig();
IssueLog::Enable(APPROOT.'log/error.log'); // refresh log file used
$sLogFileNameParam = $oConfig->Get('log_filename_builder_impl');
$aConfigValuesNoRotation = array('', 'DefaultLogFileNameBuilder');
$bIsLogRotationActivated = (!in_array($sLogFileNameParam, $aConfigValuesNoRotation, true));
if (!$bIsLogRotationActivated)
{
return;
}
IssueLog::Warning("Log name builder set to '$sLogFileNameParam', renaming legacy log files");
$aLogFilesToRename = array(
'log/setup.log' => 'log/setup.LEGACY.log',
'log/error.log' => 'log/error.LEGACY.log',
);
foreach ($aLogFilesToRename as $sLogCurrentName => $sLogNewName)
{
$sSource = APPROOT.$sLogCurrentName;
if (!file_exists($sSource))
{
IssueLog::Debug("Log file '$sLogCurrentName' (legacy) does not exists, renaming skipped");
continue;
}
$sDestination = APPROOT.$sLogNewName;
$bResult = rename($sSource, $sDestination);
if (!$bResult)
{
IssueLog::Error("Log file '$sLogCurrentName' (legacy) cannot be renamed to '$sLogNewName'");
continue;
}
IssueLog::Info("Log file '$sLogCurrentName' (legacy) renamed to '$sLogNewName'");
}
}
public function Error($sText, $sChannel = '', $aContext = array())
{
$this->Write($sText, __FUNCTION__, $sChannel, $aContext);
@@ -224,6 +495,12 @@ class FileLog
$this->Write($sText, __FUNCTION__, $sChannel, $aContext);
}
public function Trace($sText, $sChannel = '', $aContext = array())
{
$this->Write($sText, __FUNCTION__, $sChannel, $aContext);
}
protected function Write($sText, $sLevel = '', $sChannel = '', $aContext = array())
{
$sTextPrefix = empty($sLevel) ? '' : (str_pad($sLevel, 7).' | ');
@@ -261,25 +538,24 @@ abstract class LogAPI
{
const CHANNEL_DEFAULT = '';
const LEVEL_DEBUG = 'Debug';
const LEVEL_OK = 'Ok';
const LEVEL_INFO = 'Info';
const LEVEL_WARNING = 'Warning';
const LEVEL_ERROR = 'Error';
// const LEVEL_CRITICAL = 'Critical';
// const LEVEL_ALERT = 'Alert';
// const LEVEL_EMERGENCY = 'Emergency';
protected static $m_oMockMetaModelConfig = null;
const LEVEL_WARNING = 'Warning';
const LEVEL_INFO = 'Info';
const LEVEL_OK = 'Ok';
const LEVEL_DEBUG = 'Debug';
const LEVEL_TRACE = 'Trace';
protected static $aLevelsPriority = array(
self::LEVEL_DEBUG => 100,
self::LEVEL_OK => 150,
self::LEVEL_INFO => 200,
self::LEVEL_WARNING => 300,
self::LEVEL_ERROR => 400,
self::LEVEL_WARNING => 300,
self::LEVEL_INFO => 200,
self::LEVEL_OK => 200,
self::LEVEL_DEBUG => 100,
self::LEVEL_TRACE => 50,
);
protected static $m_oMockMetaModelConfig = null;
public static function Enable($sTargetFile)
{
// m_oFileLog is not defined as a class attribute so that each impl will have its own
@@ -317,6 +593,11 @@ abstract class LogAPI
static::Log(self::LEVEL_DEBUG, $sMessage, $sChannel, $aContext);
}
public static function Trace($sMessage, $sChannel = null, $aContext = array())
{
static::Log(self::LEVEL_TRACE, $sMessage, $sChannel, $aContext);
}
public static function Log($sLevel, $sMessage, $sChannel = null, $aContext = array())
{
if (! static::$m_oFileLog)
@@ -417,3 +698,72 @@ class ToolsLog extends LogAPI
protected static $m_oFileLog = null;
}
class LogFileRotationProcess implements iScheduledProcess
{
/**
* Cannot get this list from anywhere as log file name is provided by the caller using LogAPI::Enable
* @var string[]
*/
const LOGFILES_TO_ROTATE = array(
'setup.log',
'error.log',
'tools.log',
'itop-fence.log',
);
/**
* @inheritDoc
*/
public function Process($iUnixTimeLimit)
{
$sLogFileNameBuilder = $this->GetLogFileNameBuilderClassName();
foreach (self::LOGFILES_TO_ROTATE as $sLogFileName)
{
$sLogFileFullPath = APPROOT
.DIRECTORY_SEPARATOR.'log'
.DIRECTORY_SEPARATOR.$sLogFileName;
/** @var \RotatingLogFileNameBuilder $oLogFileNameBuilder */
$oLogFileNameBuilder = new $sLogFileNameBuilder($sLogFileFullPath);
$oLogFileNameBuilder->ResetLastModifiedDateForFile();
$oLogFileNameBuilder->CheckAndRotateLogFile();
}
}
/**
* @inheritDoc
*/
public function GetNextOccurrence()
{
try
{
$sLogFileNameBuilder = $this->GetLogFileNameBuilderClassName();
}
catch (ProcessException $e)
{
return new DateTime('3000-01-01');
}
/** @var \RotatingLogFileNameBuilder $oLogFileNameBuilder */
$oLogFileNameBuilder = new $sLogFileNameBuilder();
return $oLogFileNameBuilder->GetCronProcessNextOccurrence(new DateTime());
}
/**
* @return string RotatingLogFileNameBuilder implementation configured
* @throws \ProcessException if the class is invalid
*/
private function GetLogFileNameBuilderClassName()
{
$sLogFileNameBuilder = MetaModel::GetConfig()->Get('log_filename_builder_impl');
if (is_a($sLogFileNameBuilder, RotatingLogFileNameBuilder::class, true))
{
return $sLogFileNameBuilder;
}
throw new ProcessException(self::class.' : The configured filename builder is invalid (log_filename_builder_impl="'.$sLogFileNameBuilder.'")');
}
}

View File

@@ -543,7 +543,7 @@ abstract class MetaModel
*
* @return array rule id as key, rule properties as value
* @throws \CoreException
* @since 2.6 N°659 uniqueness constraint
* @since 2.6.0 N°659 uniqueness constraint
* @see #SetUniquenessRuleRootClass that fixes a specific 'root_class' property to know which class is root per rule
*/
final public static function GetUniquenessRules($sClass, $bClassDefinitionOnly = false)
@@ -688,7 +688,7 @@ abstract class MetaModel
* @param array $aRuleProperties
*
* @return bool
* @since 2.6 N°659 uniqueness constraint
* @since 2.6.0 N°659 uniqueness constraint
*/
private static function IsUniquenessRuleContainingOnlyDisabledKey($aRuleProperties)
{
@@ -918,6 +918,20 @@ abstract class MetaModel
return self::$m_aAttribOrigins[$sClass][$sAttCode];
}
/**
* @deprecated
* @param string $sClass
* @param string $sAttCode
*
* @return mixed
* @throws \CoreException
*/
final static public function GetFilterCodeOrigin($sClass, $sAttCode)
{
self::_check_subclass($sClass);
return self::$m_aFilterOrigins[$sClass][$sAttCode];
}
/**
* @param string $sClass
* @param string $sAttCode
@@ -2495,6 +2509,32 @@ abstract class MetaModel
return array();
}
/**
* Return an hash array of the possible attribute flags (code => value)
*
* Example:
* [
* "read_only" => OPT_ATT_READONLY,
* "mandatory" => OPT_ATT_MANDATORY,
* ...
* ]
*
* @return array
* @since 2.7.0
*/
public static function EnumPossibleAttributeFlags()
{
return $aPossibleAttFlags = array(
'normal' => OPT_ATT_NORMAL,
'hidden' => OPT_ATT_HIDDEN,
'read_only' => OPT_ATT_READONLY,
'mandatory' => OPT_ATT_MANDATORY,
'must_change' => OPT_ATT_MUSTCHANGE,
'must_prompt' => OPT_ATT_MUSTPROMPT,
'slave' => OPT_ATT_SLAVE
);
}
/**
* @param string $sClass
* @param string $sState
@@ -3201,7 +3241,7 @@ abstract class MetaModel
*
* @throws \CoreUnexpectedValue if the rule is invalid
*
* @since 2.6 N°659 uniqueness constraint
* @since 2.6.0 N°659 uniqueness constraint
* @since 2.6.1 N°1968 (joli mois de mai...) disallow overrides of 'attributes' properties
*/
public static function CheckUniquenessRuleValidity($aUniquenessRuleProperties, $bRuleOverride = true, $aExistingClassFields = array())
@@ -5661,10 +5701,14 @@ abstract class MetaModel
{
$sChangeList = implode(', ', $aChangeList);
$aCondensedQueries[] = "ALTER TABLE `$sTable` $sChangeList";
}
foreach($aPostTableAlteration as $sTable => $aChangeList)
{
$aCondensedQueries = array_merge($aCondensedQueries, $aChangeList);
// Add request right after the ALTER TABLE
if (isset($aPostTableAlteration[$sTable]))
{
foreach ($aPostTableAlteration[$sTable] as $sQuery)
{
$aCondensedQueries[] = $sQuery;
}
}
}
return array($aErrors, $aSugFix, $aCondensedQueries);
@@ -5672,6 +5716,8 @@ abstract class MetaModel
/**
* @deprecated 2.7.0 N°2369 will be removed in 2.8
*
* @return array
* @throws \CoreException
* @throws \Exception
@@ -6690,6 +6736,10 @@ abstract class MetaModel
else
{
// do the job for the real target class
if (!class_exists($aRow[$sClassAlias."finalclass"]))
{
throw new CoreException("Class {$aRow[$sClassAlias."finalclass"]} derived from $sClass does not exist anymore, please remove corresponding tables in the database", array('row' => $aRow));
}
$sClass = $aRow[$sClassAlias."finalclass"];
}
return new $sClass($aRow, $sClassAlias, $aAttToLoad, $aExtendedDataSpec);
@@ -6753,7 +6803,7 @@ abstract class MetaModel
* @throws CoreException if no result found and $bMustBeFound=true
* @throws \Exception
*
* @since 2.4 introduction of the archive functionalities
* @since 2.4.0 introduction of the archive functionality
*
* @see MetaModel::GetObject() same but returns null or ArchivedObjectFoundException if object exists but is
* archived

View File

@@ -811,7 +811,7 @@ class BinaryExpression extends Expression
/**
* @since 2.6 N°931 tag fields
* @since 2.6.0 N°931 tag fields
*/
class MatchExpression extends BinaryExpression
{
@@ -1146,6 +1146,38 @@ class ScalarExpression extends UnaryExpression
IssueLog::Error($e->getMessage());
}
break;
case ($oAttDef instanceof AttributeEnumSet):
try
{
if (!empty($this->GetValue()))
{
$aValues = array();
$sValue = $this->GetValue();
if (is_string($sValue))
{
$aTags = $oAttDef->FromStringToArray($sValue, ' ');
}
else
{
$aTags = array();
}
foreach($aTags as $sLabel => $sValue)
{
$aValue['label'] = $sLabel;
$aValue['value'] = $sValue;
$aValues[] = $aValue;
}
$aCriterion['values'] = $aValues;
}
else
{
$aCriterion['has_undefined'] = true;
}
} catch (Exception $e)
{
IssueLog::Error($e->getMessage());
}
break;
case $oAttDef->IsExternalKey():
try
{

View File

@@ -64,12 +64,26 @@ class OQLActualClassTreeResolver
$aTranslateFields = array();
foreach ($aExpectedAttributes as $sAttCode => $oExpression)
{
if (!MetaModel::IsValidAttCode($sClass, $sAttCode))
// 'id' is managed later
if ($sAttCode == 'id')
{
continue;
}
$sOriginClass = MetaModel::GetAttributeOrigin($sClass, $sAttCode);
if (is_null($aClassAndAncestorsNodes[$sOriginClass]))
// Attributes can be stored in attributes list or for magic ones into filter codes list.
$sOriginClass = null;
if (MetaModel::IsValidAttCode($sClass, $sAttCode))
{
$sOriginClass = MetaModel::GetAttributeOrigin($sClass, $sAttCode);
}
else if (MetaModel::IsValidFilterCode($sClass, $sAttCode))
{
$sOriginClass = MetaModel::GetFilterCodeOrigin($sClass, $sAttCode);
}
else
{
continue;
}
if (!isset($aClassAndAncestorsNodes[$sOriginClass]) || is_null($aClassAndAncestorsNodes[$sOriginClass]))
{
if ($sOriginClass == $sClass)
{
@@ -198,4 +212,4 @@ class OQLActualClassTreeResolver
}
}
}
}
}

View File

@@ -128,6 +128,19 @@ class OQLClassNode
return $sOQL;
}
public function Browse(Closure $callback)
{
$callback($this);
foreach ($this->GetJoins() as $aJoins)
{
/** @var \OQLJoin $oJoin */
foreach ($aJoins as $oJoin)
{
$oJoin->GetOOQLClassNode()->Browse($callback);
}
}
}
public function GetExternalKeys()
{
return $this->aExtKeys;
@@ -318,4 +331,4 @@ class OQLJoin
return $this->sRightField;
}
}
}

View File

@@ -8,7 +8,7 @@
class OQLClassTreeBuilder
{
/** @var \DBObjectSearch */
private $oDBObjetSearch;
private $oDBObjectSearch;
/** @var OQLClassNode */
private $oOQLClassNode;
/** @var \QueryBuilderContext */
@@ -23,10 +23,10 @@ class OQLClassTreeBuilder
* @param \DBObjectSearch $oDBObjetSearch
* @param \QueryBuilderContext $oBuild
*/
public function __construct($oDBObjetSearch, $oBuild)
protected function __construct($oDBObjetSearch, $oBuild)
{
$this->oBuild = $oBuild;
$this->oDBObjetSearch = $oDBObjetSearch;
$this->oDBObjectSearch = $oDBObjetSearch;
$this->sClass = $oDBObjetSearch->GetFirstJoinedClass();
$this->sClassAlias = $oDBObjetSearch->GetFirstJoinedClassAlias();
if (empty($this->sClassAlias))
@@ -36,6 +36,25 @@ class OQLClassTreeBuilder
$this->oOQLClassNode = new OQLClassNode($oBuild, $this->sClass, $this->sClassAlias);
}
/**
* @param \DBObjectSearch $oDBObjetSearch
* @param \QueryBuilderContext $oBuild
*
* @return \OQLClassNode
* @throws \CoreException
*/
public static function GetOQLClassTree($oDBObjetSearch, $oBuild)
{
$oOQLClassTreeBuilder = new OQLClassTreeBuilder($oDBObjetSearch, $oBuild);
$oOQLClassNode = $oOQLClassTreeBuilder->DevelopOQLClassNode();
$oOQLClassTreeOptimizer = new OQLClassTreeOptimizer($oOQLClassNode, $oBuild);
$oOQLClassTreeOptimizer->OptimizeClassTree();
$oOQLActualClassTreeResolver = new OQLActualClassTreeResolver($oOQLClassNode, $oBuild);
$oOQLClassNode = $oOQLActualClassTreeResolver->Resolve();
return $oOQLClassNode;
}
/**
* Develop OQL.
* Add joins from OQL (outgoing and incoming)
@@ -70,7 +89,7 @@ class OQLClassTreeBuilder
*/
private function AddExternalKeysFromSearch()
{
foreach ($this->oDBObjetSearch->GetCriteria_PointingTo() as $sKeyAttCode => $aPointingTo)
foreach ($this->oDBObjectSearch->GetCriteria_PointingTo() as $sKeyAttCode => $aPointingTo)
{
if (array_key_exists(TREE_OPERATOR_EQUALS, $aPointingTo))
{
@@ -203,7 +222,7 @@ class OQLClassTreeBuilder
private function JoinClassesForExternalKeys()
{
// Get filters from the search outgoing joins
$aAllPointingTo = $this->oDBObjetSearch->GetCriteria_PointingTo();
$aAllPointingTo = $this->oDBObjectSearch->GetCriteria_PointingTo();
// Add filters from external keys
foreach (array_keys($this->oOQLClassNode->GetExternalKeys()) as $sKeyAttCode)
@@ -317,7 +336,7 @@ class OQLClassTreeBuilder
*/
private function JoinClassesReferencedBy()
{
foreach ($this->oDBObjetSearch->GetCriteria_ReferencedBy() as $sForeignClass => $aReferences)
foreach ($this->oDBObjectSearch->GetCriteria_ReferencedBy() as $sForeignClass => $aReferences)
{
foreach ($aReferences as $sForeignExtKeyAttCode => $aFiltersByOperator)
{
@@ -382,7 +401,7 @@ class OQLClassTreeBuilder
*/
private function TranslateNestedRequests()
{
$aClassAliases = $this->oDBObjetSearch->GetJoinedClasses();
$this->oDBObjetSearch->RenameNestedQueriesAliasesInNameSpace($aClassAliases);
$aClassAliases = $this->oDBObjectSearch->GetJoinedClasses();
$this->oDBObjectSearch->RenameNestedQueriesAliasesInNameSpace($aClassAliases);
}
}

View File

@@ -29,6 +29,7 @@ class ormSet
protected $sClass; // class of the field
protected $sAttCode; // attcode of the field
protected $aOriginalObjects = null;
protected $m_bDisplayPartial = false;
/**
* Object from the original set, minus the removed objects
@@ -111,7 +112,7 @@ class ormSet
/**
*
* @param array $aItems
* @param string[] $aItems
*
* @throws \CoreException
* @throws \CoreUnexpectedValue when a code is invalid
@@ -126,7 +127,7 @@ class ormSet
$aValues = array();
$iCount = 0;
$bError = false;
foreach($aItems as $oItem)
foreach($aItems as $sItem)
{
$iCount++;
if (($this->iLimit != 0) && ($iCount > $this->iLimit))
@@ -134,7 +135,7 @@ class ormSet
$bError = true;
continue;
}
$aValues[] = $oItem;
$aValues[] = $sItem;
}
$this->aPreserved = &$aValues;
@@ -160,10 +161,21 @@ class ormSet
public function GetValues()
{
$aValues = array_merge($this->aPreserved, $this->aAdded);
sort($aValues);
return $aValues;
}
public function GetLabels()
{
$aLabels = array();
$aValues = $this->GetValues();
foreach ($aValues as $sValue)
{
$aLabels[$sValue] = $sValue;
}
return $aLabels;
}
/**
* @return array of tag labels indexed by code for only the added tags
*/
@@ -376,5 +388,19 @@ class ormSet
return implode(', ', $this->GetValue()) === implode(', ', $other->GetValue());
}
/**
* @return bool
*/
public function DisplayPartial()
{
return $this->m_bDisplayPartial;
}
}
/**
* @param bool $m_bDisplayPartial
*/
public function SetDisplayPartial($m_bDisplayPartial)
{
$this->m_bDisplayPartial = $m_bDisplayPartial;
}
}

View File

@@ -251,17 +251,27 @@ class ormStopWatch
return $sRes;
}
/**
* @param \DBObject $oObject
* @param \AttributeStopWatch $oAttDef
*
* @return float goal value (in second)
* @uses \iMetricComputer::ComputeMetric()
* @throws \CoreException
*/
protected function ComputeGoal($oObject, $oAttDef)
{
$sMetricComputer = $oAttDef->Get('goal_computing');
/** @var \iMetricComputer $oComputer */
$oComputer = new $sMetricComputer();
$aCallSpec = array($oComputer, 'ComputeMetric');
if (!is_callable($aCallSpec))
{
throw new CoreException("Unknown class/verb '$sMetricComputer/ComputeMetric'");
}
$iRet = call_user_func($aCallSpec, $oObject);
return $iRet;
return $oComputer->ComputeMetric($oObject);
}
/**

View File

@@ -26,9 +26,6 @@
*/
final class ormTagSet extends ormSet
{
private $m_bDisplayPartial = false;
/**
* ormTagSet constructor.
*
@@ -557,22 +554,4 @@ final class ormTagSet extends ormSet
{
return TagSetFieldData::GetTagDataClassName($this->sClass, $this->sAttCode);
}
/**
* @return bool
*/
public function DisplayPartial()
{
return $this->m_bDisplayPartial;
}
/**
* @param bool $m_bDisplayPartial
*/
public function SetDisplayPartial($m_bDisplayPartial)
{
$this->m_bDisplayPartial = $m_bDisplayPartial;
}
}
}

View File

@@ -303,7 +303,7 @@ class CoreServices implements iRestServiceProvider
*
* @param string $sVersion The version (e.g. 1.0) supported by the services
* @param string $sVerb
* @param $aParams
* @param object $aParams
*
* @return RestResult The standardized result structure (at least a message)
* @throws \CoreException
@@ -476,6 +476,7 @@ class CoreServices implements iRestServiceProvider
break;
case 'core/delete':
RestUtils::InitTrackingComment($aParams);
$sClass = RestUtils::GetClass($aParams, 'class');
$key = RestUtils::GetMandatoryParam($aParams, 'key');
$bSimulate = RestUtils::GetOptionalParam($aParams, 'simulate', false);

View File

@@ -318,7 +318,40 @@ class SQLObjectQuery extends SQLQuery
return "UPDATE $sFrom SET $sValues WHERE $sWhere";
}
// Interface, build the SQL query
/**
* Generate an INSERT statement.
* Note : unlike `RenderUpdate` and `RenderSelect`, it is limited to one and only one table.
*
*
* @param array $aArgs
* @return string
* @throws CoreException
*/
public function RenderInsert($aArgs = array())
{
$this->PrepareRendering();
$aJoinInfo = reset($this->__aFrom);
if ($aJoinInfo['jointype'] != 'first' || count($this->__aFrom) > 1)
{
throw new CoreException('Cannot render insert');
}
$sFrom = "`{$aJoinInfo['tablename']}`";
$sColList = '`'.implode('`,`', array_keys($this->m_aValues)).'`';
$aSetValues = array();
foreach ($this->__aSetValues as $sFieldSpec => $value)
{
$aSetValues[] = CMDBSource::Quote($value);
}
$sValues = implode(',', $aSetValues);
return "INSERT INTO $sFrom ($sColList) VALUES ($sValues)";
}
/**
* @param array $aOrderBy
@@ -424,7 +457,21 @@ class SQLObjectQuery extends SQLQuery
{
$sLimit = '';
}
$sSQL = "SELECT $sSelect,$sLineSep COUNT(*) AS _itop_count_$sLineSep FROM $sFrom$sLineSep WHERE $sWhere$sLineSep $sGroupBy $sOrderBy$sLineSep $sLimit";
if (count($this->__aSelectedIdFields) > 0)
{
$aCountFields = array();
foreach ($this->__aSelectedIdFields as $sFieldExpr)
{
$aCountFields[] = "COALESCE($sFieldExpr, 0)"; // Null values are excluded from the count
}
$sCountFields = implode(', ', $aCountFields);
$sCountClause = "DISTINCT $sCountFields";
}
else
{
$sCountClause = '*';
}
$sSQL = "SELECT $sSelect,$sLineSep COUNT($sCountClause) AS _itop_count_$sLineSep FROM $sFrom$sLineSep WHERE $sWhere$sLineSep $sGroupBy $sOrderBy$sLineSep $sLimit";
return $sSQL;
}

View File

@@ -92,14 +92,7 @@ class SQLObjectQueryBuilder
*/
private function GetOQLClassTree($oBuild)
{
$oOQLClassTreeBuilder = new OQLClassTreeBuilder($this->oDBObjetSearch, $oBuild);
$oOQLClassNode = $oOQLClassTreeBuilder->DevelopOQLClassNode();
$oOQLClassTreeOptimizer = new OQLClassTreeOptimizer($oOQLClassNode, $oBuild);
$oOQLClassTreeOptimizer->OptimizeClassTree();
$oOQLActualClassTreeResolver = new OQLActualClassTreeResolver($oOQLClassNode, $oBuild);
$oOQLClassNode = $oOQLActualClassTreeResolver->Resolve();
return $oOQLClassNode;
return OQLClassTreeBuilder::GetOQLClassTree($this->oDBObjetSearch, $oBuild);
}
/**

View File

@@ -131,7 +131,7 @@ class SQLUnionQuery extends SQLQuery
if ($bGetCount)
{
$sSelects = "({$sLimitStart}".implode(" {$sLimit}{$sLimitEnd}{$sLineSep} UNION{$sLineSep} {$sLimitStart}", $aSelects)." {$sLimit}{$sLimitEnd})";
$sSelects = "{$sLimitStart}".implode(" {$sLimit}{$sLimitEnd}{$sLineSep} UNION{$sLineSep} {$sLimitStart}", $aSelects)." {$sLimit}{$sLimitEnd}";
$sFrom = "({$sLineSep}{$sSelects}{$sLineSep}) as __selects__";
$sSQL = "SELECT COUNT(*) AS COUNT FROM (SELECT$sLineSep 1 $sLineSep FROM {$sFrom}{$sLineSep}) AS _union_alderaan_";
}

View File

@@ -1,20 +1,21 @@
<?php
// Copyright (C) 2018 Combodo SARL
//
// This file is part of iTop.
//
// iTop is free software; you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// iTop 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 Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with iTop. If not, see <http://www.gnu.org/licenses/>
/**
* Copyright (C) 2013-2020 Combodo SARL
*
* This file is part of iTop.
*
* iTop is free software; you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* iTop 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
*/
/**
@@ -24,7 +25,7 @@
* \MFCompiler::CompileClass).<br> Only this abstract class will exists in the DB : the implementations won't had any
* new field.
*
* @since 2.6 N°931 tag fields
* @since 2.6.0 N°931 tag fields
*/
abstract class TagSetFieldData extends cmdbAbstractObject
{
@@ -318,7 +319,7 @@ abstract class TagSetFieldData extends cmdbAbstractObject
$oFilter = DBSearch::FromOQL("SELECT $sClass WHERE $sAttCode MATCHES '$sTagCode'");
$oSet = new DBObjectSet($oFilter);
$iCount = $oSet->Count();
$oPage->SetCurrentTab(Dict::Format('Core:TagSetFieldData:WhereIsThisTagTab', $iCount));
$oPage->SetCurrentTab('Core:TagSetFieldData:WhereIsThisTagTab', Dict::Format('Core:TagSetFieldData:WhereIsThisTagTab', $iCount));
if ($iCount === 0)
{

View File

@@ -56,15 +56,48 @@ abstract class Trigger extends cmdbAbstractObject
//MetaModel::Init_InheritAttributes();
MetaModel::Init_AddAttribute(new AttributeString("description", array("allowed_values" => null, "sql" => "description", "default_value" => null, "is_null_allowed" => false, "depends_on" => array())));
MetaModel::Init_AddAttribute(new AttributeLinkedSetIndirect("action_list", array("linked_class" => "lnkTriggerAction", "ext_key_to_me" => "trigger_id", "ext_key_to_remote" => "action_id", "allowed_values" => null, "count_min" => 1, "count_max" => 0, "depends_on" => array())));
$aTags = ContextTag::GetTags();
MetaModel::Init_AddAttribute( new AttributeEnumSet("context", array("allowed_values" => null, "possible_values" => new ValueSetEnumPadded($aTags), "sql" => "context", "depends_on" => array(), "is_null_allowed" => true, "max_items" => 12)));
// Display lists
MetaModel::Init_SetZListItems('details', array('finalclass', 'description', 'action_list')); // Attributes to be displayed for the complete details
MetaModel::Init_SetZListItems('details', array('finalclass', 'description', 'context', 'action_list')); // Attributes to be displayed for the complete details
MetaModel::Init_SetZListItems('list', array('finalclass')); // Attributes to be displayed for a list
// Search criteria
// MetaModel::Init_SetZListItems('standard_search', array('name')); // Criteria of the std search form
// MetaModel::Init_SetZListItems('advanced_search', array('name')); // Criteria of the advanced search form
}
/**
* Check if the trigger can be used in the current context
*
* @return bool true if context OK
* @throws \ArchivedObjectException
* @throws \CoreException
*/
public function IsContextValid()
{
// Check the context
$oContext = $this->Get('context');
$bChecked = false;
$bValid = false;
foreach ($oContext->GetValues() as $sValue)
{
$bChecked = true;
if (ContextTag::Check($sValue))
{
$bValid = true;
break;
}
}
if ($bChecked && !$bValid)
{
// Trigger does not match the current context
return false;
}
return true;
}
/**
* @param $aContextArgs
*
@@ -73,6 +106,16 @@ abstract class Trigger extends cmdbAbstractObject
*/
public function DoActivate($aContextArgs)
{
// Check the context
if (!$this->IsContextValid())
{
// Trigger does not match the current context
$sClass = get_class($this);
$sName = $this->Get('friendlyname');
IssueLog::Debug("Context NOT valid for : {$sClass} '$sName'");
return;
}
// Find the related actions
$oLinkedActions = $this->Get('action_list');
while ($oLink = $oLinkedActions->Fetch())
@@ -133,7 +176,7 @@ abstract class TriggerOnObject extends Trigger
MetaModel::Init_AddAttribute(new AttributeOQL("filter", array("allowed_values" => null, "sql" => "filter", "default_value" => null, "is_null_allowed" => true, "depends_on" => array())));
// Display lists
MetaModel::Init_SetZListItems('details', array('description', 'target_class', 'filter', 'action_list')); // Attributes to be displayed for the complete details
MetaModel::Init_SetZListItems('details', array('description', 'context', 'target_class', 'filter', 'action_list')); // Attributes to be displayed for the complete details
MetaModel::Init_SetZListItems('list', array('finalclass', 'target_class', 'description')); // Attributes to be displayed for a list
// Search criteria
MetaModel::Init_SetZListItems('default_search', array('description', 'target_class')); // Default criteria of the search banner
@@ -258,7 +301,7 @@ class TriggerOnPortalUpdate extends TriggerOnObject
MetaModel::Init_InheritAttributes();
// Display lists
MetaModel::Init_SetZListItems('details', array('description', 'target_class', 'filter', 'action_list')); // Attributes to be displayed for the complete details
MetaModel::Init_SetZListItems('details', array('description', 'context', 'target_class', 'filter', 'action_list')); // Attributes to be displayed for the complete details
MetaModel::Init_SetZListItems('list', array('finalclass', 'target_class', 'description')); // Attributes to be displayed for a list
// Search criteria
}
@@ -292,7 +335,7 @@ abstract class TriggerOnStateChange extends TriggerOnObject
MetaModel::Init_AddAttribute(new AttributeClassState("state", array("class_field" => 'target_class', "allowed_values" => null, "sql" => "state", "default_value" => null, "is_null_allowed" => false, "depends_on" => array('target_class'))));
// Display lists
MetaModel::Init_SetZListItems('details', array('description', 'target_class', 'filter', 'state', 'action_list')); // Attributes to be displayed for the complete details
MetaModel::Init_SetZListItems('details', array('description', 'context', 'target_class', 'filter', 'state', 'action_list')); // Attributes to be displayed for the complete details
MetaModel::Init_SetZListItems('list', array('finalclass', 'target_class', 'state')); // Attributes to be displayed for a list
// Search criteria
MetaModel::Init_SetZListItems('standard_search', array('description', 'target_class', 'state')); // Criteria of the std search form
@@ -326,7 +369,7 @@ class TriggerOnStateEnter extends TriggerOnStateChange
MetaModel::Init_InheritAttributes();
// Display lists
MetaModel::Init_SetZListItems('details', array('description', 'target_class', 'filter', 'state', 'action_list')); // Attributes to be displayed for the complete details
MetaModel::Init_SetZListItems('details', array('description', 'context', 'target_class', 'filter', 'state', 'action_list')); // Attributes to be displayed for the complete details
MetaModel::Init_SetZListItems('list', array('target_class', 'state')); // Attributes to be displayed for a list
// Search criteria
MetaModel::Init_SetZListItems('standard_search', array('description', 'target_class', 'state')); // Criteria of the std search form
@@ -360,7 +403,7 @@ class TriggerOnStateLeave extends TriggerOnStateChange
MetaModel::Init_InheritAttributes();
// Display lists
MetaModel::Init_SetZListItems('details', array('description', 'target_class', 'filter', 'state', 'action_list')); // Attributes to be displayed for the complete details
MetaModel::Init_SetZListItems('details', array('description', 'context', 'target_class', 'filter', 'state', 'action_list')); // Attributes to be displayed for the complete details
MetaModel::Init_SetZListItems('list', array('target_class', 'state')); // Attributes to be displayed for a list
// Search criteria
MetaModel::Init_SetZListItems('standard_search', array('description', 'target_class', 'state')); // Criteria of the std search form
@@ -394,7 +437,7 @@ class TriggerOnObjectCreate extends TriggerOnObject
MetaModel::Init_InheritAttributes();
// Display lists
MetaModel::Init_SetZListItems('details', array('description', 'target_class', 'filter', 'action_list')); // Attributes to be displayed for the complete details
MetaModel::Init_SetZListItems('details', array('description', 'context', 'target_class', 'filter', 'action_list')); // Attributes to be displayed for the complete details
MetaModel::Init_SetZListItems('list', array('finalclass', 'target_class')); // Attributes to be displayed for a list
// Search criteria
MetaModel::Init_SetZListItems('standard_search', array('description', 'target_class')); // Criteria of the std search form
@@ -428,7 +471,7 @@ class TriggerOnObjectDelete extends TriggerOnObject
MetaModel::Init_InheritAttributes();
// Display lists
MetaModel::Init_SetZListItems('details', array('description', 'target_class', 'filter', 'action_list')); // Attributes to be displayed for the complete details
MetaModel::Init_SetZListItems('details', array('description', 'context', 'target_class', 'filter', 'action_list')); // Attributes to be displayed for the complete details
MetaModel::Init_SetZListItems('list', array('finalclass', 'target_class')); // Attributes to be displayed for a list
// Search criteria
MetaModel::Init_SetZListItems('standard_search', array('description', 'target_class')); // Criteria of the std search form
@@ -464,7 +507,7 @@ class TriggerOnObjectUpdate extends TriggerOnObject
MetaModel::Init_AddAttribute(new AttributeClassAttCodeSet('target_attcodes', array("allowed_values" => null, "class_field" => "target_class", "sql" => "target_attcodes", "default_value" => null, "is_null_allowed" => true, "max_items" => 20, "min_items" => 0, "attribute_definition_exclusion_list" => "AttributeDashboard,AttributeExternalField,AttributeFinalClass,AttributeFriendlyName,AttributeObsolescenceDate,AttributeObsolescenceFlag,AttributeSubItem", "attribute_definition_list" => null, "depends_on" => array('target_class'))));
// Display lists
MetaModel::Init_SetZListItems('details', array('description', 'target_class', 'filter', 'target_attcodes', 'action_list')); // Attributes to be displayed for the complete details
MetaModel::Init_SetZListItems('details', array('description', 'context', 'target_class', 'filter', 'target_attcodes', 'action_list')); // Attributes to be displayed for the complete details
MetaModel::Init_SetZListItems('list', array('finalclass', 'target_class')); // Attributes to be displayed for a list
// Search criteria
MetaModel::Init_SetZListItems('standard_search', array('description', 'target_class')); // Criteria of the std search form
@@ -599,7 +642,7 @@ class TriggerOnThresholdReached extends TriggerOnObject
MetaModel::Init_AddAttribute(new AttributeString("threshold_index", array("allowed_values" => null, "sql" => "threshold_index", "default_value" => null, "is_null_allowed" => false, "depends_on" => array())));
// Display lists
MetaModel::Init_SetZListItems('details', array('description', 'target_class', 'stop_watch_code', 'threshold_index', 'filter', 'action_list')); // Attributes to be displayed for the complete details
MetaModel::Init_SetZListItems('details', array('description', 'context', 'target_class', 'stop_watch_code', 'threshold_index', 'filter', 'action_list')); // Attributes to be displayed for the complete details
MetaModel::Init_SetZListItems('list', array('target_class', 'threshold_index', 'threshold_index')); // Attributes to be displayed for a list
// Search criteria
MetaModel::Init_SetZListItems('standard_search', array('description', 'target_class')); // Criteria of the std search form

View File

@@ -1,30 +1,22 @@
<?php
// Copyright (C) 2010-2017 Combodo SARL
//
// This file is part of iTop.
//
// iTop is free software; you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// iTop 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 Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with iTop. If not, see <http://www.gnu.org/licenses/>
/**
* User rights management API
* Copyright (C) 2013-2020 Combodo SARL
*
* @copyright Copyright (C) 2010-2017 Combodo SARL
* @license http://opensource.org/licenses/AGPL-3.0
* This file is part of iTop.
*
* iTop is free software; you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* iTop 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
*/
class UserRightException extends CoreException
{
}
@@ -419,7 +411,7 @@ abstract class User extends cmdbAbstractObject
parent::DisplayBareRelations($oPage, $bEditMode);
if (!$bEditMode)
{
$oPage->SetCurrentTab(Dict::S('UI:UserManagement:GrantMatrix'));
$oPage->SetCurrentTab('UI:UserManagement:GrantMatrix');
$this->DoShowGrantSumary($oPage, 'bizmodel,grant_by_profile');
// debug

View File

@@ -97,7 +97,7 @@ class ValueSetObjects extends ValueSetDefinition
protected $m_sFilterExpr; // in OQL
protected $m_sValueAttCode;
protected $m_aOrderBy;
protected $m_aExtraConditions;
protected $m_oExtraCondition;
private $m_bAllowAllData;
private $m_aModifierProperties;
private $m_bSort;
@@ -116,7 +116,7 @@ class ValueSetObjects extends ValueSetDefinition
$this->m_aOrderBy = $aOrderBy;
$this->m_bAllowAllData = $bAllowAllData;
$this->m_aModifierProperties = $aModifierProperties;
$this->m_aExtraConditions = array();
$this->m_oExtraCondition = null;
$this->m_bSort = true;
$this->m_iLimit = 0;
}
@@ -124,11 +124,22 @@ class ValueSetObjects extends ValueSetDefinition
public function SetModifierProperty($sPluginClass, $sProperty, $value)
{
$this->m_aModifierProperties[$sPluginClass][$sProperty] = $value;
$this->m_bIsLoaded = false;
}
/**
* @param \DBSearch $oFilter
* @deprecated use SetCondition
*/
public function AddCondition(DBSearch $oFilter)
{
$this->m_aExtraConditions[] = $oFilter;
$this->SetCondition($oFilter);
}
public function SetCondition(DBSearch $oFilter)
{
$this->m_oExtraCondition = $oFilter;
$this->m_bIsLoaded = false;
}
public function ToObjectSet($aArgs = array(), $sContains = '', $iAdditionalValue = null)
@@ -141,9 +152,9 @@ class ValueSetObjects extends ValueSetDefinition
{
$oFilter = DBObjectSearch::FromOQL($this->m_sFilterExpr);
}
foreach($this->m_aExtraConditions as $oExtraFilter)
if (!is_null($this->m_oExtraCondition))
{
$oFilter = $oFilter->Intersect($oExtraFilter);
$oFilter = $oFilter->Intersect($this->m_oExtraCondition);
}
foreach($this->m_aModifierProperties as $sPluginClass => $aProperties)
{
@@ -216,9 +227,9 @@ class ValueSetObjects extends ValueSetDefinition
$oFilter = DBObjectSearch::FromOQL($this->m_sFilterExpr);
}
if (!$oFilter) return false;
foreach($this->m_aExtraConditions as $oExtraFilter)
if (!is_null($this->m_oExtraCondition))
{
$oFilter = $oFilter->Intersect($oExtraFilter);
$oFilter = $oFilter->Intersect($this->m_oExtraCondition);
}
foreach($this->m_aModifierProperties as $sPluginClass => $aProperties)
{
@@ -350,10 +361,10 @@ class ValueSetEnum extends ValueSetDefinition
$this->m_values = $Values;
}
// Helper to export the datat model
// Helper to export the data model
public function GetValueList()
{
$this->LoadValues($aArgs = array());
$this->LoadValues(null);
return $this->m_aValues;
}
@@ -382,6 +393,29 @@ class ValueSetEnum extends ValueSetDefinition
}
}
class ValueSetEnumPadded extends ValueSetEnum
{
public function __construct($Values)
{
parent::__construct($Values);
if (is_string($Values))
{
$this->LoadValues(null);
}
else
{
$this->m_aValues = $Values;
}
$aPaddedValues = array();
foreach ($this->m_aValues as $sKey => $sVal)
{
$sKey = str_pad($sKey, 3, '_', STR_PAD_LEFT);
$aPaddedValues[$sKey] = $sVal;
}
$this->m_values = $aPaddedValues;
}
}
/**
* Fixed set values, defined as a range: 0..59 (with an optional increment)
*

View File

@@ -0,0 +1,34 @@
/*!
*
* * Copyright (C) 2013-2020 Combodo SARL
* *
* * This file is part of iTop.
* *
* * iTop is free software; you can redistribute it and/or modify
* * it under the terms of the GNU Affero General Public License as published by
* * the Free Software Foundation, either version 3 of the License, or
* * (at your option) any later version.
* *
* * iTop 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 Affero General Public License for more details.
* *
* * You should have received a copy of the GNU Affero General Public License
*
*/
$backoffice-environment-banner-background-color: #C53030 !default;
$backoffice-environment-banner-text-color: #F7FAFC !default;
$backoffice-environment-banner-text-content: "THIS IS NOT PRODUCTION INSTANCE" !default;
div#top-bar::before {
display: block;
width: 100%;
padding: 0.2rem;
text-align: center;
font-size: 1rem;
background: $backoffice-environment-banner-background-color;
color: $backoffice-environment-banner-text-color;
content: $backoffice-environment-banner-text-content;
}

View File

@@ -1,222 +0,0 @@
/* CSS Document */
body {
font-family: Verdana, Arial, Helevtica;
font-size: smaller;
background-color: #68a;
color:#000000;
margin: 0; /* Remove body margin/padding */
padding: 0;
overflow: hidden; /* Remove scroll bars on browser window */
}
table {
border: 1px solid #000000;
}
.raw_output {
font-family: Courier-New, Courier, Arial, Helevtica;
font-size: smaller;
background-color: #eeeeee;
color: #000000;
border: 1px dashed #000000;
padding: 0.25em;
margin-top: 1em;
}
th {
font-family: Verdana, Arial, Helvetica;
font-size: smaller;
color: #000000;
background-color:#ace27d;
}
td {
font-family: Verdana, Arial, Helvetica;
font-size: smaller;
background-color: #b7cfe8;
}
tr.clicked td {
font-family: Verdana, Arial, Helvetica;
font-size: smaller;
background-color: #ffcfe8;
}
td.label {
font-family: Verdana, Arial, Helvetica;
font-size: smaller;
color: #000000;
background-color:#ace27d;
padding: 0.2em;
}
td a, td a:visited {
text-decoration:none;
color:#000000;
}
td a:hover {
text-decoration:underline;
color:#FFFFFF;
}
a.small_action {
font-family: Verdana, Arial, Helvetica;
font-size: smaller;
color: #000000;
text-decoration:none;
}
.display_block {
noborder: 1px dashed #CCC;
background: #79b;
padding:0.25em;
}
div#TopPane .display_block {
background: #f0eee0;
padding:0.25em;
text-align:center;
}
div#TopPane label {
color:#000;
background: #f0eee0;
}
div#TopPane td {
color:#000;
background: #f0eee0;
}
.loading {
noborder: 1px dashed #CCC;
background: #b9c1c8;
padding:0.25em;
}
label {
font-family:Georgia, "Times New Roman", Times, serif;
color:#FFFFFF;
text-align:right;
}
input.textSearch {
border:1px solid #333;
noheight:1.2em;
font-size:0.8em;
font-family:Verdana, Arial, Helvetica, sans-serif;
color:#000000;
}
/* By Rom */
.csvimport_createobj {
color: #AA0000;
background-color:#EEEEEE;
}
.csvimport_error {
font-weight: bold;
color: #FF0000;
background-color:#EEEEEE;
}
.csvimport_warning {
color: #CC8888;
background-color:#EEEEEE;
}
.csvimport_ok {
color: #000000;
background-color:#BBFFBB;
}
.csvimport_reconkey {
font-style: italic;
color: #888888;
background-color:#FFFFFF;
}
.csvimport_extreconkey {
color: #888888;
background-color:#FFFFFF;
}
.treeview, .treeview ul {
padding: 0;
margin: 0;
list-style: none;
}
.treeview li {
margin: 0;
padding: 3px 0pt 3px 16px;
font-size:0.9em;
}
ul.dir li {
padding: 2px 0 0 16px;
}
.treeview li { background: url(../images/tv-item.gif) 0 0 no-repeat; }
.treeview .collapsable { background-image: url(../images/tv-collapsable.gif); }
.treeview .expandable { background-image: url(../images/tv-expandable.gif); }
.treeview .last { background-image: url(../images/tv-item-last.gif); }
.treeview .lastCollapsable { background-image: url(../images/tv-collapsable-last.gif); }
.treeview .lastExpandable { background-image: url(../images/tv-expandable-last.gif); }
#Header { padding: 0; background:#ccc url(../images/bandeau2.gif) repeat-x center;}
div.iTopLogo {
background:url(../images/iTop.gif) no-repeat center;
width:100px;
height:56px;
}
div.iTopLogo span {
display:none;
}
#MySplitter {
/* Height is set to match window size in $().ready() below */
border:0px;
margin:4px;
padding:0px;
min-width: 100px; /* Splitter can't be too thin ... */
min-height: 100px; /* ... or too flat */
}
#LeftPane {
background: #f0eee0;
padding: 4px;
overflow: auto; /* Scroll bars appear as needed */
color:#666;
}
#TopPane { /* Top nested in right pane */
background: #f0eee0;
padding: 4px;
height: 150px; /* Initial height */
min-height: 75px; /* Minimum height */
overflow: auto;
color:#666;
}
#RightPane { /* Bottom nested in right pane */
background: #79b;
height:150px; /* Initial height */
min-height:130px;
no.padding:15px;
no.margin:10px;
overflow:auto;
color:#fff;
}
#BottomPane { /* Bottom nested in right pane */
background: #79b;
padding: 4px;
overflow: auto;
color:#fff;
}
#MySplitter .vsplitbar {
width: 7px;
height: 50px;
background: #68a url(../images/vgrabber2.gif) no-repeat center;
}
#MySplitter .vsplitbar.active, #MySplitter .vsplitbar:hover {
background: #68a url(../images/vgrabber2_active.gif) no-repeat center;
}
#MySplitter .hsplitbar {
height: 8px;
background: #68a url(../images/hgrabber2.gif) no-repeat center;
}
#MySplitter .hsplitbar.active, #MySplitter .hsplitbar:hover {
background: #68a url(../images/hgrabber2_active.gif) no-repeat center;
}

View File

@@ -1,6 +1,24 @@
/*!
* Copyright (C) 2013-2020 Combodo SARL
*
* This file is part of iTop.
*
* iTop is free software; you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* iTop 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
*/
// Beware the version number MUST be enclosed with quotes otherwise v2.3.0 becomes v2 0.3 .0
$version: "v2.7.0-beta";
$approot-relative: "../../../../../"; // relative to env-***/branding/themes/***/main.css
$version: "v2.7.0-2";
$approot-relative: "../../../../../" !default; // relative to env-***/branding/themes/***/main.css
// Base colors
$gray-base: #000 !default;
@@ -21,8 +39,26 @@ $combodo-orange-darker: darken($combodo-orange, 18%) !default;
$combodo-dark-gray-dark: darken($combodo-dark-gray, 13.5%) !default;
$combodo-dark-gray-darker: darken($combodo-dark-gray, 18%) !default;
// Brand colors
// - Bases
$brand-primary: $combodo-orange !default;
$brand-secondary: $combodo-dark-gray !default;
// - Shades
$brand-primary-lightest: lighten($brand-primary, 15%) !default;
$brand-primary-lighter: lighten($brand-primary, 10%) !default;
$brand-primary-light: lighten($brand-primary, 6%) !default;
$brand-primary-dark: darken($brand-primary, 6%) !default;
$brand-primary-darker: darken($brand-primary, 10%) !default;
$brand-primary-darkest: darken($brand-primary, 15%) !default;
$brand-secondary-lightest: lighten($brand-secondary, 15%) !default;
$brand-secondary-lighter: lighten($brand-secondary, 10%) !default;
$brand-secondary-light: lighten($brand-secondary, 6%) !default;
$brand-secondary-dark: darken($brand-secondary, 6%) !default;
$brand-secondary-darker: darken($brand-secondary, 10%) !default;
$brand-secondary-darkest: darken($brand-secondary, 15%) !default;
// Vars
$highlight-color: $combodo-orange !default;
$highlight-color: $brand-primary !default;
$grey-color: #555555 !default;
$complement-color: #1c94c4 !default;
$complement-light: #d6e8ef !default;
@@ -30,48 +66,60 @@ $frame-background-color: $gray-extra-light !default;
$text-color: #000 !default;
$box-radius: 0px !default;
$box-shadow-regular: 0 1px 1px rgba(0, 0, 0, 0.15) !default;
$body-background-color : $white !default;
$hyperlink-color: $complement-color !default;
$hyperlink-text-decoration: none !default;
////////////
// Search //
$search-form-container-color: $white !default;
$search-form-container-bg-color: $complement-color !default;
//
$search-criteria-box-color: #2D2D2D !default;
$search-criteria-box-picto-color: #E87C1E !default;
$search-criteria-box-picto-color: $brand-primary !default;
$search-criteria-box-bg-color: #EEEEEE !default;
$search-criteria-box-hover-color: $white !default;
$search-criteria-box-border-color: #CCCCCC !default;
$search-criteria-box-border: 1px solid $search-criteria-box-border-color !default;
$search-criteria-box-radius: 1px !default;
$search-criteria-more-less-details-color: #3F7294 !default;
//
$search-add-criteria-box-color: $search-criteria-box-color !default;
$search-add-criteria-box-bg-color: $white !default;
$search-add-criteria-box-hover-color: $gray-extra-light !default;
//
$search-button-box-color: $combodo-orange !default;
$search-button-box-color: $brand-primary !default;
$search-button-box-bg-color: $white !default;
$search-button-box-bg-hover-color: $gray-extra-light !default;
/////////////
// Buttons //
/////////////
// Toggle button
$toggle-button-bg-color: #CCCCCC !default;
$toggle-button-bg-checked-color: $brand-primary !default;
$toggle-button-slider-bg-color: #FFFFFF !default;
// Console elements
$summary-details-background: $grey-color !default;
$main-header-background: $frame-background-color !default;
$table-even-background: $frame-background-color !default;
$table-hover-background: #fdf5d0 !default;
$popup-menu-highlight-color: $highlight-color !default;
$popup-menu-text-color: #000 !default;
$popup-menu-background-color: #fff !default;
$popup-menu-text-higlight-color: #fff !default;
$breadcrumb-color: #555 !default;
$breadcrumb-text-color: #fff !default;
$breadcrumb-color: $grey-color !default;
$breadcrumb-highlight-color: $highlight-color !default;
$breadcrumb-text-highlight-color: #fff !default;
// JQuery UI widgets vars
// jQuery UI widgets vars
$primary-text-color: #333333 !default;
$secondary-text-color: $grey-color !default;
$error-text-color: $white !default;
$highlight-text-color: #363636 !default;
$hover-background-color: #fde17c !default;
$border-highlight-color: #f26522 !default;
$border-highlight-color: $brand-primary-dark !default;
$highlight-item-color: $white !default;
$content-color: #eeeeee !default;
$default-font-family: Trebuchet MS,Tahoma,Verdana,Arial,sans-serif !default;

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -1,12 +1,12 @@
<?xml version="1.0" standalone="no"?>
<!--
Font Awesome Free 5.9.0 by @fontawesome - https://fontawesome.com
Font Awesome Free 5.12.0 by @fontawesome - https://fontawesome.com
License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License)
-->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" >
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1">
<metadata>
Created by FontForge 20190112 at Tue Jun 4 15:16:44 2019
Created by FontForge 20190801 at Tue Dec 10 16:09:21 2019
By Robert Madole
Copyright (c) Font Awesome
</metadata>
@@ -22,8 +22,8 @@ Copyright (c) Font Awesome
descent="-64"
bbox="-0.200195 -66.9505 641.5 448.3"
underline-thickness="25"
underline-position="-51"
unicode-range="U+0020-F842"
underline-position="-50"
unicode-range="U+0020-F949"
/>
<missing-glyph />
<glyph glyph-name="twitter-square" unicode="&#xf081;"
@@ -165,13 +165,10 @@ c-9.60059 27.9336 -14.4004 55 -14.4004 81.2002c0 88.7002 59.2998 132.3 115.1 133
M262.1 343.5c-19.5996 -22.9004 -43.3994 -36.2998 -69.5 -34.2998c-2.19922 27.5996 8.10059 52.0996 25.6006 71.8994c15.8994 18.5 43.7998 33.5 67.8994 34.9004c0.800781 -10.5996 3.30078 -40.0996 -24 -72.5z" />
<glyph glyph-name="windows" unicode="&#xf17a;"
d="M0 354.3l183.6 25.2998v-177.399h-183.6v152.1zM0 29.7002v149.899h183.6v-175.199zM203.8 1.7002v177.899h244.2v-211.6zM203.8 382.3l244.2 33.7002v-213.8h-244.2v180.1z" />
<glyph glyph-name="android" unicode="&#xf17b;"
d="M89.5996 243.5v-115.8c0 -15.4004 -12.0996 -27.7002 -27.5 -27.7002c-15.2998 0 -30.0996 12.4004 -30.0996 27.7002v115.8c0 15.0996 14.7998 27.5 30.0996 27.5c15.1006 0 27.5 -12.4004 27.5 -27.5zM100.4 86.5v179.4h247.3v-179.4
c0 -16.4004 -13.2002 -29.5996 -29.4004 -29.5996h-20.2002v-61.1006c0 -36.7998 -55.5 -36.7002 -55.5 0v61.1006h-37.1992v-61.1006c0 -36.5996 -55.2002 -36.8994 -55.2002 0l-0.299805 61.1006h-19.9004c-16.4004 0 -29.5996 13.1992 -29.5996 29.5996zM348.4 275.6
h-249.101c0 42.8008 25.6006 80 63.6006 99.4004l-19.1006 35.2998c-2.7998 4.90039 4.2998 8 6.7002 3.7998l19.4004 -35.5996c34.8994 15.5 75 14.7002 108.3 0l19.2998 35.5c2.5 4.2998 9.5 1.09961 6.7002 -3.7998l-19.1006 -35.2002
c37.7002 -19.4004 63.3008 -56.5996 63.3008 -99.4004zM177.7 331.1c0 5.7002 -4.60059 10.5 -10.5 10.5c-5.7002 0 -10.2002 -4.7998 -10.2002 -10.5c0 -5.69922 4.59961 -10.5 10.2002 -10.5c5.89941 0 10.5 4.80078 10.5 10.5zM291.1 331.1
c0 5.7002 -4.59961 10.5 -10.1992 10.5c-5.90039 0 -10.5 -4.7998 -10.5 -10.5c0 -5.69922 4.59961 -10.5 10.5 -10.5c5.59961 0 10.1992 4.80078 10.1992 10.5zM385.9 271c15.2998 0 30.0996 -12.0996 30.0996 -27.5v-115.8
c0 -15.2998 -14.7002 -27.7002 -30.0996 -27.7002c-15.1006 0 -27.5 12.2998 -27.5 27.7002v115.8c0 15.4004 12.3994 27.5 27.5 27.5z" />
<glyph glyph-name="android" unicode="&#xf17b;" horiz-adv-x="576"
d="M420.55 146.07c-13.248 0 -24 10.752 -24 24s10.752 24 24 24s24 -10.752 24 -24s-10.752 -24 -24 -24zM155.45 146.07c-13.248 0 -24 10.752 -24 24s10.752 24 24 24s24 -10.752 24 -24s-10.752 -24 -24 -24zM429.15 290.55l47.9395 83
c0.936523 1.39551 1.69629 3.8916 1.69629 5.57227c0 5.51953 -4.47949 10 -10 10c-3.43066 0 -7.44727 -2.49609 -8.96582 -5.57227v0l-48.54 -84.0693c-32.4678 14.5615 -87.6973 26.3789 -123.28 26.3789s-90.8125 -11.8174 -123.28 -26.3789l-48.54 84.0693
c-1.51855 3.07617 -5.53516 5.57227 -8.96582 5.57227c-5.52051 0 -10 -4.48047 -10 -10c0 -1.68066 0.759766 -4.17676 1.69629 -5.57227v0l47.9395 -83c-82.3193 -44.7695 -138.609 -128.1 -146.85 -226.55h576c-8.24023 98.4502 -64.54 181.78 -146.85 226.55z" />
<glyph glyph-name="linux" unicode="&#xf17c;"
d="M220.8 324.7c-1.09961 0.599609 -3.09961 0.399414 -3.39941 1.7002c-0.200195 0.399414 0.199219 0.899414 0.599609 1.09961c1.59961 0.900391 3.7998 0.599609 5.5 -0.0996094c1.2998 -0.600586 3.40039 -1.5 3.2002 -2.90039
c-0.100586 -1.09961 -1.7998 -1.5 -2.90039 -1.5c-1.2002 0 -2 1.2002 -3 1.7002zM198.9 323c-1 -0.0996094 -2.7002 0.400391 -2.80078 1.40039c-0.199219 1.39941 1.90039 2.2998 3.2002 2.89941c1.7002 0.700195 3.90039 1 5.5 0.100586
@@ -474,8 +471,8 @@ c56.2998 -191.7 -137.4 -222.3 -134.3 -124c0 0.700195 -0.299805 53.7998 -0.299805
c-53.1992 21.7002 -88 49.4004 -106.3 72c-9.09961 13.7002 0.900391 28.3008 16 17.7002c2 -1.39941 4.2998 -2.89941 6.2998 -4.2998v198.3c0 27.4004 20.6006 49.7002 46 49.7002h359.101c25.3994 0 46 -22.2998 46 -49.7002v-198.3zM457.2 185.1h0.0996094v190.601
c0 32.7998 -10.5996 45.7002 -40.8994 45.7002h-317.7c-31.7002 0 -40.6006 -10.8008 -40.6006 -45.7002v-192.4c67.7002 -35.3994 125.7 -29.0996 157.4 -28c13.4004 0.299805 22 -2.2998 27.0996 -7.7002c1.7002 -1.59961 10 -9.39941 20.3008 -17.0996
c1.09961 15.7998 10 25.7998 33.6992 24.9004c32.3008 -1.40039 91.7002 -7.7002 160.601 29.6992z" />
<glyph glyph-name="twitch" unicode="&#xf1e8;"
d="M40.0996 416h397.9v-274.2l-117 -117h-87l-56.7998 -56.7998h-60.2002v56.7998h-107v314.3zM397.9 161.9v214h-321v-280.9h90.2998v-56.7998l56.7998 56.7998h107zM331 299v-116.9h-40.0996v116.9h40.0996zM224 299v-116.9h-40.0996v116.9h40.0996z" />
<glyph glyph-name="twitch" unicode="&#xf1e8;" horiz-adv-x="512"
d="M391.17 344.53v-109.7h-38.6299v109.7h38.6299zM285 345v-109.75h-38.6299v109.75h38.6299zM120.83 448h366.86v-256l-173.771 -164.58h-77.25l-96.5303 -91.4199v91.4199h-115.83v329.16zM449.07 210.25v201.17h-308.931v-274.29h86.8701v-64l67.6006 64h77.2393z" />
<glyph glyph-name="yelp" unicode="&#xf1e9;" horiz-adv-x="384"
d="M42.9004 207.68l99.6191 -48.6094c19.2002 -9.40039 16.2002 -37.5107 -4.5 -42.71l-107.52 -26.8105c-1.51074 -0.379883 -4 -0.6875 -5.55762 -0.6875c-11.2676 0 -21.415 9.08887 -22.6523 20.2881c-0.708984 6.18164 -1.28516 16.25 -1.28516 22.4727
c0 17.8105 4.60742 45.9658 10.2852 62.8467c2.88574 8.56836 12.5664 15.5215 21.6074 15.5215c2.9082 0 7.38867 -1.03516 10.0029 -2.31152zM86.9004 -31.5703c-5.48535 3.75195 -9.92773 12.1904 -9.92773 18.8359c0 4.8291 2.61914 11.6631 5.84766 15.2539
@@ -792,42 +789,49 @@ c15 29.7002 57.8008 109.2 75.3008 142.8c-13.9004 28.3008 -58.6006 133.9 -72.8008
c18.8994 -40 30.5996 -68.1006 48.0996 -104.7c5.59961 10.7998 34.7002 69.4004 48.0996 100.8c8.90039 20.6006 -3.89941 28.6006 -38.5996 29.4004c0.299805 3.59961 0 10.2998 0.299805 13.5996c44.4004 0.299805 111.101 0.299805 123.101 0.600586v-13.6006
c-22.5 -0.799805 -45.8008 -12.7998 -58.1006 -31.7002l-59.2002 -122.8c6.40039 -16.0996 63.3008 -142.8 69.2002 -156.7l122.4 282.601c-8.60059 23.0996 -36.4004 28.0996 -47.2002 28.2998v13.9004l127.8 -1.10059z" />
<glyph glyph-name="safari" unicode="&#xf267;" horiz-adv-x="512"
d="M236.9 191.2c0 9.09961 6.59961 17.7002 16.2998 17.7002c8.89941 0 17.3994 -6.40039 17.3994 -16.1006c0 -9.09961 -6.39941 -17.7002 -16.0996 -17.7002c-9 0 -17.5996 6.7002 -17.5996 16.1006zM504 192c0 -137 -111 -248 -248 -248s-248 111 -248 248
s111 248 248 248s248 -111 248 -248zM477.4 192c0 122.3 -99.1006 221.4 -221.4 221.4s-221.4 -99.1006 -221.4 -221.4s99.1006 -221.4 221.4 -221.4s221.4 99.1006 221.4 221.4zM404.9 95.4004c0 -3.60059 13 -10.2002 16.2998 -12.2002
c-27.4004 -41.5 -69.7998 -71.4004 -117.9 -83.2998l-4.39941 18.5c-0.300781 2.5 -1.90039 2.7998 -4.2002 2.7998c-1.90039 0 -3 -2.7998 -2.7998 -4.2002l4.39941 -18.7998c-13.2998 -2.7998 -26.7998 -4.2002 -40.3994 -4.2002c-36.3008 0 -72 10.2002 -103 29.0996
c1.69922 2.80078 12.1992 18 12.1992 20.2002c0 1.90039 -1.69922 3.60059 -3.59961 3.60059c-3.90039 0 -12.2002 -16.6006 -14.7002 -19.9004c-41.7998 27.7002 -72 70.5996 -83.5996 119.6l19.0996 4.2002c2.2002 0.600586 2.7998 2.2002 2.7998 4.2002
c0 1.90039 -2.7998 3 -4.39941 2.7998l-18.7002 -4.2998c-2.5 12.7002 -3.90039 25.5 -3.90039 38.5c0 37.0996 10.5 73.5996 30.2002 104.9c2.7998 -1.7002 16.1006 -10.8008 18.2998 -10.8008c1.90039 0 3.60059 1.40039 3.60059 3.30078
c0 3.89941 -14.7002 11.2998 -18 13.5996c28.2002 41.2002 71.0996 70.9004 119.8 81.9004l4.2002 -18.5c0.599609 -2.2002 2.2002 -2.80078 4.2002 -2.80078s3 2.80078 2.7998 4.40039l-4.2002 18.2998c12.2002 2.2002 24.5996 3.60059 37.0996 3.60059
c37.1006 0 73.3008 -10.5 104.9 -30.2002c-1.90039 -2.7998 -10.7998 -15.7998 -10.7998 -18c0 -1.90039 1.39941 -3.60059 3.2998 -3.60059c3.90039 0 11.2998 14.4004 13.2998 17.7002c41 -27.7002 70.2998 -70 81.7002 -118.2l-15.5 -3.2998
c-2.5 -0.599609 -2.7998 -2.2002 -2.7998 -4.39941c0 -1.90039 2.7998 -3 4.2002 -2.80078l15.7998 3.60059c2.5 -12.7002 3.89941 -25.7002 3.89941 -38.7002c0 -36.2998 -10 -72 -28.7998 -102.7c-2.7998 1.40039 -14.3994 9.7002 -16.5996 9.7002
c-2.10059 0 -3.7998 -1.7002 -3.7998 -3.59961zM371.7 337.6c-13 -12.1992 -134.2 -123.699 -137.601 -129.5l-96.5996 -160.5c12.7002 11.9004 134.2 124 137.3 129.301z" />
d="M274.69 173.31l-108.69 -71.3096l71.3096 108.69zM256 440c137 0 248 -111 248 -248s-111 -248 -248 -248s-248 111 -248 248s111 248 248 248zM411.85 265.21c-2.71094 -1.13477 -4.91211 -4.44043 -4.91211 -7.37988c0 -0.880859 0.274414 -2.25684 0.612305 -3.07031
v0c1.12988 -2.72559 4.44043 -4.9375 7.39062 -4.9375c0.87793 0 2.24902 0.272461 3.05957 0.607422l14.75 6.11035c2.72754 1.12891 4.94141 4.44043 4.94141 7.39258c0 0.879883 -0.273438 2.25391 -0.611328 3.06738v0
c-1.12793 2.73047 -4.44043 4.94629 -7.39453 4.94629c-0.876953 0 -2.24512 -0.271484 -3.05566 -0.606445zM314.43 354c-0.341797 -0.818359 -0.620117 -2.20117 -0.620117 -3.08789c0 -2.95215 2.21387 -6.26367 4.94043 -7.39258v0
c0.810547 -0.334961 2.18164 -0.607422 3.05957 -0.607422c2.9502 0 6.26074 2.21191 7.39062 4.9375l6.12988 14.7803c0.335938 0.811523 0.608398 2.18164 0.608398 3.05957c0 2.9502 -2.21289 6.26172 -4.93848 7.39062v0
c-0.813477 0.337891 -2.18848 0.612305 -3.07031 0.612305c-2.93848 0 -6.24512 -2.20117 -7.37988 -4.91211zM256 388c-4.41602 0 -8 -3.58398 -8 -8v-16c0 -4.41602 3.58398 -8 8 -8v0c4.41602 0 8 3.58398 8 8v16c0 4.41602 -3.58398 8 -8 8v0zM181 373.08
c-2.72461 -1.12988 -4.93555 -4.44043 -4.93555 -7.38965c0 -0.869141 0.266602 -2.22656 0.595703 -3.03027l6.12988 -14.7803c1.09863 -2.80664 4.43555 -5.08398 7.44922 -5.08398c4.41602 0 8 3.58398 8 8c0 0.922852 -0.299805 2.3584 -0.668945 3.2041l-6.11035 14.75
c-1.12891 2.72754 -4.44043 4.94141 -7.39258 4.94141c-0.879883 0 -2.25391 -0.273438 -3.06738 -0.611328zM117.42 330.59c-1.29297 -1.29297 -2.35156 -3.82617 -2.35156 -5.65527c0 -1.81445 1.03613 -4.33398 2.31152 -5.625l11.3105 -11.3096
c1.29297 -1.29199 3.82617 -2.34082 5.6543 -2.34082s4.3623 1.04883 5.65527 2.34082v0c1.28418 1.29199 2.32617 3.81836 2.32617 5.63965c0 1.82227 -1.04199 4.34863 -2.32617 5.64062l-11.2695 11.3096c-1.29395 1.29297 -3.82715 2.3418 -5.65527 2.3418
s-4.3623 -1.04883 -5.65527 -2.3418v0zM60 192c0 -4.41602 3.58398 -8 8 -8h16c4.41602 0 8 3.58398 8 8v0c0 4.41602 -3.58398 8 -8 8h-16c-4.41602 0 -8 -3.58398 -8 -8v0zM100.15 118.79c2.71094 1.13477 4.91211 4.44043 4.91211 7.37988
c0 0.880859 -0.274414 2.25684 -0.612305 3.07031v0c-1.12988 2.72559 -4.44043 4.9375 -7.39062 4.9375c-0.87793 0 -2.24902 -0.272461 -3.05957 -0.607422l-14.75 -6.11035c-2.72754 -1.12891 -4.94141 -4.44043 -4.94141 -7.39258
c0 -0.879883 0.273438 -2.25391 0.611328 -3.06738v0c1.12793 -2.73047 4.44043 -4.94629 7.39453 -4.94629c0.876953 0 2.24512 0.271484 3.05566 0.606445zM104.48 254.79c0.333008 0.80957 0.604492 2.14551 0.604492 3.02051
c0 2.94922 -2.21094 6.25977 -4.93457 7.38965l-14.7803 6.12988c-0.811523 0.335938 -2.18164 0.608398 -3.05957 0.608398c-2.9502 0 -6.26172 -2.21289 -7.39062 -4.93848v0c-0.337891 -0.813477 -0.612305 -2.18848 -0.612305 -3.07031
c0 -2.93848 2.20117 -6.24512 4.91211 -7.37988l14.7803 -6.12012c0.814453 -0.338867 2.19141 -0.614258 3.07422 -0.614258c2.96582 0 6.28418 2.22852 7.40625 4.97461v0zM197.57 30c0.369141 0.845703 0.668945 2.28125 0.668945 3.2041c0 4.41602 -3.58398 8 -8 8
c-3.01367 0 -6.35059 -2.27734 -7.44922 -5.08398l-6.12988 -14.7803c-0.335938 -0.811523 -0.608398 -2.18164 -0.608398 -3.05957c0 -4.41797 3.58594 -8.00293 8.00293 -8.00293c2.95312 0 6.2666 2.21387 7.39551 4.94238zM264 4v16c0 4.41602 -3.58398 8 -8 8v0
c-4.41602 0 -8 -3.58398 -8 -8v-16c0 -4.41602 3.58398 -8 8 -8v0c4.41602 0 8 3.58398 8 8zM331 10.9199c2.72461 1.12988 4.93555 4.44043 4.93555 7.38965c0 0.869141 -0.266602 2.22656 -0.595703 3.03027l-6.12988 14.7803
c-1.12891 2.72559 -4.44043 4.9375 -7.39062 4.9375c-0.87793 0 -2.24805 -0.272461 -3.05957 -0.607422v0c-2.72559 -1.12988 -4.9375 -4.44043 -4.9375 -7.39062c0 -0.87793 0.272461 -2.24902 0.607422 -3.05957l6.11035 -14.75
c1.12891 -2.72754 4.44043 -4.94141 7.39258 -4.94141c0.879883 0 2.25391 0.273438 3.06738 0.611328v0zM394.58 53.4102c1.29297 1.29297 2.35156 3.82617 2.35156 5.65527c0 1.81445 -1.03613 4.33398 -2.31152 5.625l-11.3105 11.3096
c-1.29297 1.29199 -3.82617 2.34082 -5.6543 2.34082s-4.3623 -1.04883 -5.65527 -2.34082v0c-1.28418 -1.29199 -2.32617 -3.81836 -2.32617 -5.63965c0 -1.82227 1.04199 -4.34863 2.32617 -5.64062l11.2695 -11.3096c1.29395 -1.29297 3.82715 -2.3418 5.65527 -2.3418
s4.3623 1.04883 5.65527 2.3418v0zM286.25 161.75l115.41 175.91l-175.91 -115.41l-115.41 -175.91zM437.08 117c0.337891 0.813477 0.612305 2.18848 0.612305 3.07031c0 2.93848 -2.20117 6.24512 -4.91211 7.37988l-14.7803 6.12012
c-0.818359 0.341797 -2.20117 0.620117 -3.08789 0.620117c-2.95215 0 -6.26367 -2.21387 -7.39258 -4.94043v0c-0.334961 -0.810547 -0.607422 -2.18164 -0.607422 -3.05957c0 -2.9502 2.21191 -6.26074 4.9375 -7.39062l14.7803 -6.12988
c0.811523 -0.335938 2.18164 -0.608398 3.05957 -0.608398c2.9502 0 6.26172 2.21289 7.39062 4.93848v0zM444 184c4.41602 0 8 3.58398 8 8v0c0 4.41602 -3.58398 8 -8 8h-16c-4.41602 0 -8 -3.58398 -8 -8v0c0 -4.41602 3.58398 -8 8 -8h16z" />
<glyph glyph-name="chrome" unicode="&#xf268;" horiz-adv-x="496"
d="M131.5 230.5l-76.4004 117.4c47.6006 59.1992 119 91.7998 192 92.0996c42.3008 0.299805 85.5 -10.5 124.801 -33.2002c43.3994 -25.2002 76.3994 -61.3994 97.3994 -103l-205.3 10.7998c-58.0996 3.40039 -113.4 -29.2998 -132.5 -84.0996zM164.4 192
c0 46.2998 37.3994 83.5996 83.5996 83.5996s83.5996 -37.3994 83.5996 -83.5996s-37.3994 -83.5996 -83.5996 -83.5996s-83.5996 37.3994 -83.5996 83.5996zM479.3 281.2c43.5 -111.9 0 -241.9 -107.399 -303.9c-43.4004 -25.2002 -91.3008 -35.3994 -137.801 -32.8994
l112.101 172.399c31.8994 49 31.2998 112.9 -6.60059 157.2zM133.7 144.4c26.2998 -51.7002 81.8994 -83.3008 139.5 -72.5l-63.7002 -124.801c-118.7 18.2002 -209.5 120.9 -209.5 244.9c0 50.0996 14.9004 96.9004 40.4004 135.9z" />
<glyph glyph-name="firefox" unicode="&#xf269;" horiz-adv-x="480"
d="M478.1 212.7c1.30078 -7.10059 1.90039 -14.2998 1.90039 -21.6006v-2.7998c-1.40039 -34 -11.5996 -67 -29.5996 -95.8994c-1 -1.5 -1.80078 -2.90039 -2.7002 -4.30078c2.7002 -7.19922 2.59961 -15.0996 -0.400391 -22.1992
c-5 -19.4004 -16.5996 -36.4004 -32.8994 -48.1006c-10.8008 -8.7002 -22.7002 -16.2002 -35.3008 -22.0996l-1.89941 -0.900391l-1 -0.5c-1.7002 -0.700195 -3.2998 -1.39941 -4.90039 -2.09961c-2.39941 -5.10059 -5.7998 -9.60059 -9.89941 -13.2998
c-2.5 -3.10059 -30.1006 -35 -113.801 -35c-23.5996 0 -47.1992 3.5 -69.7998 10.2998c0.799805 -0.299805 1.60059 -0.700195 2.40039 -1c-2.60059 0.899414 -5.2002 1.7998 -7.7002 2.7002c-19.0996 5.89941 -37.2002 14.5996 -53.7998 25.7998
c-40.7002 24.7002 -72.9004 61.2002 -92.2998 104.7c-14.5 31.3994 -21.1006 65.7998 -19.4004 100.3c-2.7998 -8.2998 -5.2002 -16.7002 -7 -25.2998c0 29.1992 5.5 58.0996 16.2002 85.1992c-5.5 -7.89941 -10.2998 -16.2998 -14.2998 -25.0996
c5.69922 23.0996 14.6992 45.2002 26.7998 65.5996c3.7002 6.10059 7.89941 11.9004 12.7002 17.1006v0.200195c-0.100586 2.69922 0.0996094 5.5 0.5 8.2998c1.5 16.2998 5.69922 32.2002 12.3994 47.0996l0.299805 0.700195c0.100586 0.299805 0 -1 0 -1.7002
s-0.0996094 -1.2998 0 -1c0.600586 2 1.40039 4 2.30078 5.90039c1 2.09961 2.39941 4.09961 3.89941 5.7998c0.100586 0.0996094 0.200195 0.200195 0.299805 0.400391c0.100586 0.199219 -0.399414 -2 -0.5 -3.10059v-0.5c0.600586 1.2002 1.30078 2.40039 2.2002 4.5
c2.10059 5.90039 6 11 11.1006 14.5l0.199219 0.100586c-0.299805 -9 1.2002 -17.9004 4.40039 -26.2002v-0.100586c0.299805 -0.399414 0.5 1.30078 0.900391 1.30078c0.0996094 0 0.199219 -0.100586 0.199219 -0.200195
c0.900391 -1.7998 1.80078 -3.60059 2.7002 -5.2002c1.2998 -2.2002 2.5 -4.2002 3.7002 -6l0.400391 -0.200195l0.199219 0.100586c2.60059 -4.2002 5.90039 -7.80078 9.7002 -10.9004h-0.200195l0.200195 -0.0996094c18.2998 3.59961 37.2002 2 54.6006 -4.7002
l0.0996094 0.0996094c2.09961 2.60059 4.59961 4.90039 7.2998 6.90039c0 -0.900391 -0.0996094 -1.7998 -0.200195 -2.7002c4 5 9.10059 9 15 11.5c-0.399414 -0.700195 -0.5 -1.40039 -0.5 -2.2002c7.40039 4.2998 15.5 7.40039 23.9004 9
c1.09961 0 -3.5 -1.7998 -5.09961 -3.09961c3.69922 1.59961 7.69922 2.59961 11.6992 2.7998c6.60059 0.700195 14 -2.09961 12.6006 -2.7002c-2.7998 -1 -5.5 -2.2002 -8.2002 -3.5c-0.799805 -0.700195 3.2002 0.200195 2.40039 -0.5
c-14 -9.2002 -24.8008 -22.5996 -30.8008 -38.2998v-0.0996094c2.5 -11 11.4004 -19.3008 22.5 -21.1006c31.5 -3 37.5 -5.59961 38.4004 -9.09961v-1.5c-0.0996094 -1 -0.200195 -1.90039 -0.299805 -2.7998c-1.2002 -6.90039 -4.90039 -13.2002 -10.2002 -17.7002
c-1.40039 -1.2998 -2.90039 -2.5 -4.5 -3.5c-1.09961 -0.700195 -6.40039 -2.7998 -12.7998 -5.60059c-7.90039 -3.19922 -15.5 -7.09961 -22.7002 -11.5996c-1.2998 -0.799805 -2.40039 -1.7002 -3.40039 -2.7002c-0.399414 -0.399414 -1.19922 -1.5 -1.19922 -1.5
v-0.0996094c0.5 -1.2002 1 -2.40039 1.19922 -3.7002c-1.39941 1.7002 -2.69922 1.09961 -1.89941 -0.5c0.899414 -2.5 1.2998 -5.2002 1.09961 -7.7998c0.200195 -4.7998 -0.700195 -9.60059 -2.59961 -14c-2.10059 1.5 -4.2998 2.89941 -6.60059 4.09961h-0.199219
c2.5 -1.59961 4.2998 -3.89941 5.39941 -6.59961c0.700195 -2.2002 -0.299805 -2.7002 -0.299805 -2.7002c-1.40039 2 -3.09961 3.59961 -5.2002 4.7002c-3.09961 1.7998 -8.7998 4.7002 -11.3994 5.7998c-0.300781 -0.200195 -0.5 -0.0996094 -0.800781 -0.200195
c0.800781 -1.2998 2.10059 -3.7998 2.10059 -3.7998s-1.7998 1.09961 -4.7998 2.59961c-3.90039 -1.7998 -7.2002 -4.89941 -9.30078 -8.69922c-3.5 -7.7002 -3.09961 -16.7002 1 -24.1006c4 -6 9.10059 -11.2002 15 -15.2002
c0.400391 -0.299805 -3.39941 1.10059 -3.09961 0.800781c4.59961 -3.2002 9.40039 -6.10059 14.4004 -8.60059c1.5 -1 -5 1.2002 -3.40039 0.299805c1.40039 -0.899414 2.7998 -1.69922 4.2998 -2.5c22.9004 -12.0996 38.9004 0.400391 56.4004 2.90039
c16.7998 3 33.7998 -3.59961 44.2002 -17c6 -8.5 -0.600586 -16.7002 -9 -14h-0.200195c-8.60059 2.90039 -19.1006 -4.2998 -36.6006 -14c-17.2998 -8.2998 -36.8994 -10.5996 -55.5996 -6.59961c-4.7998 0.899414 -9.40039 2.09961 -14 3.69922l-2 0.700195
l0.200195 -0.299805c8.7998 -12.2002 19.8994 -22.5 32.7998 -30.2998c8.7002 -4.40039 17.9004 -7.5 27.4004 -9.2998c8 -1.90039 16.1992 -2.80078 24.5 -2.80078c61 -0.0996094 110.6 49.4004 110.6 110.4c0.0996094 15.9004 -3.09961 31.7998 -9.2998 46.5
c20.7002 -12.2998 37.5996 -30.2002 48.7998 -51.5c-13.9004 40.5996 -40.2998 56.4004 -64.7002 76.5996c-19.5996 14.8008 -34.7002 34.9004 -43.3994 57.9004c-25.2002 67.7998 33.0996 132.9 33.0996 132.9s-3.59961 -15.1006 27.4004 -44.3008
c6.39941 -5.89941 16.7998 -14.5 28.8994 -26.6992c1.7002 9.2998 4.2002 18.3994 7.40039 27.2998c2.5 -14.7002 7.7998 -28.7998 15.3994 -41.6006c11.7002 -16.6992 21.9004 -25.5996 30.7002 -40c1.90039 -2.5 3.7998 -5.19922 5.60059 -7.89941
c5.09961 -7.2002 9.5 -14.7998 13.2998 -22.7998c6 -12 10.7998 -24.5 14.5 -37.4004c3 -10.4004 4.89941 -20.9004 5.7998 -31.5996c2.90039 3.89941 4.7002 5.89941 4.7002 5.89941s0.700195 -2.59961 1.39941 -7.09961zM179.1 310.3
c-0.5 -1.2002 -0.899414 -2.2998 -1.2998 -3.5c0.400391 1.2002 0.900391 2.40039 1.2998 3.5z" />
<glyph glyph-name="firefox" unicode="&#xf269;" horiz-adv-x="512"
d="M503.52 206.52c0.240234 -4.43945 0.360352 -9 0.480469 -13.5195c0 -137.19 -111.23 -248.42 -248.32 -248.42c-122.779 0 -224.859 89.2695 -244.779 206.38c-0.360352 3.24023 -0.720703 6.36035 -1.08008 9.59961c-4.91992 42.6006 0.479492 87.3604 16.0801 124.79
c10.7998 25.8809 32.6396 54 49.7998 62.8809c-16.2002 -31.8008 -24.1201 -63 -25.7998 -83.8809c11.2793 37.2002 32.6299 68.3604 62.5098 90.3604c51.2402 37.6699 120.229 39.3604 147.71 15.3604c-51 -17.5107 -106.55 -87.96 -94.3105 -170.511
c1.65137 -11.3535 7.08105 -28.9326 12.1201 -39.2393c-9.51953 25.0801 -10.3594 60.3594 5 83.2793c17.1602 25.5508 41.6299 30.9502 54.71 28.1904c-5.15918 1.08008 -16.5596 -20.75 -18.2393 -24.5898c-3.4502 -7.85645 -6.25098 -21.1953 -6.25098 -29.7754
c0 -0.337891 0.00488281 -0.886719 0.0107422 -1.22461c0.326172 -19.1992 11.7773 -45.6309 25.5596 -59c47.6504 -46.4307 124.561 -28.1602 159 24.8398c23.6406 36.4795 26.5205 98.3896 -3.83984 147.59c-6.29297 9.96582 -18.335 24.6416 -26.8799 32.7598
c-47.6602 45.4707 -116.06 64.6699 -180.24 52.9902c-0.240234 0 -0.599609 -0.120117 -0.839844 -0.120117c-1.7998 -0.359375 -3.47949 -0.719727 -5.16016 -1.08008c-0.359375 -0.120117 -0.839844 -0.120117 -1.2002 -0.239258l-5.87988 -1.44043
c-14.5195 -3.55957 -34.7998 -10.7998 -49.4395 -19.5596c-0.078125 -0.0107422 -0.185547 -0.0654297 -0.240234 -0.120117l0.120117 0.120117c0 -0.0664062 -0.0537109 -0.120117 -0.120117 -0.120117v0l-0.120117 -0.120117l0.120117 0.120117h-0.129883
l0.479492 0.479492c0.480469 0.480469 1.32031 1.16016 2.40039 2.16016c19.6797 17.7598 49.3203 31.9199 82.9102 39c12.417 2.60938 32.792 4.84961 45.4795 5h10.6299c10.5781 -0.25293 27.6016 -2.04492 38 -4c0.960938 -0.120117 1.76074 -0.360352 2.76074 -0.479492
h0.120117c1.7998 -0.360352 3.71973 -0.84082 5.63965 -1.2002c15.9277 -3.61621 40.7598 -12.3799 55.4297 -19.5605c2.40039 -1.2002 4.7998 -2.39941 7.2002 -3.71973c7.16211 -3.56738 18.1826 -10.3408 24.5996 -15.1201
c4.32031 -3.12012 8.48047 -6.36035 12.4805 -9.83984c5.35449 -4.27344 13.5479 -11.7559 18.29 -16.7002c7.01562 -6.8877 17.5479 -18.8223 23.5098 -26.6396c0.959961 -1.2002 1.75977 -2.40039 2.75977 -3.71973c0.400391 -0.480469 0.640625 -0.84082 1 -1.32031
l1.80078 -2.52051c0.359375 -0.479492 0.719727 -1.08008 1.08008 -1.55957c0.479492 -0.719727 1.0791 -1.56055 1.55957 -2.28027c0.365234 -0.473633 0.90332 -1.28027 1.2002 -1.7998l1.43945 -2.12988c0.366211 -0.473633 0.90332 -1.28027 1.2002 -1.7998
c0.480469 -0.720703 0.959961 -1.56055 1.32031 -2.16016c0.359375 -0.600586 0.839844 -1.24023 1.2002 -1.91992c0.359375 -0.680664 0.839844 -1.32031 1.19922 -2c0.360352 -0.680664 0.84082 -1.28027 1.2002 -2c0.367188 -0.53125 0.904297 -1.42676 1.2002 -2
c0.360352 -0.720703 0.839844 -1.56055 1.2002 -2.16016c0.359375 -0.599609 0.719727 -1.32031 1.08008 -1.91992c0.359375 -0.839844 0.799805 -1.67969 1.2002 -2.28027c0.399414 -0.599609 0.639648 -1.2002 1 -1.7998
c0.359375 -0.839844 0.839844 -1.56055 1.19922 -2.40039c0.240234 -0.479492 0.480469 -1.08008 0.720703 -1.55957c0.479492 -0.839844 0.839844 -1.63965 1.31934 -2.63965l0.360352 -0.720703c1.75977 -3.71973 3.44043 -7.55957 5 -11.3994
c0 -0.120117 0.120117 -0.240234 0.120117 -0.360352c0.439453 -1.2002 0.959961 -2.28027 1.43945 -3.48047c0.120117 -0.239258 0.240234 -0.599609 0.360352 -0.839844c0.480469 -1.08008 0.839844 -2.2793 1.32031 -3.35938
c0.117188 -0.269531 0.27832 -0.717773 0.359375 -1c0.360352 -1.08008 0.84082 -2.28027 1.2002 -3.36035l0.360352 -1.08008c0.479492 -1.2002 0.839844 -2.28027 1.2002 -3.47949c0.119141 -0.400391 0.239258 -0.640625 0.359375 -1
c0.360352 -1.08008 0.720703 -2.28027 1.08008 -3.48047c0.120117 -0.240234 0.120117 -0.599609 0.240234 -0.839844c0.360352 -1.2002 0.719727 -2.52051 1.08008 -3.71973c0.120117 -0.120117 0.120117 -0.360352 0.240234 -0.600586l1.08008 -4
c0.119141 -0.120117 0.119141 -0.120117 0.119141 -0.240234c2.98926 -11.1846 6.26855 -29.6201 7.32031 -41.1494v-0.120117l0.360352 -4.67969v-0.120117c0 -1.56055 0.120117 -3.12012 0.239258 -4.68066z" />
<glyph glyph-name="opera" unicode="&#xf26a;" horiz-adv-x="496"
d="M313.9 415.3c-170.2 0 -252.601 -223.8 -147.5 -355.1c36.5 -45.4004 88.5996 -75.6006 147.5 -75.6006c36.2998 0 70.2998 11.1006 99.3994 30.4004c-43.7998 -39.2002 -101.899 -63 -165.3 -63c-3.90039 0 -8 0 -11.9004 0.299805
c-131.5 6.10059 -236.1 114.601 -236.1 247.7c0 137 111 248 248 248h0.799805c63.1006 -0.299805 120.7 -24.0996 164.4 -63.0996c-29 19.3994 -63.1006 30.3994 -99.2998 30.3994zM415.7 17.5996c-40.9004 -24.6992 -90.7002 -23.5996 -132 5.80078
@@ -993,9 +997,11 @@ c-4.5 0 -9.7998 1.39941 -15.7002 4.2002c-7.5 3.5 -20.2998 -1.80078 -21.9004 -10.
c-0.0996094 -0.0996094 -0.200195 -0.199219 -0.200195 -0.299805c-0.899414 -2 -21.7002 -49.5 -68 -57.0996c-3.59961 -0.600586 -6.09961 -3.7998 -5.89941 -7.40039c0.699219 -13.8994 31.6992 -19.2998 45.5 -21.3994c1.39941 -1.90039 2.5 -9.90039 4.2998 -16
c0.799805 -2.7002 2.89941 -6 8.2998 -6s13.2998 3.09961 25.7998 3.09961c17.6006 0 23.6006 -4 37.4004 -13.7002c9.89941 -7 27.5 -19.7998 48.5 -18.2002c20.7998 -0.899414 34.7002 7.90039 49.2002 18.2002c13.6992 9.7002 19.7998 13.7002 37.3994 13.7002
c13 0 19.6006 -2.90039 25.7998 -2.90039h0.200195c4.40039 0 7 2.2002 8.10059 5.90039c1.7998 6.09961 2.89941 14 4.2998 15.9004c26.7002 4.19922 41.2998 10.0996 44.7998 18.1992z" />
<glyph glyph-name="pied-piper" unicode="&#xf2ae;"
d="M32 29l-32 -60.2002l0.799805 328c0 65.9004 53.2002 119.2 119.2 119.2h327.2c-93 -28.9004 -189.9 -94.2002 -253.9 -168.6c-70.5996 -81.4004 -110.7 -137.4 -161.3 -218.4zM448 416c0 0 0 -328.8 0.0996094 -328.8c0 -65.9004 -53.2998 -119.2 -119.3 -119.2
h-328.399c18.5 25.5 61.6992 54 84.8994 66c35.5 18.0996 76.4004 28.5 105.3 56.2998c42.1006 40.5 47.8008 105 71 158.601c43.6006 100.3 186.4 167.1 186.4 167.1z" />
<glyph glyph-name="pied-piper" unicode="&#xf2ae;" horiz-adv-x="480"
d="M455.93 424.8c9.41992 2.40039 15.0703 -10.25 6.99023 -15.6797c-98.2295 -65.9199 -120.439 -127.561 -126.229 -160.18c-33.5205 -188.881 -101.37 -119.32 -184.311 -226.65c22.4619 -12.916 61.7197 -23.3984 87.6299 -23.4004
c97.6504 0 177.09 79.4502 177.09 177.11c-0.00390625 37.1318 -20.0967 89.7314 -44.8496 117.41c3.90332 8.05176 11.5186 20.3271 17 27.3994c32.4297 -33.3115 58.75 -98.0781 58.75 -144.569v-0.240234c0 -114.87 -93.1299 -208 -208 -208s-208 93.1201 -208 208
s93.1299 208 208 208c29.9082 -0.000976562 75.3125 -11.9443 101.35 -26.6602c46.4404 38.9697 87.8809 60.6602 114.58 67.46zM125 41.5996c64.7695 140.881 125.64 231.641 191.63 293.75c-19.9951 9.79883 -54.2959 17.75 -76.5635 17.75h-0.0664062
c-97.6504 0 -177.1 -79.4395 -177.1 -177.1c0.0195312 -45.0049 27.8408 -105.216 62.0996 -134.4z" />
<glyph glyph-name="first-order" unicode="&#xf2b0;"
d="M12.9004 218.8c0.0996094 0.100586 0.199219 0.299805 0.299805 0.400391c0 -0.100586 0 -0.299805 -0.100586 -0.400391h-0.199219zM224 351.4c7.40039 0 14.5996 -0.5 21.7002 -1.7002l-4 -67.7002l22.2998 64.2998c14.2998 -3.7998 27.7002 -9.5 40 -16.8994
l-29.4004 -61.1006l45.1006 50.9004c11.5 -8.90039 21.7002 -19.2002 30.5996 -30.9004l-50.5996 -45.3994l60.8994 29.6992c7.5 -12.2998 12.9004 -26 16.6006 -40.2998l-64 -22.2998l67.7002 4c1.09961 -7.09961 1.39941 -14.5996 1.39941 -22
@@ -1052,15 +1058,14 @@ d="M440.5 61.2998c1.7998 -18 -7.2002 -93.2998 -89 -93.2998c-49.5 0 -75.5 28.7002
c14.2002 -21.5996 29 -35.7998 49.5 -35.7998c22.5 0 31.5 17.2998 33 30.7998h29.2998zM297 118.8c11.2998 24.9004 16.7998 58.7002 16.7002 100.5c0 104.2 -32.5 157.7 -108.7 157.7c-75 0 -107.5 -53.5 -107.5 -157.9c0 -103.699 32.5 -156.699 107.5 -156.699
c12 0 22.7002 1.19922 32.7002 4.19922c-15.5 30.5 -33.7002 61.3008 -69.2002 61.3008c-6.7998 0 -13.5996 -1 -19.7998 -4l-12.2002 24.2998c14.7002 12.7998 38.5 22.7998 69 22.7998c47.7998 0 72 -23 91.5 -52.2002z" />
<glyph glyph-name="free-code-camp" unicode="&#xf2c5;" horiz-adv-x="576"
d="M69.2998 303.5c-41 -68.5 -36.3994 -163 1 -227c22.2002 -38.2002 49.7002 -52.4004 49.7002 -66.5c0 -6.7998 -6 -13 -12.7998 -13c-19.5 0 -99.2002 75.5 -99.2002 197.8c0 111.5 78 186 97.0996 186c6 0 14.9004 -4.7998 14.9004 -11.0996
c0 -12.7002 -28.2998 -28.6006 -50.7002 -66.2002zM265.1 89.7002c-37.1992 13.5996 -65.5 45.8994 -65.2998 86.2002c0 48 57.7002 90.0996 57.7002 136.199c0 16.8008 -10.4004 32.6006 -19.5996 38.2002c-1.90039 1 -4.60059 2.7002 -4.60059 5.10059
c0 9.59961 26.1006 2.7998 36.5 -2.2002c33.6006 -15.9004 40.6006 -40.2998 46.4004 -74.1006c1.39941 -7.89941 4.2998 -33.2998 15.8994 -33.2998c7.5 0 12.3008 5.10059 12.3008 12.2998c0 12.6006 -15.4004 31.2002 -7.2002 31.2002
c6.09961 0 18.5996 -12.7998 22.5 -16.8994c23.3994 -24.9004 32.0996 -49 32.0996 -82.6006c0 -42.2002 -23.3994 -74.7002 -53.0996 -89.7998c-9.2002 -5.7998 -12.1006 0.900391 -12.1006 1.90039c0 7 29.5 23.5996 29.5 56c0 10.5996 -2.69922 22.5 -8.5 31.3994
c-1.69922 2.40039 -7.69922 10.1006 -11.0996 10.1006c-0.700195 0 -0.700195 -0.5 -0.700195 -1.2002c0 -5.7998 3.60059 -11.4004 3.60059 -17.4004c0 -13 -31.9004 -20.2002 -31.9004 6.7998c0 7.10059 0.700195 14.3008 0.700195 21.3008
c0 5.09961 -0.200195 6.5 -2.40039 11.0996c-3.39941 6.5 -14.5 19.7998 -22.5 19.7998c-2.2002 0 -2.89941 0 -2.89941 -2.2002c0 -3.39941 7.69922 -7 7.69922 -19.2998c0 -32.0996 -44.1992 -37.8994 -44.1992 -70c0 -14.3994 1.89941 -26.5 10.0996 -38.5996
c5.09961 -7.5 10.5996 -11.7998 19.0996 -15.2002c2.10059 -0.700195 4.30078 -0.900391 4.30078 -3.59961c0 -6.40039 -7.80078 -3 -12.3008 -1.2002zM470.4 381c21.3994 0 97.5996 -78.9004 97.5 -198.2c0 -104.899 -73.4004 -185.7 -98.8008 -185.7
c-5 0 -13.1992 6.30078 -13.1992 11.4004c0 8.2002 28.2998 34.5996 35.2998 43.5c61 76.7002 64 205.9 -17.6006 291c-5.5 5.7998 -17.5996 16.7002 -17.5996 25.4004c0 6.09961 8.40039 12.5996 14.4004 12.5996zM428.1 57.9004c8.40039 0 11.9004 -7 11.9004 -15.5
c0 -8.90039 -2.5 -16.4004 -11.9004 -16.4004h-261.1c-8.5 0 -15.5 7 -15.5 15.5c0 8.90039 6.09961 16.4004 15.5 16.4004h261.1z" />
d="M97.2197 351.79c-43.2197 -41.6201 -64.9697 -92.5898 -64.8193 -154.021c0.15918 -68 23.0293 -122.67 67.4795 -165c9.33984 -8.34961 13.2002 -14.9199 13.2002 -20.5498c0 -2.75 -1.90039 -5.62012 -3.81055 -8.37988
c-1.92676 -1.89453 -5.67676 -3.61426 -8.36914 -3.83984c-10.2803 0 -24.6807 12.1396 -43.4707 35.79c-36.5898 44.8701 -53.1992 94.3398 -54.0596 161.87s20.3096 113.34 61.79 160.6c14.9199 16.9004 27.3594 25.6904 35.8398 25.6904
c2.56152 -0.0585938 6.32031 -1.33105 8.38965 -2.83984c1.91016 -1.91016 3.83008 -4.66016 3.83008 -7.41992c0 -4.78027 -5.63965 -11.25 -16 -21.9004zM239.47 27.9297c0.580078 -0.370117 0.910156 -0.549805 0.910156 -0.549805zM333.26 27.3799l0.169922 0.129883
c-0.189453 -0.129883 -0.259766 -0.179688 -0.169922 -0.129883zM336.39 185.56c16.2305 -4.14941 24.04 24.04 30.0303 30.0508c84.71 -110.101 -27.5098 -184.45 -33 -188.101c3.86035 3.04004 44.3301 49.7705 21.5801 76.5498
c-1 1.03027 -67.2998 -20.0596 -54.8398 53.54c8.30957 48.6807 -7.60059 71.1309 -7.60059 71.1309c-17.9697 -37.29 -32.5 -53.8604 -43.5 -72.1602c-56.9492 -92.9404 -16.2793 -124.29 -9.5498 -128.641c-10.54 6.5 -108.27 70.8799 -34 175.23
c78.3701 110.189 62.8301 159.57 62.8301 159.57c118.46 -94.2803 51.8105 -173.021 68.0498 -177.171zM510.88 358.31c41.4404 -47.3096 62.6699 -93.1592 61.75 -160.649s-17.4697 -117.021 -54.0596 -161.87c-18.79 -23.6602 -33.1904 -35.79 -43.4707 -35.79
c-2.69238 0.231445 -6.44141 1.95605 -8.36914 3.84961c-1.91016 2.76074 -3.81055 5.63086 -3.81055 8.38086c0.0205078 5.62988 3.86035 12.1992 13.2002 20.5498c44.4795 42.3701 67.3203 97 67.4795 165c0.180664 61.4697 -21.5898 112.45 -64.8193 154.06
c-10.4004 10.6406 -16 17.1201 -16 21.9004c0 2.75977 1.91992 5.50977 3.83008 7.41992c2.06934 1.50977 5.82812 2.78125 8.38965 2.83984c8.51953 0 21 -8.79004 35.8799 -25.6904z" />
<glyph glyph-name="telegram" unicode="&#xf2c6;" horiz-adv-x="496"
d="M248 440c137 0 248 -111 248 -248s-111 -248 -248 -248s-248 111 -248 248s111 248 248 248zM369.8 270.1c3.60059 16.8008 -6.09961 23.5 -17.2002 19.5l-239.1 -92.1992c-16.4004 -6.40039 -16.0996 -15.5 -2.7998 -19.7002l61.2002 -19.1006l142 89.4004
c6.59961 4.40039 12.6992 1.90039 7.69922 -2.5l-114.899 -103.8l-4.40039 -63.1006c6.40039 0 9.2002 2.80078 12.5 6.10059l29.9004 28.7998l62 -45.7002c11.2998 -6.39941 19.3994 -3.09961 22.3994 10.5z" />
@@ -1694,15 +1699,24 @@ c-16.3994 15.8994 -44.5996 17.2998 -61.3994 -7l-44.8008 -64.7002v38.7998z" />
<glyph glyph-name="kickstarter-k" unicode="&#xf3bc;" horiz-adv-x="384"
d="M147.3 333.6v-70.5996l82.7998 118.2c31.2002 44.3994 83.3008 41.7998 113.601 12.7998c27.8994 -26.7002 27.7998 -65.0996 10.3994 -89.7998l-74.8994 -107.4l90.7998 -114.8c19.9004 -24.7998 19.5996 -64.5996 -7.40039 -92.2002
c-31.0996 -30.7002 -80.5 -27.2002 -103.199 0l-112.101 138.3v-76.5c0 -57.7998 -32.5996 -83.3994 -72.3994 -83.3994c-49.6006 0 -74.9004 36.0996 -74.9004 83.3994v283c0 45.2002 26.2002 81.4004 73.9004 81.4004c40.8994 0 73.3994 -26.2002 73.3994 -82.4004z" />
<glyph glyph-name="laravel" unicode="&#xf3bd;" horiz-adv-x="640"
d="M637.5 206.4c4.2998 -4.80078 3.2002 -8.60059 -4.7002 -10.6006c-6.7002 -1.89941 -69.5996 -18.5996 -87.2998 -23.2998c25.7998 -34.5996 75.0996 -100.6 79.2998 -106.8c5.7002 -8.5 0.5 -10.9004 -7.89941 -14.4004c-8.40039 -3.39941 -195.2 -70.5996 -208 -74.5
c-16.3008 -5 -23.7002 -7.5 -34.3008 7.40039c-8 11.0996 -51.0996 88.7002 -72.1992 127c-40 -10.5 -113.2 -29.6006 -134.301 -34.7002c-20.5996 -5 -29.3994 7.40039 -32.7998 15c-3.39941 7.59961 -124.8 269.2 -132.399 287.2c-7.60059 18 0.799805 21.3994 8.39941 22
c7.60059 0.700195 114.5 9.59961 128.5 10.2002c14 0.699219 15.2998 -2.5 21.4004 -11.6006l154.2 -257.5l193.699 46.4004c-10.7998 15.2002 -59.5 84.2998 -64.1992 90.8994c-5.30078 7.40039 0.0996094 10.8008 8.69922 12.3008
c8.60059 1.39941 82.7002 13.8994 89.1006 14.7998c6.2998 0.899414 11.3994 3.09961 21.7002 -9.2998c10.2998 -12.4004 68.8994 -85.7002 73.0996 -90.5zM285.3 134.4c2.2998 0.5 3.7998 1.7998 1.2002 6.09961c-2.40039 4.2998 -144.6 249.7 -144.6 249.7
c-1.30078 2.2002 -0.900391 3 -4.5 2.7998c-3.5 -0.200195 -104.301 -9.2002 -106 -9.2002c-1.7002 0 -1.80078 -2.59961 0 -5.89941c1.7998 -3.30078 130.1 -268 130.8 -270s0.700195 -2.60059 6.5 -1.30078c5.7998 1.30078 114.3 27.3008 116.6 27.8008zM591.3 77
c-1.7002 2.7002 -61.2002 83.4004 -64.0996 88.2002c-3 4.7002 -4.5 3.7002 -9.2002 2.2002l-188.8 -49.1006s58 -100.3 62.3994 -106.8c4.40039 -6.5 7.10059 -6 10.6006 -4.5c3.39941 1.5 181.7 61.5996 187.1 63.5996c5.5 1.90039 3.7002 3.7002 2 6.40039zM603.4 211.1
c4.19922 1 7.39941 2.40039 5.59961 4.7002c-1.90039 2.40039 -50.9004 64.5 -54.5 69.4004c-3.59961 4.89941 -6.09961 4.09961 -9 3.39941c-2.90039 -0.599609 -67.2998 -12.2998 -71.2998 -12.7998s-2.7002 -2.7002 -1.10059 -5l56.7002 -77.7998
s69.4004 17.2002 73.6006 18.0996z" />
<glyph glyph-name="laravel" unicode="&#xf3bd;" horiz-adv-x="512"
d="M504.4 332.17c0.131836 -0.549805 0.240234 -1.45605 0.240234 -2.02246c0 -0.0185547 0 -0.0488281 -0.000976562 -0.0673828v-109.85c0.000976562 -0.0205078 0.000976562 -0.0527344 0.000976562 -0.0722656c0 -2.5498 -1.79199 -5.65332 -4.00098 -6.92773
l-92.2393 -53.1104v-105.26v-0.0224609c0 -2.54883 -1.79199 -5.65332 -4 -6.92773l-192.561 -110.84c-0.37207 -0.194336 -0.999023 -0.454102 -1.39941 -0.580078c-0.180664 -0.0605469 -0.350586 -0.169922 -0.550781 -0.220703
c-0.555664 -0.148438 -1.47363 -0.269531 -2.0498 -0.269531c-0.575195 0 -1.49414 0.121094 -2.0498 0.269531c-0.219727 0.0605469 -0.419922 0.180664 -0.629883 0.260742c-0.378906 0.119141 -0.975586 0.360352 -1.33008 0.540039l-192.5 110.84
c-2.20801 1.27441 -4 4.37891 -4 6.92773v0.0224609v329.699c0.00195312 0.589844 0.126953 1.53125 0.280273 2.10059c0.0693359 0.189453 0.199219 0.489258 0.290039 0.669922c0.111328 0.354492 0.339844 0.910156 0.509766 1.24023
c0.149414 0.259766 0.370117 0.469727 0.549805 0.719727c0.177734 0.270508 0.496094 0.6875 0.709961 0.929688c0.208008 0.179688 0.561523 0.448242 0.790039 0.600586c0.226562 0.210938 0.621094 0.520508 0.879883 0.689453v0l96.2705 55.4199
c1.02441 0.591797 2.81641 1.07227 4 1.07227c1.18262 0 2.97461 -0.480469 4 -1.07227l96.29 -55.4199v0c0.25293 -0.173828 0.647461 -0.478516 0.879883 -0.679688c0.223633 -0.154297 0.573242 -0.422852 0.779297 -0.599609
c0.21582 -0.24707 0.538086 -0.667969 0.720703 -0.94043c0.169922 -0.25 0.399414 -0.459961 0.540039 -0.719727c0.170898 -0.331055 0.404297 -0.886719 0.519531 -1.24023c0.0800781 -0.230469 0.219727 -0.44043 0.280273 -0.679688
c0.154297 -0.561523 0.280273 -1.48926 0.280273 -2.07129v-0.0195312v-205.93l80.2197 46.1904v105.239c0.00195312 0.584961 0.126953 1.5166 0.280273 2.08008c0.0693359 0.240234 0.199219 0.450195 0.279297 0.680664
c0.120117 0.354492 0.352539 0.915039 0.520508 1.25c0.149414 0.259766 0.370117 0.469727 0.540039 0.709961c0.179688 0.270508 0.50293 0.6875 0.719727 0.929688c0.205078 0.179688 0.553711 0.448242 0.780273 0.599609
c0.229492 0.208008 0.624023 0.516602 0.879883 0.69043v0l96.2803 55.4502c1.02441 0.591797 2.81641 1.07129 4 1.07129c1.18262 0 2.97461 -0.479492 4 -1.07129l96.2598 -55.4199c0.259766 -0.171875 0.663086 -0.476562 0.899414 -0.680664
c0.25 -0.199219 0.540039 -0.379883 0.770508 -0.599609c0.214844 -0.24707 0.538086 -0.667969 0.719727 -0.94043c0.164062 -0.18457 0.40625 -0.50293 0.540039 -0.709961c0.173828 -0.333008 0.411133 -0.892578 0.530273 -1.25
c0.0888672 -0.182617 0.214844 -0.487305 0.280273 -0.679688zM111.6 430.72l-80.1895 -46.1602l80.1797 -46.1699l80.2002 46.1807l-80.1904 46.1494v0zM199.85 370.72l-33.6895 -19.4297l-46.5303 -26.79v-201.29l33.6904 19.4004l46.5293 26.79v201.319zM199.85 -42.0596
l-0.109375 92.3594l-92.1904 52.1807v0v0c-0.248047 0.166992 -0.633789 0.462891 -0.859375 0.65918c-0.25 0.200195 -0.540039 0.360352 -0.770508 0.580078v0c-0.198242 0.219727 -0.494141 0.595703 -0.660156 0.839844
c-0.177734 0.206055 -0.446289 0.555664 -0.599609 0.780273v0c-0.139648 0.266602 -0.328125 0.713867 -0.419922 1c-0.125977 0.240234 -0.295898 0.643555 -0.379883 0.900391v0c-0.0683594 0.322266 -0.140625 0.850586 -0.160156 1.17969
c-0.0498047 0.246094 -0.103516 0.649414 -0.120117 0.900391v215.18l-46.5205 26.7998l-33.6895 19.3799v-311.18zM207.85 64.1104l117.62 67.1494l58.7998 33.5605l-80.1299 46.1299l-92.2598 -53.1104l-84.0898 -48.4102zM392.37 59.54v91.4102l-45.7705 -26.1504
l-130.72 -74.5996v-92.3105zM392.37 178.67v91.3301l-46.5303 26.8096l-33.6895 19.4004v-91.4199l46.5293 -26.79zM400.37 283.95l80.1797 46.1797l-80.1797 46.1504l-80.2002 -46.1602zM408.37 178.67l80.3096 46.1504v0v91.3896l-33.6797 -19.4004l-46.6299 -26.8096
v-91.3301z" />
<glyph glyph-name="line" unicode="&#xf3c0;"
d="M272.1 243.8v-71.0996c0 -1.7998 -1.39941 -3.2002 -3.19922 -3.2002h-11.4004c-1.09961 0 -2.09961 0.599609 -2.59961 1.2998l-32.6006 44v-42.2002c0 -1.7998 -1.39941 -3.19922 -3.2002 -3.19922h-11.3994c-1.7998 0 -3.2002 1.39941 -3.2002 3.19922v71.1006
c0 1.7998 1.40039 3.2002 3.2002 3.2002h11.2998c1 0 2.09961 -0.5 2.59961 -1.40039l32.6006 -44v42.2002c0 1.7998 1.39941 3.2002 3.2002 3.2002h11.3994c1.7998 0.0996094 3.2998 -1.40039 3.2998 -3.10059zM190.1 247c1.80078 0 3.2002 -1.5 3.2002 -3.2002v-71.0996
@@ -2462,22 +2476,20 @@ l-10.9004 20.5996h37.5l54.9004 -109.9zM243.7 134.2c29.7998 0 50.2002 21.5 50.200
c-11.7998 0 -26.2998 -0.0996094 -39.3994 -0.599609c-29.1006 -0.900391 -47.2002 -6.2002 -47.2002 -25.2998c0 -12.4004 9.90039 -25.8008 35 -25.8008c33.7002 0 51.5996 18.4004 51.5996 48.4004zM32.7002 179.9c3.5 -58.3008 79.2002 -57.4004 91.2002 -21.6006
h33.0996c-6.40039 -34.3994 -43 -46.0996 -74.4004 -46.0996c-57.1992 0 -82.5 31.5 -82.5 74c0 46.7998 26.2002 77.5996 83 77.5996c45.3008 0 78.4004 -23.7002 78.4004 -75.3994v-8.5h-128.8zM127.7 201.3c-2.2998 54.7002 -87.5 56.6006 -94.4004 0h94.4004z" />
<glyph glyph-name="keybase" unicode="&#xf4f5;"
d="M195.21 17.2998c0 -9.8252 -7.97461 -17.7998 -17.7998 -17.7998c-9.82617 0 -17.7998 7.97461 -17.7998 17.7998c0 9.82617 7.97363 17.7998 17.7998 17.7998c9.80371 -0.0214844 17.7783 -7.99609 17.7998 -17.7998zM288 35.2002
c9.80371 -0.0224609 17.7783 -7.99609 17.7998 -17.7998c0 -9.82617 -7.97461 -17.8008 -17.7998 -17.8008s-17.7998 7.97461 -17.7998 17.8008c0 9.8252 7.97461 17.7998 17.7998 17.7998zM430.3 71.2002c0 -38.9004 -7.59961 -73.9004 -22.2002 -103h-27.2998
c23.5 38.7002 30.5 94.7998 22.4004 134.3c-16.1006 -29.5 -52.1006 -38.5996 -85.9004 -28.7998c-127.8 37.5 -192.5 -19.7002 -234.6 -50.2998l18.8994 59.2998l-39.8994 -42.2998c3.95605 -21.9639 17.9336 -54.3545 31.2002 -72.3008h-28.79
c-8.1543 13.2822 -18.0996 36.2646 -22.2002 51.3008l-23.7998 -25.2002c0 74.8994 -5.5 147.6 61.5 215.2c16.4688 16.7402 47.4248 37.6621 69.0996 46.6992c-6.7998 13.5 -9.5 29.2002 -7.7998 46l-19.9102 1.2002c-16.918 1.05371 -30.6484 15.666 -30.6484 32.6172
c0 0.492188 0.0214844 1.29102 0.0488281 1.7832v0.0996094l1.59961 26.2002c1.10449 16.7988 15.665 30.5078 32.5 30.5996c1.2998 0 -0.299805 0.100586 28.2002 -1.69922c7.65918 -0.414062 17.873 -5.52148 22.7998 -11.4004c7.11035 10.4004 14.5 20.5 24.6104 34.5
l20.5996 -12.0996c-13.5996 -29 -9.09961 -36.2002 -9 -36.3008c3.90039 0 13.9004 0.5 32.4004 -5.69922c28.8379 -9.54883 52.2422 -41.9512 52.2422 -72.3291c0 -8.61914 -2.75195 -22.0469 -6.14258 -29.9717c19 -6.09961 51.2998 -19.8994 82.4004 -51.7998
c36.5996 -37.5996 57.6992 -87.3994 57.6992 -136.6h-0.00976562zM146 325.9c2.80762 8.47461 8.67578 21.6455 13.0996 29.3994c0.100586 2 2.2002 13.1006 -7.7998 13.7998c-28.5 1.80078 -26.2998 1.60059 -26.7002 1.60059h-0.0429688
c-4.47754 0 -8.31152 -3.62891 -8.55664 -8.10059l-1.59961 -26.1992c-0.00683594 -0.121094 -0.0117188 -0.318359 -0.0117188 -0.439453c0 -4.48633 3.63379 -8.36719 8.11133 -8.66113zM171.8 264.1c4.50488 -7.35938 14.4951 -16.3193 22.2998 -20
c0 21.2002 28.5 41.9004 52.8008 17.5l8.39941 -10.2998c20.7998 18.7998 19.4004 45.2998 12.1006 60.9004c-13.8008 29.0996 -46.9004 32 -54.3008 31.7002c-0.319336 -0.015625 -0.837891 -0.0283203 -1.15723 -0.0283203c-9.09863 0 -19.1973 6.86719 -22.542 15.3281
c-13.6904 -21.2002 -37.1904 -62.5 -17.5908 -95.1006h-0.00976562zM254.7 195.7l-19.7002 -16.1006c-0.900391 -0.738281 -1.63086 -2.2832 -1.63086 -3.44727c0 -0.890625 0.461914 -2.16797 1.03125 -2.85254l8.89941 -10.8994
c0.742188 -0.896484 2.28809 -1.62305 3.45117 -1.62305c0.887695 0 2.16406 0.458008 2.84863 1.02246l19.6006 16l5.5 -6.7998c4.89941 -6 13.7998 1.40039 9 7.2998c-63.6006 78.2998 -41.5 51.1006 -55.2998 68.1006c-4.7002 6 -13.9004 -1.40039 -9 -7.30078
c1.89941 -2.2998 18.3994 -22.5996 19.7998 -24.2998l-9.60059 -7.89941c-4.59961 -3.80078 2.60059 -13.3008 7.40039 -9.40039l9.7002 8zM373.11 170c-16.9004 23.7002 -42.6006 46.7002 -73.4004 60.4004c-6.18359 2.73633 -16.4434 6.58887 -22.9004 8.59961
c-1.64355 -1.83789 -4.51074 -4.61523 -6.39941 -6.2002l31.8994 -39.2002c3.70605 -4.54102 6.71289 -12.9834 6.71289 -18.8447c0 -7.78906 -4.88867 -18.1172 -10.9121 -23.0547c-1.30078 -1.10059 -13.1006 -10.7002 -29 -4.90039
c-2.90039 -2.2998 -10.1006 -9.89941 -22.2002 -9.89941h-0.0419922c-7.46777 0 -17.3496 4.70312 -22.0586 10.5l-8.89941 10.8994c-3.5293 4.33984 -6.39355 12.4014 -6.39355 17.9951c0 2.49121 0.624023 6.43555 1.39355 8.80469
c-3.83398 4.43945 -6.94531 12.8018 -6.94531 18.667c0 3.26172 1.05078 8.33984 2.34473 11.333c-7.19922 1.30078 -26.6992 6.2002 -42.6992 21.4004c-55.8008 -20.7002 -88 -64.4004 -101.301 -91.2002c-14.8994 -30.2002 -18.7998 -60.8994 -19.8994 -90.2002
c8.2002 8.7002 -3.90039 -4.09961 114 120.9l-29.9004 -93.5996c57.7998 31.0996 124 36 197.4 14.3994c23.5996 -6.89941 45.0996 -1.59961 56 13.9004c11.0996 15.5996 8.5 37.7002 -6.7998 59.2998zM128.61 340.9l1 15.5996l15.5996 -1l-1 -15.5996z" />
d="M286.17 29c9.93652 0 18 -8.06445 18 -18s-8.06348 -18 -18 -18c-9.93555 0 -18 8.06445 -18 18s8.06445 18 18 18zM398.09 176.6c22.9102 -33.46 35.9102 -72.3398 35.9102 -110.92c0 -31.6797 -5 -60.6797 -14.5996 -86.2295
c-3.04004 -8.0498 -10.9502 -12.7197 -18.3701 -11.1504c-6.83984 1.24023 -11.1201 9.28027 -8.60059 15.7402c11.1904 28.71 14.8799 58.3398 14.8799 81.6396c-0.0517578 7.91797 -1.30566 20.6543 -2.7998 28.4307
c-0.649414 -1.06055 -1.12988 -2.2207 -1.84961 -3.2207c-17.29 -24.5293 -50.54 -33.8896 -84.7402 -23.8398c-78.8701 23.1699 -178.02 3.81055 -236.25 -38.5898l24.6602 74.1104l-46.8203 -59.8301c2.04297 -15.3486 9.10352 -39.1504 15.7598 -53.1299
c6.25 -13.1904 0.460938 -18.2402 -3.75 -20.1104c-4.76953 -2.12012 -13.8594 -2.7998 -19.6396 7.33008c-5.43652 9.81641 -11.96 26.6436 -14.5596 37.5596l-23.3203 -29.7998v33.6406c0 55.7695 0 125.109 62.6504 188.409c11.4258 11.5684 32.1631 27.4902 46.29 35.54
l-8.93066 0.540039c-27.8799 1.64062 -49.2402 24.8506 -47.6299 51.8506l2.36035 36.6797c0 -6.24023 0.139648 45.8799 50.75 45.8799c2.05957 0 -0.470703 0.120117 41.0596 -2.33008c2.31641 -0.15625 6.03027 -0.71582 8.29004 -1.25
c7.41992 11.3398 15.6504 22.8301 24.3398 34.8906l5.48047 7.55957l22.8994 -13.5195c-11.29 -24 -10 -33 -9.39941 -35c9.08008 0.229492 20 -1.6709 32.4102 -5.77051c29.6523 -9.84375 53.7188 -43.1914 53.7188 -74.4355
c0 -8.5127 -2.61621 -21.8154 -5.83887 -29.6943c6.18652 -2.13965 12.3135 -4.56348 18.3799 -7.27051c47.8896 -21.2598 77.7598 -59.0898 87.2598 -73.71zM142.37 319.42c1.55664 5.42773 4.69336 14.0156 7 19.1699l-29.1104 1.73047
c0.610352 -0.0507812 -12.2598 0.849609 -13.2598 -11.3203l-2.41016 -36.6602c-0.00585938 -0.143555 -0.0107422 -0.376953 -0.0107422 -0.520508c0 -6.50293 5.27344 -12 11.7705 -12.2695l22.3809 -1.33984c-0.380859 3.10645 -0.689453 8.16797 -0.689453 11.2969
c0 2.28809 0.165039 5.99414 0.369141 8.27344l-13.1299 0.779297l1.38965 21.79zM290.79 147.24c2.06152 1.58789 3.73438 4.9873 3.73438 7.58887c0 1.80273 -0.893555 4.42383 -1.99414 5.85059l-81.0898 96.3203c-1.71484 1.99023 -5.23828 3.60547 -7.86523 3.60547
c-1.99023 0 -4.87305 -1.00098 -6.43555 -2.23535c-2.05957 -1.58398 -3.73242 -4.97949 -3.73242 -7.57812c0 -1.7998 0.892578 -4.41699 1.99316 -5.8418c0.0898438 -0.140625 18.5996 -22.1406 18.5996 -22.1406l-16.9102 -13.29
c-1.59473 -1.22266 -2.88867 -3.8457 -2.88867 -5.85547c0 -1.37988 0.680664 -3.38867 1.51855 -4.48438c0.0800781 -0.109375 2.52246 -3.07324 3.7998 -4.5293c1.27832 -1.45703 3.8877 -2.63867 5.8252 -2.63867c1.4707 0 3.60547 0.734375 4.76562 1.63867
l17.0898 13.4492l14.1396 -16.7393l-34.5703 -27.1807c-1.58398 -1.22266 -2.86914 -3.83984 -2.86914 -5.84082c0 -1.38574 0.685547 -3.40039 1.5293 -4.49902l15.7803 -18.6396c1.33594 -1.55176 4.08203 -2.81055 6.12988 -2.81055
c1.54492 0 3.78516 0.775391 5 1.73047l34.4199 27l9.68066 -11.4902c1.7334 -1.98242 5.27832 -3.5918 7.91211 -3.5918c1.98438 0 4.86816 0.986328 6.4375 2.20215zM187.44 29c9.93555 0 18 -8.06445 18 -18s-8.06445 -18 -18 -18c-9.93652 0 -18 8.06445 -18 18
s8.06348 18 18 18z" />
<glyph glyph-name="mastodon" unicode="&#xf4f6;"
d="M433 268.89c0 0 0.799805 -71.6992 -9 -121.5c-6.23047 -31.5996 -55.1104 -66.1992 -111.23 -72.8994c-20.0996 -2.40039 -93.1191 -14.2002 -178.75 6.7002v-0.339844c0 -3.75977 0.40332 -9.83496 0.900391 -13.5605c6.62988 -49.5996 49.2197 -52.5996 89.6299 -54
c40.8105 -1.2998 77.1201 10.0996 77.1201 10.0996l1.7002 -36.8994s-28.5098 -15.2998 -79.3203 -18.1006c-28.0098 -1.59961 -62.8193 0.700195 -103.33 11.4004c-112.229 29.7002 -105.63 173.4 -105.63 289.1c0 97.2002 63.7197 125.7 63.7197 125.7
@@ -3438,5 +3450,86 @@ c0 7.7207 7 14.6104 20.4102 14.6104c14.0898 0 20.79 -8.4502 20.79 -18.3496h30.70
c17.2598 -6.15039 21.9102 -10.4004 21.9102 -19.4795c0 -15.2002 -19.1309 -14.2305 -19.4707 -14.2305c-20.3994 0 -25.6494 9.09961 -25.6494 21.9004h-30.7998l-0.180664 -0.560547c-0.679688 -31.3203 28.3799 -45.2197 56.6299 -45.2197
c29.9805 0 51.1201 13.5498 51.1201 38.29zM276.68 215.79c0 25.2998 -18.4297 45.46 -53.4199 45.46h-51.7793v-138.18h32.1699v47.3594h19.6094c30.25 0 53.4199 15.9502 53.4199 45.3604zM297.94 123l49.0596 138.22h-31.0898l-47.9102 -138.22h29.9404zM404.46 261.22
h-31.0898l-47.9102 -138.22h29.9404z" />
<glyph glyph-name="cotton-bureau" unicode="&#xf89e;" horiz-adv-x="512"
d="M474.31 117.59h25.1807c-25.7998 -109.78 -111.4 -173.59 -239.67 -173.59c-154.63 -0.339844 -247.82 92.8604 -247.82 248.18c0 154.63 93 247.82 247.82 247.82c128.399 0 214.06 -63.5098 240.18 -173.61h-25.2598
c-24.8506 95.6104 -99.9199 148.811 -214.69 148.811c-141.85 0 -223.2 -81.3799 -223.2 -223.2c0 -137.93 76.6699 -218 211.101 -223v49.2002c0 48.1602 -26.5498 74.3896 -74.5498 74.3896c-62.1309 0 -99.4004 37.2803 -99.4004 99.4102
c0 61.3701 36.5195 98.2803 97.3799 99.0596c30.7402 64.6504 144.24 69.3203 177.24 0c60.8496 -0.779297 97.3799 -37.6895 97.3799 -99.0596c0 -62.0098 -37.2002 -99.21 -99.2002 -99.21c-47.9795 0 -74.3896 -26.3896 -74.3896 -74.3896v-49.1602
c107.67 3.75977 178.24 56.5 201.899 148.35zM357 265.67c3.7998 -21.0801 11.2695 -104.2 -71.79 -120.75c12.2598 -17.7402 32.9805 -27.3301 61.5898 -27.3301c47.9697 0 74.4004 26.4102 74.4004 74.4102c0 44.6699 -22.8301 70.2197 -64.2002 73.6699zM275.32 168.31
c72.7803 9.89062 58.5 86.9102 56.2295 97c-72.5596 -10 -58.6895 -86.6592 -56.2295 -97zM260 316l-0.179688 -0.259766c-28.3008 0 -49.1602 -9.66016 -61.5703 -27.3506c28.3701 -5.44922 49.3701 -20.5898 61.5996 -43.4492
c12.2305 22.8594 33.2305 37.9697 61.5908 43.4492c-12.4404 17.9404 -32.8301 27.6104 -61.4404 27.6104zM188.48 265.28h0.239258c-2.75 -10.0498 -16.1602 -87.1602 56.25 -97c2.41992 10.1895 16.6807 86.4297 -56.4893 97zM173.2 117.59l0.330078 0.0302734
c28.2998 0 49 9.66992 61.1396 27.2998c-73.0303 14.2197 -78.4004 83.5498 -71.6504 120.75c-41.3594 -3.66992 -64.2197 -29.3096 -64.2197 -73.6699c0 -48.0098 26.4004 -74.4102 74.4004 -74.4102zM226.41 105.2h0.269531
c14.4902 -7.60059 25.5605 -19.3301 33.5605 -33.8301c6.36523 12.2188 21.4092 27.374 33.5801 33.8301c-14.4902 8.00977 -26.0508 19.0596 -33.8203 33.5498c-6.4248 -12.1094 -21.4736 -27.1396 -33.5898 -33.5498z" />
<glyph glyph-name="buy-n-large" unicode="&#xf8a6;" horiz-adv-x="576"
d="M288 416c154.73 0 280.21 -100.32 280.21 -224s-125.479 -224 -280.21 -224s-280.21 100.32 -280.21 224s125.479 224 280.21 224zM202.61 58.8096c61.5498 0.600586 99.4697 24.3604 117.71 61.5205c-35.79 6.4502 -62.9307 37.3096 -62.9307 74.4502
c0 41.7695 34.3408 75.6494 76.6904 75.6494h0.0341797c4.80078 0 12.4951 -0.864258 17.1758 -1.92969c0.524414 1.86621 1.19629 4.93555 1.5 6.84961c6.92969 44.1904 -14.8496 72.8408 -78 72.8408h-133.44l-77.25 -290.74zM358 240.89l-9.4502 -36.75l-15 36.75
h-31.3398l-26.6299 -90.3096h37.8301l7.83008 35.6299l11.1895 -35.6299h35.4102l22.1602 90.3096h-32zM503.86 58.8096l21.1992 84.0605h-103.869l53.0498 205.36h-92.5l-21.3301 -82.3506c29.3799 -10.5996 50.3799 -38.4102 50.3799 -71.0596
c0 -41.7803 -34.3496 -75.6504 -76.6904 -75.6504h-0.0625c-3.16504 0 -8.27539 0.37207 -11.4072 0.830078l-15.8398 -61.1904h197.07zM211.7 178.61c16.1494 0 29.7002 -7.51074 24.1396 -29.8203c-5.83008 -23.4697 -21.7998 -26.6504 -37.9395 -26.6504h-24.7002
l13.7998 56.4707h24.7002zM233 278c18.0703 0 32.2305 1.29004 27.5801 -17.5703c-3.83008 -15.5 -21.21 -30.1396 -39.21 -30.1396h-21.3701l11.6602 47.71h21.3398z" />
<glyph glyph-name="mdb" unicode="&#xf8ca;" horiz-adv-x="576"
d="M17.3701 287.59h46.2998l42.3301 -117.33l40.7002 117.33h45.5098l12.79 -191.59h-45.5303l-4.79004 77.4297l-25.54 -77.4297h-44.71l-27.9297 79.8301l-5.58984 -79.8301h-43.9102zM298.37 287.59c0 0 93.4199 -1.58984 94.2002 -95.7998
c0.799805 -96.5898 -94.2002 -95.79 -94.2002 -95.79h-47.9004v191.59h47.9004zM297.17 141.13c0 0 47.5996 5.21973 46.7998 51.5205c-0.799805 46.2998 -46.7998 50.5693 -46.7998 50.5693v-102.09zM535.46 215.37c0 0 33.54 -11.96 33.54 -55.1006
c0 -68.6396 -87 -63.8496 -87 -63.8496h-45.5195v191.58h51.8994s49.7402 1.44043 55.0801 -34.3203c0.348633 -2.30371 0.630859 -6.06445 0.630859 -8.39453c0 -8.94336 -3.86621 -22.3457 -8.63086 -29.915zM483.56 247.31v-21.5898h12s5.43066 5.33984 4 12
c-2.42969 11.1807 -16 9.58984 -16 9.58984zM483.46 137.85c0 0 41.04 -4.92969 41.3701 20.7207c0.389648 27.1602 -41.1904 22.4297 -41.1904 22.4297h-0.0800781v-18.2305z" />
<glyph glyph-name="orcid" unicode="&#xf8d2;" horiz-adv-x="512"
d="M294.75 259.81c58.1299 0 84.6699 -35.2598 84.6699 -76.8994c0 -25.5703 -15.5 -76.9102 -83.1201 -76.9102h-47.4697v153.81h45.9199zM256 440c137 0 248 -111 248 -248s-111 -248 -248 -248s-248 111 -248 248s111 248 248 248zM175.21 79.2402v207.5h-29.8398v-207.5
h29.8398zM160.29 310.38c10.7646 0.0380859 19.5312 8.80566 19.5703 19.5703c0 10.8027 -8.76758 19.5693 -19.5703 19.5693s-19.5703 -8.7666 -19.5703 -19.5693s8.76758 -19.5703 19.5703 -19.5703v0zM300 79c68.3799 0 110 50.6104 110.04 103.89
c0 49.0205 -33.71 103.851 -110.44 103.851h-80.5996v-207.74h81z" />
<glyph glyph-name="swift" unicode="&#xf8e1;"
d="M448 291.91c0 -5.35059 -0.000976562 -10.7002 0.00878906 -16.0498v-183.771c-0.0292969 -4.50977 -0.0800781 -9.00977 -0.200195 -13.5098c-0.0966797 -8.1748 -1.25781 -21.3545 -2.58984 -29.4199c-1.38477 -8.11035 -5.51465 -20.6543 -9.21973 -28
c-7.66406 -15.0459 -26.0898 -33.4854 -41.1299 -41.1602c-7.34766 -3.69824 -19.8916 -7.82422 -28 -9.20996c-8.07129 -1.32715 -21.2607 -2.4873 -29.4404 -2.58984c-4.51953 -0.120117 -9.00977 -0.200195 -13.5195 -0.200195h-199.79
c-4.52051 0.0302734 -9.02051 0.0800781 -13.5205 0.200195c-8.17676 0.0976562 -21.3613 1.25781 -29.4297 2.58984c-8.1084 1.38379 -20.6523 5.50977 -28 9.20996c-15.0342 7.67676 -33.4609 26.1113 -41.1299 41.1504c-3.70508 7.3457 -7.83496 19.8896 -9.21973 28
c-1.3252 8.06543 -2.48145 21.2461 -2.58008 29.4199c-0.129883 4.50977 -0.209961 9 -0.209961 13.5098v199.83c0.0292969 4.51953 0.0800781 9.00977 0.209961 13.5195c0.0888672 8.16797 1.22754 21.3389 2.54004 29.4004c1.38672 8.10938 5.5166 20.6533 9.21973 28
c3.74121 7.34473 11.5146 18.0293 17.3496 23.8496c1.74023 1.7207 3.55078 3.39062 5.43066 5c4.6748 3.99805 12.9141 9.51758 18.3896 12.3203c2.2334 1.11328 4.50391 2.15332 6.81152 3.12012c5.67188 2.31348 15.1738 5.04688 21.21 6.09961
c6.04688 1.03516 15.9297 2.07422 22.0596 2.32031c2.45996 0.120117 4.91992 0.200195 7.37012 0.269531c4.51953 0.120117 9.00977 0.200195 13.5195 0.200195h199.75c4.52051 -0.0292969 9.01074 -0.0800781 13.5205 -0.200195
c8.17676 -0.0976562 21.3613 -1.25781 29.4297 -2.58984c8.11035 -1.38281 20.6543 -5.51367 28 -9.21973c15.0547 -7.66211 33.4941 -26.0977 41.1602 -41.1504c3.70117 -7.34668 7.83105 -19.8906 9.21973 -28c1.3252 -8.06543 2.48047 -21.2461 2.58008 -29.4199
c0.120117 -4.51953 0.200195 -9.00977 0.200195 -13.5195zM378.119 50.9102c4.91016 -9.58008 15.3604 41.1797 -23.1602 88.5801c0.490234 1.68945 1 3.35938 1.44043 5.08984c18.5996 74.0801 -26.79 161.67 -103.58 207.75
c33.6494 -45.6201 48.5293 -100.87 35.3096 -149.2c-0.970703 -3.50098 -2.83398 -9.08789 -4.16016 -12.4697c-1.72949 1.14941 -3.84961 2.41992 -6.72949 4c0 0 -76.3906 47.1699 -159.181 130.59c-2.16992 2.2002 44.1504 -66.25 96.7207 -121.74
c-24.7803 13.9004 -93.7803 64.1201 -137.48 104.12c4.60156 -7.57031 13.0146 -19.1738 18.7803 -25.8994c36.4902 -46.2207 84.0898 -103.37 141.09 -147.221c-40 -24.4902 -96.6396 -26.3994 -153 0c-11.4521 5.37598 -29 15.8457 -39.1699 23.3701
c21.3398 -33.9365 68.5098 -74.4219 105.29 -90.3701c53.3203 -22.9199 106.35 -21.3799 145.85 -0.379883l0.419922 0.25c1.77051 1 3.53027 2 5.25 3c19.0801 9.7998 56.3105 19.46 76.3105 -19.4697z" />
<glyph glyph-name="umbraco" unicode="&#xf8e8;" horiz-adv-x="510"
d="M255.35 440c136.99 -0.169922 247.83 -111.31 247.65 -248.28c-0.179688 -136.97 -111.15 -247.67 -248 -247.67c-137 0.0703125 -248.07 111.271 -248 248.271c0.139648 136.96 111.36 247.85 248.35 247.68zM400.35 174
c0.296875 4.31738 0.518555 11.3311 0.518555 15.6582c0 4.16406 -0.222656 10.9141 -0.498047 15.0693c-0.354492 12.1631 -1.97168 31.8213 -3.61035 43.8799c-1.87012 13.2197 -3.56934 22.3799 -5.38965 32c-1.02051 4.87988 -1.28027 6.39941 -1.83008 8.44922
c-0.489258 2.14746 -2.67285 3.89062 -4.875 3.89062h-0.0253906h-0.819336l-32 -5c-2.31934 -0.375977 -4.20117 -2.58691 -4.20117 -4.93555c0 -0.0175781 0.000976562 -0.046875 0.000976562 -0.0644531c-0.00878906 -0.106445 -0.0146484 -0.27832 -0.0146484 -0.384766
s0.00585938 -0.279297 0.0146484 -0.385742l1.68945 -8.7793c1.60645 -8.86719 3.23633 -20.0938 4.88965 -33.6807c1.35156 -11.5938 2.5166 -30.4775 2.59961 -42.1494c0.266602 -26.9072 -2.44336 -46.834 -8.12988 -59.7803
c-5.01953 -11.3809 -18.9746 -22.6836 -31.1504 -25.2305c-13.7178 -2.9043 -36.2324 -5.26074 -50.2549 -5.26074c-1.93652 0 -5.0791 0.0449219 -7.01465 0.101562h-10.25c-1.9668 -0.0576172 -5.15918 -0.104492 -7.12695 -0.104492
c-14.0098 0 -36.5059 2.34863 -50.2129 5.24414c-12.2217 2.49805 -26.248 13.7793 -31.3105 25.1797c-5.60645 12.9336 -8.31641 32.877 -8.12988 59.8301c0.0820312 11.6738 1.26562 30.5576 2.64062 42.1504c1.62012 13.6201 3.2334 24.8467 4.83984 33.6797
l1.7002 8.78027c0.0078125 0.105469 0.0146484 0.27832 0.0146484 0.384766s-0.00683594 0.279297 -0.0146484 0.384766v0.0126953c0 2.33398 -1.86426 4.56836 -4.16016 4.9873l-32 5h-0.69043c-2.18848 -0.0195312 -4.38379 -1.7627 -4.89941 -3.88965
c-0.540039 -2.03027 -0.820312 -3.57031 -1.82031 -8.4502c-1.83008 -9.41992 -3.52051 -18.6094 -5.40039 -32c-1.63184 -12.0586 -3.24414 -31.7168 -3.59961 -43.8799c-0.290039 -4.2334 -0.525391 -11.1123 -0.525391 -15.3545
c0 -4.24316 0.235352 -11.1221 0.525391 -15.3555c0.766602 -27.0928 5.43359 -48.7598 14 -65c8.57324 -16.2061 23.0801 -27.873 43.5195 -35c20.4404 -7.12695 48.9209 -10.6172 85.4414 -10.4697h4.59961c36.5605 -0.15332 65.0439 3.33691 85.4502 10.4707
c20.4336 7.12012 34.9365 18.7871 43.5098 35.001s13.2402 37.8809 14 65.001z" />
<glyph glyph-name="firefox-browser" unicode="&#xf907;" horiz-adv-x="512"
d="M130.63 324.51c0.160156 -0.00976562 0.0800781 -0.00976562 0 0zM482.05 279.16c15.2803 -36.7598 20.6709 -80.748 15.8213 -122.578c-0.370117 -3.15039 -0.700195 -6.29004 -1.11035 -9.41016c-19.6094 -115.04 -119.79 -202.62 -240.43 -202.62
c-134.71 0 -243.92 109.19 -243.92 243.891v1.23926c0.149414 2.70996 0.30957 5.41016 0.490234 8.12012c0.0498047 0.240234 0.0498047 0.480469 0.0498047 0.719727c0.439453 6.29004 0.870117 10.3105 1.43945 14c0.240234 1.91309 0.5 3.82617 0.780273 5.73926
c1.66992 12.2705 3.94043 22.21 4 22.4805c4.9502 22.2051 19.6123 55.3125 32.7305 73.8994v0c5.65527 8.06738 15.8564 20.3115 22.7695 27.3301c6.08203 6.21973 16.7627 15.3721 23.8398 20.4307c0.930664 0.629883 8.03027 4.83984 8.15039 4.30957
c-0.570312 -8.42969 -1.24023 -48.8301 8.42969 -61.0801h0.120117c14.1602 15.9199 33.6504 33.96 58.71 45.3701c-2.02344 -7.75098 -3.66504 -20.543 -3.66504 -28.5537c0 -8.74512 1.95117 -22.668 4.35547 -31.0762
c1.81641 -1.21777 4.64258 -3.35449 6.30957 -4.77051c3.71973 -3.14941 7.91992 -7.34961 16.7705 -16.0596c16.5498 -16.3096 59 -33.1797 59.0898 -35.1797c-0.400391 -6.08008 -21.8301 -27 -29.3301 -27c-69.3701 0 -80.6201 -41.9502 -80.6201 -41.9502
c3.07031 -35.3301 27.6699 -64.4102 57.5098 -79.75c1.36035 -0.730469 2.74023 -1.37012 4.12012 -2c2.36035 -1.04004 4.74023 -2.02051 7.16016 -2.92969c8.50586 -3.00977 22.7246 -5.75195 31.7402 -6.12012c121.569 -5.7002 145.13 145.34 57.3896 189.199
c22.4697 3.91016 45.8203 -5.12988 58.8203 -14.2793c-8.68652 15.1641 -27.7988 34.9346 -42.6602 44.1299c-0.993164 0.620117 -1.99316 1.21973 -3 1.7998c-1.55957 0.913086 -3.13965 1.79004 -4.74023 2.62988c-0.75 0.390625 -1.5 0.759766 -2.25 1.12988
c-1.65332 0.813477 -3.32031 1.59668 -5.00098 2.34961c-1.07031 0.469727 -2.16016 0.910156 -3.25 1.34961c-1.33984 0.580078 -2.68945 1.08008 -4.0498 1.58008c-1.86035 0.669922 -3.73047 1.2998 -5.62012 1.87012c-0.679688 0.209961 -1.33008 0.429688 -2 0.629883
c-9.20996 2.66309 -24.4668 4.82422 -34.0537 4.82422c-0.275391 0 -0.72168 -0.00195312 -0.996094 -0.00390625c-2 -0.0205078 -4 -0.100586 -6 -0.220703l-1.41992 -0.0996094c-12.1934 -0.852539 -31.0586 -5.78027 -42.1104 -11l-0.519531 -0.209961
c-0.536133 -0.18457 -1.43066 -0.334961 -1.99805 -0.334961c-2.40918 0 -5.00391 1.84863 -5.79199 4.125c-0.210938 0.575195 -0.381836 1.53906 -0.381836 2.15137c0 2.13965 1.55469 4.64746 3.47168 5.59863c12.6738 6.01074 34.3252 11.5342 48.3301 12.3301
c5.7793 35.3994 28.2695 91.0098 82.5 122.78l-0.100586 -0.140625l0.180664 0.100586l0.120117 0.0693359c0.0615234 0.0166016 0.165039 0.0302734 0.229492 0.0302734s0.167969 -0.0136719 0.230469 -0.0302734c0.303711 -0.0380859 0.550781 -0.318359 0.550781 -0.625
c0 -0.00976562 -0.000976562 -0.0253906 -0.000976562 -0.0351562c0.698242 -2.77051 2.3291 -7.08008 3.63965 -9.61914c0.830078 -1.70996 1.69043 -3.40039 2.69043 -5.05078c1.87988 -3.21973 3.80957 -6.2793 5.73926 -9.33008
c38.2002 -60.3594 84.9707 -88.0791 112.551 -156.829c-0.0507812 0.269531 -0.0507812 0.40918 -0.0507812 0.40918c-3.0293 20.1201 -10.9795 47.1104 -24.6992 74c16.8594 -8.72949 38.3301 -36.2295 48.9395 -61.7295z" />
<glyph glyph-name="ideal" unicode="&#xf913;" horiz-adv-x="576"
d="M125.61 282.52c27.0693 -0.0107422 49.0488 -21.9893 49.0596 -49.0596v-0.00976562c0 -27.0869 -21.9834 -49.0703 -49.0703 -49.0703c-27.0859 0 -49.0693 21.9834 -49.0693 49.0703s21.9834 49.0693 49.0693 49.0693h0.0107422zM86.1504 22.1602v140.52h78.9395
v-140.52h-78.9395zM237.61 233.76c0 -20.4502 -8.99023 -23.2598 -18.7402 -23.2598h-14.0498v45.79h14.0498c8.74023 0 18.7402 -2.53027 18.7402 -22.5303zM439.3 187.76h57.0898c-1.7793 -98.4795 -52.1094 -165.64 -196.72 -165.64h-94.8301v165.62h14
c25.9805 0 41.5 17.1895 41.5 46c0 27.9102 -15.8994 45.2598 -41.5 45.2598h-14v82.8096h94.8301c88.9404 0 186.83 -26.8896 196.07 -151.31h-33.6904v68.5703h-22.75v-91.3105zM329.55 187.76l-0.0400391 22.7402h-33.5098v12.5h30v22.6904h-30v10.5791h31.7305v22.7305
h-54.4307v-91.2402h56.25zM404.21 187.76l23.6699 -0.0195312l-27.5303 91.3398h-32.3496l-27.5303 -91.3203h23.6602l5.17969 17.6699h29.7402zM299.65 416c218.35 0 250.97 -140 251 -223.48c0 -144.789 -89.1504 -224.52 -251 -224.52h-267.65v448h267.65z
M299.65 -10.9199c148.899 0 229.899 69.3496 229.899 203.439c0 137.801 -87.7998 202.41 -229.899 202.41h-246.58v-405.85h246.58zM383.51 253.93h1.37012l7.52051 -25.8096h-16.4004z" />
<glyph glyph-name="microblog" unicode="&#xf91a;"
d="M399.36 85.7695l0.149414 0.0605469c-12.0234 -13.6182 -21.7812 -39.4141 -21.7812 -57.5811c0 -16.3584 8.10547 -40.1514 18.0918 -53.1094c0.521484 -0.658203 0.944336 -1.87402 0.944336 -2.71387c0 -0.25293 -0.0419922 -0.658203 -0.0947266 -0.90625
c-0.40332 -1.94336 -2.34277 -3.52051 -4.32715 -3.52051c-0.249023 0 -0.649414 0.0410156 -0.892578 0.0908203c-32.2803 7.17969 -61.3105 24.8301 -79.8906 49.9199c-1.18652 1.62598 -3.78516 2.94629 -5.79785 2.94629
c-0.658203 0 -1.69824 -0.172852 -2.32129 -0.385742c-21.1924 -7.41895 -56.6133 -13.4404 -79.0654 -13.4404h-0.375c-122.86 0 -222.46 91.4805 -222.46 204.43c0 112.95 99.5996 204.44 222.46 204.44s222.46 -91.4902 222.46 -204.44
c0 -47.4492 -17.6104 -91.0996 -47.0996 -125.79zM329.52 235.6c1.4209 1.07617 2.57422 3.36816 2.57422 5.15039c0 3.5625 -2.8916 6.47461 -6.4541 6.5l-71.8799 1.50977l-23.6602 67.9199c-0.836914 2.41113 -3.58789 4.36719 -6.13965 4.36719
s-5.30273 -1.95605 -6.13965 -4.36719l-23.6602 -67.9199l-71.8799 -1.50977c-3.51953 -0.0673828 -6.375 -2.97949 -6.375 -6.49902c0 -1.7832 1.15332 -4.10449 2.5752 -5.18066l57.2998 -43.4902l-20.79 -68.8604
c-0.152344 -0.505859 -0.276367 -1.3457 -0.276367 -1.87402c0 -3.59375 2.91699 -6.51074 6.51074 -6.51074c1.12598 0 2.79102 0.522461 3.71582 1.16504l59.0596 41.0801l59.0596 -41.0498c0.925781 -0.646484 2.59277 -1.1709 3.72168 -1.1709
c3.58789 0 6.5 2.91211 6.5 6.5c0 0.533203 -0.125977 1.38086 -0.28125 1.89062l-20.7803 68.8604z" />
<glyph glyph-name="pied-piper-square" unicode="&#xf91e;"
d="M32 29l-32 -60.2002l0.799805 328c0 65.9004 53.2002 119.2 119.2 119.2h327.2c-93 -28.9004 -189.9 -94.2002 -253.9 -168.6c-70.5996 -81.4004 -110.7 -137.4 -161.3 -218.4zM448 416c0 0 0 -328.8 0.0996094 -328.8c0 -65.9004 -53.2998 -119.2 -119.3 -119.2
h-328.399c18.5 25.5 61.6992 54 84.8994 66c35.5 18.0996 76.4004 28.5 105.3 56.2998c42.1006 40.5 47.8008 105 71 158.601c43.6006 100.3 186.4 167.1 186.4 167.1z" />
<glyph glyph-name="unity" unicode="&#xf949;" horiz-adv-x="576"
d="M498.11 241.6l-30 -49.5996l30 -49.6299l-52.8008 -191.62l-197.079 51.3604l-29.2402 50l-59.1699 -0.430664l-144.28 140.32l144.26 140.29l59.2002 -0.429688l29.2002 50.0596l197.109 51.3604zM223.77 323.8l-108.899 -108.13h173.13l86.5498 145.82zM223.77 60.1699
l150.78 -37.6895l-86.5498 145.81h-173.13zM416.77 46.1699l41.79 145.83l-41.8096 145.84l-86.5801 -145.84z" />
</font>
</defs></svg>

Before

Width:  |  Height:  |  Size: 674 KiB

After

Width:  |  Height:  |  Size: 692 KiB

View File

@@ -1,12 +1,12 @@
<?xml version="1.0" standalone="no"?>
<!--
Font Awesome Free 5.9.0 by @fontawesome - https://fontawesome.com
Font Awesome Free 5.12.0 by @fontawesome - https://fontawesome.com
License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License)
-->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" >
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1">
<metadata>
Created by FontForge 20190112 at Tue Jun 4 15:16:44 2019
Created by FontForge 20190801 at Tue Dec 10 16:09:21 2019
By Robert Madole
Copyright (c) Font Awesome
</metadata>
@@ -22,7 +22,7 @@ Copyright (c) Font Awesome
descent="-64"
bbox="-0.0663408 -64.0662 640.01 448.1"
underline-thickness="25"
underline-position="-51"
underline-position="-50"
unicode-range="U+0020-F5C8"
/>
<missing-glyph />
@@ -435,14 +435,14 @@ c-44.1123 0 -80 35.8877 -80 80v8c0 30.8779 25.1211 56 56 56h293.917c24.5 0 47.08
c-4.41113 0 -8 -3.58887 -8 -8v-8c0 -17.6445 14.3555 -32 32 -32h213.471c25.2021 0 42.626 -25.293 33.6299 -48.8457l-24.5518 -64.2812c-7.05371 -18.4658 -25.0732 -30.873 -44.8398 -30.873h-113.709c-22.0557 0 -40 -17.9443 -40 -40c0 -4.41113 3.58887 -8 8 -8
h131.552h0.0517578c7.44141 0 19.1074 -2.19238 26.041 -4.89355l99.752 -38.7881c18.5898 -7.22852 30.6035 -24.7881 30.6035 -44.7363v-23.582h128z" />
<glyph glyph-name="hand-spock" unicode="&#xf259;"
d="M21.0957 66.21c-26.9688 25.3818 -28.2471 67.7461 -2.87109 94.707c24.1982 25.7139 64.2881 28.2373 91.4824 5.72168l-31.04 136.509c-9.38379 41.2803 21.4336 81.0127 64.0713 81.8438c1.74414 28.9062 22.2656 54.4912 51.8818 61.2949
c36.001 8.27539 72.0176 -14.2266 80.3037 -50.2959l21.6748 -131.99l16.9014 105.25c9.02344 36.0947 45.4473 57.7021 81.25 48.75c27.3066 -6.82715 45.7061 -29.1357 49.8496 -53.9922c43.2285 0.212891 75.6436 -40.1133 65.5439 -82.5244l-31.7295 -133.41
c-0.938477 -3.94141 -1.41406 -7.99414 -1.41406 -12.0449v-36.8389v-0.00683594c0 -9.29102 -2.14355 -24.0596 -4.78516 -32.9668l-31.8145 -107.312c-4.02734 -13.585 -16.5107 -22.9043 -30.6807 -22.9043h-237.6c-7.00586 0 -16.8311 3.89648 -21.9316 8.69824z
M53.1641 128.021c-7.17969 -7.62891 -6.81543 -19.6777 0.813477 -26.8574l124.487 -117.164h219.311l28.4199 95.8613c1.86133 6.27637 2.80469 12.7793 2.80469 19.3281v36.8389c0.000976562 6.48047 1.21973 16.8574 2.71973 23.1621l31.7549 133.407
c5.83105 24.4893 -31.1445 33.25 -36.9658 8.80273l-26.9229 -113.105c-1.61523 -6.78711 -8.58887 -12.2949 -15.5645 -12.2949h-9.69434c-10.4072 0 -18.043 9.79199 -15.5225 19.8799l38.127 152.512c6.09766 24.376 -30.7607 33.6396 -36.8643 9.21777l-42.3721 -169.49
c-1.67285 -6.68945 -8.62695 -12.1191 -15.5225 -12.1191h-13.2168v0c-7.0332 0 -14.0195 5.5625 -15.5938 12.417l-45.2207 196.828c-5.64453 24.5684 -42.6572 15.9609 -37.0342 -8.50781l41.6191 -181.153c2.30078 -10.0156 -5.31738 -19.583 -15.5938 -19.583h-8.60352
h-0.000976562c-7.0498 0 -14.04 5.5791 -15.6025 12.4541l-30.3984 133.757c-5.55273 24.4395 -42.6504 16.1963 -37.0547 -8.4209l34.1299 -150.172c0.263672 -1.16309 0.397461 -2.35352 0.397461 -3.5459v-69.4795c0 -13.9941 -16.7754 -21.2432 -26.9658 -11.6523
l-53.0117 49.8936c-7.61523 7.16699 -19.6377 6.85938 -26.8564 -0.8125z" />
d="M501.03 331.824c6.05762 -9.77832 10.9746 -27.0498 10.9746 -38.5518c0 -4.80664 -0.915039 -12.499 -2.04297 -17.1709l-57.623 -241.963c-12.748 -54.1729 -68.2627 -98.1387 -123.915 -98.1387h-0.345703h-107.455h-0.224609
c-33.8135 0 -81.2148 18.834 -105.807 42.041l-91.3652 85.9766c-12.8213 12.0469 -23.2266 36.1016 -23.2266 53.6943c0 16.1299 8.97266 38.7529 20.0273 50.499c5.31836 5.66406 29.875 29.3926 68.1152 21.8477l-24.3594 82.1973
c-1.68164 5.66406 -3.0459 15.0576 -3.0459 20.9668c0 37.5938 30.417 70.502 67.8955 73.4551c-0.204102 2.03125 -0.369141 5.33691 -0.369141 7.37891c0 31.627 24.8594 63.6895 55.4902 71.5684c43.248 10.9785 80.5645 -17.7012 89.6602 -53.0723l13.6836 -53.207
l4.64648 22.6602c6.76074 32.417 39.123 58.8115 72.2373 58.916c8.73438 0 56.625 -3.26953 70.7383 -54.0801c15.0664 0.710938 46.9199 -3.50977 66.3105 -35.0176zM463.271 287.219c7.86914 32.9844 -42.1211 45.2695 -50.0859 11.9219l-24.8008 -104.146
c-4.38867 -18.4141 -31.7783 -11.8926 -28.0557 6.2168l28.5479 139.166c7.39844 36.0703 -43.3076 45.0703 -50.1182 11.9629l-31.791 -154.971c-3.54883 -17.3086 -28.2832 -18.0469 -32.7109 -0.804688l-47.3262 184.035
c-8.43359 32.8105 -58.3691 20.2676 -49.8652 -12.8359l42.4414 -165.039c4.81641 -18.7207 -23.3711 -26.9121 -28.9648 -8.00781l-31.3438 105.779c-9.6875 32.6465 -59.1191 18.2578 -49.3867 -14.625l36.0137 -121.539
c5.61816 -18.9521 10.1777 -50.377 10.1777 -70.1436v-0.00878906c0 -6.54297 -8.05664 -10.9355 -13.4824 -5.82617l-51.123 48.1074c-24.7852 23.4082 -60.0527 -14.1875 -35.2793 -37.4902l91.3691 -85.9805c16.9629 -16.0068 49.6592 -28.998 72.9824 -28.998h0.154297
h107.455h0.216797c34.7402 0 69.3936 27.4443 77.3525 61.2598z" />
<glyph glyph-name="hand-pointer" unicode="&#xf25a;" horiz-adv-x="448"
d="M358.182 268.639c43.1934 16.6348 89.8184 -15.7949 89.8184 -62.6387v-84c-0.000976562 -4.25 -0.775391 -11.0615 -1.72754 -15.2041l-27.4297 -118.999c-6.98242 -30.2969 -33.7549 -51.7969 -64.5566 -51.7969h-178.286c-21.2588 0 -41.3682 10.4102 -53.791 27.8457
l-109.699 154.001c-21.2432 29.8193 -14.8047 71.3574 14.5498 93.1523c18.8115 13.9658 42.1748 16.2822 62.083 8.87207v161.129c0 36.9443 29.7363 67 66.2861 67s66.2861 -30.0557 66.2861 -67v-73.6338c20.4131 2.85742 41.4678 -3.94238 56.5947 -19.6289

Before

Width:  |  Height:  |  Size: 141 KiB

After

Width:  |  Height:  |  Size: 141 KiB

View File

@@ -1,12 +1,12 @@
<?xml version="1.0" standalone="no"?>
<!--
Font Awesome Free 5.9.0 by @fontawesome - https://fontawesome.com
Font Awesome Free 5.12.0 by @fontawesome - https://fontawesome.com
License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License)
-->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" >
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1">
<metadata>
Created by FontForge 20190112 at Tue Jun 4 15:16:44 2019
Created by FontForge 20190801 at Tue Dec 10 16:09:21 2019
By Robert Madole
Copyright (c) Font Awesome
</metadata>
@@ -22,16 +22,16 @@ Copyright (c) Font Awesome
descent="-64"
bbox="-0.983398 -64.9834 640.104 448.427"
underline-thickness="25"
underline-position="-51"
unicode-range="U+0020-F897"
underline-position="-50"
unicode-range="U+0020-F941"
/>
<missing-glyph />
<glyph glyph-name="glass-martini" unicode="&#xf000;"
d="M502.05 390.4l-214.05 -214.04v-192.36h56c22.0898 0 40 -17.9102 40 -40c0 -4.41992 -3.58008 -8 -8 -8h-240c-4.41992 0 -8 3.58008 -8 8c0 22.0898 17.9102 40 40 40h56v192.36l-214.05 214.04c-21.25 21.2598 -6.2002 57.5996 23.8496 57.5996h444.4
c30.0498 0 45.0996 -36.3398 23.8496 -57.5996z" />
<glyph glyph-name="music" unicode="&#xf001;"
d="M511.99 415.99l0.00976562 -351.99c0 -35.3496 -42.9805 -64 -96 -64s-96 28.6504 -96 64s42.9805 64 96 64c11.2803 0 21.9502 -1.54004 32 -3.91992v184.63l-256 -75.0195v-233.69c0 -35.3496 -42.9805 -64 -96 -64s-96 28.6504 -96 64s42.9805 64 96 64
c11.2803 0 21.9502 -1.54004 32 -3.91992v261.42c0 14 9.09961 26.2998 22.4004 30.5l319.989 94.5c20.5 6.5 41.6006 -8.7998 41.6006 -30.5098z" />
d="M470.38 446.49c2.59277 0.816406 6.90234 1.48047 9.62012 1.48047c17.6475 0 31.9834 -14.3232 32 -31.9707v-352c0 -35.3496 -43 -64 -96 -64s-96 28.6602 -96 64s43 64 96 64c8.95898 -0.0488281 23.2949 -1.80957 32 -3.92969v184.609l-256 -75v-233.68
c0 -35.3398 -43 -64 -96 -64s-96 28.6602 -96 64s43 64 96 64c8.95801 -0.0507812 23.2939 -1.80664 32 -3.91992v261.41c0.0078125 12.958 10.0479 26.626 22.4102 30.5098z" />
<glyph glyph-name="search" unicode="&#xf002;"
d="M505 5.2998c9.2998 -9.39941 9.2998 -24.5996 -0.0996094 -34l-28.3008 -28.2998c-9.2998 -9.40039 -24.5 -9.40039 -33.8994 0l-99.7002 99.7002c-4.5 4.5 -7 10.5996 -7 17v16.2998c-35.2998 -27.5996 -79.7002 -44 -128 -44c-114.9 0 -208 93.0996 -208 208
s93.0996 208 208 208s208 -93.0996 208 -208c0 -48.2998 -16.4004 -92.7002 -44 -128h16.2998c6.40039 0 12.5 -2.5 17 -7zM208 112c70.7998 0 128 57.2998 128 128c0 70.7998 -57.2998 128 -128 128c-70.7998 0 -128 -57.2998 -128 -128c0 -70.7998 57.2998 -128 128 -128z
@@ -834,9 +834,10 @@ c22.4004 26.7998 55.2998 42.2002 90.2002 42.2002s67.7998 -15.4004 90.2002 -42.20
d="M248 440c137 0 248 -111 248 -248s-111 -248 -248 -248s-248 111 -248 248s111 248 248 248zM168 272c-17.7002 0 -32 -14.2998 -32 -32s14.2998 -32 32 -32s32 14.2998 32 32s-14.2998 32 -32 32zM344 80c21.2002 0 21.2002 32 0 32h-192c-21.2002 0 -21.2002 -32 0 -32
h192zM328 208c17.7002 0 32 14.2998 32 32s-14.2998 32 -32 32s-32 -14.2998 -32 -32s14.2998 -32 32 -32z" />
<glyph glyph-name="gamepad" unicode="&#xf11b;" horiz-adv-x="640"
d="M480 352c88.4004 0 159.9 -71.5996 159.9 -160s-71.6006 -160 -160 -160c-44.7002 0 -85.2002 18.4004 -114.2 48h-91.5c-29 -29.5996 -69.4004 -48 -114.2 -48c-88.4004 0 -160 71.5996 -160 160s71.5996 160 160 160h320zM256 172v40c0 6.59961 -5.40039 12 -12 12h-52
v52c0 6.59961 -5.40039 12 -12 12h-40c-6.59961 0 -12 -5.40039 -12 -12v-52h-52c-6.59961 0 -12 -5.40039 -12 -12v-40c0 -6.59961 5.40039 -12 12 -12h52v-52c0 -6.59961 5.40039 -12 12 -12h40c6.59961 0 12 5.40039 12 12v52h52c6.59961 0 12 5.40039 12 12zM440 104
c26.5 0 48 21.5 48 48s-21.5 48 -48 48s-48 -21.5 -48 -48s21.5 -48 48 -48zM520 184c26.5 0 48 21.5 48 48s-21.5 48 -48 48s-48 -21.5 -48 -48s21.5 -48 48 -48z" />
d="M480.07 352c88.2939 -0.0263672 159.952 -71.7061 159.952 -160c0 -88.3203 -71.6797 -160 -160 -160c-37.1016 0 -88.291 21.5039 -114.263 48h-91.5195c-25.9717 -26.4961 -77.1611 -48 -114.263 -48c-88.3203 0 -160 71.6797 -160 160s71.6797 160 160 160h0.0224609
h320.07zM248 180v24c0 6.62402 -5.37598 12 -12 12h-52v52c0 6.62402 -5.37598 12 -12 12h-24c-6.62402 0 -12 -5.37598 -12 -12v-52h-52c-6.62402 0 -12 -5.37598 -12 -12v-24c0 -6.62402 5.37598 -12 12 -12h52v-52c0 -6.62402 5.37598 -12 12 -12h24
c6.62402 0 12 5.37598 12 12v52h52c6.62402 0 12 5.37598 12 12zM464 104c22.0801 0 40 17.9199 40 40s-17.9199 40 -40 40s-40 -17.9199 -40 -40s17.9199 -40 40 -40zM528 200c22.0801 0 40 17.9199 40 40s-17.9199 40 -40 40s-40 -17.9199 -40 -40s17.9199 -40 40 -40z
" />
<glyph glyph-name="keyboard" unicode="&#xf11c;" horiz-adv-x="576"
d="M528 0h-480c-26.5098 0 -48 21.4902 -48 48v288c0 26.5098 21.4902 48 48 48h480c26.5098 0 48 -21.4902 48 -48v-288c0 -26.5098 -21.4902 -48 -48 -48zM128 268v40c0 6.62695 -5.37305 12 -12 12h-40c-6.62695 0 -12 -5.37305 -12 -12v-40
c0 -6.62695 5.37305 -12 12 -12h40c6.62695 0 12 5.37305 12 12zM224 268v40c0 6.62695 -5.37305 12 -12 12h-40c-6.62695 0 -12 -5.37305 -12 -12v-40c0 -6.62695 5.37305 -12 12 -12h40c6.62695 0 12 5.37305 12 12zM320 268v40c0 6.62695 -5.37305 12 -12 12h-40
@@ -932,10 +933,10 @@ c0 -13.2549 -10.7451 -24 -24 -24h-144c-13.2549 0 -24 10.7451 -24 24v246.795c0 44
c-12.3066 4.92285 -18.293 18.8906 -13.3701 31.1973c14.668 36.6709 38.0107 77.833 90.0498 90.8838c-14.1406 36.5273 12.793 76.2031 52.2275 76.2031c37.4463 0 64.3525 -36.1084 53.668 -72h58.332c0 4.2002 -1.30664 15.7822 10.0273 17.6709zM144 376
c8.82227 0 16 7.17773 16 16s-7.17773 16 -16 16s-16 -7.17773 -16 -16s7.17773 -16 16 -16z" />
<glyph glyph-name="rocket" unicode="&#xf135;"
d="M505.05 428.9c6.9502 -32.2002 6.9502 -57.4004 6.85059 -82.6006c0 -102.689 -55.4102 -164.79 -128 -211.09v-104.41v-0.0400391c0 -16.3516 -11.8721 -35.5527 -26.5 -42.8594l-98.7002 -49.3906c-2.79004 -1.38965 -7.58398 -2.5166 -10.7002 -2.5166
c-13.248 0 -24 10.752 -24 24v0.00683594v103.84l-22.4697 -22.4697c-5.17383 -5.1748 -15.3125 -9.375 -22.6299 -9.375c-7.31836 0 -17.4561 4.2002 -22.6309 9.375l-50.8994 50.9102c-5.17285 5.17285 -9.37012 15.3096 -9.37012 22.625s4.19727 17.4512 9.37012 22.625
l22.4697 22.4697h-103.77h-0.0126953c-13.248 0 -24 10.752 -24 24c0 3.12012 1.12988 7.91797 2.52246 10.71l49.4199 98.7998c7.32324 14.6094 26.5283 26.4766 42.8701 26.4902h104.2c46.1895 72.7998 108.09 128 211.29 128c25.0996 0 50.29 0 82.4893 -6.90039
c5.54395 -1.19043 11.0098 -6.65527 12.2002 -12.1992zM384 280c22.0801 0 40 17.9199 40 40s-17.9199 40 -40 40s-40 -17.9199 -40 -40s17.9199 -40 40 -40z" />
d="M505.12 428.906c6.95508 -32.2031 6.95508 -57.4062 6.86133 -82.6094c0 -102.688 -55.4375 -164.781 -128.035 -211.094v-104.438c0 -16.3594 -11.8789 -35.5625 -26.5078 -42.8594l-98.7275 -49.3906c-2.81934 -1.27441 -7.61621 -2.40137 -10.707 -2.51562
c-13.2471 0.00195312 -24.002 10.7539 -24.0059 24v103.844l-22.4746 -22.4688c-13.1211 -13.1562 -34.1211 -11.1875 -45.2773 0l-50.9043 50.9062c-12.9961 12.9922 -11.3652 33.8887 0 45.25l22.4746 22.4688h-103.811c-13.2461 0.00195312 -24.001 10.7539 -24.0059 24
c0.111328 3.09082 1.23828 7.88574 2.51562 10.7031l49.4355 98.8125c7.33008 14.6094 26.5391 26.4688 42.8867 26.4844h104.215c46.2168 72.7969 108.122 128 211.354 128c25.0996 0 50.3086 0 82.5059 -6.90625c5.54883 -1.1875 11.0176 -6.65625 12.207 -12.1875z
M384.04 280c22.0732 0.0078125 39.9971 17.9277 40.0098 40c0 22.0801 -17.9199 40 -40 40s-40 -17.9199 -40 -40c0 -22.0742 17.916 -39.9951 39.9902 -40z" />
<glyph glyph-name="chevron-circle-left" unicode="&#xf137;"
d="M256 -56c-137 0 -248 111 -248 248s111 248 248 248s248 -111 248 -248s-111 -248 -248 -248zM142.1 175l135.5 -135.5c9.40039 -9.40039 24.6006 -9.40039 33.9004 0l17 17c9.40039 9.40039 9.40039 24.5996 0 33.9004l-101.6 101.6l101.6 101.6
c9.40039 9.40039 9.40039 24.6006 0 33.9004l-17 17c-9.40039 9.40039 -24.5996 9.40039 -33.9004 0l-135.5 -135.5c-9.39941 -9.40039 -9.39941 -24.5996 0 -34z" />
@@ -1159,11 +1160,11 @@ c10.9004 -8.7998 22.8008 -17.0996 35.4004 -24.8994c5.7998 -3.5 13.2998 -1.60059
c6.59961 0 12 5.40039 12 12zM0 328c0 13.2998 10.7002 24 24 24h280v-320h-280c-13.2998 0 -24 10.7002 -24 24v272zM58.9004 111.9c-2.60059 -7.80078 3.19922 -15.9004 11.3994 -15.9004h22.9004c5.2998 0 10 3.59961 11.5 8.7002l9.09961 31.7998h60.2002
l9.40039 -31.9004c1.40137 -4.74316 6.55273 -8.59668 11.5 -8.59961h22.8994c8.2998 0 14 8.09961 11.4004 15.9004l-57.5 169.1c-1.7002 4.7998 -6.2998 8.09961 -11.4004 8.09961h-32.5c-5.2002 0 -9.7002 -3.19922 -11.3994 -8.09961z" />
<glyph glyph-name="fax" unicode="&#xf1ac;"
d="M64 320c17.6699 0 32 -14.3301 32 -32v-320c0 -17.6699 -14.3301 -32 -32 -32h-32c-17.6699 0 -32 14.3301 -32 32v320c0 17.6699 14.3301 32 32 32h32zM480 288c17.6699 0 32 -14.3301 32 -32v-288c0 -17.6699 -14.3301 -32 -32 -32h-320c-17.6699 0 -32 14.3301 -32 32
v448c0 17.6699 14.3301 32 32 32h242.74c8.49023 0 16.6299 -3.37012 22.6299 -9.37012l45.2598 -45.25c6 -6.00977 9.37012 -14.1396 9.37012 -22.6299v-82.75zM288 16v32c0 8.83984 -7.16016 16 -16 16h-32c-8.83984 0 -16 -7.16016 -16 -16v-32
c0 -8.83984 7.16016 -16 16 -16h32c8.83984 0 16 7.16016 16 16zM288 144v32c0 8.83984 -7.16016 16 -16 16h-32c-8.83984 0 -16 -7.16016 -16 -16v-32c0 -8.83984 7.16016 -16 16 -16h32c8.83984 0 16 7.16016 16 16zM416 16v32c0 8.83984 -7.16016 16 -16 16h-32
c-8.83984 0 -16 -7.16016 -16 -16v-32c0 -8.83984 7.16016 -16 16 -16h32c8.83984 0 16 7.16016 16 16zM416 144v32c0 8.83984 -7.16016 16 -16 16h-32c-8.83984 0 -16 -7.16016 -16 -16v-32c0 -8.83984 7.16016 -16 16 -16h32c8.83984 0 16 7.16016 16 16zM432 256v96h-32
c-8.83984 0 -16 7.16016 -16 16v32h-208v-144h256z" />
d="M480 288c17.6641 0 32 -14.3359 32 -32v-288c0 -17.6641 -14.3359 -32 -32 -32h-320c-17.6641 0 -32 14.3359 -32 32v448c0 17.6641 14.3359 32 32 32h242.75c7.31348 -0.000976562 17.4473 -4.19922 22.6201 -9.37012l45.25 -45.25
c5.17676 -5.17285 9.37891 -15.3115 9.37988 -22.6299v-82.75zM288 16v32c0 8.83203 -7.16797 16 -16 16h-32c-8.83203 0 -16 -7.16797 -16 -16v-32c0 -8.83203 7.16797 -16 16 -16h32c8.83203 0 16 7.16797 16 16zM288 144v32c0 8.83203 -7.16797 16 -16 16h-32
c-8.83203 0 -16 -7.16797 -16 -16v-32c0 -8.83203 7.16797 -16 16 -16h32c8.83203 0 16 7.16797 16 16zM416 16v32c0 8.83203 -7.16797 16 -16 16h-32c-8.83203 0 -16 -7.16797 -16 -16v-32c0 -8.83203 7.16797 -16 16 -16h32c8.83203 0 16 7.16797 16 16zM416 144v32
c0 8.83203 -7.16797 16 -16 16h-32c-8.83203 0 -16 -7.16797 -16 -16v-32c0 -8.83203 7.16797 -16 16 -16h32c8.83203 0 16 7.16797 16 16zM416 256v64h-48c-8.83203 0 -16 7.16797 -16 16v48h-160v-128h224zM64 320c17.6641 0 32 -14.3359 32 -32v-320
c0 -17.6641 -14.3359 -32 -32 -32h-32c-17.6641 0 -32 14.3359 -32 32v320c0 17.6641 14.3359 32 32 32h32z" />
<glyph glyph-name="building" unicode="&#xf1ad;" horiz-adv-x="448"
d="M436 -32c6.62695 0 12 -5.37305 12 -12v-20h-448v20c0 6.62695 5.37305 12 12 12h20v456c0 13.2549 10.7451 24 24 24h336c13.2549 0 24 -10.7451 24 -24v-456h20zM128 372v-40c0 -6.62695 5.37305 -12 12 -12h40c6.62695 0 12 5.37305 12 12v40
c0 6.62695 -5.37305 12 -12 12h-40c-6.62695 0 -12 -5.37305 -12 -12zM128 276v-40c0 -6.62695 5.37305 -12 12 -12h40c6.62695 0 12 5.37305 12 12v40c0 6.62695 -5.37305 12 -12 12h-40c-6.62695 0 -12 -5.37305 -12 -12zM180 128c6.62695 0 12 5.37305 12 12v40
@@ -1331,8 +1332,8 @@ d="M416 400v-48h-96v48c0 8.83984 7.16016 16 16 16h64c8.83984 0 16 -7.16016 16 -1
c3.45996 129.78 61.4004 150.16 63.9102 244.01zM448.09 288.01c2.50977 -93.8496 60.4502 -114.229 63.9102 -244.01v-44c0 -17.6699 -14.3301 -32 -32 -32h-96c-17.6699 0 -32 14.3301 -32 32v160h-32v160h96.1602c17.6299 0 31.4502 -14.3701 31.9297 -31.9902zM176 416
c8.83984 0 16 -7.16016 16 -16v-48h-96v48c0 8.83984 7.16016 16 16 16h64zM224 160v160h64v-160h-64z" />
<glyph glyph-name="plug" unicode="&#xf1e6;" horiz-adv-x="384"
d="M256 304v112c0 17.6729 14.3271 32 32 32s32 -14.3271 32 -32v-112h-64zM368 288c8.83691 0 16 -7.16309 16 -16v-32c0 -8.83691 -7.16309 -16 -16 -16h-16v-32c0 -77.4062 -54.9688 -141.971 -128 -156.796v-99.2041h-64v99.2041
c-73.0312 14.8252 -128 79.3896 -128 156.796v32h-16c-8.83691 0 -16 7.16309 -16 16v32c0 8.83691 7.16309 16 16 16h352zM128 304h-64v112c0 17.6729 14.3271 32 32 32s32 -14.3271 32 -32v-112z" />
d="M320 416v-96h-64v96c0 17.6641 14.3359 32 32 32s32 -14.3359 32 -32zM368 288c8.83203 0 16 -7.16797 16 -16v-32c0 -8.83203 -7.16797 -16 -16 -16h-16v-32c-0.0107422 -72.1074 -57.3555 -142.354 -128 -156.8v-99.2002h-64v99.2002
c-70.6445 14.4463 -127.989 84.6924 -128 156.8v32h-16c-8.83203 0 -16 7.16797 -16 16v32c0 8.83203 7.16797 16 16 16h352zM128 416v-96h-64v96c0 17.6641 14.3359 32 32 32s32 -14.3359 32 -32z" />
<glyph glyph-name="newspaper" unicode="&#xf1ea;" horiz-adv-x="576"
d="M552 384c13.2549 0 24 -10.7451 24 -24v-312c0 -26.5098 -21.4902 -48 -48 -48h-472c-30.9277 0 -56 25.0723 -56 56v272c0 13.2549 10.7451 24 24 24h40v8c0 13.2549 10.7451 24 24 24h464zM56 48c4.41602 0 8 3.58398 8 8v248h-16v-248c0 -4.41602 3.58398 -8 8 -8z
M292 64c6.62695 0 12 5.37305 12 12v8c0 6.62695 -5.37305 12 -12 12h-152c-6.62695 0 -12 -5.37305 -12 -12v-8c0 -6.62695 5.37305 -12 12 -12h152zM500 64c6.62695 0 12 5.37305 12 12v8c0 6.62695 -5.37305 12 -12 12h-152c-6.62695 0 -12 -5.37305 -12 -12v-8
@@ -1625,10 +1626,12 @@ d="M384 -32v61.4609c0 7.28906 -4.99707 16.3711 -11.1543 20.2734l-111.748 70.8105
c11.7754 0 25.0088 8.82227 29.5371 19.6924l21.4102 51.3848c4.94141 11.8555 -3.77051 24.9229 -16.6143 24.9229h-229.981c-30.9277 0 -56 25.0723 -56 56v16c0 13.2549 10.7451 24 24 24h333.544c14.6035 0 32.7852 -10.0205 40.583 -22.3682l163.04 -258.146
c8.1875 -12.9639 14.833 -35.9297 14.833 -51.2627v-0.000976562v-116.222h-192z" />
<glyph glyph-name="hand-spock" unicode="&#xf259;"
d="M481.3 350.9c21.4004 -5.10059 34.7002 -26.7002 29.7002 -48.2002l-36.2998 -152.5c-1.7002 -7.2002 -2.60059 -14.7002 -2.60059 -22.2002v-42c0 -9.2998 -1.39941 -18.4004 -4 -27.2998l-26.1992 -88.2998c-6 -20.4004 -24.7002 -34.4004 -46 -34.4004h-216.7
c-12.2002 0 -24 4.59961 -32.9004 13l-133.7 125.9c-16.0996 15.0996 -16.7998 40.3994 -1.69922 56.5c15.0996 16.0996 40.3994 16.7998 56.5 1.69922l60.5996 -57v79.4004l-39 171.6c-4.90039 21.6006 8.59961 43 30.0996 47.9004
c21.6006 4.90039 43 -8.59961 47.9004 -30.0996l34.7998 -152.801h9.7998l-47.5996 207c-5 21.5 8.5 43 30 47.9004c21.5996 4.90039 43 -8.5 48 -30.0996l51.7002 -224.9h15.0996l48.4004 193.7c5.39941 21.3994 27.0996 34.5 48.5 29.0996
c21.3994 -5.39941 34.5 -27.0996 29.0996 -48.5l-43.5996 -174.3h11.0996l30.7998 129.3c5.10059 21.4004 26.7002 34.7002 48.2002 29.6006z" />
d="M510.9 302.729l-68.2969 -286.823c-10.502 -44.1084 -55.8252 -79.9062 -101.166 -79.9062h-127.363c-29.7637 0 -71.5107 16.5547 -93.1855 36.9531l-108.298 101.92c-6.92383 6.53418 -12.542 19.5635 -12.542 29.083c0 22.0762 17.916 39.9922 39.9922 39.9922
c8.7334 0 20.9922 -4.84961 27.3623 -10.8252l60.5928 -57.0254v0c0 22.6758 -5.22852 58.7256 -11.6699 80.4668l-42.6885 144.075c-0.90918 3.06934 -1.64746 8.1582 -1.64746 11.3594c0 22.083 17.9229 40.0059 40.0059 40.0059
c16.4922 0 33.6768 -12.833 38.3594 -28.6465l37.1543 -125.395c0.975586 -3.29199 4.55469 -5.96484 7.98828 -5.96484c4.59863 0 8.33105 3.73242 8.33105 8.33105c0 0.582031 -0.117188 1.51172 -0.262695 2.0752l-50.3047 195.641
c-0.696289 2.70703 -1.26172 7.17285 -1.26172 9.96875c0 22.0781 17.918 39.9961 39.9961 39.9961c17.1152 0 34.4678 -13.4521 38.7344 -30.0273l56.0947 -218.158c1.11035 -4.31934 5.63184 -7.82617 10.0918 -7.82617c4.69238 0 9.26562 3.73047 10.208 8.32715
l37.6826 183.704c3.6416 17.6387 21.2139 31.9541 39.2246 31.9541c3.41309 0 8.82422 -0.835938 12.0781 -1.86426c19.8604 -6.2998 30.8623 -27.6738 26.6758 -48.085l-33.8389 -164.967c-0.0849609 -0.414062 -0.154297 -1.09375 -0.154297 -1.51758
c0 -4.16797 3.38281 -7.55176 7.55176 -7.55176c3.29297 0 6.58398 2.59961 7.34668 5.80273l29.3975 123.459c4.03906 16.9619 21.4688 30.7285 38.9053 30.7285c22.0771 0 39.9941 -17.917 39.9941 -39.9941c0 -2.59277 -0.487305 -6.74316 -1.08789 -9.26562z" />
<glyph glyph-name="hand-pointer" unicode="&#xf25a;" horiz-adv-x="448"
d="M448 208v-96c0 -3.08398 -0.356445 -6.15918 -1.06348 -9.16211l-32 -136c-4.25098 -18.0684 -20.375 -30.8379 -38.9365 -30.8379h-208c-11.2432 0 -25.7363 7.37988 -32.3496 16.4727l-127.997 176c-12.9932 17.8662 -9.04297 42.8838 8.82129 55.876
c17.8672 12.9941 42.8848 9.04297 55.877 -8.82227l31.6484 -43.5186v275.992c0 22.0908 17.9082 40 40 40s40 -17.9092 40 -40v-200h8v40c0 22.0908 17.9082 40 40 40s40 -17.9092 40 -40v-40h8v24c0 22.0908 17.9082 40 40 40s40 -17.9092 40 -40v-24h8
@@ -1648,8 +1651,8 @@ d="M285.363 240.525c0 -18.6006 -9.83105 -28.4316 -28.4316 -28.4316h-29.876v56.14
M363.411 87.5859c-46.7295 84.8252 -43.2988 78.6357 -44.7021 80.9805c23.4316 15.1719 37.9453 42.9785 37.9453 74.4854c0 54.2441 -31.5 89.252 -105.498 89.252h-70.667c-13.2549 0 -24 -10.7451 -24 -24v-232.304c0 -13.2549 10.7451 -24 24 -24h22.5664
c13.2549 0 24 10.7451 24 24v71.6631h25.5566l44.1289 -82.9375c3.73828 -7.02441 13.2305 -12.7266 21.1875 -12.7266h24.4639c18.2617 0.000976562 29.8291 19.5908 21.0186 35.5869z" />
<glyph glyph-name="tv" unicode="&#xf26c;" horiz-adv-x="640"
d="M592 448c26.5 0 48 -21.5 48 -48v-320c0 -26.5 -21.5 -48 -48 -48h-234.9v-32h160c17.7002 0 32 -14.2998 32 -32s-14.2998 -32 -32 -32h-384c-17.6992 0 -32 14.2998 -32 32s14.3008 32 32 32h160v32h-245.1c-26.5 0 -48 21.5 -48 48v320c0 26.5 21.5 48 48 48h544z
M576 96v288h-512v-288h512z" />
d="M592 448c26.4961 0 48 -21.5039 48 -48v-320c0 -26.4961 -21.5039 -48 -48 -48h-240v-32h176c8.83203 0 16 -7.16797 16 -16v-32c0 -8.83203 -7.16797 -16 -16 -16h-416c-8.83203 0 -16 7.16797 -16 16v32c0 8.83203 7.16797 16 16 16h176v32h-240
c-26.4961 0 -48 21.5039 -48 48v320c0 26.4961 21.5039 48 48 48h544zM576 96v288h-512v-288h512z" />
<glyph glyph-name="calendar-plus" unicode="&#xf271;" horiz-adv-x="448"
d="M436 288h-424c-6.59961 0 -12 5.40039 -12 12v36c0 26.5 21.5 48 48 48h48v52c0 6.59961 5.40039 12 12 12h40c6.59961 0 12 -5.40039 12 -12v-52h128v52c0 6.59961 5.40039 12 12 12h40c6.59961 0 12 -5.40039 12 -12v-52h48c26.5 0 48 -21.5 48 -48v-36
c0 -6.59961 -5.40039 -12 -12 -12zM12 256h424c6.59961 0 12 -5.40039 12 -12v-260c0 -26.5 -21.5 -48 -48 -48h-352c-26.5 0 -48 21.5 -48 48v260c0 6.59961 5.40039 12 12 12zM328 116c0 6.59961 -5.40039 12 -12 12h-60v60c0 6.59961 -5.40039 12 -12 12h-40
@@ -1844,20 +1847,23 @@ d="M192 64c0 -35.3457 -28.6543 -64 -64 -64s-64 28.6543 -64 64s28.6543 64 64 64s6
c-70.3018 0.488281 -127.448 58.3613 -127.089 128.664c0.164062 32.1982 12.2227 61.5781 31.998 83.9863v203.347c0 53.0186 42.9814 96 96 96s96 -42.9814 96 -96v-203.347zM208 64c0 34.3389 -19.3701 52.1904 -32 66.502v221.498c0 26.4668 -21.5332 48 -48 48
s-48 -21.5332 -48 -48v-221.498c-12.7324 -14.4277 -31.8252 -32.0996 -31.999 -66.0801c-0.223633 -43.876 35.5635 -80.1162 79.4229 -80.4199l0.576172 -0.00195312c44.1123 0 80 35.8877 80 80z" />
<glyph glyph-name="shower" unicode="&#xf2cc;"
d="M389.66 312.4l-158.061 -158.061c-9.36914 -9.37012 -24.5693 -9.37012 -33.9395 0l-11.3203 11.3203c-9.37012 9.37012 -9.37012 24.5703 0 33.9395l0.110352 0.110352c-34.0303 40.21 -35.1602 98.9404 -3.39062 140.38
c-11.9697 7.5498 -26.1396 11.9102 -41.2998 11.9102c-42.8799 0 -77.7598 -34.8799 -77.7598 -77.7598v-306.24h-64v306.24c0 78.1699 63.5898 141.76 141.76 141.76c36.9307 0 70.6104 -14.2002 95.8604 -37.4199c35.8994 11.5098 76.5 4.5 106.67 -21.0303
l0.110352 0.110352c9.36914 9.37012 24.5693 9.37012 33.9395 0l11.3203 -11.3203c9.37012 -9.37012 9.37012 -24.5703 0 -33.9395zM384 240c0 -8.83691 -7.16309 -16 -16 -16s-16 7.16309 -16 16s7.16309 16 16 16s16 -7.16309 16 -16zM416 240c0 8.83691 7.16309 16 16 16
s16 -7.16309 16 -16s-7.16309 -16 -16 -16s-16 7.16309 -16 16zM512 240c0 -8.83691 -7.16309 -16 -16 -16s-16 7.16309 -16 16s7.16309 16 16 16s16 -7.16309 16 -16zM352 208c0 -8.83691 -7.16309 -16 -16 -16s-16 7.16309 -16 16s7.16309 16 16 16s16 -7.16309 16 -16z
M400 224c8.83691 0 16 -7.16309 16 -16s-7.16309 -16 -16 -16s-16 7.16309 -16 16s7.16309 16 16 16zM480 208c0 -8.83691 -7.16309 -16 -16 -16s-16 7.16309 -16 16s7.16309 16 16 16s16 -7.16309 16 -16zM320 176c0 -8.83691 -7.16309 -16 -16 -16s-16 7.16309 -16 16
s7.16309 16 16 16s16 -7.16309 16 -16zM352 176c0 8.83691 7.16309 16 16 16s16 -7.16309 16 -16s-7.16309 -16 -16 -16s-16 7.16309 -16 16zM448 176c0 -8.83691 -7.16309 -16 -16 -16s-16 7.16309 -16 16s7.16309 16 16 16s16 -7.16309 16 -16zM320 144
c0 8.83691 7.16309 16 16 16s16 -7.16309 16 -16s-7.16309 -16 -16 -16s-16 7.16309 -16 16zM416 144c0 -8.83691 -7.16309 -16 -16 -16s-16 7.16309 -16 16s7.16309 16 16 16s16 -7.16309 16 -16zM320 112c0 -8.83691 -7.16309 -16 -16 -16s-16 7.16309 -16 16
s7.16309 16 16 16s16 -7.16309 16 -16zM384 112c0 -8.83691 -7.16309 -16 -16 -16s-16 7.16309 -16 16s7.16309 16 16 16s16 -7.16309 16 -16zM352 80c0 -8.83691 -7.16309 -16 -16 -16s-16 7.16309 -16 16s7.16309 16 16 16s16 -7.16309 16 -16zM320 48
c0 -8.83691 -7.16309 -16 -16 -16s-16 7.16309 -16 16s7.16309 16 16 16s16 -7.16309 16 -16z" />
d="M304 128c8.83203 0 16 -7.16797 16 -16s-7.16797 -16 -16 -16s-16 7.16797 -16 16s7.16797 16 16 16zM336 224c8.83203 0 16 -7.16797 16 -16s-7.16797 -16 -16 -16s-16 7.16797 -16 16s7.16797 16 16 16zM368 160c-8.83203 0 -16 7.16797 -16 16s7.16797 16 16 16
s16 -7.16797 16 -16s-7.16797 -16 -16 -16zM336 128c-8.83203 0 -16 7.16797 -16 16s7.16797 16 16 16s16 -7.16797 16 -16s-7.16797 -16 -16 -16zM304 192c8.83203 0 16 -7.16797 16 -16s-7.16797 -16 -16 -16s-16 7.16797 -16 16s7.16797 16 16 16zM432 224
c-8.83203 0 -16 7.16797 -16 16s7.16797 16 16 16s16 -7.16797 16 -16s-7.16797 -16 -16 -16zM384 208c0 8.83203 7.16797 16 16 16s16 -7.16797 16 -16s-7.16797 -16 -16 -16s-16 7.16797 -16 16zM368 256c8.83203 0 16 -7.16797 16 -16s-7.16797 -16 -16 -16
s-16 7.16797 -16 16s7.16797 16 16 16zM464 224c8.83203 0 16 -7.16797 16 -16s-7.16797 -16 -16 -16s-16 7.16797 -16 16s7.16797 16 16 16zM496 256c8.83203 0 16 -7.16797 16 -16s-7.16797 -16 -16 -16s-16 7.16797 -16 16s7.16797 16 16 16zM432 192
c8.83203 0 16 -7.16797 16 -16s-7.16797 -16 -16 -16s-16 7.16797 -16 16s7.16797 16 16 16zM400 160c8.83203 0 16 -7.16797 16 -16s-7.16797 -16 -16 -16s-16 7.16797 -16 16s7.16797 16 16 16zM336 96c8.83203 0 16 -7.16797 16 -16s-7.16797 -16 -16 -16
s-16 7.16797 -16 16s7.16797 16 16 16zM304 64c8.83203 0 16 -7.16797 16 -16s-7.16797 -16 -16 -16s-16 7.16797 -16 16s7.16797 16 16 16zM368 128c8.83203 0 16 -7.16797 16 -16s-7.16797 -16 -16 -16s-16 7.16797 -16 16s7.16797 16 16 16zM389.65 346.35
c2.58691 -2.58691 4.6875 -7.65527 4.6875 -11.3145s-2.10059 -8.72852 -4.6875 -11.3154l-169.381 -169.37c-2.58691 -2.58691 -7.65527 -4.6875 -11.3145 -4.6875s-8.72852 2.10059 -11.3154 4.6875l-11.2998 11.3105c-2.58496 2.58594 -4.68262 7.65332 -4.68262 11.3096
c0 3.65723 2.09766 8.72363 4.68262 11.3105l5.66016 5.66992c-17.6602 17.9219 -31.9961 52.8887 -32 78.0498c0 19.2402 5.2998 37.0801 13.9297 52.8604l-10 10c-9.44434 9.47461 -27.9678 17.1641 -41.3457 17.1641c-2.10254 0 -5.5 -0.22168 -7.58398 -0.494141
c-30 -3.73047 -51 -31.7803 -51 -61.9307v-305.6c0 -8.83203 -7.16797 -16 -16 -16h-32c-8.83203 0 -16 7.16797 -16 16v303.15c0 67.9395 55.4902 129.35 123.44 128.85c27.7246 -0.138672 66.1006 -16.1992 85.6592 -35.8496l10 -10
c15.8203 8.5498 33.6602 13.8496 52.9004 13.8496c25.1631 -0.000976562 60.1289 -14.3369 78.0498 -32l5.66992 5.66016c2.58691 2.58691 7.65625 4.6875 11.3154 4.6875s8.72754 -2.10059 11.3145 -4.6875z" />
<glyph glyph-name="bath" unicode="&#xf2cd;"
d="M488 192c13.2549 0 24 -10.7451 24 -24v-16c0 -13.2549 -10.7451 -24 -24 -24h-8v-32c0 -28.4297 -12.3623 -53.9688 -32 -71.5469v-32.4531c0 -13.2549 -10.7451 -24 -24 -24h-16c-13.2549 0 -24 10.7451 -24 24v8h-256v-8c0 -13.2549 -10.7451 -24 -24 -24h-16
c-13.2549 0 -24 10.7451 -24 24v32.4531c-19.6377 17.5781 -32 43.1172 -32 71.5469v32h-8c-13.2549 0 -24 10.7451 -24 24v16c0 13.2549 10.7451 24 24 24h8v144c0 44.1123 35.8877 80 80 80c27.2119 0 51.2812 -13.667 65.7393 -34.4873
c21.8838 6.06445 46.2285 1.10449 64.1777 -15.3643c4.71289 4.1748 11.916 4.02051 16.4277 -0.491211l11.3145 -11.3145c4.68555 -4.68652 4.68555 -12.2852 0 -16.9707l-95.0303 -95.0293c-4.68652 -4.68555 -12.2852 -4.68555 -16.9707 0l-11.3145 11.3145
c-4.51172 4.51172 -4.66699 11.7148 -0.491211 16.4277c-21.5244 23.459 -23.3291 57.8281 -6.83789 83.0352c-5.68262 8.93457 -15.6641 14.8799 -27.0146 14.8799c-17.6445 0 -32 -14.3555 -32 -32v-144h408z" />
d="M32 64v48h448v-48c-0.0478516 -23.5742 -14.3848 -55.4229 -32 -71.0898v-40.9102c0 -8.83203 -7.16797 -16 -16 -16h-32c-8.83203 0 -16 7.16797 -16 16v16h-256v-16c0 -8.83203 -7.16797 -16 -16 -16h-32c-8.83203 0 -16 7.16797 -16 16v40.9102
c-17.6152 15.667 -31.9521 47.5156 -32 71.0898zM496 192c8.83203 0 16 -7.16797 16 -16v-16c0 -8.83203 -7.16797 -16 -16 -16h-480c-8.83203 0 -16 7.16797 -16 16v16c0 8.83203 7.16797 16 16 16h16v186.75v0.00585938c0 38.2256 31.0244 69.25 69.25 69.25
c15.835 0 37.7734 -9.08789 48.9697 -20.2861l19.2607 -19.2695c29.8994 13.1299 59.1094 7.60938 79.7295 -8.62012l0.169922 0.169922c2.58691 2.58496 7.65332 4.68262 11.3105 4.68262c3.65625 0 8.72266 -2.09766 11.3096 -4.68262l11.3096 -11.3096
c2.58789 -2.58691 4.68848 -7.65625 4.68848 -11.3154s-2.10059 -8.72852 -4.68848 -11.3154l-105.369 -105.369c-2.58691 -2.58789 -7.65625 -4.68848 -11.3154 -4.68848s-8.72852 2.10059 -11.3154 4.68848l-11.3096 11.3096
c-2.57617 2.58496 -4.66797 7.64551 -4.66797 11.2949s2.0918 8.70996 4.66797 11.2949l0.169922 0.169922c-16.2295 20.6201 -21.75 49.8506 -8.62012 79.7305l-19.2695 19.2598c-3.43652 3.42969 -10.165 6.21387 -15.0205 6.21387
c-11.71 0 -21.2344 -9.50391 -21.2598 -21.2139v-186.75h416z" />
<glyph glyph-name="podcast" unicode="&#xf2ce;" horiz-adv-x="448"
d="M267.429 -40.5635c-5.14258 -19.0098 -24.5703 -23.4365 -43.4287 -23.4365c-18.8574 0 -38.2861 4.42676 -43.4277 23.4365c-7.64551 28.4297 -20.5723 99.665 -20.5723 132.813c0 35.1562 31.1416 43.75 64 43.75s64 -8.59375 64 -43.75
c0 -32.9492 -12.8711 -104.179 -20.5713 -132.813zM156.867 159.446c2.6748 -2.61914 2.39941 -6.98535 -0.628906 -9.18555c-9.3125 -6.76465 -16.4609 -15.3418 -21.2354 -25.3623c-1.74219 -3.65723 -6.5 -4.6582 -9.45312 -1.8877
@@ -1987,10 +1993,10 @@ v-70.9004h-116c-6.59961 0 -12 -5.40039 -12 -12v-64c0 -6.59961 5.40039 -12 12 -12
<glyph glyph-name="arrow-alt-circle-up" unicode="&#xf35b;"
d="M8 192c0 137 111 248 248 248s248 -111 248 -248s-111 -248 -248 -248s-248 111 -248 248zM300 76v116h70.9004c10.6992 0 16.0996 13 8.5 20.5l-114.9 114.3c-4.7002 4.7002 -12.2002 4.7002 -16.9004 0l-115 -114.3c-7.59961 -7.59961 -2.19922 -20.5 8.5 -20.5
h70.9004v-116c0 -6.59961 5.40039 -12 12 -12h64c6.59961 0 12 5.40039 12 12z" />
<glyph glyph-name="external-link-alt" unicode="&#xf35d;" horiz-adv-x="576"
d="M576 424v-127.984c0 -21.4609 -25.96 -31.9795 -40.9707 -16.9707l-35.707 35.709l-243.523 -243.522c-9.37305 -9.37305 -24.5674 -9.37305 -33.9404 0l-22.627 22.627c-9.37305 9.37305 -9.37305 24.5684 0 33.9404l243.524 243.525l-35.7031 35.7051
c-15.0703 15.0703 -4.39648 40.9707 16.9717 40.9707h127.976c13.2549 0 24 -10.7451 24 -24zM407.029 177.206c15.1191 15.1201 40.9707 4.41211 40.9707 -16.9697v-176.236c0 -26.5098 -21.4902 -48 -48 -48h-352c-26.5098 0 -48 21.4902 -48 48v352
c0 26.5098 21.4902 48 48 48h296c21.3809 0 32.0889 -25.8506 16.9697 -40.9707l-16 -16c-3.87988 -3.87988 -11.4824 -7.0293 -16.9697 -7.0293h-264v-320h320v144.235v0.000976562c0 5.4873 3.14941 13.0898 7.0293 16.9697z" />
<glyph glyph-name="external-link-alt" unicode="&#xf35d;"
d="M432 128c8.83203 0 16 -7.16797 16 -16v-128c0 -26.4961 -21.5039 -48 -48 -48h-352c-26.4961 0 -48 21.5039 -48 48v352c0 26.4961 21.5039 48 48 48h160c8.83203 0 16 -7.16797 16 -16v-32c0 -8.83203 -7.16797 -16 -16 -16h-144v-320h320v112
c0 8.83203 7.16797 16 16 16h32zM488 448c13.248 0 24 -10.752 24 -24v-128c0 -21.5 -26 -32 -41 -17l-35.7197 35.6797l-243.61 -243.68c-3.88281 -3.89648 -11.499 -7.05859 -17 -7.05859s-13.1172 3.16211 -17 7.05859l-22.6699 22.6299
c-3.89648 3.88281 -7.05859 11.499 -7.05859 17s3.16211 13.1172 7.05859 17l243.73 243.64l-35.7305 35.7305c-15.0498 15.0898 -4.37012 41 17 41h128z" />
<glyph glyph-name="external-link-square-alt" unicode="&#xf360;" horiz-adv-x="448"
d="M448 368v-352c0 -26.5098 -21.4902 -48 -48 -48h-352c-26.5098 0 -48 21.4902 -48 48v352c0 26.5098 21.4902 48 48 48h352c26.5098 0 48 -21.4902 48 -48zM360 352h-111.971c-21.3135 0 -32.0801 -25.8613 -16.9717 -40.9707l31.9844 -31.9873l-195.527 -195.527
c-4.68555 -4.68555 -4.68555 -12.2832 0 -16.9707l31.0293 -31.0293c4.6875 -4.68555 12.2852 -4.68555 16.9707 0l195.526 195.526l31.9883 -31.9912c15.0283 -15.0264 40.9707 -4.47461 40.9707 16.9717v111.979c0 13.2549 -10.7451 24 -24 24z" />
@@ -2068,6 +2074,14 @@ c22.3008 -10.2002 46.9004 -16 72.9004 -16s50.7002 5.7998 72.9004 16h55.0996z" />
d="M464 416c26.5 0 48 -21.5 48 -48v-352c0 -26.5 -21.5 -48 -48 -48h-416c-26.5 0 -48 21.5 -48 48v352c0 26.5 21.5 48 48 48h416zM380.4 125.5l-67.1006 66.5l67.1006 66.5c4.7998 4.7998 4.7998 12.5996 0 17.4004l-40.5 40.5
c-4.80078 4.7998 -12.6006 4.7998 -17.4004 0l-66.5 -67.1006l-66.5 67.1006c-4.7998 4.7998 -12.5996 4.7998 -17.4004 0l-40.5 -40.5c-4.7998 -4.80078 -4.7998 -12.6006 0 -17.4004l67.1006 -66.5l-67.1006 -66.5c-4.7998 -4.7998 -4.7998 -12.5996 0 -17.4004
l40.5 -40.5c4.80078 -4.7998 12.6006 -4.7998 17.4004 0l66.5 67.1006l66.5 -67.1006c4.7998 -4.7998 12.5996 -4.7998 17.4004 0l40.5 40.5c4.7998 4.80078 4.7998 12.6006 0 17.4004z" />
<glyph glyph-name="compress-alt" unicode="&#xf422;" horiz-adv-x="448"
d="M4.68555 20.6855l99.3145 99.3145l-32.9219 31.0293c-15.1201 15.1201 -4.41211 40.9707 16.9697 40.9707h112c13.2549 0 23.9521 -10.7451 23.9521 -24v-112c0 -21.3818 -25.8027 -32.0898 -40.9219 -16.9707l-31.0781 32.9707l-99.3145 -99.3145
c-6.24707 -6.24707 -16.3789 -6.24707 -22.627 0l-25.373 25.373c-6.24707 6.24805 -6.24707 16.3799 0 22.627zM443.314 363.314l-99.3145 -99.3145l32.9219 -31.0293c15.1201 -15.1201 4.41211 -40.9707 -16.9697 -40.9707h-112c-13.2549 0 -23.9521 10.7451 -23.9521 24
v112c0 21.3818 25.8027 32.0898 40.9219 16.9707l31.0781 -32.9707l99.3145 99.3145c6.24707 6.24707 16.3789 6.24707 22.627 0l25.373 -25.373c6.24707 -6.24805 6.24707 -16.3799 0 -22.627z" />
<glyph glyph-name="expand-alt" unicode="&#xf424;" horiz-adv-x="448"
d="M212.686 132.686l-92.6855 -92.6855l32.9219 -31.0293c15.1201 -15.1201 4.41211 -40.9707 -16.9697 -40.9707h-112c-13.2549 0 -23.9521 10.7451 -23.9521 24v112c0 21.3818 25.8027 32.0898 40.9219 16.9707l31.0781 -32.9707l92.6855 92.6855
c6.24805 6.24805 16.3799 6.24805 22.6279 0l25.3721 -25.3721c6.24902 -6.24805 6.24902 -16.3789 0 -22.6279zM235.314 251.314l92.6855 92.6855l-32.9219 31.0293c-15.1201 15.1201 -4.41211 40.9707 16.9697 40.9707h112c13.2549 0 23.9521 -10.7451 23.9521 -24v-112
c0 -21.3818 -25.8027 -32.0898 -40.9219 -16.9707l-31.0781 32.9707l-92.6855 -92.6855c-6.24805 -6.24805 -16.3799 -6.24805 -22.6279 0l-25.3721 25.3721c-6.24902 6.24805 -6.24902 16.3789 0 22.6279z" />
<glyph glyph-name="baseball-ball" unicode="&#xf433;" horiz-adv-x="496"
d="M368.5 84.0996c12.9004 -26.6992 30.2998 -50.1992 51.4004 -70.5996c-44.6006 -43 -105.101 -69.5 -171.9 -69.5c-66.9004 0 -127.5 26.5996 -172 69.7002c21.2002 20.3994 38.5996 44 51.5 70.7002l-28.7998 13.8994c-11.1006 -23 -26.1006 -43.2998 -44.2998 -61
c-34 42.4004 -54.4004 96.1006 -54.4004 154.7s20.4004 112.3 54.4004 154.8c17.7998 -17.2998 32.5 -37.0996 43.5 -59.3994l28.6992 14.0996c-12.7998 25.9004 -30 48.9004 -50.6992 68.7998c44.5996 43.1006 105.199 69.7002 172.1 69.7002
@@ -2354,13 +2368,15 @@ d="M275.3 197.5l-108.899 114.2c-31.6006 33.2002 -29.7002 88.2002 5.59961 118.8c3
l-108.9 -114.2c-7.09961 -7.40039 -18.5 -7.40039 -25.5 0zM565.3 119.9c15.1006 -13.6006 13.9004 -36.8008 -1.2998 -48.9004l-151.2 -121c-11.3994 -9.09961 -25.5 -14 -40 -14h-356.8c-8.7998 0 -16 7.2002 -16 16v96c0 8.7998 7.2002 16 16 16h55.4004l46.5 37.7002
c21 17 47.0996 26.2998 74.0996 26.2998h160c19.5 0 34.9004 -17.4004 31.5996 -37.4004c-2.59961 -15.6992 -17.3994 -26.5996 -33.2998 -26.5996h-78.2998c-8.7998 0 -16 -7.2002 -16 -16s7.2002 -16 16 -16h118.3c14.6006 0 28.7002 4.90039 40 14l92.4004 73.9004
c12.3994 10 30.7998 10.6992 42.5996 0z" />
<glyph glyph-name="hand-holding-usd" unicode="&#xf4c0;" horiz-adv-x="544"
d="M257.6 303.7c-22.1992 6.39941 -40 24.7002 -42.8994 47.7002c-4 32 19 59.3994 49.2998 63v17.5996c0 8.7998 7.2002 16 16 16h16c8.7998 0 16 -7.2002 16 -16v-17.7002c11.5 -1.39941 22.2998 -5.2002 31.7998 -11.5c6.2002 -4.09961 6.7998 -13.0996 1.5 -18.3994
l-17.5 -17.5c-3.7002 -3.7002 -9.2998 -4.2002 -14.0996 -2c-3.2002 1.39941 -6.7002 2.19922 -10.2998 2.19922h-32.8008c-4.59961 0 -8.39941 -3.7998 -8.39941 -8.39941c0 -3.7002 2.5 -7.10059 6.09961 -8.10059l50 -14.2998
c22.2002 -6.39941 40 -24.7002 42.9004 -47.7002c4 -32 -19 -59.3994 -49.2998 -63v-17.5996c0 -8.7998 -7.2002 -16 -16 -16h-16c-8.80078 0 -16 7.2002 -16 16v17.7002c-11.5 1.39941 -22.3008 5.2002 -31.8008 11.5c-6.19922 4.09961 -6.7998 13.0996 -1.5 18.3994
l17.5 17.5c3.7002 3.7002 9.30078 4.2002 14.1006 2c3.2002 -1.39941 6.7002 -2.19922 10.2998 -2.19922h32.7998c4.60059 0 8.40039 3.7998 8.40039 8.39941c0 3.7002 -2.5 7.10059 -6.10059 8.10059zM533.9 119.9c14.1992 -13.6006 13.0996 -36.8008 -1.30078 -48.9004
l-142.8 -121c-10.7998 -9.09961 -24.0996 -14 -37.7998 -14h-336.9c-8.2998 0 -15.0996 7.2002 -15.0996 16v96c0 8.7998 6.7998 16 15.0996 16h52.4004l43.9004 37.7002c19.6992 17 44.3994 26.2998 69.8994 26.2998h151.101c18.2998 0 32.8994 -17.4004 29.7998 -37.4004
c-2.40039 -15.6992 -16.2998 -26.5996 -31.4004 -26.5996h-73.8994c-8.30078 0 -15.1006 -7.2002 -15.1006 -16s6.7998 -16 15.1006 -16h111.699c13.8008 0 27.1006 4.90039 37.8008 14l87.1992 73.9004c11.8008 10 29.1006 10.6992 40.3008 0z" />
<glyph glyph-name="hand-holding-usd" unicode="&#xf4c0;" horiz-adv-x="576"
d="M271.06 303.7c-24.0596 6.39941 -43.4297 24.7002 -46.5693 47.7002c-4.33984 32 20.6201 59.3994 53.5098 63v17.5996c0 8.7998 7.82031 16 17.3701 16h17.3701c9.5498 0 17.3701 -7.2002 17.3701 -16v-17.7197c10.2324 -1.05566 25.6982 -6.20801 34.5195 -11.5
c3.05469 -1.83984 5.53418 -6.22656 5.53418 -9.79199c0 -1.78516 -0.758789 -4.46777 -1.69434 -5.98828c-0.490234 -0.808594 -1.46191 -1.97266 -2.16992 -2.59961l-19 -17.5c-4.01953 -3.7002 -10.0693 -4.2002 -15.2998 -2
c-2.98145 1.20898 -8.0127 2.19434 -11.2305 2.19922h-35.5996c-5.03027 0 -9.12012 -3.7998 -9.12012 -8.39941c0.112305 -3.6416 3.08301 -7.27051 6.62988 -8.10059l54.2705 -14.2998c24.0996 -6.39941 43.4102 -24.7002 46.5596 -47.7002
c4.33984 -32 -20.5693 -59.3994 -53.5 -63v-17.5996c0 -8.7998 -7.83008 -16 -17.3799 -16h-17.3701c-9.54004 0 -17.3701 7.2002 -17.3701 16v17.7002c-10.2305 1.05566 -25.6904 6.20703 -34.5098 11.5c-3.06348 1.83594 -5.54883 6.22363 -5.54883 9.79492
c0 1.77051 0.74707 4.43359 1.66895 5.94531c0.510742 0.827148 1.51855 2.01953 2.25 2.65918l19 17.5c4.01953 3.7002 10.0596 4.2002 15.2998 2c2.9707 -1.20508 7.98438 -2.19043 11.1904 -2.19922h35.5996c5.03027 0 9.12012 3.7998 9.12012 8.39941
c-0.112305 3.6416 -3.08203 7.27051 -6.62988 8.10059zM565.27 119.9c5.92383 -5.26953 10.7432 -15.9814 10.7432 -23.9102c0 -8.49121 -5.38184 -19.6865 -12.0127 -24.9902l-151.23 -121c-9.67188 -7.72754 -27.5693 -14 -39.9492 -14h-0.0507812h-356.77
c-8.83203 0 -16 7.16797 -16 16v96c0 8.83203 7.16797 16 16 16h55.4004l46.5 37.71c17.8789 14.5059 51.0762 26.2842 74.0996 26.29h160v0c17.6309 0 31.9668 -14.3096 32 -31.9404v-0.120117c0 -1.48438 -0.206055 -3.87695 -0.459961 -5.33984
c-2.54004 -15.6992 -17.3496 -26.5996 -33.25 -26.5996h-78.29c-8.83203 0 -16 -7.16797 -16 -16s7.16797 -16 16 -16h118.27h0.176758c12.3496 0 30.1904 6.27148 39.8232 14l92.4004 73.9004c12.4004 10 30.7998 10.6992 42.5996 0z" />
<glyph glyph-name="hands" unicode="&#xf4c2;" horiz-adv-x="640"
d="M204.8 217.6l57.6006 -76.7998c16.5996 -22.2002 25.5996 -49.0996 25.5996 -76.7998v-112c0 -8.7998 -7.2002 -16 -16 -16h-131.7c-7.2002 0 -13.5 4.7002 -15.2998 11.5996c-2 7.80078 -5.40039 15.2002 -10.4004 21.7002l-104.1 134.3
c-6.7998 8.5 -10.5 19.1006 -10.5 30v218.4c0 17.7002 14.2998 32 32 32s32 -14.2998 32 -32v-148.4l89.7998 -107.8c6 -7.2998 16.9004 -7.7998 23.6006 -1.09961l12.7998 12.7998c5.59961 5.59961 6.2998 14.5 1.5 20.9004l-38.1006 50.7998
@@ -2720,9 +2736,11 @@ l38.4004 -44.7998l54.4004 44.7998c2.35059 1.78027 6.65137 3.22559 9.59961 3.2255
M320 88v16c0 4.40039 -3.59961 8 -8 8h-240c-4.40039 0 -8 -3.59961 -8 -8v-16c0 -4.40039 3.59961 -8 8 -8h240c4.40039 0 8 3.59961 8 8zM320 184v16c0 4.40039 -3.59961 8 -8 8h-240c-4.40039 0 -8 -3.59961 -8 -8v-16c0 -4.40039 3.59961 -8 8 -8h240
c4.40039 0 8 3.59961 8 8zM320 280v16c0 4.40039 -3.59961 8 -8 8h-240c-4.40039 0 -8 -3.59961 -8 -8v-16c0 -4.40039 3.59961 -8 8 -8h240c4.40039 0 8 3.59961 8 8z" />
<glyph glyph-name="robot" unicode="&#xf544;" horiz-adv-x="640"
d="M0 192c0 17.7002 14.2998 32 32 32h32v-192h-32c-17.7002 0 -32 14.2998 -32 32v128zM464 352c44.2002 0 80 -35.7998 80 -80v-272c0 -35.2998 -28.7002 -64 -64 -64h-320c-35.2998 0 -64 28.7002 -64 64v272c0 44.2002 35.7998 80 80 80h112v64
c0 17.7002 14.2998 32 32 32s32 -14.2998 32 -32v-64h112zM256 32v32h-64v-32h64zM224 152c22.0996 0 40 17.9004 40 40s-17.9004 40 -40 40s-40 -17.9004 -40 -40s17.9004 -40 40 -40zM352 32v32h-64v-32h64zM448 32v32h-64v-32h64zM416 152c22.0996 0 40 17.9004 40 40
s-17.9004 40 -40 40s-40 -17.9004 -40 -40s17.9004 -40 40 -40zM608 224c17.7002 0 32 -14.2998 32 -32v-128c0 -17.7002 -14.2998 -32 -32 -32h-32v192h32z" />
d="M32 224h32v-192h-32h-0.0380859c-17.6436 0 -31.9619 14.3184 -31.9619 31.9619v0.0380859v128v0.0380859c0 17.6436 14.3184 31.9619 31.9619 31.9619h0.0380859zM544 272v-272c-0.0351562 -35.293 -28.707 -63.9648 -64 -64h-320
c-35.293 0.0351562 -63.9648 28.707 -64 64v272v0.0263672c0 44.1455 35.8281 79.9736 79.9736 79.9736h0.0263672h112v64c0 17.6641 14.3359 32 32 32s32 -14.3359 32 -32v-64h112h0.0263672c44.1455 0 79.9736 -35.8281 79.9736 -79.9736v-0.0263672zM264 192
c0 22.0801 -17.9199 40 -40 40s-40 -17.9199 -40 -40s17.9199 -40 40 -40h0.00292969c22.0781 0 39.9971 17.9189 39.9971 39.9971v0.00292969zM256 64h-64v-32h64v32zM352 64h-64v-32h64v32zM456 192c0 22.0801 -17.9199 40 -40 40s-40 -17.9199 -40 -40
s17.9199 -40 40 -40h0.00292969c22.0781 0 39.9971 17.9189 39.9971 39.9971v0.00292969zM448 64h-64v-32h64v32zM640 192v-128v-0.0380859c0 -17.6436 -14.3184 -31.9619 -31.9619 -31.9619h-0.0380859h-32v192h32h0.0380859c17.6436 0 31.9619 -14.3184 31.9619 -31.9619
v-0.0380859z" />
<glyph glyph-name="ruler" unicode="&#xf545;" horiz-adv-x="640"
d="M635.7 280.8c8.7998 -15 3.59961 -34.2002 -11.6006 -42.7998l-496.8 -281.9c-15.2002 -8.59961 -34.7002 -3.5 -43.5 11.5l-79.5996 135.601c-8.7998 15 -3.5 34.0996 11.7002 42.7998l69 39.0996l59.6992 -101.399c2.2002 -3.7998 7.10059 -5.10059 10.9004 -2.90039
l13.7998 7.7998c3.7998 2.2002 5.10059 7 2.90039 10.7002l-59.7002 101.7l55.2002 31.2998l27.8994 -47.5c2.2002 -3.7998 7.10059 -5.09961 10.9004 -2.89941l13.7998 7.7998c3.7998 2.2002 5.10059 6.89941 2.90039 10.7002l-27.9004 47.3994l55.2002 31.2998
@@ -2912,11 +2930,12 @@ c-4.99023 7.56934 -2.20996 17.9297 5.64062 22.4697l27.75 16.0703c7.40918 4.29004
s96 -42.9805 96 -96c0 -16.6299 -4.61035 -32.0303 -12.0596 -45.6602l51.79 -89.71c-23.0508 -23.1699 -51.3809 -39.96 -82.6104 -48.9199l-51.0898 88.5c-0.69043 -0.0195312 -1.33984 -0.209961 -2.04004 -0.209961s-1.33984 0.19043 -2.04004 0.209961
l-67.3604 -116.68c22.1797 -7.28027 45.4805 -11.5303 69.4102 -11.5303c76.25 0 147.01 38.8496 188.12 102.38c4.64941 7.17969 13.7803 9.87012 21.2598 5.71973l28.0703 -15.5693c7.93945 -4.40039 10.9102 -14.7207 6.0498 -22.3906zM256 384
c-17.6699 0 -32 -14.3301 -32 -32s14.3301 -32 32 -32s32 14.3301 32 32s-14.3301 32 -32 32z" />
<glyph glyph-name="drum" unicode="&#xf569;" horiz-adv-x="576"
d="M458.08 327.12c71.3799 -23.29 117.91 -60.75 117.92 -103.13v-160.83c0 -30.46 -24.0303 -58.4004 -64 -80.3701v96.3701c0 17.5996 -14.4004 32 -32 32s-32 -14.4004 -32 -32v-122.41c-37.4004 -11.1299 -81 -18.4404 -128 -20.75v111.16c0 17.5996 -14.4004 32 -32 32
s-32 -14.4004 -32 -32v-111.15c-47 2.31055 -90.5996 9.62012 -128 20.75v122.41c0 17.5996 -14.4004 32 -32 32s-32 -14.4004 -32 -32v-96.3701c-39.9697 21.9697 -64 49.9102 -64 80.3701v160.83c0 70.6904 128.94 128 288 128
c21.8467 -0.00585938 57.167 -2.2373 78.8398 -4.98047l160.69 96.4102c15.1699 9.10059 34.8096 4.18066 43.9102 -10.9697c9.08984 -15.1602 4.18945 -34.8203 -10.9707 -43.9102zM288 144c132.54 0 240 35.8096 240 79.9902c0 30.2695 -50.4502 56.5996 -124.82 70.1895
l-162.71 -97.6201c-14.3994 -8.63965 -34.3496 -4.95996 -43.9102 10.9707c-9.08984 15.1602 -4.18945 34.8193 10.9707 43.9102l87.4102 52.4395c-2.32031 0.0205078 -4.60059 0.120117 -6.94043 0.120117c-132.55 0 -240 -35.8203 -240 -80s107.45 -80 240 -80z" />
<glyph glyph-name="drum" unicode="&#xf569;"
d="M431.34 325.95c44.9004 -16.3398 80.6602 -42.7803 80.6602 -86.1006v-160.229c0 -30.2705 -27.5 -57.6797 -72 -77.8604v101.9c0 13.248 -10.752 24 -24 24s-24 -10.752 -24 -24v-118.93c-33.0498 -9.11035 -71.0703 -15.0605 -112 -16.7305v103.61
c0 13.248 -10.752 24 -24 24s-24 -10.752 -24 -24v-103.61c-40.9297 1.66992 -78.9502 7.62012 -112 16.7305v118.93c0 13.248 -10.752 24 -24 24s-24 -10.752 -24 -24v-101.9c-44.5 20.1807 -72 47.5898 -72 77.8604v160.229c0 107.601 219.55 112.15 256 112.15
c15.2197 0 62.4297 -0.910156 112.19 -9.69043l110.06 71c2.22461 1.4834 6.20117 2.6875 8.875 2.6875c4.72852 0 10.6934 -3.19238 13.3154 -7.12695l8.86914 -13.3105c1.4834 -2.22461 2.6875 -6.20117 2.6875 -8.875c0 -4.72754 -3.19238 -10.6924 -7.12695 -13.3145z
M256 175.76c114.87 0 208 28.6904 208 64.0898c0 21.3105 -33.9102 40.1504 -85.8604 51.75l-118.64 -76.5195c-2.22461 -1.4834 -6.20117 -2.6875 -8.875 -2.6875c-4.72852 0 -10.6934 3.19336 -13.3154 7.12695l-8.86914 13.3105
c-1.48535 2.22559 -2.69043 6.2041 -2.69043 8.87988c0 4.72461 3.18945 10.6875 7.12012 13.3096l72.8096 47c-15.9492 1.2002 -32.5293 1.91016 -49.6797 1.91016c-114.88 0 -208 -28.6797 -208 -64.0801c0 -35.3994 93.1201 -64.0898 208 -64.0898z" />
<glyph glyph-name="drum-steelpan" unicode="&#xf56a;" horiz-adv-x="576"
d="M288 416c159.06 0 288 -57.3096 288 -128v-192c0 -70.6904 -128.94 -128 -288 -128s-288 57.3096 -288 128v192c0 70.6904 128.94 128 288 128zM205.01 257.64c5.11035 19.0605 2.49023 38.96 -7.37012 56.0508l-25.5996 44.3398
c-73.9297 -13.6406 -124.04 -39.8701 -124.04 -70.0303c0 -30.7803 52.2305 -57.46 128.7 -70.8398c13.7695 9.91016 23.8594 23.8701 28.3096 40.4795zM288 208c21.0801 0 41.4102 1 60.8896 2.7002c-8.05957 26.1299 -32.1494 45.2998 -60.8896 45.2998
@@ -3341,11 +3360,10 @@ c-4.41992 0 -8 -3.58008 -8 -8v-16c0 -4.41992 3.58008 -8 8 -8h240c4.41992 0 8 3.5
<glyph glyph-name="surprise" unicode="&#xf5c2;" horiz-adv-x="496"
d="M248 440c137 0 248 -111 248 -248s-111 -248 -248 -248s-248 111 -248 248s111 248 248 248zM136 240c0 -17.7002 14.2998 -32 32 -32s32 14.2998 32 32s-14.2998 32 -32 32s-32 -14.2998 -32 -32zM248 32c35.2998 0 64 28.7002 64 64s-28.7002 64 -64 64
s-64 -28.7002 -64 -64s28.7002 -64 64 -64zM328 208c17.7002 0 32 14.2998 32 32s-14.2998 32 -32 32s-32 -14.2998 -32 -32s14.2998 -32 32 -32z" />
<glyph glyph-name="swatchbook" unicode="&#xf5c3;" horiz-adv-x="511"
d="M479.06 128c17.6406 0 31.9404 -14.3301 31.9404 -32v-128c0 -17.6699 -14.2998 -32 -31.9404 -32h-299.579c2.17969 1.91016 4.60938 3.41992 6.66992 5.49023l186.14 186.51h106.77zM434.56 280.9c12.4707 -12.4902 12.4707 -32.7607 0 -45.2607l-211.869 -212.279
c0.199219 2.90918 0.869141 5.67969 0.869141 8.63965v263.76l75.5 75.6504c12.4805 12.5 32.7002 12.5 45.1709 0zM191.62 416v-384c0 -53.0195 -42.9004 -96 -95.8105 -96c-52.9092 0 -95.8096 42.9805 -95.8096 96v384c0 17.6699 14.2998 32 31.9404 32h127.739
c17.6406 0 31.9404 -14.3301 31.9404 -32zM95.8096 8c13.2305 0 23.96 10.75 23.9502 24c0 13.2598 -10.7295 24 -23.9502 24c-13.2197 0 -23.9492 -10.7402 -23.9492 -24c0 -13.25 10.7197 -24 23.9492 -24zM127.75 192l0.00976562 64h-63.8799v-64h63.8701zM127.75 320
l0.00976562 64h-63.8799v-64h63.8701z" />
<glyph glyph-name="swatchbook" unicode="&#xf5c3;"
d="M434.66 280.29c5.15527 -5.1709 9.33984 -15.293 9.33984 -22.5947s-4.18457 -17.4248 -9.33984 -22.5957l-210.66 -211.1v271.12l75.4297 75.5195l0.0703125 0.0703125v0c5.14258 5.12305 15.2061 9.28027 22.4648 9.28027c7.29102 0 17.3867 -4.18848 22.5352 -9.35059
l90.1602 -90.3496v0zM480 128c17.6641 0 32 -14.3359 32 -32v-128c0 -17.6641 -14.3359 -32 -32 -32h-300c2.17969 1.91016 4.62012 3.41992 6.67969 5.49023l186.41 186.51h106.91zM192 416v-384c0 -52.9922 -43.0078 -96 -96 -96s-96 43.0078 -96 96v384
c0 17.6641 14.3359 32 32 32h128c17.6641 0 32 -14.3359 32 -32zM96 8c13.248 0 24 10.752 24 24s-10.752 24 -24 24s-24 -10.752 -24 -24s10.752 -24 24 -24zM128 192v64h-64v-64h64zM128 320v64h-64v-64h64z" />
<glyph glyph-name="swimmer" unicode="&#xf5c4;" horiz-adv-x="640"
d="M189.61 137.42c-5.04004 4.65039 -10.3906 8.34961 -15.8604 11.5801l68.6299 98.04c7.36035 10.5 16.3398 19.5498 26.7197 26.9404l80.0205 57.1699c25.54 18.2598 57.8301 24.96 88.5596 18.3799l100.351 -21.5303c25.9297 -5.55957 42.4297 -31.0801 36.8799 -57
c-5.56055 -25.9102 -31.0898 -42.4102 -57 -36.8799l-100.351 21.5303c-4.33984 0.90918 -8.97949 -0.0302734 -12.6191 -2.61035l-18 -12.8604l112.84 -80.5996c-17.5107 -1.04004 -34.5303 -8.4502 -49.3906 -22.1602
@@ -3405,16 +3423,15 @@ c-5.32031 28.6699 -5.66992 57.3301 -1 86c5.32031 31.3301 15.3096 57.3301 29.96 7
c16.6494 9.33008 36.96 17.3301 60.9297 24c27.9795 7.33008 49.96 9.66992 65.9395 7zM295.91 360c-9.32031 -8.66992 -21.6504 -15 -36.96 -19c-10.6602 -3.33008 -22.2998 -5 -34.96 -5l-14.9805 1c-1.33008 9.33008 -1.33008 20 0 32
c2.66992 24 10.3203 42.3301 22.9707 55c9.31934 8.66992 21.6494 15 36.96 19c10.6592 3.33008 22.2998 5 34.96 5l14.9795 -1l1 -15c0 -12.6699 -1.66992 -24.3301 -4.99023 -35c-3.98926 -15.3301 -10.3096 -27.6699 -18.9795 -37z" />
<glyph glyph-name="atom" unicode="&#xf5d2;" horiz-adv-x="448"
d="M413.03 192c40.1396 -54.9102 41.5195 -98.5996 25.1396 -128c-29.2197 -52.3398 -101.689 -43.5801 -116.33 -41.8799c-21.4697 -51.2197 -54.2002 -86.1201 -97.8398 -86.1201s-76.3701 34.9004 -97.8398 86.1201c-14.6504 -1.7002 -87.1201 -10.46 -116.33 41.8799
c-16.3701 29.3799 -14.9902 73.1104 25.1396 128c-40.1396 54.9102 -41.5195 98.5996 -25.1396 128c10.9004 19.5195 40.5996 50.6602 116.33 41.8799c21.4795 51.2305 54.2002 86.1201 97.8398 86.1201s76.3604 -34.8896 97.8398 -86.1201
c75.79 8.85059 105.42 -22.3604 116.33 -41.8799c16.3701 -29.3799 14.9902 -73.1104 -25.1396 -128zM63.3799 96c3.69043 -6.59961 19.0205 -11.8604 43.5801 -10.9697c-2.75977 13 -5.0498 26.3701 -6.75977 40.0801c-7.66992 6.29004 -14.9102 12.6494 -21.8701 19.1797
c-15.1396 -23.4902 -18.9805 -41.0801 -14.9502 -48.29zM100.2 258.88c1.39355 11.1816 4.43555 29.2002 6.79004 40.2197c-1.82031 0.0703125 -3.98047 0.370117 -5.69043 0.370117c-21.5303 0 -34.5098 -5.33008 -37.9199 -11.4697
c-4.01953 -7.20996 -0.179688 -24.7998 14.9502 -48.2998c6.96973 6.53027 14.21 12.8896 21.8701 19.1797zM224 384c-9.46973 0 -22.2002 -13.5195 -33.8604 -37.2598c11.1904 -3.7002 22.4404 -8 33.8604 -12.8604c11.4199 4.86035 22.6699 9.16016 33.8604 12.8604
c-11.6602 23.7402 -24.3906 37.2598 -33.8604 37.2598zM224 0c9.46973 0 22.2002 13.5195 33.8604 37.2598c-11.1904 3.7002 -22.4404 8 -33.8604 12.8604c-11.4199 -4.86035 -22.6699 -9.16016 -33.8604 -12.8604c11.6602 -23.7402 24.3906 -37.2598 33.8604 -37.2598z
M286.5 157.33c1.99023 27.7998 1.98047 41.5498 0 69.3301c-26.6396 19.04 -46.1104 29.3096 -62.5 37.4795c-16.3701 -8.15918 -35.8301 -18.4297 -62.5 -37.4795c-1.99023 -27.79 -1.99023 -41.54 0 -69.3301c26.7002 -19.0703 46.1504 -29.3398 62.5 -37.4805
c16.3604 8.15039 35.7998 18.4004 62.5 37.4805zM384.62 96c4.01953 7.20996 0.179688 24.7998 -14.9502 48.29c-6.96973 -6.53027 -14.21 -12.8896 -21.8701 -19.1797c-1.70996 -13.6904 -4 -27.0605 -6.75977 -40.0605c24.5801 -0.870117 39.9102 4.33008 43.5801 10.9502
zM369.67 239.71c15.1299 23.4902 18.9697 41.0801 14.9502 48.2998c-3.41016 6.12988 -16.4004 11.4707 -37.9199 11.4707c-1.71973 0 -3.87012 -0.300781 -5.69043 -0.370117c2.35254 -11.0205 5.39453 -29.0391 6.79004 -40.2207
c7.66992 -6.29004 14.9102 -12.6494 21.8701 -19.1797zM224 224c17.6699 0 32 -14.3301 32 -32s-14.3301 -32 -32 -32s-32 14.3301 -32 32s14.3301 32 32 32z" />
d="M223.999 224c17.6328 -0.03125 31.9727 -14.3672 32.0078 -32c0 -17.6641 -14.3359 -32 -32 -32s-32 14.3359 -32 32c0 17.6602 14.333 31.9961 31.9922 32zM438.171 320c16.3789 -29.375 15.0039 -73.125 -25.1309 -128c40.1348 -54.875 41.5098 -98.625 25.1309 -128
c-29.1309 -52.375 -101.646 -43.625 -116.275 -41.875c-21.5039 -51.25 -54.2617 -86.125 -97.8965 -86.125s-76.3906 34.875 -97.8965 86.125c-14.627 -1.75 -87.1426 -10.5 -116.273 41.875c-16.3789 29.375 -15.0039 73.125 25.1289 128
c-40.1328 54.875 -41.5078 98.625 -25.1289 128c10.877 19.5 40.5078 50.625 116.273 41.875c21.5059 51.25 54.2617 86.125 97.8965 86.125s76.3926 -34.875 97.8965 -86.125c75.7656 8.875 105.398 -22.375 116.275 -41.875zM63.3389 96
c3.75195 -6.625 19.0059 -11.875 43.6348 -11c-2.75 13 -5.125 26.375 -6.75 40.125c-7.75195 6.25 -15.0039 12.625 -21.8809 19.125c-15.1289 -23.5 -19.0039 -41 -15.0039 -48.25zM100.224 258.875c1.625 13.5 3.875 26.875 6.75 40.25c-1.875 0 -4 0.375 -5.75 0.375
c-21.5059 0 -34.5078 -5.375 -37.8848 -11.5c-4 -7.25 -0.125 -24.75 15.0039 -48.25c6.87695 6.5 14.1289 12.875 21.8809 19.125zM223.999 384c-9.50195 0 -22.2539 -13.5 -33.8828 -37.25c11.2539 -3.75 22.5059 -8 33.8828 -12.875
c11.3789 4.875 22.6309 9.125 33.8828 12.875c-11.627 23.75 -24.3809 37.25 -33.8828 37.25zM223.999 0c9.50195 0 22.2559 13.5 33.8828 37.25c-11.252 3.75 -22.5039 8 -33.8828 12.875c-11.377 -4.875 -22.6289 -9.125 -33.8828 -12.875
c11.6289 -23.75 24.3809 -37.25 33.8828 -37.25zM223.999 112c44.1602 0 80 35.8398 80 80s-35.8398 80 -80 80s-80 -35.8398 -80 -80s35.8398 -80 80 -80zM384.659 96c4 7.25 0.125 24.75 -15.0039 48.25c-6.875 -6.5 -14.127 -12.875 -21.8789 -19.125
c-1.625 -13.75 -4 -27.125 -6.75195 -40.125c24.6309 -0.875 40.0098 4.375 43.6348 11zM369.655 239.75c15.1289 23.5 19.0039 41 15.0039 48.25c-3.375 6.125 -16.3789 11.5 -37.8828 11.5c-1.75 0 -3.87695 -0.375 -5.75195 -0.375
c2.87695 -13.375 5.12695 -26.75 6.75195 -40.25c7.75195 -6.25 15.0039 -12.625 21.8789 -19.125z" />
<glyph glyph-name="bone" unicode="&#xf5d7;" horiz-adv-x="640"
d="M598.88 203.44c-9.42969 -4.70996 -9.42969 -18.1709 -0.00976562 -22.8809c25.2002 -12.5996 41.1201 -38.3496 41.1201 -66.5293v-7.64062c0 -41.0898 -33.2998 -74.3896 -74.3799 -74.3896c-32.0107 0 -60.4404 20.4902 -70.5703 50.8604
c-6.53027 19.5996 -10.7305 45.1396 -38.1104 45.1396h-273.87c-26.5098 0 -30.4297 -22.1104 -38.1094 -45.1396c-10.1299 -30.3701 -38.5498 -50.8604 -70.5703 -50.8604c-41.0801 0 -74.3799 33.2998 -74.3799 74.3896v7.64062
@@ -3499,8 +3516,8 @@ d="M451.36 78.8604c34.3301 -5.48047 60.6396 -34.9805 60.6396 -70.8604c0 -39.7598
c0 39.7695 32.2402 72 72 72h14.0703c-13.4199 11.7305 -22.0703 28.7803 -22.0703 48c0 35.3496 28.6504 64 64 64h16c44.1797 0 80 35.8203 80 80c0 17.3799 -5.69043 33.3604 -15.1104 46.4805c4.95996 0.779297 9.94043 1.51953 15.1104 1.51953
c53.0195 0 96 -42.9805 96 -96c0 -11.2803 -2.30957 -21.9502 -5.87988 -32h5.87988c35.3496 0 64 -28.6504 64 -64c0 -19.2197 -8.65039 -36.2695 -22.0703 -48h14.0703c39.7598 0 72 -32.2305 72 -72c0 -23.4102 -11.3398 -43.9902 -28.6396 -57.1396z" />
<glyph glyph-name="shapes" unicode="&#xf61f;"
d="M512 128v-160c0 -17.6699 -14.3301 -32 -32 -32h-160c-17.6699 0 -32 14.3301 -32 32v160c0 17.6699 14.3301 32 32 32h160c17.6699 0 32 -14.3301 32 -32zM128 192c70.6904 0 128 -57.3096 128 -128s-57.3096 -128 -128 -128s-128 57.3096 -128 128s57.3096 128 128 128
zM479.03 224h-190.061c-25.3398 0 -41.1797 26.6699 -28.5098 48l95.0303 160c12.6699 21.3301 44.3496 21.3301 57.0195 0l95.0303 -160c12.6699 -21.3301 -3.16992 -48 -28.5098 -48z" />
d="M128 192c70.6562 0 128 -57.3438 128 -128s-57.3438 -128 -128 -128s-128 57.3438 -128 128s57.3438 128 128 128zM507 246.86c14.2402 -24.3799 -3.58008 -54.8604 -32.0898 -54.8604h-213.82c-28.5098 0 -46.3301 30.4805 -32.0898 54.8604l106.93 182.85
c5.97266 10.0967 20.3398 18.291 32.0703 18.291s26.0977 -8.19434 32.0703 -18.291zM480 160c17.6641 0 32 -14.3359 32 -32v-160c0 -17.6641 -14.3359 -32 -32 -32h-160c-17.6641 0 -32 14.3359 -32 32v160c0 17.6641 14.3359 32 32 32h160z" />
<glyph glyph-name="star-of-life" unicode="&#xf621;" horiz-adv-x="480"
d="M471.99 113.57c7.66016 -4.41992 10.2793 -14.2002 5.85938 -21.8506l-32.0195 -55.4297c-4.41992 -7.66016 -14.21 -10.2803 -21.8701 -5.86035l-135.93 78.4307v-156.86c0 -8.83984 -7.16992 -16 -16.0107 -16h-64.0391c-8.84082 0 -16.0107 7.16016 -16.0107 16
v156.85l-135.93 -78.4297c-7.66016 -4.41016 -17.4502 -1.79004 -21.8701 5.86035l-32.0195 55.4297c-4.41992 7.65039 -1.80078 17.4404 5.85938 21.8604l135.931 78.4297l-135.931 78.4297c-7.66016 4.41992 -10.2793 14.21 -5.85938 21.8604l32.0195 55.4199
@@ -3646,38 +3663,41 @@ d="M509.34 140.75c1.46875 -3.37012 2.66016 -9.08984 2.66016 -12.7656c0 -6.95703
c-4.74707 5.08496 -8.59961 14.8574 -8.59961 21.8145c0 3.67578 1.19141 9.39551 2.66016 12.7656c5.05957 11.6904 16.5898 19.25 29.3398 19.25h64v208c0 22 18 40 40 40s40 -18 40 -40v-134c0 -5.51953 4.48047 -10 10 -10h20c5.51953 0 10 4.48047 10 10v174
c0 22 18 40 40 40s40 -18 40 -40v-174c0 -5.51953 4.48047 -10 10 -10h20c5.51953 0 10 4.48047 10 10v134c0 22 18 40 40 40s40 -18 40 -40v-208h64c12.75 0 24.2803 -7.55957 29.3398 -19.25zM256 32c53.0195 0 96 64 96 64s-42.9805 64 -96 64s-96 -64 -96 -64
s42.9805 -64 96 -64zM256 128c17.6699 0 32 -14.3301 32 -32s-14.3301 -32 -32 -32s-32 14.3301 -32 32s14.3301 32 32 32z" />
<glyph glyph-name="haykal" unicode="&#xf666;"
<glyph glyph-name="bahai" unicode="&#xf666;"
d="M496.25 245.48c17.54 -2.46094 21.6797 -26.2705 6.04004 -34.6602l-98.1602 -52.6602l74.4805 -83.54c11.8594 -13.29 0.00976562 -34.25 -17.3506 -30.4902l-108.569 23.6504l4.10938 -112.55c0.430664 -11.6504 -8.87012 -19.2207 -18.4102 -19.2207
c-5.15918 0 -10.3896 2.20996 -14.1992 7.18066l-68.1807 88.8994l-68.1797 -88.8994c-3.81055 -4.9707 -9.0498 -7.18066 -14.2002 -7.18066c-9.54004 0 -18.8398 7.57031 -18.4102 19.2207l4.11035 112.55l-108.57 -23.6504
c-1.39941 -0.30957 -2.75977 -0.450195 -4.06934 -0.450195c-15.0107 0 -24.21 18.6807 -13.29 30.9307l74.4795 83.54l-98.1602 52.6592c-15.6494 8.40039 -11.5098 32.21 6.03027 34.6709l110 15.4297l-41.8203 104.34c-6.66016 16.6396 11.6006 32.1797 26.5898 22.6299
l94.04 -59.8896l34.0908 107.189c2.70996 8.55078 10.0293 12.8203 17.3496 12.8203s14.6396 -4.26953 17.3496 -12.8203l34.0908 -107.18l94.04 59.8896c14.9893 9.55078 33.2598 -5.98926 26.5898 -22.6299l-41.8203 -104.34zM338.51 136.32l-35.6094 39.9297
l46.9199 25.1699l-52.5703 7.37988l19.9902 49.8701l-44.9502 -28.6201l-16.29 51.2305l-16.3096 -51.2305l-44.9502 28.6201l19.9902 -49.8701l-52.5703 -7.37988l46.9199 -25.1699l-35.5996 -39.9297l51.8896 11.2998l-1.95996 -53.79l32.5898 42.4902l32.5898 -42.4902
l-1.96973 53.79z" />
<glyph glyph-name="jedi" unicode="&#xf669;" horiz-adv-x="544"
d="M479.99 96h39.96c-42.6299 -94.1699 -137.641 -160 -247.98 -160c-4.25977 0 -8.5498 0.0898438 -12.8496 0.290039c-103.97 4.76953 -193.851 69.4795 -235.101 159.71h39.9102l-58.5996 58.5996c-2.57031 12.8809 -4.49023 25.9805 -5.11035 39.4102
c-0.469727 10.0801 -0.129883 20.0703 0.5 29.9902h47.21l-41.3799 41.3799c14.3701 64.7002 52.1006 122.55 107.97 162.07c2.77051 1.95996 5.9707 3 9.27051 3c5.37988 0 10.4297 -2.70996 13.5098 -7.25c3.0498 -4.5 3.64062 -10 1.62012 -15.0898
c-6.53027 -16.4502 -9.83984 -33.7002 -9.83984 -51.2607c0 -45.1191 21.04 -86.5801 57.71 -113.739c4.00977 -2.9707 6.4502 -7.48047 6.69043 -12.3799c0.239258 -4.90039 -1.76074 -9.65039 -5.48047 -13.0107c-26.5498 -23.9795 -41.1699 -56.5 -41.1699 -91.5801
c0 -60.0293 42.9502 -110.279 99.8896 -121.92l2.5 65.2607l-27.1602 -18.4805c-2.96973 -2 -7.40918 -1.7002 -10 0.75c-2.72949 2.61035 -3.30957 6.70996 -1.38965 9.94043l20.1299 33.7695l-42.0693 8.71973c-3.71094 0.75 -6.38086 4.05078 -6.38086 7.83008
c0 3.78027 2.68066 7.08008 6.38086 7.83008l42.0693 8.73047l-20.1094 33.7295c-1.94043 3.27051 -1.36035 7.35059 1.35938 9.94043c2.73047 2.60938 6.86035 2.89941 10 0.779297l30.3906 -20.6592l11.5195 287.97c0.160156 4.29004 3.66992 7.66992 8 7.66992h0.0400391
c4.25293 0 7.81934 -3.44922 7.95996 -7.7002l11.5303 -287.93l30.3896 20.6699c3.03027 2.08984 7.2998 1.75 10 -0.799805c2.71973 -2.60059 3.2998 -6.68066 1.37988 -9.91016l-20.1299 -33.7705l42.0703 -8.72949c3.68945 -0.770508 6.37988 -4.06055 6.37988 -7.83008
c0 -3.78027 -2.67969 -7.08008 -6.37988 -7.83008l-42.0703 -8.71973l20.1104 -33.7305c0.631836 -1.05078 1.14453 -2.89844 1.14453 -4.12402c0 -1.89355 -1.11328 -4.49023 -2.48438 -5.7959c-2.63086 -2.49023 -7.04004 -2.85938 -10.0205 -0.799805l-27.1699 18.4697
l2.5 -65.3398c48.4697 9.40039 87.5703 48.1504 97.3096 96.5c8.78027 43.5605 -5.63965 87.3203 -38.5693 117.07c-3.73047 3.37012 -5.73047 8.10938 -5.49023 13.0303c0.240234 4.89941 2.67969 9.41992 6.7002 12.3994c36.6602 27.1602 57.6895 68.6104 57.6895 113.73
c0 17.5801 -3.30957 34.8496 -9.85938 51.3096c-2.03027 5.09961 -1.44043 10.5996 1.60938 15.0898c3.08008 4.53027 8.12012 7.24023 13.4902 7.24023c3.28027 0 6.48047 -1.03027 9.25 -2.99023c55.4805 -39.2197 93.4102 -97.4795 107.91 -162.27l-41.25 -41.2402
h46.9502c0.370117 -5.75977 1.0498 -11.46 1.0498 -17.2695c0 -17.7402 -1.83984 -35.0605 -5.12988 -51.8604z" />
<glyph glyph-name="jedi" unicode="&#xf669;" horiz-adv-x="576"
d="M535.953 96c-42.6406 -94.1719 -137.641 -160 -247.984 -160c-4.26562 0 -8.54688 0.0986328 -12.8447 0.296875c-103.969 4.76562 -193.859 69.4688 -235.109 159.703h39.9219l-58.6094 58.5938c-2.22949 10.7744 -4.51758 28.4355 -5.10938 39.4219
c-0.109375 2.87891 -0.199219 7.55469 -0.199219 10.4365c0 5.40234 0.313477 14.1592 0.699219 19.5479h47.2188l-41.3906 41.375c12.4873 56.2656 60.8574 128.877 107.969 162.078c2.29785 1.64453 6.45605 2.98828 9.28125 3
c4.78613 -0.0263672 10.835 -3.27441 13.5 -7.25c1.54883 -2.25977 2.80566 -6.31836 2.80566 -9.05762c0 -1.72949 -0.529297 -4.43359 -1.18066 -6.03613c-5.43359 -13.626 -9.84375 -36.5908 -9.84375 -51.2598v-0.00585938
c0 -45.1094 21.0469 -86.5781 57.7188 -113.734c3.70312 -2.69531 6.70801 -8.59863 6.70801 -13.1787c0 -4.05469 -2.46582 -9.52637 -5.50488 -12.2119c-26.5469 -23.9844 -41.1719 -56.5 -41.1719 -91.5781c0 -60.0312 42.9531 -110.281 99.8906 -121.922l2.5 65.2656
l-27.1562 -18.4844c-1.13477 -0.728516 -3.15234 -1.31934 -4.50098 -1.31934c-1.73242 0 -4.19629 0.926758 -5.49902 2.06934c-1.38965 1.31152 -2.5166 3.92578 -2.5166 5.83691c0 1.2168 0.504883 3.05469 1.12598 4.10059l20.125 33.7656l-42.0625 8.73438
c-3.52734 0.720703 -6.39062 4.22754 -6.39062 7.82812s2.86328 7.10742 6.39062 7.82812l42.0625 8.71875l-20.1094 33.7344c-0.632812 1.05078 -1.14648 2.89844 -1.14648 4.12598c0 4.41113 3.58008 7.99121 7.99121 7.99121
c1.36523 0 3.38867 -0.626953 4.51465 -1.39844l30.3906 -20.6562l11.5166 287.969c0.15918 4.23535 3.72754 7.67188 7.96484 7.67188h0.0351562h0.046875c4.22266 -0.0322266 7.78516 -3.4834 7.95312 -7.70312l11.5312 -287.922l30.3906 20.6719
c1.12402 0.75 3.13477 1.35938 4.48633 1.35938c1.75781 0 4.22754 -0.972656 5.51367 -2.17188c1.38672 -1.30762 2.5127 -3.91504 2.5127 -5.82129c0 -1.21191 -0.50293 -3.04199 -1.12207 -4.08496l-20.1406 -33.7656l42.0781 -8.73438
c3.51855 -0.727539 6.375 -4.23438 6.375 -7.82812s-2.85645 -7.10059 -6.375 -7.82812l-42.0781 -8.71875l20.1094 -33.7344c0.637695 -1.05273 1.15625 -2.90625 1.15625 -4.13672c0 -1.8916 -1.11328 -4.48242 -2.48438 -5.78516
c-1.30176 -1.1748 -3.78125 -2.12891 -5.53418 -2.12891c-1.35059 0 -3.36523 0.59668 -4.49707 1.33203l-27.1719 18.4688l2.5 -65.3438c48.4844 9.40625 87.5781 48.1562 97.3125 96.5c1.41602 6.84082 2.56641 18.0625 2.56641 25.0488
c0 30.4727 -18.4258 71.7021 -41.1289 92.0293c-3.04688 2.6875 -5.52051 8.16602 -5.52051 12.2285c0 4.58691 3.0127 10.498 6.72363 13.1934c36.6562 27.1719 57.6875 68.6094 57.6875 113.734v0.0839844c0 14.6631 -4.41699 37.6133 -9.85938 51.2285
c-0.658203 1.60645 -1.19238 4.31934 -1.19238 6.05566c0 2.73438 1.25488 6.7832 2.80176 9.03809c2.66895 3.96875 8.7168 7.20996 13.5 7.23438c2.81445 -0.0107422 6.95898 -1.34863 9.25 -2.98438c47.0215 -33.3271 95.3633 -106.028 107.906 -162.281l-41.25 -41.2344
h46.9531c0.359375 -5.76562 1.04688 -11.4531 1.04688 -17.2656c-0.0273438 -14.4502 -2.32324 -37.6836 -5.125 -51.8594l-58.8906 -58.875h39.9688z" />
<glyph glyph-name="journal-whills" unicode="&#xf66a;" horiz-adv-x="448"
d="M448 89.5996c0 -9.59961 -3.2002 -16 -9.59961 -19.1992c-3.2002 -12.8008 -3.2002 -57.6006 0 -73.6006c6.39941 -6.39941 9.59961 -12.7998 9.59961 -19.2002v-16c0 -16 -12.7998 -25.5996 -25.5996 -25.5996h-326.4c-54.4004 0 -96 41.5996 -96 96v320
c0 54.4004 41.5996 96 96 96h326.4c16 0 25.5996 -9.59961 25.5996 -25.5996v-332.801zM133.08 303.61c-2.98047 -10.0908 -5.08008 -20.5605 -5.07031 -31.6201c0 -0.520508 0.140625 -0.990234 0.150391 -1.50977l37.1094 -32.4707
c3.33008 -2.89941 3.6709 -7.9502 0.75 -11.2793c-1.5791 -1.81055 -3.7998 -2.73047 -6.01953 -2.73047h-0.0175781c-1.65527 0 -4.00879 0.886719 -5.25195 1.98047l-23.5908 20.6396c11.54 -49.5801 55.7705 -86.6201 108.86 -86.6201s97.3203 37.04 108.87 86.6299
l-23.5898 -20.6396c-1.52051 -1.32031 -3.39062 -1.98047 -5.27051 -1.98047h-0.0146484c-2 0 -4.69043 1.22363 -6.00488 2.73047c-1.09668 1.24707 -1.98633 3.60645 -1.98633 5.2666c0 2.00293 1.22559 4.69727 2.73633 6.0127l37.1094 32.4707
c0.0107422 0.519531 0.150391 0.990234 0.150391 1.50977c0 11.0498 -2.09961 21.5195 -5.07031 31.5996l-21.2598 -21.2598c-1.57031 -1.55957 -3.61035 -2.33984 -5.66016 -2.33984s-4.09961 0.780273 -5.66016 2.33984c-3.11914 3.12012 -3.11914 8.19043 0 11.3105
l26.4199 26.4199c-10 20.8994 -26.2393 37.9795 -46.3691 49.2598c5.97949 -9.73047 9.59961 -21.0703 9.59961 -33.3301c0 -19.96 -9.33008 -37.5703 -23.6602 -49.3096c9.65039 -10.0605 15.6602 -23.6504 15.6602 -38.6904c0 -26.9404 -19.04 -49.4004 -44.3701 -54.7402
l-1.42969 34.2803l12.6797 -8.62012c0.69043 -0.459961 1.46973 -0.689453 2.25 -0.689453c0.980469 0 1.98047 0.369141 2.75 1.08984c1.36035 1.2793 1.63965 3.33984 0.69043 4.94922l-8.54004 14.3105l17.9102 3.71973
c1.85938 0.390625 3.18945 2.03027 3.18945 3.91992c0 1.89062 -1.33008 3.53027 -3.18945 3.91992l-17.9102 3.7207l8.54004 14.3096c0.308594 0.521484 0.55957 1.43652 0.55957 2.04297c0 0.950195 -0.55957 2.25293 -1.25 2.90723
c-0.645508 0.59668 -1.88281 1.08105 -2.76172 1.08105c-0.672852 0 -1.67578 -0.300781 -2.23828 -0.670898l-14.2002 -9.65039l-4.67969 112.29c-0.0898438 2.13965 -1.86035 3.83008 -4 3.83008s-3.91016 -1.69043 -4 -3.83008l-4.62012 -110.81l-12.0098 8.15918
c-1.56055 1.03027 -3.63965 0.890625 -5 -0.40918c-1.36035 -1.28027 -1.63965 -3.34082 -0.69043 -4.9502l8.54004 -14.3105l-17.9102 -3.71973c-1.85938 -0.389648 -3.18945 -2.03027 -3.18945 -3.91992s1.33008 -3.53027 3.18945 -3.91992l17.9102 -3.71973
l-8.54004 -14.3105c-0.308594 -0.521484 -0.55957 -1.43652 -0.55957 -2.04297c0 -0.950195 0.55957 -2.25293 1.25 -2.90723c0.769531 -0.709961 1.75 -1.08984 2.75 -1.08984c0.780273 0 1.55957 0.240234 2.25 0.69043l10.3701 7.04004l-1.36035 -32.71
c-25.3398 5.35938 -44.3799 27.8193 -44.3799 54.7598c0 15.04 6.00977 28.6299 15.6602 38.6904c-14.3301 11.7393 -23.6602 29.3496 -23.6602 49.3096c0 12.2598 3.62012 23.5996 9.61035 33.3398c-20.1299 -11.29 -36.3701 -28.3594 -46.3701 -49.2598l26.4199 -26.4199
c3.12012 -3.12012 3.12012 -8.19043 0 -11.3105c-1.57031 -1.55957 -3.61035 -2.33984 -5.66016 -2.33984s-4.09961 0.780273 -5.66016 2.33984zM380.8 0v64h-284.8c-16 0 -32 -12.7998 -32 -32s12.7998 -32 32 -32h284.8z" />
d="M438.406 70.4062c-3.20312 -12.8125 -3.20312 -57.6094 0 -73.6094c6.39062 -6.39062 9.58887 -12.792 9.59375 -19.2031v-16c0 -16 -12.7969 -25.5938 -25.5938 -25.5938h-326.406c-54.4062 0 -96 41.5938 -96 96v320c0 54.4062 41.5938 96 96 96h326.406
c16 0 25.5938 -9.59375 25.5938 -25.5938v-332.812c0 -9.59375 -3.19824 -15.9893 -9.59375 -19.1875zM380.797 64h-284.797c-16 0 -32 -12.7969 -32 -32s12.7969 -32 32 -32h284.797v64zM128.016 271.984c0 -0.515625 0.140625 -0.984375 0.140625 -1.5l37.1094 -32.4688
c1.50488 -1.31934 2.72656 -4.01465 2.72656 -6.01562c0 -4.41211 -3.58008 -7.99609 -7.99219 -8h-0.015625c-1.625 0.0820312 -3.97656 0.97168 -5.25 1.98438l-23.5938 20.6406c11.5469 -49.5781 55.7656 -86.625 108.859 -86.625s97.3125 37.0469 108.875 86.625
l-23.5938 -20.6406c-1.25 -1.08691 -3.60938 -1.96875 -5.26562 -1.96875v0h-0.015625c-1.9502 0.108398 -4.64551 1.32617 -6.01562 2.71875c-1.01074 1.27832 -1.89941 3.6377 -1.98438 5.26562c0.107422 1.9541 1.33203 4.64941 2.73438 6.01562l37.1094 32.4688
c0.015625 0.53125 0.15625 1 0.15625 1.51562c0 11.0469 -2.09375 21.5156 -5.0625 31.5938l-21.2656 -21.25c-1.29492 -1.2959 -3.83105 -2.34766 -5.66309 -2.34766c-4.41895 0 -8.00488 3.58594 -8.00488 8.00488c0 1.82812 1.04883 4.36133 2.33984 5.65527
l26.4219 26.4062c-8.47949 17.6582 -29.249 39.7295 -46.3594 49.2656c5.2959 -8.46484 9.59375 -23.4395 9.59375 -33.4248c0 -16.7217 -10.5977 -38.7705 -23.6562 -49.2158c8.64258 -8.95605 15.6562 -26.3262 15.6562 -38.7725
c0 -25.0283 -19.8799 -49.5117 -44.375 -54.6494l-1.42188 34.2812l12.6719 -8.625c0.557617 -0.379883 1.55762 -0.6875 2.23242 -0.6875h0.0175781h0.0253906c2.19727 0 3.98145 1.7832 3.98145 3.98047c0 0.609375 -0.254883 1.52832 -0.569336 2.05078l-8.53125 14.3125
l17.9062 3.71875c1.75977 0.367188 3.1875 2.12402 3.1875 3.92188s-1.42773 3.55469 -3.1875 3.92188l-17.9062 3.71875l8.53125 14.3125c0.314453 0.522461 0.569336 1.44141 0.569336 2.05078c0 2.19727 -1.78418 3.98047 -3.98145 3.98047h-0.0253906
c-0.668945 -0.0263672 -1.67676 -0.327148 -2.25 -0.671875l-14.1875 -9.65625l-4.6875 112.297c-0.0927734 2.11328 -1.88477 3.82812 -4 3.82812s-3.90723 -1.71484 -4 -3.82812l-4.625 -110.812l-12 8.15625c-0.561523 0.380859 -1.56836 0.69043 -2.24707 0.69043
c-2.20996 0 -4.00293 -1.79297 -4.00293 -4.00293c0 -0.607422 0.251953 -1.52441 0.5625 -2.04688l8.53125 -14.3125l-17.9062 -3.71875c-1.75977 -0.364258 -3.1875 -2.11719 -3.1875 -3.91406s1.42773 -3.5498 3.1875 -3.91406l17.9062 -3.73438l-8.53125 -14.2969
c-0.285156 -0.529297 -0.537109 -1.44629 -0.5625 -2.04688c0.0507812 -0.928711 0.611328 -2.23047 1.25 -2.90625c0.639648 -0.603516 1.87109 -1.09277 2.75 -1.09375c0.677734 0.00292969 1.68555 0.311523 2.25 0.6875l10.3594 7.04688l-1.35938 -32.7188
c-24.4951 5.14746 -44.375 29.6396 -44.375 54.6699c0 12.4482 7.01367 29.8232 15.6562 38.7832c-13.0586 10.4434 -23.6562 32.4893 -23.6562 49.21c0 9.99316 4.30469 24.9775 9.60938 33.4463c-17.1104 -9.53906 -37.8867 -31.6104 -46.375 -49.2656l26.4219 -26.4219
c1.28516 -1.29199 2.3291 -3.81934 2.3291 -5.64258c0 -4.41504 -3.58398 -7.99902 -7.99902 -7.99902c-1.82324 0 -4.35059 1.04395 -5.64258 2.3291l-21.2656 21.2656c-2.98438 -10.0938 -5.07812 -20.5625 -5.0625 -31.625z" />
<glyph glyph-name="kaaba" unicode="&#xf66b;" horiz-adv-x="576"
d="M554.12 364.49c13.0703 -4.36035 21.8799 -16.5898 21.8799 -30.3604v-49.0098l-265 79.5098c-15.0596 4.5 -30.9502 4.5 -45.9805 0l-265.02 -79.5098v49.0098c0.000976562 12.7314 9.80273 26.332 21.8799 30.3604l235.771 78.5801
c8.15723 2.71973 21.7559 4.92676 30.3545 4.92676s22.1982 -2.20703 30.3555 -4.92676zM274.22 333.97c9 2.7207 18.5498 2.7207 27.5898 0l274.2 -82.2598v-228.39c0 -15 -10.4199 -27.9902 -25.0596 -31.2402l-242.12 -53.7998
@@ -3889,10 +3909,10 @@ l-100.43 175.75h100.43z" />
d="M422.19 338.05c5.3291 -3.24023 5.2998 -11.2695 -0.0507812 -14.46l-198.14 -118.14l-198.13 118.14c-5.35059 3.19043 -5.37988 11.2305 -0.0605469 14.46l165.971 100.88c19.9102 12.1006 44.5195 12.1006 64.4297 0zM436.03 293.42
c5.33008 3.17969 11.9697 -0.839844 11.9697 -7.25v-197.7c0 -23.7598 -12.1104 -45.7393 -31.79 -57.7002l-152.16 -92.4795c-10.6602 -6.48047 -24.0498 1.5498 -24.0498 14.4297v223.82zM0 286.17c0 6.41016 6.63965 10.4297 11.9697 7.25l196.03 -116.88v-223.81
c0 -12.8906 -13.3799 -20.9102 -24.0498 -14.4307l-152.16 92.4697c-19.6797 11.9609 -31.79 33.9307 -31.79 57.7002v197.7z" />
<glyph glyph-name="dog" unicode="&#xf6d3;"
d="M496 352c8.83984 0 16 -7.16016 16 -16v-32c0 -35.3496 -28.6504 -64 -64 -64h-32v-35.5801l-128 45.71v149.84c0 14.25 17.2305 21.3906 27.3203 11.3105l27.2793 -27.2803h53.6201c10.917 -0.000976562 23.7383 -7.92578 28.6201 -17.6904l7.16016 -14.3096h64z
M384 304c8.83984 0 16 7.16016 16 16s-7.16016 16 -16 16s-16 -7.16016 -16 -16s7.16016 -16 16 -16zM96 224h170.05l149.95 -53.5498v-218.45c0 -8.83984 -7.16016 -16 -16 -16h-64c-8.83984 0 -16 7.16016 -16 16v112h-160v-112c0 -8.83984 -7.16016 -16 -16 -16h-64
c-8.83984 0 -16 7.16016 -16 16v213.9c-37.1699 13.25 -64 48.4395 -64 90.0996c0 17.6699 14.3301 32 32 32s32 -14.3301 32 -32c0 -17.6396 14.3604 -32 32 -32z" />
<glyph glyph-name="dog" unicode="&#xf6d3;" horiz-adv-x="576"
d="M298.06 224l149.94 -53.5498v-218.45c0 -8.83203 -7.16797 -16 -16 -16h-64c-8.83203 0 -16 7.16797 -16 16v112h-160v-112c0 -8.83203 -7.16797 -16 -16 -16h-64c-8.83203 0 -16 7.16797 -16 16v213.91c-37.1602 13.25 -64 48.4297 -64 90.0898
c0 17.6641 14.3359 32 32 32s32 -14.3359 32 -32c0.0332031 -17.6309 14.3691 -31.9668 32 -32h170.06zM544 336v-32c0 -35.3281 -28.6719 -64 -64 -64h-32v-35.5801l-128 45.71v149.87c0 14.25 17.2197 21.3896 27.3096 11.3096l27.2803 -27.3096h53.6299
c10.9102 0 23.75 -7.91992 28.6201 -17.6904l7.16016 -14.3096h64c8.83203 0 16 -7.16797 16 -16zM432 336c0 8.83203 -7.16797 16 -16 16s-16 -7.16797 -16 -16s7.16797 -16 16 -16s16 7.16797 16 16z" />
<glyph glyph-name="dragon" unicode="&#xf6d5;" horiz-adv-x="640"
d="M18.3203 192.22c-15.96 -2.2793 -24.8906 17.8105 -12.5107 28.1406l117.4 116.34c21.7705 18.5996 53.2402 20.4697 77.0596 4.58984l119.73 -87.5996v-42.2705c0 -28.9102 5.29004 -56.9795 14.7305 -83.3799h-222.7c-14.25 0 -21.3906 17.2295 -11.3105 27.3096
l91.2803 68.6904zM575.19 158.12c41.9092 -20.96 67.1592 -64.0801 64.6396 -111.36c-3.37988 -63.2002 -59.7002 -110.77 -122.99 -110.76h-499.08c-9.80957 0 -17.7598 8 -17.7598 17.7998c0 8.32031 5.78027 15.5303 13.9004 17.3301
@@ -4131,10 +4151,13 @@ c22.6006 11.5 49.4004 -1.5 49.4004 -26.5996v-30.7998c-105.2 -49.1006 -150.8 -35.
c0 8.89941 -7.2002 16 -16 16s-16 -7.2002 -16 -16c0 -8.90039 7.2002 -16 16 -16zM224 327.8c8.7998 0 16 7.2002 16 16c0 8.90039 -7.2002 16 -16 16s-16 -7.2002 -16 -16c0 -8.89941 7.2002 -16 16 -16zM224 383.7c8.7998 0 16 7.2002 16 16c0 8.89941 -7.2002 16 -16 16
s-16 -7.2002 -16 -16c0 -8.90039 7.2002 -16 16 -16z" />
<glyph glyph-name="meteor" unicode="&#xf753;"
d="M491.2 447.3c12.3994 3.7002 23.7998 -7.7002 20.2002 -20.0996c-11.6006 -38.7002 -34.3008 -111.7 -61.3008 -187.7c7 -2.09961 13.4004 -4 18.6006 -5.59961c9.7002 -3 14.2002 -13.9004 9.5 -22.9004c-22.1006 -42.2998 -82.7002 -152.8 -142.5 -214.4
c-1 -1.09961 -2 -2.5 -3 -3.5c-38.1006 -38.0996 -88 -57.0996 -137.9 -57.0996c-49.8994 -0.0996094 -99.7998 19 -137.8 57c-38 38.0996 -57 88 -57 137.8c0 49.9004 19 99.7998 57.0996 137.8c1 1 2.40039 2 3.5 3c61.6006 59.9004 172 120.4 214.4 142.5
c9 4.7002 19.9004 0.200195 22.9004 -9.5c1.59961 -5.09961 3.5 -11.5996 5.59961 -18.5996c75.9004 27 149 49.7002 187.7 61.2998zM192 0c70.7002 0 128 57.2998 128 128s-57.2998 128 -128 128s-128 -57.2998 -128 -128s57.2998 -128 128 -128zM160 192
c17.7002 0 32 -14.2998 32 -32s-14.2998 -32 -32 -32s-32 14.2998 -32 32s14.2998 32 32 32zM208 96c8.7998 0 16 -7.2002 16 -16s-7.2002 -16 -16 -16s-16 7.2002 -16 16s7.2002 16 16 16z" />
d="M511.328 427.197c-11.6074 -38.7021 -34.3076 -111.702 -61.3037 -187.701c6.99902 -2.09375 13.4043 -4 18.6074 -5.59277c6.28125 -1.91504 11.3789 -8.79785 11.3789 -15.3643c0 -2.21094 -0.842773 -5.58984 -1.88086 -7.54199
c-22.1055 -42.2969 -82.6904 -152.795 -142.479 -214.403c-0.999023 -1.09375 -1.99902 -2.5 -2.99902 -3.5c-31.501 -31.5098 -93.2285 -57.083 -137.784 -57.083c-107.546 0 -194.83 87.2842 -194.83 194.831c0 44.5391 25.5566 106.25 57.0469 137.748
c1 1 2.40625 2 3.49902 3c61.6006 59.9053 171.975 120.405 214.374 142.498c1.95215 1.03809 5.33008 1.88086 7.54102 1.88086c6.56641 0 13.4492 -5.09863 15.3613 -11.3809c1.59375 -5.09375 3.5 -11.5928 5.59277 -18.5928
c75.8955 26.999 148.978 49.7021 187.675 61.2959c1.26465 0.382812 3.36426 0.692383 4.68555 0.692383c8.93262 0 16.1826 -7.25 16.1826 -16.1826c0 -1.29785 -0.298828 -3.35938 -0.667969 -4.60352zM319.951 127.998
c-0.00976562 70.6348 -57.3457 127.962 -127.98 127.962c-70.6455 0 -127.98 -57.335 -127.98 -127.98c0 -70.6445 57.335 -127.979 127.98 -127.979h0.00488281c70.6426 0 127.976 57.333 127.976 127.976v0.0224609zM191.971 159.997
c-0.00292969 -17.6582 -14.3359 -31.9902 -31.9951 -31.9902c-17.6611 0 -31.9951 14.334 -31.9951 31.9951s14.334 31.9951 31.9951 31.9951h0.0361328c17.6416 0 31.959 -14.3174 31.959 -31.959v-0.0410156zM223.966 79.998
c-0.000976562 -8.8291 -7.16797 -15.9951 -15.998 -15.9951s-15.9971 7.16699 -15.9971 15.998c0 8.83008 7.16699 15.9971 15.9971 15.9971c8.80371 -0.0283203 15.9707 -7.19629 15.998 -16z" />
<glyph glyph-name="person-booth" unicode="&#xf756;" horiz-adv-x="576"
d="M192 -48v176h64v-176c0 -8.7998 -7.2002 -16 -16 -16h-32c-8.7998 0 -16 7.2002 -16 16zM224 224c17.7002 0 32 -14.2998 32 -32s-14.2998 -32 -32 -32h-57.5c-12.7998 0 -24.7998 5 -33.9004 14.0996l-20.8994 20.9004v-80.5996l41.2002 -61.3008
c4.39941 -8.7998 6.69922 -18.6992 6.69922 -28.5996v-56.5c0 -17.7002 -14.2998 -32 -32 -32c-17.6992 0 -32 14.2998 -32 32v56l-29.0996 43c-0.900391 0.400391 -1.59961 1.2002 -2.5 1.7002l-0.0996094 -100.7c0 -17.7002 -14.4004 -32 -32 -32
@@ -4298,10 +4321,11 @@ c0 8.7998 7.2002 16 16 16h480z" />
d="M96 -48c0 -8.7998 -7.2002 -16 -16 -16h-32c-8.7998 0 -16 7.2002 -16 16v480c0 8.7998 7.2002 16 16 16h32c8.7998 0 16 -7.2002 16 -16v-480zM224 -48c0 -8.7998 -7.2002 -16 -16 -16h-32c-8.7998 0 -16 7.2002 -16 16v480c0 8.7998 7.2002 16 16 16h32
c8.7998 0 16 -7.2002 16 -16v-480z" />
<glyph glyph-name="guitar" unicode="&#xf7a6;"
d="M502.6 393.4c12.5 -12.5 12.5 -32.8008 0.100586 -45.2002l-67.9004 -67.9004c-12.5 -12.5 -32.7998 -12.5 -45.2998 0l-54.2002 -54.2002c28.9004 -45.3994 28.9004 -100.399 -4.2002 -133.5c-9.69922 -9.69922 -21.1992 -16.3994 -33.8994 -20.5
c-18.7998 -6.09961 -33.1006 -23.5996 -34.9004 -42.6992c-2.2998 -24.1006 -11.5996 -46.4004 -28.7998 -63.5c-46.0996 -46.1006 -129.1 -37.9004 -185.3 18.2998s-64.5 139.2 -18.2998 185.3c17.0996 17.2002 39.3994 26.5 63.3994 28.7998
c19.2002 1.7998 36.6006 16.1006 42.7002 34.9004c4.09961 12.7002 10.7998 24.2002 20.5 33.8994c33.0996 33.1006 88.0996 33.2002 133.5 4.2002l54.2002 54.1006c-12.5 12.5 -12.5 32.7998 0 45.2998l67.8994 67.8994c12.5 12.5 32.8008 12.5 45.3008 0zM208 96
c26.5 0 48 21.5 48 48s-21.5 48 -48 48s-48 -21.5 -48 -48s21.5 -48 48 -48z" />
d="M502.63 409c5.15625 -5.1709 9.33984 -15.293 9.33984 -22.5947c0 -7.31543 -4.19727 -17.4521 -9.37012 -22.625l-46.3301 -46.3203c-3.24707 -3.25684 -9.4248 -7.07812 -13.7891 -8.53027l-36.4805 -12.1602l-76.2402 -76.2393
c8.79004 -12.2002 15.7705 -25.5605 19.1602 -40.2002c7.74023 -33.3896 0.870117 -66.8701 -22 -89.75c-7.87793 -7.8418 -22.877 -16.9141 -33.4795 -20.25c-18.54 -6.00977 -32.6709 -23.29 -34.4307 -42.1396c-2.29004 -23.8105 -11.4502 -45.8301 -28.4502 -62.71
c-45.5596 -45.4805 -127.5 -37.3809 -182.979 18.0693c-55.4805 55.4502 -63.6904 137.45 -18.0498 182.96c16.8799 16.9902 38.9102 26.1699 62.6094 28.4404c18.9404 1.76953 36.1504 15.8994 42.1504 34.46c3.33105 10.6016 12.3984 25.5957 20.2402 33.4697
c22.8799 22.8799 56.4297 29.7803 89.8799 22c14.5996 -3.39941 27.9395 -10.3799 40.0996 -19.1396l76.2598 76.2598l12.1602 36.5098c1.45215 4.36426 5.27344 10.542 8.53027 13.79l46.2803 46.3301c5.17383 5.1748 15.3115 9.375 22.6299 9.375
c7.31738 0 17.4561 -4.2002 22.6299 -9.375zM208 96c26.4961 0 48 21.5039 48 48s-21.5039 48 -48 48s-48 -21.5039 -48 -48s21.5039 -48 48 -48z" />
<glyph glyph-name="heart-broken" unicode="&#xf7a9;"
d="M473.7 374.2c48.7002 -49.7998 50.7998 -129.101 7.2998 -182.101l-212.2 -218.699c-7.09961 -7.30078 -18.5996 -7.30078 -25.7002 0l-212.1 218.6c-43.5 53.0996 -41.4004 132.4 7.2998 182.2l2.40039 2.39941c46.2998 47.4004 119 51.8008 170.7 14l28.5996 -86.5
l-96 -64l144 -144l-48 128l96 64l-34.2998 103.4c51.5996 36.9004 123.6 32.2002 169.6 -14.7998z" />
@@ -4352,16 +4376,20 @@ c14.2998 -1.2002 26.5 -10.7002 29.7998 -24.2002zM336 448c8.7998 0 16 -7.2002 16
c0 -13.2998 -10.7002 -24 -24 -24h-8v-136c0 -13.2998 -10.7002 -24 -24 -24h-80c-13.2998 0 -24 10.7002 -24 24v136h-8c-13.2998 0 -24 10.7002 -24 24v136c0 25.0996 19.2998 45.5 43.9004 47.5996c15 -9.7998 32.8994 -15.5996 52.0996 -15.5996
s37.0996 5.7998 52.0996 15.5996z" />
<glyph glyph-name="satellite" unicode="&#xf7bf;"
d="M502.7 183c12.3994 -12.4004 12.3994 -32.5996 -0.100586 -45l-96.6992 -96.7002c-6.2002 -6.2002 -14.4004 -9.2998 -22.5 -9.2998c-8.10059 0 -16.3008 3.09961 -22.5 9.2998l-80.3008 80.4004l-9.89941 -9.90039c24.2998 -53.7002 22.7002 -116.2 -5.40039 -168.5
c-4.5 -8.5 -16.3994 -9.59961 -23.2002 -2.7998l-107.5 107.5l-17.7998 -17.7998c0.700195 -2.60059 1.60059 -5 1.60059 -7.7998c0 -17.7002 -14.3008 -32 -32 -32c-17.7002 0 -32 14.2998 -32 32c0 17.6992 14.2998 32 32 32c2.7998 0 5.19922 -0.900391 7.7998 -1.60059
l17.7998 17.7998l-107.5 107.5c-6.7998 6.80078 -5.7002 18.6006 2.7998 23.2002c52.2998 28.1006 114.8 29.7002 168.5 5.40039l9.7998 9.7998l-80.2998 80.4004c-12.3994 12.5 -12.3994 32.6992 0 45.0996l96.7002 96.7002c6.2002 6.2002 14.2998 9.2998 22.5 9.2998
s16.2998 -3.09961 22.5996 -9.2998l80.3008 -80.2998l47.7998 47.8994c13.0996 13.1006 34.3994 13.1006 47.5 0l47.5 -47.5c13.0996 -13.0996 13.0996 -34.3994 0 -47.5l-47.7998 -47.8994zM150.7 319.5l68.8994 -68.9004l73.8008 73.8008l-68.9004 68.8994zM383.5 86.7002
l73.7998 73.7998l-68.8994 68.9004l-73.8008 -73.8008z" />
d="M502.609 137.958l-96.7041 -96.7168c-5.15039 -5.13184 -15.2324 -9.29785 -22.5029 -9.29785c-7.27148 0 -17.3535 4.16602 -22.5039 9.29785l-80.3262 80.418l-9.89258 -9.9082c9.41016 -20.7256 17.0469 -56.0186 17.0469 -78.7803
c0 -26.3193 -10.0596 -66.5244 -22.4541 -89.7422c-4.50098 -8.50098 -16.3936 -9.59473 -23.207 -2.79785l-107.519 107.515l-17.7998 -17.7988c0.703125 -2.60938 1.60938 -5.00098 1.60938 -7.79785v-0.000976562c0 -17.667 -14.3379 -32.0059 -32.0049 -32.0059
s-32.0059 14.3389 -32.0059 32.0059s14.3389 32.0049 32.0059 32.0049c2.79688 0 5.18848 -0.90625 7.79785 -1.60938l17.7998 17.7998l-107.518 107.515c-6.79883 6.8125 -5.7041 18.6113 2.79688 23.2061c23.2197 12.3936 63.4248 22.4531 89.7451 22.4531
c22.7627 0 58.0576 -7.63672 78.7832 -17.0469l9.79883 9.79883l-80.3105 80.417c-5.13086 5.16602 -9.29395 15.2686 -9.29395 22.5498s4.16309 17.3838 9.29395 22.5498l96.7197 96.7168c5.11621 5.13281 15.1514 9.29785 22.3984 9.29785h0.105469h0.0449219
c7.28223 0 17.3857 -4.16602 22.5527 -9.29785l80.3262 -80.3076l47.8047 47.8965c5.43262 5.42773 16.0742 9.83398 23.7539 9.83398s18.3213 -4.40625 23.7539 -9.83398l47.5088 -47.5059c5.42188 -5.43555 9.82129 -16.0771 9.82129 -23.7539
s-4.39941 -18.3184 -9.82129 -23.7529l-47.8057 -47.8975l80.3105 -80.417c5.12305 -5.13672 9.28125 -15.1934 9.28125 -22.4482c0 -7.30469 -4.20703 -17.4111 -9.39062 -22.5576zM219.562 250.567l73.8252 73.8223l-68.918 68.8994l-73.8096 -73.8066zM457.305 160.461
l-68.9023 68.916l-73.8242 -73.8232l68.918 -68.8994z" />
<glyph glyph-name="satellite-dish" unicode="&#xf7c0;"
d="M188.8 102.1l116.601 -116.6c7.39941 -7.2998 6.19922 -20.0996 -3 -25c-77.7002 -41.7998 -176.7 -29.9004 -242.301 35.7002c-65.5996 65.5996 -77.5 164.5 -35.6992 242.3c4.89941 9.09961 17.6992 10.2998 25 3l116.8 -116.8l27.3994 27.3994
c-0.699219 2.60059 -1.59961 5 -1.59961 7.80078c0 17.6992 14.2998 32 32 32s32 -14.3008 32 -32c0 -17.7002 -14.2998 -32 -32 -32c-2.7998 0 -5.2002 0.899414 -7.7998 1.59961zM209 448c163.2 -8.59961 294.4 -139.8 302.9 -303c0.5 -9.2002 -6.80078 -17 -16 -17
h-32.1006c-8.39941 0 -15.3994 6.59961 -15.8994 15c-7.5 129.5 -111.5 234.5 -240.9 241.5c-8.40039 0.400391 -15 7.40039 -15 15.9004v31.5996c0 9.2002 7.7998 16.5 17 16zM209.3 352c110.101 -8.5 198.2 -96.5996 206.601 -206.7
c0.699219 -9.2998 -6.80078 -17.2998 -16.1006 -17.2998h-32.2002c-8.2998 0 -15.0996 6.40039 -15.8994 14.7002c-6.90039 77 -68.1006 138.899 -144.9 145.2c-8.2998 0.599609 -14.7998 7.5 -14.7998 15.8994v32.1006c0 9.39941 8 16.7998 17.2998 16.0996z" />
d="M305.449 -14.5898c7.3916 -7.29785 6.18848 -20.0967 -3 -25.0039c-77.7129 -41.8027 -176.726 -29.9102 -242.344 35.708c-65.6016 65.6035 -77.5098 164.523 -35.6914 242.332c4.89062 9.09473 17.6895 10.2979 25.0029 3l116.812 -116.813l27.3945 27.3945
c-0.6875 2.60938 -1.59375 5.00098 -1.59375 7.81348c0 17.666 14.3379 32.0039 32.0039 32.0039s32.0039 -14.3379 32.0039 -32.0039s-14.3379 -32.0039 -32.0039 -32.0039c-2.79785 0 -5.2041 0.890625 -7.79785 1.59375l-27.4102 -27.4102zM511.976 144.933
c0.0136719 -0.248047 0.0253906 -0.650391 0.0253906 -0.899414c0 -8.84668 -7.18066 -16.0615 -16.0273 -16.1025h-32.1133c-8.27148 0.0244141 -15.3916 6.74512 -15.8926 15.002c-7.50098 129.519 -111.515 234.533 -240.937 241.534
c-8.28125 0.441406 -15.0029 7.5293 -15.0029 15.8223c0 0.0234375 0 0.0625 0.000976562 0.0859375v31.5986c0.0361328 8.84766 7.24609 16.0273 16.0938 16.0273c0.250977 0 0.657227 -0.0107422 0.908203 -0.0253906c163.224 -8.59473 294.443 -139.816 302.944 -303.043
zM415.964 145.229c0.0195312 -0.299805 0.0361328 -0.788086 0.0361328 -1.08887c0 -8.91309 -7.23438 -16.1758 -16.1475 -16.21h-32.208c-8.08594 0.0585938 -15.2061 6.64648 -15.8926 14.7051c-6.90625 77.0107 -68.1172 138.91 -144.924 145.224
c-8.16602 0.585938 -14.7959 7.70605 -14.7988 15.8926v32.1143v0.00390625c0 8.90625 7.22754 16.1338 16.1338 16.1338c0.322266 0 0.84375 -0.0185547 1.16504 -0.0419922c110.123 -8.50098 198.229 -96.6074 206.636 -206.732z" />
<glyph glyph-name="sd-card" unicode="&#xf7c2;" horiz-adv-x="384"
d="M320 448c35.2998 0 64 -28.7002 64 -64v-384c0 -35.2998 -28.7002 -64 -64 -64h-256c-35.2998 0 -64 28.7002 -64 64v320l128 128h192zM160 288v96h-48v-96h48zM240 288v96h-48v-96h48zM320 288v96h-48v-96h48z" />
<glyph glyph-name="sim-card" unicode="&#xf7c4;" horiz-adv-x="384"
@@ -4528,11 +4556,10 @@ d="M32 -16v336h384v-336c0 -26.4961 -21.5039 -48 -48 -48h-288c-26.4961 0 -48 21.5
c14.2598 0 21.3994 18.1797 11.3203 28.7998l-89.3809 94.2598c-2.52441 2.72949 -7.5918 4.94336 -11.3096 4.94336s-8.78516 -2.21387 -11.3096 -4.94336zM432 416c8.83203 0 16 -7.16797 16 -16v-32c0 -8.83203 -7.16797 -16 -16 -16h-416c-8.83203 0 -16 7.16797 -16 16
v32c0 8.83203 7.16797 16 16 16h120l9.40039 18.7002c3.58984 7.3418 13.1357 13.2998 21.3086 13.2998h0.0908203h114.3h0.0175781c8.20215 0 17.8262 -5.95801 21.4824 -13.2998l9.40039 -18.7002h120z" />
<glyph glyph-name="user-nurse" unicode="&#xf82f;" horiz-adv-x="448"
d="M57.7803 160c-8.82227 0.00976562 -15.9814 7.17773 -15.9814 16c0 2.09277 0.761719 5.30957 1.70117 7.17969c15.2305 29.8203 31.2803 62.2305 42.1699 95.54c7.58008 23.1904 10.3301 47.6904 10.3301 72.0801v49.2002l128 48l128 -48v-49.2002
c0 -24.3896 2.78027 -48.8896 10.3496 -72.0801c10.8701 -33.3096 26.9199 -65.6895 42.1504 -95.54c0.939453 -1.87012 1.70117 -5.08691 1.70117 -7.17969c0 -8.82227 -7.15918 -15.9902 -15.9814 -16h-82.3594c-22.5107 -19.6797 -51.6201 -32 -83.8604 -32
s-61.3496 12.3203 -83.8604 32h-82.3594zM184 376.33v-16.6602c0 -2.75977 2.24023 -5 5 -5h21.6699v-21.6699c0 -2.75977 2.24023 -5 5 -5h16.6602c2.75977 0 5 2.24023 5 5v21.6699h21.6699c2.75977 0 5 2.24023 5 5v16.6602c0 2.75977 -2.24023 5 -5 5h-21.6699v21.6699
c0 2.75977 -2.24023 5 -5 5h-16.6602c-2.75977 0 -5 -2.24023 -5 -5v-21.6699h-21.6699c-2.75977 0 -5 -2.24023 -5 -5zM144 288v-32c0 -44.1602 35.8398 -80 80 -80s80 35.8398 80 80v32h-160zM319.41 128c71.4902 -3.09961 128.59 -61.5996 128.59 -133.79
c0 -32.1318 -26.0781 -58.21 -58.21 -58.21v0h-331.58c-32.1318 0 -58.21 26.0781 -58.21 58.21c0 72.1904 57.0996 130.69 128.59 133.79l95.4102 -95.3896z" />
d="M319.41 128c71.4902 -3.09961 128.59 -61.5996 128.59 -133.79c0 -32.1318 -26.0781 -58.21 -58.21 -58.21h-331.58c-32.1318 0 -58.21 26.0781 -58.21 58.21c0 72.1904 57.0996 130.69 128.59 133.79l95.4102 -95.3896zM224 144c-70.6562 0 -128 57.3438 -128 128
v110.18c0 12.2393 9.30078 25.6611 20.7598 29.96l84.7705 31.79c5.99707 2.24902 16.0645 4.07422 22.4697 4.07422s16.4727 -1.8252 22.4697 -4.07422l84.7705 -31.75c11.459 -4.29883 20.7598 -17.7217 20.7598 -29.9609v-0.0390625v-110.18
c0 -70.6562 -57.3438 -128 -128 -128zM184 376.33v-16.6602c0 -2.75977 2.24023 -5 5 -5h21.6699v-21.6699c0 -2.75977 2.24023 -5 5 -5h16.6602c2.75977 0 5 2.24023 5 5v21.6699h21.6699c2.75977 0 5 2.24023 5 5v16.6602c0 2.75977 -2.24023 5 -5 5h-21.6699v21.6699
c0 2.75977 -2.24023 5 -5 5h-16.6602c-2.75977 0 -5 -2.24023 -5 -5v-21.6699h-21.6699c-2.75977 0 -5 -2.24023 -5 -5zM144 288v-16c0 -44.1602 35.8398 -80 80 -80s80 35.8398 80 80v16h-160z" />
<glyph glyph-name="wave-square" unicode="&#xf83e;" horiz-adv-x="640"
d="M476 -32h-152c-19.8721 0 -36 16.1279 -36 36v348h-96v-156c0 -19.8721 -16.1279 -36 -36 -36h-140c-8.83203 0 -16 7.16797 -16 16v32c0 8.83203 7.16797 16 16 16h112v156c0 19.8721 16.1279 36 36 36h152c19.8721 0 36 -16.1279 36 -36v-348h96v156
c0 19.8721 16.1279 36 36 36h140c8.83203 0 16 -7.16797 16 -16v-32c0 -8.83203 -7.16797 -16 -16 -16h-112v-156c0 -19.8721 -16.1279 -36 -36 -36z" />
@@ -4645,5 +4672,29 @@ c2.57324 2.60352 7.63379 4.71777 11.2949 4.71777s8.72168 -2.11426 11.2949 -4.717
d="M496 320c79.4883 0 144 -64.5117 144 -144s-64.5117 -144 -144 -144h-352c-79.4844 0.00390625 -143.993 64.5156 -143.993 144c0 79.4883 64.5117 144 144 144s144 -64.5117 144 -144c0 -24.1113 -10.8711 -59.9512 -24.2666 -80h112.52
c-13.3955 20.0488 -24.2666 55.8887 -24.2666 80c0 79.4883 64.5117 144 144 144h0.00683594zM64 176c0 -44.1602 35.8398 -80 80 -80s80 35.8398 80 80s-35.8398 80 -80 80s-80 -35.8398 -80 -80zM496 96c44.1602 0 80 35.8398 80 80s-35.8398 80 -80 80
s-80 -35.8398 -80 -80s35.8398 -80 80 -80z" />
<glyph glyph-name="hat-cowboy" unicode="&#xf8c0;" horiz-adv-x="640"
d="M490 151.1c-38.7695 -12.5898 -93.7305 -23.0996 -170 -23.0996s-131.19 10.5303 -169.99 23.1201c9.50977 57.4102 39.5098 232.88 97.71 232.88c14 0 26.4902 -6 37 -14c8.62988 -6.57812 24.4395 -11.917 35.29 -11.917s26.6611 5.33887 35.29 11.917
c10.5098 8.07031 23 14 37 14c58.21 0 88.21 -175.51 97.7002 -232.9zM632.9 188.28c3.90625 -2.625 7.08594 -8.57422 7.08594 -13.2803c0 -1.5752 -0.442383 -4.05273 -0.986328 -5.53027c-0.730469 -2.01953 -77.3203 -201.47 -319 -201.47s-318.27 199.45 -319 201.47
c-0.537109 1.46973 -0.973633 3.93164 -0.973633 5.49512c0 8.83203 7.16797 16 16 16c3.39844 0 8.20215 -1.84766 10.7236 -4.125c1.01953 -0.899414 102.42 -90.8398 293.24 -90.8398c191.89 0 292.16 89.8799 293.16 90.7803
c2.53418 2.3291 7.38477 4.21875 10.8262 4.21875c2.69141 0 6.68945 -1.21777 8.92383 -2.71875z" />
<glyph glyph-name="hat-cowboy-side" unicode="&#xf8c1;" horiz-adv-x="640"
d="M260.8 156.94l98.0098 -84.4805c78.1904 -67.3896 129.98 -104.46 233.19 -104.46h-546.12c-14.0498 0 -27.1299 7.53027 -35.8799 20.6396c-9 13.4707 -12.1201 30.7002 -8.57031 47.3008c20.04 93.3398 85.5703 156.06 162.971 156.06
c34.3994 0 67.7695 -12.1201 96.3994 -35.0596zM495.45 175.23c114.95 -7.90039 144.55 -101.841 144.55 -127.23c0 -26.4961 -21.5039 -48 -48 -48c-97.0996 0 -141.24 35.46 -212.31 96.7002l-98 84.4795c-35.29 28.2705 -75.5 42.8203 -117.29 42.8203
c-7.09082 0 -13.8906 -1.16992 -20.79 -2l6.88965 65.21c2.72852 25.4766 25.2852 50.4707 50.3496 55.79l191.15 40.5898c3.63574 0.773438 9.60254 1.40137 13.3193 1.40137c29.7891 0 58.0498 -23.8301 63.0811 -53.1914z" />
<glyph glyph-name="mouse" unicode="&#xf8cc;" horiz-adv-x="384"
d="M0 96v128h384v-128c0 -88.3203 -71.6797 -160 -160 -160h-64c-88.3203 0 -160 71.6797 -160 160zM176 448v-192h-176v32c0 88.3203 71.6797 160 160 160h16zM224 448c88.3203 0 160 -71.6797 160 -160v-32h-176v192h16z" />
<glyph glyph-name="record-vinyl" unicode="&#xf8d9;"
d="M256 296c57.4082 0 104 -46.5918 104 -104s-46.5918 -104 -104 -104s-104 46.5918 -104 104s46.5918 104 104 104zM256 168c13.248 0 24 10.752 24 24s-10.752 24 -24 24s-24 -10.752 -24 -24s10.752 -24 24 -24zM256 440c137 0 248 -111 248 -248s-111 -248 -248 -248
s-248 111 -248 248s111 248 248 248zM256 64c70.6562 0 128 57.3438 128 128s-57.3438 128 -128 128s-128 -57.3438 -128 -128s57.3438 -128 128 -128z" />
<glyph glyph-name="caravan" unicode="&#xf8ff;" horiz-adv-x="640"
d="M416 240c8.83203 0 16 -7.16797 16 -16s-7.16797 -16 -16 -16s-16 7.16797 -16 16s7.16797 16 16 16zM624 128c8.83203 0 16 -7.16797 16 -16v-32c0 -8.83203 -7.16797 -16 -16 -16h-336c0 -52.9922 -43.0078 -96 -96 -96s-96 43.0078 -96 96h-32
c-35.3281 0 -64 28.6719 -64 64v256c0 35.3281 28.6719 64 64 64h352c88.3203 0 160 -71.6797 160 -160v-160h48zM192 16c26.4688 0.0273438 47.9727 21.5312 48 48c0 26.4961 -21.5039 48 -48 48s-48 -21.5039 -48 -48s21.5039 -48 48 -48zM256 256v64
c0 17.6641 -14.3359 32 -32 32h-128c-17.6641 0 -32 -14.3359 -32 -32v-64c0 -17.6641 14.3359 -32 32 -32h128c17.6641 0 32 14.3359 32 32zM448 128v192c0 17.6641 -14.3359 32 -32 32h-64c-17.6641 0 -32 -14.3359 -32 -32v-192h128z" />
<glyph glyph-name="trailer" unicode="&#xf941;" horiz-adv-x="640"
d="M624 128c8.83203 0 16 -7.16797 16 -16v-32c0 -8.83203 -7.16797 -16 -16 -16h-337.61c-7.83008 54.21 -54 96 -110.39 96s-102.56 -41.79 -110.39 -96h-49.6104c-8.83203 0 -16 7.16797 -16 16v288c0 8.83203 7.16797 16 16 16h512c8.83203 0 16 -7.16797 16 -16v-240
h80zM96 204.32v107.68c0 4.41602 -3.58398 8 -8 8h-16c-4.41602 0 -8 -3.58398 -8 -8v-128.39c8.20996 6.67578 22.5469 15.9541 32 20.71zM192 222.86v89.1396c0 4.41602 -3.58398 8 -8 8h-16c-4.41602 0 -8 -3.58398 -8 -8v-89.1396
c5.30957 0.489258 10.5703 1.13965 16 1.13965s10.6904 -0.650391 16 -1.13965zM288 183.61v128.39c0 4.41602 -3.58398 8 -8 8h-16c-4.41602 0 -8 -3.58398 -8 -8v-107.68c9.45312 -4.75586 23.79 -14.0342 32 -20.71zM384 128v184c0 4.41602 -3.58398 8 -8 8h-16
c-4.41602 0 -8 -3.58398 -8 -8v-184h32zM480 128v184c0 4.41602 -3.58398 8 -8 8h-16c-4.41602 0 -8 -3.58398 -8 -8v-184h32zM176 128c44.1602 0 80 -35.8398 80 -80s-35.8398 -80 -80 -80s-80 35.8398 -80 80s35.8398 80 80 80zM176 16c17.6641 0 32 14.3359 32 32
s-14.3359 32 -32 32s-32 -14.3359 -32 -32s14.3359 -32 32 -32z" />
</font>
</defs></svg>

Before

Width:  |  Height:  |  Size: 820 KiB

After

Width:  |  Height:  |  Size: 829 KiB

Some files were not shown because too many files have changed in this diff Show More