Extension talk:GroupPermissionsManager

Archive 1

Association with Namespaces
I am not sure if I am going to ask the question correctly, but here I go.

I am about 3 months into using and setting up our wiki and each day we are expanding the requirements. We have been playing around with GroupPermissionManager for the past week and today we experimented with Lockdown and began to read up on HNP.

I really like this extension because of the GUI interface and how easy it is to use, but what do you use to associate the groups and permission you have assigned with namespaces? We are currently using namespaces to break up various areas of work assignments and our plan was to assign various groups (1 or more) to the namespaces to complete the work.

I have not exercised Lockdown extensively yet, but it seems to have what I might need except everything is defined in files on the server side (LocalSettings.php) and thus only I can access it and set it up.

I have not installed HNP yet, but atleast the information is held in a sub-page that someone other then me can edit.

So my real question is do you assign your groups to namespaces and if so do you have an extension you like.

--Wolcott 14:49 EST 03 July 2008


 * I will answer my own question by defining the following in LocalSettings.php
 * define ("NS_Test_OddAll", 1520);
 * $wgExtraNamespaces[NS_Test_OddAll] = "TstOddAll";
 * $wgNamespaceProtection[NS_Test_OddAll] = array('edit-tstoddall');


 * Then using Special:SortPermissions add edit-tstoddall permission and finally assign the permission to a group.
 * --Wolcott 16:42 EST 03 July 2008


 * A GUI method for doing something like this would be nice. Any plans for a future version of GPM? 192.73.45.37 13:55, 9 July 2008 (UTC)
 * Perhaps, depends on how hard it is to code or whether I get bored halfway through. -- Skiz zerz  14:41, 18 July 2008 (UTC)

Special:SortPermissions [Add Permission button]
After typing in a new permission and pressing the Add Permission button, nothing happens. --Wolcott 16:52 EST 03 July 2008
 * That was fixed in the latest version from Subversion (you might need to reload the page to see the change, though). -- Skiz zerz  22:43, 3 July 2008 (UTC)
 * Now fixed for IE as well :) -- Skiz zerz  02:01, 3 August 2008 (UTC)

SortPermission buttons
I downloaded 3.2.2 last Friday and have installed it on my office server and home computer. I have not been able to type in a new permission name 'edit-soccer', press the "Add Permission" button and have it be added to the list. Am I missing something? JavaScript is enabled.

When the "Save" button is pressed the config/SortPermission.php file is updated, but without the new permission. Wolcott 18:11, 22 July 2008 (UTC)
 * I cannot reproduce the specific issue you are having. When I add in a permission and click "Save", the permission is added to the listing in the appropriate place alphabetically on the Special:SortPermissions page and the config/SortPermissions.php file appears to be updated correctly. The only advice I can give is make sure that you click on one of the sort types after you add the permission, otherwise the data about the new permission won't be submitted when you save and as such, no new permission will be added. However, it seems that I can't assign that permission via Special:GroupPermissions... which I'm looking into right now. -- Skiz zerz  19:48, 22 July 2008 (UTC)
 * Question 1 - When the "Add Button" is pressed what code is being executed? When I press the button the screen does not flash or updated.
 * Question 2 - To make sure I have this correct (I know it is straight forward). You should type the new permission into the Add Permission text box and press the "Add Permission" button. I assume that should ass it to the above list.  Then you should select Sort Type toggle for the new permission and press save. --Wolcott 20:00, 22 July 2008 (UTC)
 * For #1, The code at /scripts/permsort.js is being executed. It should add another row to the bottom of the large list of permissions. Please note that it does not add in duplicate permissions, so if the permission you're trying to add is already in there, it won't add it again. Also, it requires javascript, so that must be enabled on your browser. I do not plan on making it work for browsers with javascript disabled, since site admins should have js on anyway. For #2, yes, that is the procedure. You may add/change/remove as many sort types and permissions as you want before pressing save. -- Skiz zerz  20:26, 22 July 2008 (UTC)
 * OK I found one thing. I would guess that you are running on Unix/Linux server.  I am running under MW 1.12 on a Windows server.  If I look at the html source for the Special:SortPermissions page it shows  .  The addScriptFile function checks if the first character of $file begins with a "/".  If so it leaves the passed in value alone, otherwise it adds {$wgStylePath}/common/ to the front and thus we end up with the above entry in the html source.  Not sure if I am missing a setting somewhere in my LocalSettings.php file but below is the code you are using to build the file path and name:

$dir = dirname(__FILE__); $pos = strpos($dir, $wgScriptPath); $inc = substr($dir, $pos); addScriptFile("$inc/scripts/permsort.js");


 * The results for me are:

echo $wgScriptPath.nl2br("\n"); /wiki echo $dir.nl2br("\n"); C:\Program Files\Apache Software Foundation\Apache2.2\htdocs\wiki\extensions\GroupPermissionsManager echo $inc.nl2br("\n"); C:\Program Files\Apache Software Foundation\Apache2.2\htdocs\wiki\extensions\GroupPermissionsManager


 * For the time being I will hard code the $file name and see what I get. I am off to ice skating and hockey camp for the boys.  Will repost in 4 hours.--Wolcott 12:18, 23 July 2008 (UTC)


 * Two ways to fix this for all operating systems might be to remove the building of $inc and pass the whole path. $wgScriptPath which is "/wiki" can not be found in "C:\Program Files\Apache Software Foundation\Apache2.2\htdocs\wiki\extensions\GroupPermissionsManager" because Windows is "\wiki" and not "/wiki".

addScriptFile($wgScriptPath."/extensions/GroupPermissionsManager/scripts/permsort.js");
 * 1) $dir = dirname(__FILE__);
 * 2) $pos = strpos($dir, $wgScriptPath);
 * 3) $inc = substr($dir, $pos);
 * 4) addScriptFile("$inc/scripts/permsort.js");


 * or just pass permsort.js and place the javascript in /wiki/skins/common directory. The addScriptFile function will append the correct path to the file.

addScriptFile("permsort.js");
 * 1) $dir = dirname(__FILE__);
 * 2) $pos = strpos($dir, $wgScriptPath);
 * 3) $inc = substr($dir, $pos);
 * 4) addScriptFile("$inc/scripts/permsort.js");


 * --Wolcott 18:39, 23 July 2008 (UTC)


 * What browser are you using? Once I fixed the pathing issue above it worked on Safari 3.1.2, Firefox 3.0.1, but did not work on Internet Explorer 7.0.7530.13.--Wolcott 19:20, 23 July 2008 (UTC)


 * Here is a URL that discusses IE 7.0 and dynamically appending a child to a table. I am not a JSCRIPT writer but I will try some stuff tonight/tomorrow.  I search for 'jscript appendChild IE 7'.
 * Example Issue - http://bytes.com/forum/thread820895.html
 * Example Solution - http://bytes.com/forum/thread799228.html


 * --Wolcott 20:35, 23 July 2008 (UTC)


 * Here is my mod to permsort.js
 * Changed function addRow table.appendChild(tr); to table.tBodies[0].appendChild(tr);
 * --Wolcott 01:13, 24 July 2008 (UTC)
 * I'll apply a fix for that in a few days... and curse at IE. -- Skiz zerz  17:28, 30 July 2008 (UTC)
 * Should be fixed now -- Skiz zerz  02:01, 3 August 2008 (UTC)

ExtendedPermissions Plugin
I am having an issue with the ExtendedPermissions plugin and a custom namespace that is protected. Either I am confused about the priority of setting permissions or the code is missing some logic. What is the reason for the ExtendedPermissions plugin? Here is my setup in the LocalSettings.php file:

define("NS_SOCCER", 5000); define("NS_SOCCER_TALK", 5001);

$wgExtraNamespaces = array(NS_SOCCER     => "Soccer",          NS_SOCCER_TALK => "Soccer_talk");

$wgContentNamespaces[] = NS_SOCCER;

$wgNamespacesWithSubpages[NS_SOCCER] = true;

$wgNamespaceProtection[NS_SOCCER] = array( 'edit-soccer' ); #Permission required to edit the namespace
 * 1) $wgGroupPermissions['sysop']['edit-soccer'] = true;       #Permission granted to users in the "sysop" group

Test Case 1 -
 * 1) Move the "ExtendedPermissions.php" file to the disabled directory (so that it is not used).
 * 2) Comment out $wgGroupPermissions so that the sysop group does not have the "edit-soccer" permission.
 * 3) Login as WikiSysop.
 * 4) Navigate to a page within the Soccer namespace
 * 5) Select the "View Source" tab (since the edit is not available).
 * 6) The source page is displayed and can't be edited or saved.

Test Case 2 -
 * 1) Leave the "ExtendedPermissions.php" file in the disabled directory (so that it is not used).
 * 2) Uncomment $wgGroupPermissions so that the sysop group has the "edit-soccer" permission.
 * 3) Login as WikiSysop.
 * 4) Navigate to a page within the Soccer namespace
 * 5) Select the "Edit" tab (since we now have the protected permission).
 * 6) The page is displayed and can be edited or saved.

Test Case 3 -
 * 1) Move the "ExtendedPermissions.php" file back into the plugins directory (so that it is used).
 * 2) Comment out $wgGroupPermissions so that the sysop group does not have the "edit-soccer" permission.
 * 3) Login as WikiSysop.
 * 4) Navigate to a page within the Soccer namespace
 * 5) Select the "View Source" tab (since the edit is not available).
 * 6) The source page is displayed and can be edited or saved. WRONG!!!

I believe that the line "} elseif( !$title->isTalkPage && $user->isAllowed('edit') ) {" in the function efGPManagerExtendedPermissionsGrant (which is the userCan hook) is not checking if the namespace is protected and has the correct edit permission.

What are your thoughts?

--Wolcott 23:00, 24 July 2008 (UTC)


 * A test for isNamespaceProtected took care of Test Case 3 above. Looks like the test needs to be performed in other parts of the ExtendedPermissions.php code, I will try to get to it this weekend.

if( $title->isTalkPage && $user->isAllowed('edittalk') ) { $result = true; return false; } elseif( !$title->isTalkPage && $user->isAllowed('edit') ) { if (!$title->isNamespaceProtected) { $result = true; return false; } }

--Wolcott 12:47, 25 July 2008 (UTC)
 * That would kind-of work, but not really. If the namespace is protected, even if the person is able to edit it, it would prevent them from doing so. I'll apply a fix for this in a few days, along with the permsort update. -- Skiz zerz  17:30, 30 July 2008 (UTC)
 * Should be fixed now. Let me know if it isn't -- Skiz zerz  02:01, 3 August 2008 (UTC)
 * Version 3.2.3 has an error with the namespace protection. There were a few other bugs I noticed (such as the versionCheck function being incorrect and the CustomToolbox plugin not working at all), so I'm bugfixing those as well before I release 3.2.4. -- Skiz zerz  22:33, 8 August 2008 (UTC)
 * 3.2.4 is out and fixes this bug properly as well as a few others. -- Skiz zerz  23:32, 12 August 2008 (UTC)

Adding extra permissions - Semantic Form's 'edit with form' tab
Hello. I'm want to use version 3.2.2 of GroupPermissionsManager along with the Semantic Forms extension. Semantic Forms has an extra tab called "edit with form". When I enable GroupPermissionsManager, this tab disappears (not very surprising!). How can I add 'edit with forms' to the list of permissions to allow control? I realise it will be a code change. Thanks! --Mitchelln 15:18, 25 July 2008 (UTC).
 * I just found the same thing this morning. I am currently looking at the CustomTabs.php plugin to understand the code logic. --Wolcott 14:54, 25 July 2008 (UTC)
 * You can disable both plugins by moving the files (CustomTabs.php, ExtenededPermissions.php) to the disabled directory. You will loose some lower fidelity permissions (thus the edit permission controls createPage, viewSource) I think, but the basics will still work until the code can be enhanced.--Wolcott 22:38, 25 July 2008 (UTC)
 * Thanks for the fast response. I can do without the fine permissions for now. The basics seem to work fine :-) --Mitchelln 14:19, 28 July 2008 (UTC).
 * I know why that's happening, should be a minor fix. There's nothing wrong with the ExtendedPermissions plugin regarding this, just that CustomTabs wasn't re-running the hook that Semantic Forms used. -- Skiz zerz  17:34, 30 July 2008 (UTC)
 * Thanks for the response. I will be at a conference early next week but will run the above fixes through our site and let you know the results.  Great extension.--Wolcott 21:47, 30 July 2008 (UTC)
 * This also has been fixed -- Skiz zerz  02:01, 3 August 2008 (UTC)

Syntax error in 1.3
just installed this extension Not sure which setting is causing the problem, but i am now getting Line:2 Char:1 Syntax error Code:0 on all pages, and all the javascript stuff is no longer working, i did add $wgAllowUserJs = true; in my locaksettings.php, and all errors goes away if i delete GroupPermissions.php. Whats wrong with it? --Zzzztz 19:43, 15 August 2008 (UTC)
 * Please provide more information, such as what version of MediaWiki you are using, what version of the extension you installed, and which file is giving that error. -- Skiz zerz  21:54, 15 August 2008 (UTC)
 * Nvm, found the problem just had to set "raw" to true, and it disappeared. --Zzzztz 23:14, 15 August 2008 (UTC)

Remove Unused Groups leads to site homepage.
Whenever an admin clicks on the Remove Unused Groups special page, they get brought back to the site's homepage (www.site.com). I quickly looked at the code, but I didn't see anything that would be causing this behavior, but I could have missed something. If it matters, the wiki is installed in site.com/wiki. Thanks. 192.73.45.37 11:58, 29 August 2008 (UTC)
 * Works for me. Please provide additional info, such as:
 * Version of MediaWiki
 * Version of GroupPermissionsManager
 * What your $wgScriptPath and $wgArticlePath are set to in LocalSettings.php
 * What other extensions you have installed
 * What hacks (if any) were made to the core MediaWiki files
 * -- Skiz zerz  13:02, 29 August 2008 (UTC)


 * Here is the data:
 * 1.13.0
 * Version 3.2.4
 * $wgScriptPath = "/wiki"; and I could not find $wgArticlePath in LocalSettings.php
 * ContactPage r37418, Contributors 1.0.1beta, SpecialInterwiki r37451, Cite r37577, Pdf Book 0.0.12, Simple Calendar 1.2.4, Custom Tabs 1.1, Custom Toolbox 1.1, Extended Permissions 1.2, Newuserlog r36653
 * No hacks to core MW files
 * ThomasOwens 13:31, 29 August 2008 (UTC)
 * This has been resolved on IRC. There was no issue with the extension itself, but rather a separate script that this person had running was preventing access to the special page. -- Skiz zerz  21:30, 30 August 2008 (UTC)

Permission to see article diffs and old versions
If you disable the history for any reasons you probably want to disable the diff view and old versions too (Which are still possible to see by using the URL you get from the watch-mail for example).

You may add this to the efGPManagerExtendedPermissionsRevoke function:

if( ($wgRequest->getVal('diff', null) != null) && !$user->isAllowed('history') ) { $result = $err; return false; } if( ($wgRequest->getVal('oldid', null) != null) && !$user->isAllowed('history') ) { $result = $err; return false; }

I am not sure if it's the best solution, but it works for me. Regards --Benjamin Garn 09:03, 2 September 2008 (UTC)
 * Good point, I'll add it in later, maybe not quite that way though (might be a separate permission, for example). -- Skiz zerz  21:49, 2 September 2008 (UTC)
 * ✅ -- Skiz zerz  20:37, 25 September 2008 (UTC)

Internal Error - Aliases file does not exist
When I install this extension I get an internal error saying "Aliases file does not exist". I've triple checked the installation instructions and can't find anything wrong... My version information is:


 * MediaWiki 1.13.1
 * PHP 	5.2.6 (cgi-fcgi)
 * MySQL 4.1.25-Debian_mt1

I have the ParserFunctions (extended), StringFunctions (Version 2.0.1), and VideoFlash extensions currently installed. Any ideas?
 * Bah, my bad. It was a typo that was trying to call the wrong file. Get the latest package from subversion and it should work. -- Skiz zerz  02:39, 14 September 2008 (UTC)
 * I just picked up the latest version (r41102), and am having the same problem.
 * My version info:
 * MediaWiki 	1.13.0
 * PHP 	5.2.0-8+etch11 (apache2handler)
 * MySQL 	5.0.32-Debian_7etch6-log
 * -- Jprice 17:06, 25 September 2008 (UTC)
 * Should be fixed now. -- Skiz zerz  20:36, 25 September 2008 (UTC)

Syntax-error, when using the Extension
When I put the extions into the Localsettings and make a refresh, I get an syntax error concerning the css on everey page.

I' m running a Mediawiki 1.13, with php 5.2

--Fightgnome 11:50, 30 September 2008 (UTC)
 * Stating what the error is would be helpful. Also, I did some bugfixes recently, so you may want to update the extension to see if it got fixed. -- Skiz zerz  03:26, 2 October 2008 (UTC)

The Syntax error only apears when an anonym user is trying to klick anything. For Example to see an article. The errors look like this when I open the wiki in the Fire Fox

Fehler: syntax error Quelldatei: http://link_to_wiki/index.php?title=-&action=raw&gen=js&useskin=monobook Zeile: 1 Quelltext: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

Fehler: Stylesheet http://link_to_wiki/index.php?title=MediaWiki:Common.css&usemsgcache=yes&action=raw&ctype=text/css&smaxage=18000 wurde nicht geladen, weil sein MIME-Typ, "text/html", nicht "text/css" ist. Quelldatei: http://link_to_wiki/index.php/Kategorie:Something. Zeile: 0

This means that a stylesheet could not be loaded because a Mime-Type is text/html and not text/css as it should be.

--Fightgnome 09:29, 9 October 2008 (UTC)
 * Make sure that the 'raw' right is set to true for a group that you belong in (and that it is not set to never for a group that you belong in). -- Skiz zerz  20:48, 9 October 2008 (UTC)
 * Actually, I think I'm going to make this a special case in the checking for action=raw, so that css/js pages aren't prevented from being shown. -- Skiz zerz  21:13, 9 October 2008 (UTC)

Editing talk pages only
I want my logged-in users (users) to be able to edit talk pages, but not main pages, and people in the group "editors" to be able to edit main named space pages, but not talk pages. I tried to do this with GroupPermissionsManager, without success. Some quirks I found: Any help would be much appreciated. --84.9.191.165 16:14, 12 November 2008 (UTC)
 * Is the "*" group the same as the "anonymous" group? The "*" group can be deleted, but not the "anonymous" group.
 * In Special:"Manage group permissions", on selecting the "*" Group and the "editing" tab, when I change "Edit pages (which are not discussion pages) (edit)" to False, it always changes back to True.
 * I thought my original query would have something to do with the "edittalk" permission, supported by Extended Permissions (showing in Special:Version). But I can not find "edittalk" in order to change it.
 * What version of GPM are you using? Are you setting any permissions after you have the require_once for GPM? As for getting those permissions to show up, you need to delete the file at /extensions/GroupPermissionsManager/GroupPermissions.php. After you delete that, all the new permissions should show up. You can also visit Special:SortPermissions and add the new permission there. And to answer your question, "*" is the default group for all users (anonymous and logged in). -- Skiz zerz  01:22, 13 November 2008 (UTC)
 * Version 3.2.6. Thanks, I'll have a look at your suggestions shortly. --84.9.191.165 20:35, 13 November 2008 (UTC)
 * You mentioned whether I am "setting any permissions after you have the require_once for GPM?" I have some basic $wgGroupPermissions set before the "require_once", eg.
 * Should I remove all of these and let the GroupPermissionsManager take care of them? Thanks again. --84.9.191.165 11:52, 14 November 2008 (UTC)
 * GPM simply overrides everything that you set before it. You don't have to remove them, but they don't do anything. You need to change it through the web UI (yeah, I know, it's kinda broken/sucky that way. Once I move the backend to the database it'll be a lot better). -- Skiz zerz  21:54, 14 November 2008 (UTC)
 * GPM simply overrides everything that you set before it. You don't have to remove them, but they don't do anything. You need to change it through the web UI (yeah, I know, it's kinda broken/sucky that way. Once I move the backend to the database it'll be a lot better). -- Skiz zerz  21:54, 14 November 2008 (UTC)

Common.js
I have created some custom edit buttons in the Editor with "MediaWiki:Common.js". However, when GroupPermissionsManager is installed, Common.js appears to be disabled, and my custom buttons disappear. As a Sysop, in "Manage group permissions", I've enabled everything, but they remain disabled. Should I enabled something for * or user, and if so, any idea what? --84.9.191.165 20:35, 13 November 2008 (UTC)
 * The "raw" right has to be true for the '*' group, and cannot be "never" for any group. -- Skiz zerz  23:02, 13 November 2008 (UTC)
 * You're a genius, I'd never have guessed that. Interestingly, the "raw" option and several others, were not appearing in the GroupPermissionsManager, and I had to view the Sort Permissions, and save them first. Likewise the Edittalk right. I suspect this is related to your comments above.
 * Additionally, with the "raw" permission not set to true for "*", I found that Firefox v3 was generating a Syntax Error in the Error Console for the line:
 * It actually had nothing to do with this line, but was caused by a line of javascript in the header:
 * I can see this is related to "raw" too.
 * I wonder whether the "Manage group permissions" online documentation could mention the relationship of "raw" to the execution of Javascript, and/or indicate the importance of keeping the "raw" rights enabled for all users? --84.9.191.165 11:47, 14 November 2008 (UTC)
 * GPM is broken in this regard, but I hope that that will be fixed once I update the backend to use the db instead (version 4.0.0). Hopefully I'll have that released next month or so. -- Skiz zerz  21:55, 14 November 2008 (UTC)
 * I wonder whether the "Manage group permissions" online documentation could mention the relationship of "raw" to the execution of Javascript, and/or indicate the importance of keeping the "raw" rights enabled for all users? --84.9.191.165 11:47, 14 November 2008 (UTC)
 * GPM is broken in this regard, but I hope that that will be fixed once I update the backend to use the db instead (version 4.0.0). Hopefully I'll have that released next month or so. -- Skiz zerz  21:55, 14 November 2008 (UTC)

Reading rights options disappear when set to False for "*"?
It seems that when I set a permission for "*" in the Reading category to false and save the changes, the entire line disappears from the editing interface for not only the "*" group but for all other groups as well. In other words, I can't go back and re-enable that right for either "*" or any other group thru the Manage group permissions GUI. Is this a known issue? (It may not be limited to the scope I described, but I think this is the only situation where I've seen it happen so far.) iprefermuffins 22:10, 5 December 2008 (UTC)
 * Yeah, this is a glitch due to the way the rights are set in the config file. This problem will disappear when the backend is changed to use the database. In the meantime you can add the rights back via Special:SortPermissions. -- Skiz zerz  22:53, 5 December 2008 (UTC)

Storing in DB instead of config file?
This looks like a fantastic extension! One misgiving I would have about using it in production is the use of a config file in a hardcoded location rather than using the database to store the permissions. It really becomes a problem if you have multiple front ends pointed at a single DB. Is this something you've thought about addressing, and if so, what are the obstacles? If the answer is "someone just needs to write the code", what recommendations would you have for someone who wanted to write this and have you accept their patch? Realistically, I doubt I'd personally get to this anytime soon, but I'd still like to know what your interest is in receiving a patch for that functionality, and to get some guidance to avoid writing the patch the wrong way. -- RobLa 21:45, 19 December 2008 (UTC)
 * Yes, I plan on eventually moving the config from the filesystem to the db, and yes, the main reason it hasn't been done yet is because the code has yet to be written :). It's going to encompass a fairly large rewrite, so I'm not quite sure if I want to have others working on the code. -- Skiz zerz  23:11, 19 December 2008 (UTC)

About "Editing" right of * group
As someone mentioned above: In Special:"Manage group permissions", on selecting the "*" Group and the "editing" tab, when I change "Edit pages (which are not discussion pages) (edit)" to False, it always changes back to True.

I have the same problem. And furthermore, when I log in, the Special:ListGroupRights says * group has the "Edit page" right. However, the page shows that * group dose not has edit page right when I log out. I checked the file GroupPermission.php and the edit right of * group is "false" there.
 * GPM version: 3.2.6
 * Mediawiki: 1.13.3
 * Extended Permissions: 1.3
 * and also with plugin: CustomTabs, CustomToolbox

--Alpha3 13:28, 13 February 2009 (UTC)
 * Um, I have no idea why that's happening. Do you have any permissions set after the require_once for GroupPermissionsManager? -- Skiz zerz  22:58, 13 February 2009 (UTC)
 * Well, I have checked the probability you mentioned. But, the  is at the last line of my Localsettings.php. And there is no line in the files of my website says that this right is "true", apart from the ExtendedPermissions.php.

--Alpha3 14:40, 19 February 2009 (UTC)