use of java.io.UnsupportedEncodingException in project android_frameworks_base by ResurrectionRemix.
the class SRTTrack method onData.
@Override
public void onData(byte[] data, boolean eos, long runID) {
// TODO make reentrant
try {
Reader r = new InputStreamReader(new ByteArrayInputStream(data), "UTF-8");
BufferedReader br = new BufferedReader(r);
String header;
while ((header = br.readLine()) != null) {
// discard subtitle number
header = br.readLine();
if (header == null) {
break;
}
TextTrackCue cue = new TextTrackCue();
String[] startEnd = header.split("-->");
cue.mStartTimeMs = parseMs(startEnd[0]);
cue.mEndTimeMs = parseMs(startEnd[1]);
String s;
List<String> paragraph = new ArrayList<String>();
while (!((s = br.readLine()) == null || s.trim().equals(""))) {
paragraph.add(s);
}
int i = 0;
cue.mLines = new TextTrackCueSpan[paragraph.size()][];
cue.mStrings = paragraph.toArray(new String[0]);
for (String line : paragraph) {
TextTrackCueSpan[] span = new TextTrackCueSpan[] { new TextTrackCueSpan(line, -1) };
cue.mStrings[i] = line;
cue.mLines[i++] = span;
}
addCue(cue);
}
} catch (UnsupportedEncodingException e) {
Log.w(TAG, "subtitle data is not UTF-8 encoded: " + e);
} catch (IOException ioe) {
// shouldn't happen
Log.e(TAG, ioe.getMessage(), ioe);
}
}
use of java.io.UnsupportedEncodingException in project android_frameworks_base by ResurrectionRemix.
the class ObexHelper method createHeader.
/**
* Creates the header part of OBEX packet based on the header provided.
* TODO: Could use getHeaderList() to get the array of headers to include
* and then use the high two bits to determine the the type of the object
* and construct the byte array from that. This will make the size smaller.
* @param head the header used to construct the byte array
* @param nullOut <code>true</code> if the header should be set to
* <code>null</code> once it is added to the array or
* <code>false</code> if it should not be nulled out
* @return the header of an OBEX packet
*/
public static byte[] createHeader(HeaderSet head, boolean nullOut) {
Long intHeader = null;
String stringHeader = null;
Calendar dateHeader = null;
Byte byteHeader = null;
StringBuffer buffer = null;
byte[] value = null;
byte[] result = null;
byte[] lengthArray = new byte[2];
int length;
HeaderSet headImpl = null;
ByteArrayOutputStream out = new ByteArrayOutputStream();
headImpl = head;
try {
/*
* Determine if there is a connection ID to send. If there is,
* then it should be the first header in the packet.
*/
if (VDBG)
Log.v(TAG, "createHeader = " + head);
if ((headImpl.mConnectionID != null) && (headImpl.getHeader(HeaderSet.TARGET) == null)) {
if (VDBG)
Log.v(TAG, " Add Header = " + HeaderSet.CONNECTION_ID);
out.write((byte) HeaderSet.CONNECTION_ID);
out.write(headImpl.mConnectionID);
}
// Count Header
intHeader = (Long) headImpl.getHeader(HeaderSet.COUNT);
if (intHeader != null) {
if (VDBG)
Log.v(TAG, " Add Header = " + HeaderSet.COUNT);
out.write((byte) HeaderSet.COUNT);
value = ObexHelper.convertToByteArray(intHeader.longValue());
out.write(value);
if (nullOut) {
headImpl.setHeader(HeaderSet.COUNT, null);
}
}
// Name Header
stringHeader = (String) headImpl.getHeader(HeaderSet.NAME);
if (stringHeader != null) {
if (VDBG)
Log.v(TAG, " Add Header = " + HeaderSet.NAME);
out.write((byte) HeaderSet.NAME);
value = ObexHelper.convertToUnicodeByteArray(stringHeader);
length = value.length + 3;
lengthArray[0] = (byte) (0xFF & (length >> 8));
lengthArray[1] = (byte) (0xFF & length);
out.write(lengthArray);
out.write(value);
if (nullOut) {
headImpl.setHeader(HeaderSet.NAME, null);
}
} else if (headImpl.getEmptyNameHeader()) {
out.write((byte) HeaderSet.NAME);
lengthArray[0] = (byte) 0x00;
lengthArray[1] = (byte) 0x03;
out.write(lengthArray);
}
// Type Header
stringHeader = (String) headImpl.getHeader(HeaderSet.TYPE);
if (stringHeader != null) {
if (VDBG)
Log.v(TAG, " Add Header = " + HeaderSet.TYPE);
out.write((byte) HeaderSet.TYPE);
try {
value = stringHeader.getBytes("ISO8859_1");
} catch (UnsupportedEncodingException e) {
throw e;
}
length = value.length + 4;
lengthArray[0] = (byte) (255 & (length >> 8));
lengthArray[1] = (byte) (255 & length);
out.write(lengthArray);
out.write(value);
out.write(0x00);
if (nullOut) {
headImpl.setHeader(HeaderSet.TYPE, null);
}
}
// Length Header
intHeader = (Long) headImpl.getHeader(HeaderSet.LENGTH);
if (intHeader != null) {
if (VDBG)
Log.v(TAG, " Add Header = " + HeaderSet.LENGTH);
out.write((byte) HeaderSet.LENGTH);
value = ObexHelper.convertToByteArray(intHeader.longValue());
out.write(value);
if (nullOut) {
headImpl.setHeader(HeaderSet.LENGTH, null);
}
}
// Time ISO Header
dateHeader = (Calendar) headImpl.getHeader(HeaderSet.TIME_ISO_8601);
if (dateHeader != null) {
if (VDBG)
Log.v(TAG, " Add dateHeader = " + HeaderSet.TIME_ISO_8601);
/*
* The ISO Header should take the form YYYYMMDDTHHMMSSZ. The
* 'Z' will only be included if it is a UTC time.
*/
buffer = new StringBuffer();
int temp = dateHeader.get(Calendar.YEAR);
for (int i = temp; i < 1000; i = i * 10) {
buffer.append("0");
}
buffer.append(temp);
temp = dateHeader.get(Calendar.MONTH);
if (temp < 10) {
buffer.append("0");
}
buffer.append(temp);
temp = dateHeader.get(Calendar.DAY_OF_MONTH);
if (temp < 10) {
buffer.append("0");
}
buffer.append(temp);
buffer.append("T");
temp = dateHeader.get(Calendar.HOUR_OF_DAY);
if (temp < 10) {
buffer.append("0");
}
buffer.append(temp);
temp = dateHeader.get(Calendar.MINUTE);
if (temp < 10) {
buffer.append("0");
}
buffer.append(temp);
temp = dateHeader.get(Calendar.SECOND);
if (temp < 10) {
buffer.append("0");
}
buffer.append(temp);
if (dateHeader.getTimeZone().getID().equals("UTC")) {
buffer.append("Z");
}
try {
value = buffer.toString().getBytes("ISO8859_1");
} catch (UnsupportedEncodingException e) {
throw e;
}
length = value.length + 3;
lengthArray[0] = (byte) (255 & (length >> 8));
lengthArray[1] = (byte) (255 & length);
out.write(HeaderSet.TIME_ISO_8601);
out.write(lengthArray);
out.write(value);
if (nullOut) {
headImpl.setHeader(HeaderSet.TIME_ISO_8601, null);
}
}
// Time 4 Byte Header
dateHeader = (Calendar) headImpl.getHeader(HeaderSet.TIME_4_BYTE);
if (dateHeader != null) {
if (VDBG)
Log.v(TAG, " Add dateHeader = " + HeaderSet.TIME_4_BYTE);
out.write(HeaderSet.TIME_4_BYTE);
/*
* Need to call getTime() twice. The first call will return
* a java.util.Date object. The second call returns the number
* of milliseconds since January 1, 1970. We need to convert
* it to seconds since the TIME_4_BYTE expects the number of
* seconds since January 1, 1970.
*/
value = ObexHelper.convertToByteArray(dateHeader.getTime().getTime() / 1000L);
out.write(value);
if (nullOut) {
headImpl.setHeader(HeaderSet.TIME_4_BYTE, null);
}
}
// Description Header
stringHeader = (String) headImpl.getHeader(HeaderSet.DESCRIPTION);
if (stringHeader != null) {
out.write((byte) HeaderSet.DESCRIPTION);
value = ObexHelper.convertToUnicodeByteArray(stringHeader);
length = value.length + 3;
lengthArray[0] = (byte) (255 & (length >> 8));
lengthArray[1] = (byte) (255 & length);
out.write(lengthArray);
out.write(value);
if (nullOut) {
headImpl.setHeader(HeaderSet.DESCRIPTION, null);
}
}
// Target Header
value = (byte[]) headImpl.getHeader(HeaderSet.TARGET);
if (value != null) {
if (VDBG)
Log.v(TAG, " Add Header = " + HeaderSet.TARGET);
out.write((byte) HeaderSet.TARGET);
length = value.length + 3;
lengthArray[0] = (byte) (255 & (length >> 8));
lengthArray[1] = (byte) (255 & length);
out.write(lengthArray);
out.write(value);
if (nullOut) {
headImpl.setHeader(HeaderSet.TARGET, null);
}
}
// HTTP Header
value = (byte[]) headImpl.getHeader(HeaderSet.HTTP);
if (value != null) {
out.write((byte) HeaderSet.HTTP);
length = value.length + 3;
lengthArray[0] = (byte) (255 & (length >> 8));
lengthArray[1] = (byte) (255 & length);
out.write(lengthArray);
out.write(value);
if (nullOut) {
headImpl.setHeader(HeaderSet.HTTP, null);
}
}
// Who Header
value = (byte[]) headImpl.getHeader(HeaderSet.WHO);
if (value != null) {
if (VDBG)
Log.v(TAG, " Add Header = " + HeaderSet.WHO);
out.write((byte) HeaderSet.WHO);
length = value.length + 3;
lengthArray[0] = (byte) (255 & (length >> 8));
lengthArray[1] = (byte) (255 & length);
out.write(lengthArray);
out.write(value);
if (nullOut) {
headImpl.setHeader(HeaderSet.WHO, null);
}
}
// Application Parameter Header
value = (byte[]) headImpl.getHeader(HeaderSet.APPLICATION_PARAMETER);
if (value != null) {
if (VDBG)
Log.v(TAG, " Add APP PARAM Header = " + HeaderSet.APPLICATION_PARAMETER);
out.write((byte) HeaderSet.APPLICATION_PARAMETER);
length = value.length + 3;
lengthArray[0] = (byte) (255 & (length >> 8));
lengthArray[1] = (byte) (255 & length);
out.write(lengthArray);
out.write(value);
if (nullOut) {
headImpl.setHeader(HeaderSet.APPLICATION_PARAMETER, null);
}
}
// Object Class Header
value = (byte[]) headImpl.getHeader(HeaderSet.OBJECT_CLASS);
if (value != null) {
out.write((byte) HeaderSet.OBJECT_CLASS);
length = value.length + 3;
lengthArray[0] = (byte) (255 & (length >> 8));
lengthArray[1] = (byte) (255 & length);
out.write(lengthArray);
out.write(value);
if (nullOut) {
headImpl.setHeader(HeaderSet.OBJECT_CLASS, null);
}
}
// Check User Defined Headers
for (int i = 0; i < 16; i++) {
//Unicode String Header
stringHeader = (String) headImpl.getHeader(i + 0x30);
if (stringHeader != null) {
out.write((byte) i + 0x30);
value = ObexHelper.convertToUnicodeByteArray(stringHeader);
length = value.length + 3;
lengthArray[0] = (byte) (255 & (length >> 8));
lengthArray[1] = (byte) (255 & length);
out.write(lengthArray);
out.write(value);
if (VDBG)
Log.v(TAG, " Add Unicode String value = " + value);
if (nullOut) {
headImpl.setHeader(i + 0x30, null);
}
}
// Byte Sequence Header
value = (byte[]) headImpl.getHeader(i + 0x70);
if (value != null) {
out.write((byte) i + 0x70);
length = value.length + 3;
lengthArray[0] = (byte) (255 & (length >> 8));
lengthArray[1] = (byte) (255 & length);
out.write(lengthArray);
out.write(value);
if (VDBG)
Log.v(TAG, " Add ByteSeq value = " + value);
if (nullOut) {
headImpl.setHeader(i + 0x70, null);
}
}
// Byte Header
byteHeader = (Byte) headImpl.getHeader(i + 0xB0);
if (byteHeader != null) {
out.write((byte) i + 0xB0);
out.write(byteHeader.byteValue());
if (VDBG)
Log.v(TAG, " Add ByteHeader value = " + byteHeader.byteValue());
if (nullOut) {
headImpl.setHeader(i + 0xB0, null);
}
}
// Integer header
intHeader = (Long) headImpl.getHeader(i + 0xF0);
if (intHeader != null) {
out.write((byte) i + 0xF0);
out.write(ObexHelper.convertToByteArray(intHeader.longValue()));
if (VDBG)
Log.v(TAG, " Add Int value = " + intHeader.longValue());
if (nullOut) {
headImpl.setHeader(i + 0xF0, null);
}
}
}
// Add the authentication challenge header
if (headImpl.mAuthChall != null) {
out.write((byte) HeaderSet.AUTH_CHALLENGE);
length = headImpl.mAuthChall.length + 3;
lengthArray[0] = (byte) (255 & (length >> 8));
lengthArray[1] = (byte) (255 & length);
out.write(lengthArray);
out.write(headImpl.mAuthChall);
if (VDBG)
Log.v(TAG, " Add mAuthChall value = " + headImpl.mAuthChall);
if (nullOut) {
headImpl.mAuthChall = null;
}
}
// Add the authentication response header
if (headImpl.mAuthResp != null) {
out.write((byte) HeaderSet.AUTH_RESPONSE);
length = headImpl.mAuthResp.length + 3;
lengthArray[0] = (byte) (255 & (length >> 8));
lengthArray[1] = (byte) (255 & length);
out.write(lengthArray);
out.write(headImpl.mAuthResp);
if (VDBG)
Log.v(TAG, " Add mAuthChall value = " + headImpl.mAuthResp);
if (nullOut) {
headImpl.mAuthResp = null;
}
}
// TODO:
// If the SRM and SRMP header is in use, they must be send in the same OBEX packet
// But the current structure of the obex code cannot handle this, and therefore
// it makes sense to put them in the tail of the headers, since we then reduce the
// chance of enabling SRM to soon. The down side is that SRM cannot be used while
// transferring non-body headers
// Add the SRM header
byteHeader = (Byte) headImpl.getHeader(HeaderSet.SINGLE_RESPONSE_MODE);
if (byteHeader != null) {
if (VDBG)
Log.v(TAG, " Add SRM Header = " + HeaderSet.SINGLE_RESPONSE_MODE);
out.write((byte) HeaderSet.SINGLE_RESPONSE_MODE);
out.write(byteHeader.byteValue());
if (VDBG)
Log.v(TAG, " Add SRM value = " + byteHeader.byteValue());
if (nullOut) {
headImpl.setHeader(HeaderSet.SINGLE_RESPONSE_MODE, null);
}
}
// Add the SRM parameter header
byteHeader = (Byte) headImpl.getHeader(HeaderSet.SINGLE_RESPONSE_MODE_PARAMETER);
if (byteHeader != null) {
if (VDBG)
Log.v(TAG, " Add Header = " + HeaderSet.SINGLE_RESPONSE_MODE_PARAMETER);
out.write((byte) HeaderSet.SINGLE_RESPONSE_MODE_PARAMETER);
out.write(byteHeader.byteValue());
if (nullOut) {
headImpl.setHeader(HeaderSet.SINGLE_RESPONSE_MODE_PARAMETER, null);
}
}
} catch (IOException e) {
} finally {
result = out.toByteArray();
try {
out.close();
} catch (Exception ex) {
}
}
return result;
}
use of java.io.UnsupportedEncodingException in project android_frameworks_base by ResurrectionRemix.
the class ObexHelper method updateHeaderSet.
/**
* Updates the HeaderSet with the headers received in the byte array
* provided. Invalid headers are ignored.
* <P>
* The first two bits of an OBEX Header specifies the type of object that is
* being sent. The table below specifies the meaning of the high bits.
* <TABLE>
* <TR>
* <TH>Bits 8 and 7</TH>
* <TH>Value</TH>
* <TH>Description</TH>
* </TR>
* <TR>
* <TD>00</TD>
* <TD>0x00</TD>
* <TD>Null Terminated Unicode text, prefixed with 2 byte unsigned integer</TD>
* </TR>
* <TR>
* <TD>01</TD>
* <TD>0x40</TD>
* <TD>Byte Sequence, length prefixed with 2 byte unsigned integer</TD>
* </TR>
* <TR>
* <TD>10</TD>
* <TD>0x80</TD>
* <TD>1 byte quantity</TD>
* </TR>
* <TR>
* <TD>11</TD>
* <TD>0xC0</TD>
* <TD>4 byte quantity - transmitted in network byte order (high byte first</TD>
* </TR>
* </TABLE>
* This method uses the information in this table to determine the type of
* Java object to create and passes that object with the full header to
* setHeader() to update the HeaderSet object. Invalid headers will cause an
* exception to be thrown. When it is thrown, it is ignored.
* @param header the HeaderSet to update
* @param headerArray the byte array containing headers
* @return the result of the last start body or end body header provided;
* the first byte in the result will specify if a body or end of
* body is received
* @throws IOException if an invalid header was found
*/
public static byte[] updateHeaderSet(HeaderSet header, byte[] headerArray) throws IOException {
int index = 0;
int length = 0;
int headerID;
byte[] value = null;
byte[] body = null;
HeaderSet headerImpl = header;
try {
while (index < headerArray.length) {
headerID = 0xFF & headerArray[index];
if (VDBG)
Log.v(TAG, "updateHeaderSet headerID = " + headerID);
switch(headerID & (0xC0)) {
/*
* 0x00 is a unicode null terminate string with the first
* two bytes after the header identifier being the length
*/
case 0x00:
/*
* 0x40 is a byte sequence with the first
* two bytes after the header identifier being the length
*/
case 0x40:
boolean trimTail = true;
index++;
length = (headerArray[index] << 8) + headerArray[index + 1];
index += 2;
if (length <= 2) {
Log.e(TAG, "Remote sent an OBEX Connect response with " + "incorrect header length = " + length);
break;
}
length -= 3;
value = new byte[length];
System.arraycopy(headerArray, index, value, 0, length);
if (length == 0 || (length > 0 && (value[length - 1] != 0))) {
trimTail = false;
}
switch(headerID) {
case HeaderSet.TYPE:
try {
// Remove trailing null
if (trimTail == false) {
headerImpl.setHeader(headerID, new String(value, 0, value.length, "ISO8859_1"));
} else {
headerImpl.setHeader(headerID, new String(value, 0, value.length - 1, "ISO8859_1"));
}
} catch (UnsupportedEncodingException e) {
throw e;
}
break;
case HeaderSet.AUTH_CHALLENGE:
headerImpl.mAuthChall = new byte[length];
System.arraycopy(headerArray, index, headerImpl.mAuthChall, 0, length);
break;
case HeaderSet.AUTH_RESPONSE:
headerImpl.mAuthResp = new byte[length];
System.arraycopy(headerArray, index, headerImpl.mAuthResp, 0, length);
break;
case HeaderSet.BODY:
/* Fall Through */
case HeaderSet.END_OF_BODY:
body = new byte[length + 1];
body[0] = (byte) headerID;
System.arraycopy(headerArray, index, body, 1, length);
break;
case HeaderSet.TIME_ISO_8601:
try {
String dateString = new String(value, "ISO8859_1");
Calendar temp = Calendar.getInstance();
if ((dateString.length() == 16) && (dateString.charAt(15) == 'Z')) {
temp.setTimeZone(TimeZone.getTimeZone("UTC"));
}
temp.set(Calendar.YEAR, Integer.parseInt(dateString.substring(0, 4)));
temp.set(Calendar.MONTH, Integer.parseInt(dateString.substring(4, 6)));
temp.set(Calendar.DAY_OF_MONTH, Integer.parseInt(dateString.substring(6, 8)));
temp.set(Calendar.HOUR_OF_DAY, Integer.parseInt(dateString.substring(9, 11)));
temp.set(Calendar.MINUTE, Integer.parseInt(dateString.substring(11, 13)));
temp.set(Calendar.SECOND, Integer.parseInt(dateString.substring(13, 15)));
headerImpl.setHeader(HeaderSet.TIME_ISO_8601, temp);
} catch (UnsupportedEncodingException e) {
throw e;
}
break;
default:
if ((headerID & 0xC0) == 0x00) {
headerImpl.setHeader(headerID, ObexHelper.convertToUnicode(value, true));
} else {
headerImpl.setHeader(headerID, value);
}
}
index += length;
break;
/*
* 0x80 is a byte header. The only valid byte headers are
* the 16 user defined byte headers.
*/
case 0x80:
index++;
try {
headerImpl.setHeader(headerID, Byte.valueOf(headerArray[index]));
} catch (Exception e) {
// Not a valid header so ignore
}
index++;
break;
/*
* 0xC0 is a 4 byte unsigned integer header and with the
* exception of TIME_4_BYTE will be converted to a Long
* and added.
*/
case 0xC0:
index++;
value = new byte[4];
System.arraycopy(headerArray, index, value, 0, 4);
try {
if (headerID != HeaderSet.TIME_4_BYTE) {
// need to be handled differently
if (headerID == HeaderSet.CONNECTION_ID) {
headerImpl.mConnectionID = new byte[4];
System.arraycopy(value, 0, headerImpl.mConnectionID, 0, 4);
} else {
headerImpl.setHeader(headerID, Long.valueOf(convertToLong(value)));
}
} else {
Calendar temp = Calendar.getInstance();
temp.setTime(new Date(convertToLong(value) * 1000L));
headerImpl.setHeader(HeaderSet.TIME_4_BYTE, temp);
}
} catch (Exception e) {
// Not a valid header so ignore
throw new IOException("Header was not formatted properly", e);
}
index += 4;
break;
}
}
} catch (IOException e) {
throw new IOException("Header was not formatted properly", e);
}
return body;
}
use of java.io.UnsupportedEncodingException in project opennms by OpenNMS.
the class InterfaceSnmpResourceType method getDomainResources.
private List<OnmsResource> getDomainResources(ResourcePath parent, Set<String> intfNames) {
final List<OnmsResource> resources = Lists.newLinkedList();
for (String intfName : intfNames) {
OnmsResource resource = getResourceByParentPathAndInterface(parent, intfName);
try {
resource.setLink("element/nodeList.htm?listInterfaces=true&snmpParm=ifAlias&snmpParmMatchType=contains&snmpParmValue=" + URLEncoder.encode(intfName, StandardCharsets.UTF_8.name()));
} catch (UnsupportedEncodingException e) {
throw new IllegalStateException("URLEncoder.encode complained about UTF-8. " + e, e);
}
resources.add(resource);
}
return resources;
}
use of java.io.UnsupportedEncodingException in project OpenAM by OpenRock.
the class ServicesSelectViewBean method fowardToAddServiceViewBean.
private void fowardToAddServiceViewBean(EntitiesModel model, String universalId, String serviceName) {
SCUtils utils = new SCUtils(serviceName, model);
String propertiesViewBeanURL = utils.getServiceDisplayURL();
String type = (String) getPageSessionAttribute(EntityEditViewBean.ENTITY_TYPE);
String realm = (String) getPageSessionAttribute(AMAdminConstants.CURRENT_REALM);
if (realm == null) {
realm = "/";
}
// This is not needed in 7.0, but is still used by old 6.3 console.
if (serviceName.equals(AMAdminConstants.AUTH_CONFIG_SERVICE)) {
propertiesViewBeanURL = null;
}
if ((propertiesViewBeanURL != null) && (propertiesViewBeanURL.trim().length() > 0)) {
try {
String charset = getCharset(model);
propertiesViewBeanURL += "?ServiceName=" + serviceName + "&type=" + Locale.URLEncodeField(type, charset) + "&realm=" + Locale.URLEncodeField(stringToHex(realm), charset) + "&User=" + Locale.URLEncodeField(stringToHex(universalId), charset) + "&Op=" + AMAdminConstants.OPERATION_ADD;
HttpServletResponse response = getRequestContext().getResponse();
response.sendRedirect(propertiesViewBeanURL);
} catch (UnsupportedEncodingException e) {
setInlineAlertMessage(CCAlert.TYPE_ERROR, "message.error", e.getMessage());
forwardTo();
} catch (IOException e) {
setInlineAlertMessage(CCAlert.TYPE_ERROR, "message.error", e.getMessage());
forwardTo();
}
} else {
ServicesAddViewBean vb = (ServicesAddViewBean) getViewBean(ServicesAddViewBean.class);
setPageSessionAttribute(ServicesAddViewBean.SERVICE_NAME, serviceName);
passPgSessionMap(vb);
vb.forwardTo(getRequestContext());
}
}
Aggregations